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