]> git.lyx.org Git - lyx.git/blob - src/frontends/Toolbars.cpp
* src/frontends/qt4/ui/TextLayoutUi.ui:
[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, bool allowauto)
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 (allowauto 
207                                    && ((flags & ToolbarInfo::MATH) 
208                                        || (flags & ToolbarInfo::TABLE)
209                                        || (flags & ToolbarInfo::REVIEW))) {
210                                 // for math etc, toggle from on -> auto
211                                 TurnOffFlag(ON);
212                                 TurnOnFlag(AUTO);
213                         } else {
214                                 // for others, toggle from on -> off
215                                 TurnOffFlag(ON);
216                                 TurnOnFlag(OFF);
217                         }
218                         cit->flags = static_cast<ToolbarInfo::Flags>(flags);
219                         return;
220                 }
221         }
222         LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
223                 << name << endl;
224 }
225 #undef TurnOnFlag
226 #undef TurnOffFlag
227
228
229 void Toolbars::update(bool in_math, bool in_table, bool review)
230 {
231         update();
232
233         // extracts the toolbars from the backend
234         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
235         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
236
237         for (; cit != end; ++cit) {
238                 if (cit->flags & ToolbarInfo::ON)
239                         displayToolbar(*cit, true);
240                 else if (cit->flags & ToolbarInfo::OFF)
241                         displayToolbar(*cit, false);
242                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::MATH))
243                         displayToolbar(*cit, in_math);
244                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::TABLE))
245                         displayToolbar(*cit, in_table);
246                 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::REVIEW))
247                         displayToolbar(*cit, review);
248         }
249 }
250
251
252 bool Toolbars::visible(string const & name) const
253 {
254         std::map<string, ToolbarPtr>::const_iterator it =
255                 toolbars_.find(name);
256         if (it == toolbars_.end())
257                 return false;
258         return it->second.get()->isVisible();
259 }
260
261
262 void Toolbars::saveToolbarInfo()
263 {
264         ToolbarSection & tb = LyX::ref().session().toolbars();
265
266         for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
267                 cit != toolbarbackend.end(); ++cit) {
268                 ToolbarsMap::iterator it = toolbars_.find(cit->name);
269                 BOOST_ASSERT(it != toolbars_.end());
270                 // get toolbar info from session.
271                 ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
272                 if (cit->flags & ToolbarInfo::ON)
273                         info.state = ToolbarSection::ToolbarInfo::ON;
274                 else if (cit->flags & ToolbarInfo::OFF)
275                         info.state = ToolbarSection::ToolbarInfo::OFF;
276                 else if (cit->flags & ToolbarInfo::AUTO)
277                         info.state = ToolbarSection::ToolbarInfo::AUTO;
278                 // save other information
279                 // if auto, frontend should *not* set on/off
280                 it->second->saveInfo(info);
281                 // maybe it is useful to update flags with real status. I do not know
282                 /*
283                 if (!(cit->flags & ToolbarInfo::AUTO)) {
284                         unsigned int flags = static_cast<unsigned int>(cit->flags);
285                         flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::OFF : ToolbarInfo::ON);
286                         flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::ON : ToolbarInfo::OFF);
287                         if (info.state == ToolbarSection::ToolbarInfo::ON)
288                         cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
289                 }
290                 */
291         }
292 }
293
294
295 void Toolbars::setLayout(string const & layout)
296 {
297         if (layout_)
298                 layout_->set(layout);
299 }
300
301
302 bool Toolbars::updateLayoutList(int textclass)
303 {
304         // update the layout display
305         if (last_textclass_ != textclass) {
306                 if (layout_)
307                         layout_->update();
308                 last_textclass_ = textclass;
309                 return true;
310         } else
311                 return false;
312 }
313
314
315 void Toolbars::openLayoutList()
316 {
317         if (layout_)
318                 layout_->open();
319 }
320
321
322 void Toolbars::clearLayoutList()
323 {
324         last_textclass_ = -1;
325         if (layout_)
326                 layout_->clear();
327 }
328
329
330 void Toolbars::add(ToolbarInfo const & tbinfo, bool newline)
331 {
332         ToolbarPtr tb_ptr = owner_.makeToolbar(tbinfo, newline);
333         toolbars_[tbinfo.name] = tb_ptr;
334
335         if (tbinfo.flags & ToolbarInfo::ON)
336                 tb_ptr->show(false);
337         else
338                 tb_ptr->hide(false);
339
340         if (tb_ptr->layout())
341                 layout_ = tb_ptr->layout();
342 }
343
344
345 void Toolbars::displayToolbar(ToolbarInfo const & tbinfo,
346                               bool show_it)
347 {
348         ToolbarsMap::iterator it = toolbars_.find(tbinfo.name);
349         BOOST_ASSERT(it != toolbars_.end());
350
351         if (show_it)
352                 it->second->show(true);
353         else
354                 it->second->hide(true);
355 }
356
357
358 void Toolbars::update()
359 {
360         ToolbarsMap::const_iterator it = toolbars_.begin();
361         ToolbarsMap::const_iterator const end = toolbars_.end();
362         for (; it != end; ++it)
363                 it->second->update();
364
365         bool const enable =
366                 lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
367
368         if (layout_)
369                 layout_->setEnabled(enable);
370 }
371
372
373 void layoutSelected(LyXView & lv, string const & name)
374 {
375         TextClass const & tc = lv.buffer()->params().getTextClass();
376
377         TextClass::const_iterator it  = tc.begin();
378         TextClass::const_iterator const end = tc.end();
379         for (; it != end; ++it) {
380                 string const & itname = (*it)->name();
381                 // Yes, the lyx::to_utf8(_()) is correct
382                 if (lyx::to_utf8(_(itname)) == name) {
383                         FuncRequest const func(LFUN_LAYOUT, itname,
384                                                FuncRequest::TOOLBAR);
385                         lv.dispatch(func);
386                         return;
387                 }
388         }
389         lyxerr << "ERROR (layoutSelected): layout not found!"
390                << endl;
391 }
392
393
394 } // namespace lyx