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