]> git.lyx.org Git - lyx.git/blob - src/frontends/Toolbars.cpp
* src/frontends/qt4/Dialogs.cpp:
[lyx.git] / src / frontends / Toolbars.cpp
1 /**
2  * \file Toolbars.cpp
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 "TextClass.h"
24 #include "LyXView.h"
25 #include "LyX.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 |= ToolbarInfo::x
41 #define TurnOffFlag(x)  flags &= ~ToolbarInfo::x
42
43 void Toolbars::initFlags(ToolbarInfo & tbinfo)
44 {
45         ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbinfo.name);
46
47         unsigned int flags = static_cast<unsigned int>(tbinfo.flags);
48
49         // Remove default.ui positions. Only when a valid postion is stored
50         // in the session file the default.ui value will be overwritten
51         unsigned int save = flags;
52         TurnOffFlag(TOP);
53         TurnOffFlag(BOTTOM);
54         TurnOffFlag(RIGHT);
55         TurnOffFlag(LEFT);
56
57         bool valid_location = true;
58         // init tbinfo.flags with saved location
59         if (info.location == ToolbarSection::ToolbarInfo::TOP)
60                 TurnOnFlag(TOP);
61         else if (info.location == ToolbarSection::ToolbarInfo::BOTTOM)
62                 TurnOnFlag(BOTTOM);
63         else if (info.location == ToolbarSection::ToolbarInfo::RIGHT)
64                 TurnOnFlag(RIGHT);
65         else if (info.location == ToolbarSection::ToolbarInfo::LEFT)
66                 TurnOnFlag(LEFT);
67         else {
68                 // use setting from default.ui
69                 flags = save;
70                 valid_location = false;
71         }
72
73         // invalid location is for a new toolbar that has no saved information,
74         // so info.visible is not used for this case.
75         if (valid_location) {
76                 // init tbinfo.flags with saved visibility,
77                 TurnOffFlag(ON);
78                 TurnOffFlag(OFF);
79                 TurnOffFlag(AUTO);
80                 if (info.state == ToolbarSection::ToolbarInfo::ON)
81                         TurnOnFlag(ON);
82                 else if (info.state == ToolbarSection::ToolbarInfo::OFF)
83                         TurnOnFlag(OFF);
84                 else
85                         TurnOnFlag(AUTO);
86         }
87         /*
88         std::cout << "State " << info.state << " FLAGS: " << flags
89                 << " ON:" << (flags & ToolbarBackend::ON)
90                 << " OFF:" << (flags & ToolbarBackend::OFF)
91                 << " L:" << (flags & ToolbarBackend::LEFT)
92                 << " R:" << (flags & ToolbarBackend::RIGHT)
93                 << " T:" << (flags & ToolbarBackend::TOP)
94                 << " B:" << (flags & ToolbarBackend::BOTTOM)
95                 << " MA:" << (flags & ToolbarBackend::MATH)
96                 << " RE:" << (flags & ToolbarBackend::REVIEW)
97                 << " TB:" << (flags & ToolbarBackend::TABLE)
98                 << " AU:" << (flags & ToolbarBackend::AUTO)
99                 << std::endl;
100         */
101         // now set the flags
102         tbinfo.flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
103 }
104
105
106 void Toolbars::init()
107 {
108         // extracts the toolbars from the backend
109         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
110         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
111
112         // init flags will also add these toolbars to session if they
113         // are not already there (e.g. first run of lyx).
114         for (; cit != end; ++cit)
115                 initFlags(*cit);
116
117         // add toolbars according the order in session
118         ToolbarSection::ToolbarList::const_iterator tb = LyX::ref().session().toolbars().begin();
119         ToolbarSection::ToolbarList::const_iterator te = LyX::ref().session().toolbars().end();
120         ToolbarSection::ToolbarInfo::Location last_loc = ToolbarSection::ToolbarInfo::NOTSET;
121         int last_posx = 0;
122         int last_posy = 0;
123         for (; tb != te; ++tb) {
124                 LYXERR(Debug::INIT) << "Adding " << tb->get<0>() << " at position " << tb->get<1>().posx << " " << tb->get<1>().posy << endl;
125                 // add toolbar break if posx or posy changes
126                 bool newline = tb->get<1>().location == last_loc && (
127                         // if two toolbars at the same location, assume uninitialized and add toolbar break
128                         (tb->get<1>().posx == last_posx && tb->get<1>().posy == last_posy) ||
129                         (last_loc == ToolbarSection::ToolbarInfo::TOP && tb->get<1>().posy != last_posy) ||
130                         (last_loc == ToolbarSection::ToolbarInfo::BOTTOM && tb->get<1>().posy != last_posy) ||
131                         (last_loc == ToolbarSection::ToolbarInfo::LEFT && tb->get<1>().posx != last_posx) ||
132                         (last_loc == ToolbarSection::ToolbarInfo::RIGHT && tb->get<1>().posx != last_posx) );
133                 // find the backend item and add
134                 for (cit = toolbarbackend.begin(); cit != end; ++cit)
135                         if (cit->name == tb->get<0>()) {
136                                 add(*cit, newline);
137                                 last_loc = tb->get<1>().location;
138                                 last_posx = tb->get<1>().posx;
139                                 last_posy = tb->get<1>().posy;
140                                 break;
141                         }
142         }
143 }
144
145
146 void Toolbars::display(string const & name, bool show)
147 {
148         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
149         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
150
151         for (; cit != end; ++cit) {
152                 if (cit->name == name) {
153                         unsigned int flags = cit->flags;
154                         TurnOffFlag(ON);
155                         TurnOffFlag(OFF);
156                         TurnOffFlag(AUTO);
157                         if (show)
158                                 TurnOnFlag(ON);
159                         else
160                                 TurnOnFlag(OFF);
161                         cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
162                         displayToolbar(*cit, show);
163                         return;
164                 }
165         }
166
167         LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
168                 << name << endl;
169 }
170
171
172 ToolbarInfo::Flags Toolbars::getToolbarState(string const & name)
173 {
174         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
175         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
176
177         for (; cit != end; ++cit) {
178                 if (cit->name == name)
179                         return cit->flags;
180         }
181
182         LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
183                 << name << endl;
184
185         // return dummy for msvc
186         return ToolbarInfo::OFF;
187 }
188
189
190 void Toolbars::toggleToolbarState(string const & name)
191 {
192         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
193         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
194
195         for (; cit != end; ++cit) {
196                 if (cit->name == name) {
197                         int flags = cit->flags;
198                         // off -> on
199                         if (flags & ToolbarInfo::OFF) {
200                                 TurnOffFlag(OFF);
201                                 TurnOnFlag(ON);
202                         // auto -> off
203                         } else if (flags & ToolbarInfo::AUTO) {
204                                 TurnOffFlag(AUTO);
205                                 TurnOnFlag(OFF);
206                         } else if ((flags & ToolbarInfo::MATH) || (flags & ToolbarInfo::TABLE)
207                                 || (flags & ToolbarInfo::REVIEW)) {
208                                 // for math etc, toggle from on -> auto
209                                 TurnOffFlag(ON);
210                                 TurnOnFlag(AUTO);
211                         } else {
212                                 // for others, toggle from on -> off
213                                 TurnOffFlag(ON);
214                                 TurnOnFlag(OFF);
215                         }
216                         cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
217                         return;
218                 }
219         }
220         LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
221                 << name << endl;
222 }
223 #undef TurnOnFlag
224 #undef TurnOffFlag
225
226
227 void Toolbars::update(bool in_math, bool in_table, bool review)
228 {
229         update();
230
231         // extracts the toolbars from the backend
232         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
233         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
234
235         for (; cit != end; ++cit) {
236                 if (cit->flags & ToolbarInfo::ON)
237                         displayToolbar(*cit, true);
238                 else if (cit->flags & ToolbarInfo::OFF)
239                         displayToolbar(*cit, false);
240                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::MATH))
241                         displayToolbar(*cit, in_math);
242                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::TABLE))
243                         displayToolbar(*cit, in_table);
244                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::REVIEW))
245                         displayToolbar(*cit, review);
246         }
247 }
248
249
250 bool Toolbars::visible(string const & name) const
251 {
252         std::map<string, ToolbarPtr>::const_iterator it =
253                 toolbars_.find(name);
254         if (it == toolbars_.end())
255                 return false;
256         return it->second.get()->isVisible();
257 }
258
259
260 void Toolbars::saveToolbarInfo()
261 {
262         ToolbarSection & tb = LyX::ref().session().toolbars();
263
264         for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
265                 cit != toolbarbackend.end(); ++cit) {
266                 ToolbarsMap::iterator it = toolbars_.find(cit->name);
267                 BOOST_ASSERT(it != toolbars_.end());
268                 // get toolbar info from session.
269                 ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
270                 if (cit->flags & ToolbarInfo::ON)
271                         info.state = ToolbarSection::ToolbarInfo::ON;
272                 else if (cit->flags & ToolbarInfo::OFF)
273                         info.state = ToolbarSection::ToolbarInfo::OFF;
274                 else if (cit->flags & ToolbarInfo::AUTO)
275                         info.state = ToolbarSection::ToolbarInfo::AUTO;
276                 // save other information
277                 // if auto, frontend should *not* set on/off
278                 it->second->saveInfo(info);
279                 // maybe it is useful to update flags with real status. I do not know
280                 /*
281                 if (!(cit->flags & ToolbarInfo::AUTO)) {
282                         unsigned int flags = static_cast<unsigned int>(cit->flags);
283                         flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::OFF : ToolbarInfo::ON);
284                         flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::ON : ToolbarInfo::OFF);
285                         if (info.state == ToolbarSection::ToolbarInfo::ON)
286                         cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
287                 }
288                 */
289         }
290 }
291
292
293 void Toolbars::setLayout(string const & layout)
294 {
295         if (layout_)
296                 layout_->set(layout);
297 }
298
299
300 bool Toolbars::updateLayoutList(int textclass)
301 {
302         // update the layout display
303         if (last_textclass_ != textclass) {
304                 if (layout_)
305                         layout_->update();
306                 last_textclass_ = textclass;
307                 return true;
308         } else
309                 return false;
310 }
311
312
313 void Toolbars::openLayoutList()
314 {
315         if (layout_)
316                 layout_->open();
317 }
318
319
320 void Toolbars::clearLayoutList()
321 {
322         last_textclass_ = -1;
323         if (layout_)
324                 layout_->clear();
325 }
326
327
328 void Toolbars::add(ToolbarInfo const & tbinfo, bool newline)
329 {
330         ToolbarPtr tb_ptr = owner_.makeToolbar(tbinfo, newline);
331         toolbars_[tbinfo.name] = tb_ptr;
332
333         if (tbinfo.flags & ToolbarInfo::ON)
334                 tb_ptr->show(false);
335         else
336                 tb_ptr->hide(false);
337
338         if (tb_ptr->layout())
339                 layout_ = tb_ptr->layout();
340 }
341
342
343 void Toolbars::displayToolbar(ToolbarInfo const & tbinfo,
344                               bool show_it)
345 {
346         ToolbarsMap::iterator it = toolbars_.find(tbinfo.name);
347         BOOST_ASSERT(it != toolbars_.end());
348
349         if (show_it)
350                 it->second->show(true);
351         else
352                 it->second->hide(true);
353 }
354
355
356 void Toolbars::update()
357 {
358         ToolbarsMap::const_iterator it = toolbars_.begin();
359         ToolbarsMap::const_iterator const end = toolbars_.end();
360         for (; it != end; ++it)
361                 it->second->update();
362
363         bool const enable =
364                 lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
365
366         if (layout_)
367                 layout_->setEnabled(enable);
368 }
369
370
371 void layoutSelected(LyXView & lv, string const & name)
372 {
373         TextClass const & tc = lv.buffer()->params().getTextClass();
374
375         TextClass::const_iterator it  = tc.begin();
376         TextClass::const_iterator const end = tc.end();
377         for (; it != end; ++it) {
378                 string const & itname = (*it)->name();
379                 // Yes, the lyx::to_utf8(_()) is correct
380                 if (lyx::to_utf8(_(itname)) == name) {
381                         FuncRequest const func(LFUN_LAYOUT, itname,
382                                                FuncRequest::TOOLBAR);
383                         lv.dispatch(func);
384                         return;
385                 }
386         }
387         lyxerr << "ERROR (layoutSelected): layout not found!"
388                << endl;
389 }
390
391
392 } // namespace lyx