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