LyX 1.5.0 is released
[lyx.git] / src / frontends / Toolbars.cpp
blobf28a2b70113cd8ebcccd7cc4d9991bd4d245c748
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.
6 * \author Lars Gullik Bjønnes
7 * \author Angus Leeming
9 * Full author contact details are available in file CREDITS.
12 #include <config.h>
14 #include "Toolbars.h"
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"
28 namespace lyx {
30 using std::endl;
31 using std::string;
34 Toolbars::Toolbars(LyXView & owner)
35 : owner_(owner),
36 layout_(0),
37 last_textclass_(-1)
40 #define TurnOnFlag(x) flags |= ToolbarInfo::x
41 #define TurnOffFlag(x) flags &= ~ToolbarInfo::x
43 void Toolbars::initFlags(ToolbarInfo & tbinfo)
45 ToolbarSection::ToolbarInfo & info = LyX::ref().session().toolbars().load(tbinfo.name);
47 unsigned int flags = static_cast<unsigned int>(tbinfo.flags);
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);
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;
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);
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;
101 // now set the flags
102 tbinfo.flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
106 void Toolbars::init()
108 // extracts the toolbars from the backend
109 ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
110 ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
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);
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;
146 void Toolbars::display(string const & name, bool show)
148 ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
149 ToolbarBackend::Toolbars::iterator end = toolbarbackend.end();
151 for (; cit != end; ++cit) {
152 if (cit->name == name) {
153 unsigned int flags = cit->flags;
154 TurnOffFlag(ON);
155 TurnOffFlag(OFF);
156 TurnOffFlag(AUTO);
157 if (show)
158 TurnOnFlag(ON);
159 else
160 TurnOnFlag(OFF);
161 cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
162 displayToolbar(*cit, show);
163 return;
167 LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
168 << name << endl;
172 ToolbarInfo * Toolbars::getToolbarInfo(string const & name)
174 return toolbarbackend.getUsedToolbarInfo(name);
178 void Toolbars::toggleToolbarState(string const & name, bool allowauto)
180 ToolbarInfo * tbi = toolbarbackend.getUsedToolbarInfo(name);
182 if (!tbi) {
183 LYXERR(Debug::GUI) << "Toolbar::display: no toolbar named "
184 << name << endl;
185 return;
188 int flags = tbi->flags;
189 // off -> on
190 if (flags & ToolbarInfo::OFF) {
191 TurnOffFlag(OFF);
192 TurnOnFlag(ON);
193 // auto -> off
194 } else if (flags & ToolbarInfo::AUTO) {
195 TurnOffFlag(AUTO);
196 TurnOnFlag(OFF);
197 } else if (allowauto
198 && ((flags & ToolbarInfo::MATH)
199 || (flags & ToolbarInfo::TABLE)
200 || (flags & ToolbarInfo::REVIEW))) {
201 // for math etc, toggle from on -> auto
202 TurnOffFlag(ON);
203 TurnOnFlag(AUTO);
204 } else {
205 // for others, toggle from on -> off
206 TurnOffFlag(ON);
207 TurnOnFlag(OFF);
209 tbi->flags = static_cast<ToolbarInfo::Flags>(flags);
211 #undef TurnOnFlag
212 #undef TurnOffFlag
215 void Toolbars::update(bool in_math, bool in_table, bool review)
217 update();
219 // extracts the toolbars from the backend
220 ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
221 ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
223 for (; cit != end; ++cit) {
224 if (cit->flags & ToolbarInfo::ON)
225 displayToolbar(*cit, true);
226 else if (cit->flags & ToolbarInfo::OFF)
227 displayToolbar(*cit, false);
228 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::MATH))
229 displayToolbar(*cit, in_math);
230 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::TABLE))
231 displayToolbar(*cit, in_table);
232 else if ((cit->flags & ToolbarInfo::AUTO) && (cit->flags & ToolbarInfo::REVIEW))
233 displayToolbar(*cit, review);
238 bool Toolbars::visible(string const & name) const
240 std::map<string, ToolbarPtr>::const_iterator it =
241 toolbars_.find(name);
242 if (it == toolbars_.end())
243 return false;
244 return it->second.get()->isVisible();
248 void Toolbars::saveToolbarInfo()
250 ToolbarSection & tb = LyX::ref().session().toolbars();
252 for (ToolbarBackend::Toolbars::iterator cit = toolbarbackend.begin();
253 cit != toolbarbackend.end(); ++cit) {
254 ToolbarsMap::iterator it = toolbars_.find(cit->name);
255 BOOST_ASSERT(it != toolbars_.end());
256 // get toolbar info from session.
257 ToolbarSection::ToolbarInfo & info = tb.load(cit->name);
258 if (cit->flags & ToolbarInfo::ON)
259 info.state = ToolbarSection::ToolbarInfo::ON;
260 else if (cit->flags & ToolbarInfo::OFF)
261 info.state = ToolbarSection::ToolbarInfo::OFF;
262 else if (cit->flags & ToolbarInfo::AUTO)
263 info.state = ToolbarSection::ToolbarInfo::AUTO;
264 // save other information
265 // if auto, frontend should *not* set on/off
266 it->second->saveInfo(info);
267 // maybe it is useful to update flags with real status. I do not know
269 if (!(cit->flags & ToolbarInfo::AUTO)) {
270 unsigned int flags = static_cast<unsigned int>(cit->flags);
271 flags &= ~(info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::OFF : ToolbarInfo::ON);
272 flags |= (info.state == ToolbarSection::ToolbarInfo::ON ? ToolbarInfo::ON : ToolbarInfo::OFF);
273 if (info.state == ToolbarSection::ToolbarInfo::ON)
274 cit->flags = static_cast<lyx::ToolbarInfo::Flags>(flags);
281 void Toolbars::setLayout(docstring const & layout)
283 if (layout_)
284 layout_->set(layout);
288 bool Toolbars::updateLayoutList(int textclass)
290 // update the layout display
291 if (last_textclass_ != textclass) {
292 if (layout_)
293 layout_->update();
294 last_textclass_ = textclass;
295 return true;
296 } else
297 return false;
301 void Toolbars::openLayoutList()
303 if (layout_)
304 layout_->open();
308 void Toolbars::clearLayoutList()
310 last_textclass_ = -1;
311 if (layout_)
312 layout_->clear();
316 void Toolbars::add(ToolbarInfo const & tbinfo, bool newline)
318 ToolbarPtr tb_ptr = owner_.makeToolbar(tbinfo, newline);
319 toolbars_[tbinfo.name] = tb_ptr;
321 if (tbinfo.flags & ToolbarInfo::ON)
322 tb_ptr->show(false);
323 else
324 tb_ptr->hide(false);
326 if (tb_ptr->layout())
327 layout_ = tb_ptr->layout();
331 void Toolbars::displayToolbar(ToolbarInfo const & tbinfo,
332 bool show_it)
334 ToolbarsMap::iterator it = toolbars_.find(tbinfo.name);
335 BOOST_ASSERT(it != toolbars_.end());
337 if (show_it)
338 it->second->show(true);
339 else
340 it->second->hide(true);
344 void Toolbars::update()
346 ToolbarsMap::const_iterator it = toolbars_.begin();
347 ToolbarsMap::const_iterator const end = toolbars_.end();
348 for (; it != end; ++it)
349 it->second->update();
351 bool const enable =
352 lyx::getStatus(FuncRequest(LFUN_LAYOUT)).enabled();
354 if (layout_)
355 layout_->setEnabled(enable);
359 void layoutSelected(LyXView & lv, docstring const & name)
361 TextClass const & tc = lv.buffer()->params().getTextClass();
363 TextClass::const_iterator it = tc.begin();
364 TextClass::const_iterator const end = tc.end();
365 for (; it != end; ++it) {
366 docstring const & itname = (*it)->name();
367 if (translateIfPossible(itname) == name) {
368 FuncRequest const func(LFUN_LAYOUT, itname,
369 FuncRequest::TOOLBAR);
370 lv.dispatch(func);
371 return;
374 lyxerr << "ERROR (layoutSelected): layout not found!"
375 << endl;
379 } // namespace lyx