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