]> git.lyx.org Git - lyx.git/blob - src/frontends/Toolbars.C
Fix remaining toolbar/session issues
[lyx.git] / src / frontends / Toolbars.C
1 /**
2  * \file Toolbars.C
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 "lyxtextclass.h"
24 #include "LyXView.h"
25 #include "lyx_main.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 |= ToolbarBackend::x
41 #define TurnOffFlag(x)  flags &= ~ToolbarBackend::x
42
43 void Toolbars::initFlags(ToolbarBackend::Toolbar & tbb)
44 {
45         ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbb.name);
46
47         unsigned int flags = static_cast<unsigned int>(tbb.flags);
48         // remove position
49         TurnOffFlag(TOP);
50         TurnOffFlag(BOTTOM);
51         TurnOffFlag(RIGHT);
52         TurnOffFlag(LEFT);
53
54         bool valid_location = true;
55         // init tbb.flags with saved location
56         if (info.location == ToolbarSection::ToolbarInfo::TOP)
57                 TurnOnFlag(TOP);
58         else if (info.location == ToolbarSection::ToolbarInfo::BOTTOM)
59                 TurnOnFlag(BOTTOM);
60         else if (info.location == ToolbarSection::ToolbarInfo::RIGHT)
61                 TurnOnFlag(RIGHT);
62         else if (info.location == ToolbarSection::ToolbarInfo::LEFT)
63                 TurnOnFlag(LEFT);
64         else {
65                 TurnOnFlag(TOP);
66                 valid_location = false;
67         }
68
69         // invalid location is for a new toolbar that has no saved information,
70         // so info.visible is not used for this case.
71         if (valid_location) {
72                 // init tbb.flags with saved visibility,
73                 TurnOffFlag(ON);
74                 TurnOffFlag(OFF);
75                 TurnOffFlag(AUTO);
76                 if (info.state == ToolbarSection::ToolbarInfo::ON)
77                         TurnOnFlag(ON);
78                 else if (info.state == ToolbarSection::ToolbarInfo::OFF)
79                         TurnOnFlag(OFF);
80                 else
81                         TurnOnFlag(AUTO);
82         }
83         /*
84         std::cout << "State " << info.state << " FLAGS: " << flags
85                 << " ON:" << (flags & ToolbarBackend::ON) 
86                 << " OFF:" << (flags & ToolbarBackend::OFF)
87                 << " L:" << (flags & ToolbarBackend::LEFT) 
88                 << " R:" << (flags & ToolbarBackend::RIGHT) 
89                 << " T:" << (flags & ToolbarBackend::TOP) 
90                 << " B:" << (flags & ToolbarBackend::BOTTOM) 
91                 << " MA:" << (flags & ToolbarBackend::MATH) 
92                 << " RE:" << (flags & ToolbarBackend::REVIEW) 
93                 << " TB:" << (flags & ToolbarBackend::TABLE) 
94                 << " AU:" << (flags & ToolbarBackend::AUTO) 
95                 << std::endl;
96         */
97         // now set the flags
98         tbb.flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
99 }
100
101
102 void Toolbars::init()
103 {
104         // extracts the toolbars from the backend
105         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
106         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
107
108         for (; cit != end; ++cit) {
109                 initFlags(*cit);
110                 add(*cit);
111         }
112 }
113
114
115 void Toolbars::display(string const & name, bool show)
116 {
117         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
118         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
119
120         for (; cit != end; ++cit) {
121                 if (cit->name == name) {
122                         displayToolbar(*cit, show);
123                         return;
124                 }
125         }
126
127         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
128                 << name << endl;
129 }
130
131
132 ToolbarBackend::Flags Toolbars::getToolbarState(string const & name)
133 {       
134         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
135         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
136
137         for (; cit != end; ++cit) {
138                 if (cit->name == name)
139                         return cit->flags;
140         }
141
142         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
143                 << name << endl;
144 }
145
146
147 void Toolbars::toggleToolbarState(string const & name)
148 {
149         ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
150         ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
151
152         for (; cit != end; ++cit) {
153                 if (cit->name == name) {
154                         int flags = cit->flags;
155                         // off -> on
156                         if (flags & ToolbarBackend::OFF) {
157                                 TurnOffFlag(OFF);
158                                 TurnOnFlag(ON);
159                         // auto -> off
160                         } else if (flags & ToolbarBackend::AUTO) {
161                                 TurnOffFlag(AUTO);
162                                 TurnOnFlag(OFF);
163                         } else if ((flags & ToolbarBackend::MATH) || (flags & ToolbarBackend::TABLE)
164                                 || (flags & ToolbarBackend::REVIEW)) {
165                                 // for math etc, toggle from on -> auto
166                                 TurnOffFlag(ON);
167                                 TurnOnFlag(AUTO);
168                         } else {
169                                 // for others, toggle from on -> off
170                                 TurnOffFlag(ON);
171                                 TurnOnFlag(OFF);
172                         }
173                         cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
174                         return;
175                 }
176         }
177         lyxerr[Debug::GUI] << "Toolbar::display: no toolbar named "
178                 << name << endl;
179 }
180 #undef TurnOnFlag
181 #undef TurnOffFlag
182
183
184 void Toolbars::update(bool in_math, bool in_table, bool review)
185 {
186         update();
187
188         // extracts the toolbars from the backend
189         ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
190         ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
191
192         for (; cit != end; ++cit) {
193                 if (cit->flags & ToolbarBackend::ON)
194                         displayToolbar(*cit, true);
195                 else if (cit->flags & ToolbarBackend::OFF)
196                         displayToolbar(*cit, false);
197                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::MATH))
198                         displayToolbar(*cit, in_math);
199                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::TABLE))
200                         displayToolbar(*cit, in_table);
201                 else if ((cit->flags & ToolbarBackend::AUTO) && (cit->flags & ToolbarBackend::REVIEW))
202                         displayToolbar(*cit, review);
203         }
204 }
205
206
207 void Toolbars::saveToolbarInfo()
208 {
209         ToolbarSection & tb = LyX::ref().session().toolbars();
210
211         for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
212                 cit != toolbarbackend.end(); ++cit) {
213                 ToolbarsMap::iterator it = toolbars_.find(cit->name);
214                 BOOST_ASSERT(it != toolbars_.end());
215                 // get toolbar info from session.
216                 ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
217                 if (cit->flags & ToolbarBackend::ON)
218                         info.state = ToolbarSection::ToolbarInfo::ON;
219                 else if (cit->flags & ToolbarBackend::OFF)
220                         info.state = ToolbarSection::ToolbarInfo::OFF;
221                 else if (cit->flags & ToolbarBackend::AUTO)
222                         info.state = ToolbarSection::ToolbarInfo::AUTO;
223                 // save other information
224                 // if auto, frontend should *not* set on/off
225                 it->second->saveInfo(info);
226                 // maybe it is useful to update flags with real status. I do not know
227                 /*
228                 if (!(cit->flags & ToolbarBackend::AUTO)) {
229                         unsigned int flags = static_cast<unsigned int>(cit->flags);
230                         flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::OFF : ToolbarBackend::ON);
231                         flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarBackend::ON : ToolbarBackend::OFF);
232                         if (info.state == ToolbarSection::ToolbarInfo::ON)
233                         cit->flags = static_cast<lyx::ToolbarBackend::Flags>(flags);
234                 }
235                 */
236         }
237 }
238
239
240 void Toolbars::setLayout(string const & layout)
241 {
242         if (layout_)
243                 layout_->set(layout);
244 }
245
246
247 bool Toolbars::updateLayoutList(int textclass)
248 {
249         // update the layout display
250         if (last_textclass_ != textclass) {
251                 if (layout_)
252                         layout_->update();
253                 last_textclass_ = textclass;
254                 return true;
255         } else
256                 return false;
257 }
258
259
260 void Toolbars::openLayoutList()
261 {
262         if (layout_)
263                 layout_->open();
264 }
265
266
267 void Toolbars::clearLayoutList()
268 {
269         last_textclass_ = -1;
270         if (layout_)
271                 layout_->clear();
272 }
273
274
275 void Toolbars::add(ToolbarBackend::Toolbar const & tbb)
276 {
277         ToolbarPtr tb_ptr = owner_.makeToolbar(tbb);
278         toolbars_[tbb.name] = tb_ptr;
279
280         if (tbb.flags & ToolbarBackend::ON)
281                 tb_ptr->show(false);
282         else
283                 tb_ptr->hide(false);
284
285         if (tb_ptr->layout())
286                 layout_ = tb_ptr->layout();
287 }
288
289
290 void Toolbars::displayToolbar(ToolbarBackend::Toolbar const & tbb,
291                               bool show_it)
292 {
293         ToolbarsMap::iterator it = toolbars_.find(tbb.name);
294         BOOST_ASSERT(it != toolbars_.end());
295
296         if (show_it)
297                 it->second->show(true);
298         else
299                 it->second->hide(true);
300 }
301
302
303 void Toolbars::update()
304 {
305         ToolbarsMap::const_iterator it = toolbars_.begin();
306         ToolbarsMap::const_iterator const end = toolbars_.end();
307         for (; it != end; ++it)
308                 it->second->update();
309
310         bool const enable =
311                 lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
312
313         if (layout_)
314                 layout_->setEnabled(enable);
315 }
316
317
318 void layoutSelected(LyXView & lv, string const & name)
319 {
320         LyXTextClass const & tc = lv.buffer()->params().getLyXTextClass();
321
322         LyXTextClass::const_iterator it  = tc.begin();
323         LyXTextClass::const_iterator const end = tc.end();
324         for (; it != end; ++it) {
325                 string const & itname = (*it)->name();
326                 // Yes, the lyx::to_utf8(_()) is correct
327                 if (lyx::to_utf8(_(itname)) == name) {
328                         FuncRequest const func(LFUN_LAYOUT, itname,
329                                                FuncRequest::UI);
330                         lv.dispatch(func);
331                         return;
332                 }
333         }
334         lyxerr << "ERROR (layoutSelected): layout not found!"
335                << endl;
336 }
337
338
339 } // namespace lyx