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