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