]> git.lyx.org Git - lyx.git/blob - src/frontends/Toolbars.C
2f68e7d1f7035d2cdba65229619309718d35b80a
[lyx.git] / src / frontends / Toolbars.C
1 /**
2  * \file Toolbars.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Angus Leeming
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "Toolbars.h"
15
16 #include "buffer.h"
17 #include "bufferparams.h"
18 #include "debug.h"
19 #include "funcrequest.h"
20 #include "FuncStatus.h"
21 #include "gettext.h"
22 #include "lyxfunc.h"
23 #include "lyxtextclass.h"
24 #include "LyXView.h"
25 #include "lyx_main.h"
26
27
28 namespace lyx {
29
30 using std::endl;
31 using std::string;
32
33
34 Toolbars::Toolbars(LyXView & owner)
35         : owner_(owner),
36           layout_(0),
37           last_textclass_(-1)
38 {}
39
40 #define TurnOnFlag(x)   flags |= ToolbarBackend::x
41 #define TurnOffFlag(x)  flags &= ~ToolbarBackend::x
42
43 void Toolbars::initFlags(ToolbarBackend::Toolbar & tbb)
44 {
45         ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbb.name);
46
47         unsigned int flags = static_cast<unsigned int>(tbb.flags);
48         // remove position
49         TurnOffFlag(TOP);
50         TurnOffFlag(BOTTOM);
51         TurnOffFlag(RIGHT);
52         TurnOffFlag(LEFT);
53
54         bool valid_location = true;
55         // init tbb.flags with saved location
56         if (info.location == ToolbarSection::ToolbarInfo::TOP)
57                 TurnOnFlag(TOP);
58         else if (info.location == ToolbarSection::ToolbarInfo::BOTTOM)
59                 TurnOnFlag(BOTTOM);
60         else if (info.location == ToolbarSection::ToolbarInfo::RIGHT)
61                 TurnOnFlag(RIGHT);
62         else if (info.location == ToolbarSection::ToolbarInfo::LEFT)
63                 TurnOnFlag(LEFT);
64         else {
65                 TurnOnFlag(TOP);
66                 valid_location = false;
67         }
68
69         // invalid location is for a new toolbar that has no saved information,
70         // so info.visible is not used for this case.
71         if (valid_location) {
72                 // init tbb.flags with saved visibility,
73                 TurnOffFlag(ON);
74                 TurnOffFlag(OFF);
75                 TurnOffFlag(AUTO);
76                 if (info.state == ToolbarSection::ToolbarInfo::ON)
77                         TurnOnFlag(ON);
78                 else if (info.state == ToolbarSection::ToolbarInfo::OFF)
79                         TurnOnFlag(OFF);
80                 else
81                         TurnOnFlag(AUTO);
82         }
83         /*
84         std::cout << "State " << info.state << " FLAGS: " << flags
85                 << " ON:" << (flags & ToolbarBackend::ON) 
86                 << " OFF:" << (flags & ToolbarBackend::OFF)
87                 << " L:" << (flags & ToolbarBackend::LEFT) 
88                 << " R:" << (flags & ToolbarBackend::RIGHT) 
89                 << " T:" << (flags & ToolbarBackend::TOP) 
90                 << " B:" << (flags & ToolbarBackend::BOTTOM) 
91                 << " MA:" << (flags & ToolbarBackend::MATH) 
92                 << " RE:" << (flags & ToolbarBackend::REVIEW) 
93                 << " TB:" << (flags & ToolbarBackend::TABLE) 
94                 << " AU:" << (flags & ToolbarBackend::AUTO) 
95                 << std::endl;
96         */
97         // now set the flags
98         tbb.flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
99 }
100
101
102 void Toolbars::init()
103 {
104         // extracts the toolbars from the backend
105         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
106         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
107
108         for (; cit != end; ++cit) {
109                 initFlags(*cit);
110                 add(*cit);
111         }
112 }
113
114
115 void Toolbars::display(string const & name, bool show)
116 {
117         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
118         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
119
120         for (; cit != end; ++cit) {
121                 if (cit->name == name) {
122                         displayToolbar(*cit, show);
123                         return;
124                 }
125         }
126
127         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
128                 << name << endl;
129 }
130
131
132 ToolbarBackend::Flags Toolbars::getToolbarState(string const & name)
133 {       
134         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
135         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
136
137         for (; cit != end; ++cit) {
138                 if (cit->name == name)
139                         return cit->flags;
140         }
141
142         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
143                 << name << endl;
144 }
145
146
147 void Toolbars::toggleToolbarState(string const & name)
148 {
149         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
150         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
151
152         for (; cit != end; ++cit) {
153                 if (cit->name == name) {
154                         int flags = cit->flags;
155                         if (flags & ToolbarBackend::ON) {
156                                 TurnOffFlag(ON);
157                                 TurnOnFlag(OFF);
158                         } else if (flags & ToolbarBackend::AUTO) {
159                                 TurnOffFlag(AUTO);
160                                 TurnOnFlag(ON);
161                         } else if ((flags & ToolbarBackend::MATH) || (flags & ToolbarBackend::TABLE)
162                                 || (flags & ToolbarBackend::REVIEW)) {
163                                 // for math etc, toggle from off -> auto
164                                 TurnOffFlag(OFF);
165                                 TurnOnFlag(AUTO);
166                         } else {
167                                 // for others, toggle from off -> on
168                                 TurnOffFlag(OFF);
169                                 TurnOnFlag(ON);
170                         }
171                         cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
172                         return;
173                 }
174         }
175         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
176                 << name << endl;
177 }
178 #undef TurnOnFlag
179 #undef TurnOffFlag
180
181
182 void Toolbars::update(bool in_math, bool in_table, bool review)
183 {
184         update();
185
186         // extracts the toolbars from the backend
187         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
188         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
189
190         for (; cit != end; ++cit) {
191                 if (cit->flags & ToolbarBackend::ON)
192                         displayToolbar(*cit, true);
193                 else if (cit->flags & ToolbarBackend::OFF)
194                         displayToolbar(*cit, false);
195                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::MATH))
196                         displayToolbar(*cit, in_math);
197                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::TABLE))
198                         displayToolbar(*cit, in_table);
199                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::REVIEW))
200                         displayToolbar(*cit, review);
201         }
202 }
203
204
205 void Toolbars::saveToolbarInfo()
206 {
207         ToolbarSection & tb = LyX::ref().session().toolbars();
208
209         for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
210                 cit != toolbarbackend.end(); ++cit) {
211                 ToolbarsMap::iterator it = toolbars_.find(cit->name);
212                 BOOST_ASSERT(it != toolbars_.end());
213                 // get toolbar info from session.
214                 ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
215                 if (cit->flags & ToolbarBackend::ON)
216                         info.state = ToolbarSection::ToolbarInfo::ON;
217                 else if (cit->flags & ToolbarBackend::OFF)
218                         info.state = ToolbarSection::ToolbarInfo::OFF;
219                 else if (cit->flags & ToolbarBackend::AUTO)
220                         info.state = ToolbarSection::ToolbarInfo::AUTO;
221                 // save other information
222                 // if auto, frontend should *not* set on/off
223                 it->second->saveInfo(info);
224                 // maybe it is useful to update flags with real status. I do not know
225                 /*
226                 if (!(cit->flags & ToolbarBackend::AUTO)) {
227                         unsigned int flags = static_cast<unsigned int>(cit->flags);
228                         flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::OFF : ToolbarBackend::ON);
229                         flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::ON : ToolbarBackend::OFF);
230                         if (info.state == ToolbarSection::ToolbarInfo::ON)
231                         cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
232                 }
233                 */
234         }
235 }
236
237
238 void Toolbars::setLayout(string const & layout)
239 {
240         if (layout_)
241                 layout_->set(layout);
242 }
243
244
245 bool Toolbars::updateLayoutList(int textclass)
246 {
247         // update the layout display
248         if (last_textclass_ != textclass) {
249                 if (layout_)
250                         layout_->update();
251                 last_textclass_ = textclass;
252                 return true;
253         } else
254                 return false;
255 }
256
257
258 void Toolbars::openLayoutList()
259 {
260         if (layout_)
261                 layout_->open();
262 }
263
264
265 void Toolbars::clearLayoutList()
266 {
267         last_textclass_ = -1;
268         if (layout_)
269                 layout_->clear();
270 }
271
272
273 void Toolbars::add(ToolbarBackend::Toolbar const & tbb)
274 {
275         ToolbarPtr tb_ptr = owner_.makeToolbar(tbb);
276         toolbars_[tbb.name] = tb_ptr;
277
278         if (tbb.flags & ToolbarBackend::ON)
279                 tb_ptr->show(false);
280         else
281                 tb_ptr->hide(false);
282
283         if (tb_ptr->layout())
284                 layout_ = tb_ptr->layout();
285 }
286
287
288 void Toolbars::displayToolbar(ToolbarBackend::Toolbar const & tbb,
289                               bool show_it)
290 {
291         ToolbarsMap::iterator it = toolbars_.find(tbb.name);
292         BOOST_ASSERT(it != toolbars_.end());
293
294         if (show_it)
295                 it->second->show(true);
296         else
297                 it->second->hide(true);
298 }
299
300
301 void Toolbars::update()
302 {
303         ToolbarsMap::const_iterator it = toolbars_.begin();
304         ToolbarsMap::const_iterator const end = toolbars_.end();
305         for (; it != end; ++it)
306                 it->second->update();
307
308         bool const enable =
309                 lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
310
311         if (layout_)
312                 layout_->setEnabled(enable);
313 }
314
315
316 void layoutSelected(LyXView & lv, string const & name)
317 {
318         LyXTextClass const & tc = lv.buffer()->params().getLyXTextClass();
319
320         LyXTextClass::const_iterator it  = tc.begin();
321         LyXTextClass::const_iterator const end = tc.end();
322         for (; it != end; ++it) {
323                 string const & itname = (*it)->name();
324                 // Yes, the lyx::to_utf8(_()) is correct
325                 if (lyx::to_utf8(_(itname)) == name) {
326                         FuncRequest const func(LFUN_LAYOUT, itname,
327                                                FuncRequest::UI);
328                         lv.dispatch(func);
329                         return;
330                 }
331         }
332         lyxerr << "ERROR (layoutSelected): layout not found!"
333                << endl;
334 }
335
336
337 } // namespace lyx