]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/Toolbar_pimpl.C
better lib building
[lyx.git] / src / frontends / xforms / Toolbar_pimpl.C
1 /**
2  * \file xforms/Toolbar_pimpl.C
3  * Copyright 1995 Matthias Ettrich
4  * Copyright 1996-1998 Lars Gullik Bjønnes
5  * This file is part of LyX, the document processor.
6  * Licence details can be found in the file COPYING.
7  *
8  * \author Lars Gullik Bjønnes
9  *
10  * Full author contact details are available in file CREDITS
11  */
12
13 //  Added pseudo-action handling, asierra 180296
14
15 #include <config.h>
16
17
18 #include "Toolbar_pimpl.h"
19 #include "debug.h"
20 #include "XFormsView.h"
21 #include "lyxfunc.h"
22 #include "FuncStatus.h"
23 #include "buffer.h"
24 #include "funcrequest.h"
25 #include "gettext.h"
26 #include "Tooltips.h"
27 #include FORMS_H_LOCATION
28 #include "combox.h"
29 #include "xforms_helpers.h"
30
31 #include "LyXAction.h"
32
33 #include "support/LAssert.h"
34 #include "support/filetools.h"
35 #include "support/lstrings.h"
36
37 using std::endl;
38
39 // some constants
40 const int standardspacing = 2; // the usual space between items
41 const int sepspace = 6; // extra space
42 const int buttonwidth = 30; // the standard button width
43 const int height = 30; // the height of all items in the toolbar
44
45 Toolbar::Pimpl::toolbarItem::toolbarItem()
46         : action(LFUN_NOACTION), icon(0)
47 {}
48
49
50 Toolbar::Pimpl::toolbarItem::~toolbarItem()
51 {
52         // Lars said here that ~XFormsView() dealt with the icons.
53         // This is not true. But enabling this causes crashes,
54         // because somehow we kill the same icon twice :(
55         // FIXME
56         //kill_icon();
57 }
58
59
60 /// Display toolbar, not implemented. But moved out of line so that
61 /// linking will work properly.
62 void Toolbar::Pimpl::displayToolbar(ToolbarBackend::Toolbar const & tb,
63                                     bool show)
64 {}
65
66
67 void Toolbar::Pimpl::toolbarItem::kill_icon()
68 {
69         if (icon) {
70                 fl_delete_object(icon);
71                 fl_free_object(icon);
72                 icon = 0;
73         }
74 }
75
76
77 Toolbar::Pimpl::toolbarItem &
78 Toolbar::Pimpl::toolbarItem::operator=(toolbarItem const & ti)
79 {
80         if (this == &ti)
81                 return *this;
82
83         // If we already have an icon, release it.
84         // But we don't copy the icon from ti
85         kill_icon();
86
87         action = ti.action;
88
89         return *this;
90 }
91
92
93
94 Toolbar::Pimpl::Pimpl(LyXView * o, int x, int y)
95         : owner_(static_cast<XFormsView *>(o)), combox_(0), xpos(x), ypos(y)
96 {
97         tooltip_ = new Tooltips();
98 }
99
100
101 Toolbar::Pimpl::~Pimpl()
102 {
103         fl_freeze_form(owner_->getForm());
104
105         // G++ vector does not have clear defined
106         //toollist.clear();
107         toollist_.erase(toollist_.begin(), toollist_.end());
108
109         fl_unfreeze_form(owner_->getForm());
110         delete tooltip_;
111 }
112
113
114 void Toolbar::Pimpl::update()
115 {
116         ToolbarList::const_iterator p = toollist_.begin();
117         ToolbarList::const_iterator end = toollist_.end();
118         for (; p != end; ++p) {
119                 if (p->action == ToolbarBackend::LAYOUTS && combox_) {
120                         LyXFunc const & lf = owner_->getLyXFunc();
121                         bool const disable =
122                                 lf.getStatus(LFUN_LAYOUT).disabled();
123                         setEnabled(combox_, !disable);
124                         continue;
125                 }
126
127                 if (!p->icon)
128                         continue;
129
130                 FuncStatus const status = owner_->getLyXFunc().getStatus(p->action);
131                 if (status.onoff(true)) {
132                         // I'd like to use a different color
133                         // here, but then the problem is to
134                         // know how to use transparency with
135                         // Xpm library. It seems pretty
136                         // complicated to me (JMarc)
137                         fl_set_object_color(p->icon, FL_LEFT_BCOL, FL_BLUE);
138                         fl_set_object_boxtype(p->icon, FL_DOWN_BOX);
139                 } else {
140                         fl_set_object_color(p->icon, FL_MCOL, FL_BLUE);
141                         fl_set_object_boxtype(p->icon, FL_UP_BOX);
142                 }
143                 if (status.disabled()) {
144                         // Is there a way here to specify a
145                         // mask in order to show that the
146                         // button is disabled? (JMarc)
147                         fl_deactivate_object(p->icon);
148                 }
149                 else
150                         fl_activate_object(p->icon);
151         }
152 }
153
154
155 namespace {
156
157 void C_layoutSelectedCB(FL_OBJECT * ob, long)
158 {
159         if (!ob || !ob->u_vdata)
160                 return;
161         Toolbar::Pimpl * ptr = static_cast<Toolbar::Pimpl *>(ob->u_vdata);
162         ptr->layoutSelected();
163 }
164
165 } // namespace anon
166
167
168 void Toolbar::Pimpl::layoutSelected()
169 {
170         if (!combox_)
171                 return;
172
173         string const & layoutguiname = getString(combox_);
174         LyXTextClass const & tc =
175                 owner_->buffer()->params.getLyXTextClass();
176
177         LyXTextClass::const_iterator end = tc.end();
178         for (LyXTextClass::const_iterator cit = tc.begin();
179              cit != end; ++cit) {
180                 if (_((*cit)->name()) == layoutguiname) {
181                         owner_->getLyXFunc().dispatch(FuncRequest(LFUN_LAYOUT, (*cit)->name()), true);
182                         return;
183                 }
184         }
185         lyxerr << "ERROR (Toolbar::Pimpl::layoutSelected): layout not found!"
186                << endl;
187 }
188
189
190 void Toolbar::Pimpl::setLayout(string const & layout)
191 {
192         if (!combox_)
193                 return;
194
195         LyXTextClass const & tc = owner_->buffer()->params.getLyXTextClass();
196         string const layoutname = _(tc[layout]->name());
197
198         int const nnames = fl_get_combox_maxitems(combox_);
199         for (int i = 1; i <= nnames; ++i) {
200                 string const name = fl_get_combox_line(combox_, i);
201                 if (name == layoutname) {
202                         fl_set_combox(combox_, i);
203                         break;
204                 }
205         }
206 }
207
208
209 void Toolbar::Pimpl::updateLayoutList(bool force)
210 {
211         if (!combox_)
212                 return;
213
214         // If textclass is different, we need to update the list
215         if (fl_get_combox_maxitems(combox_) == 0 || force) {
216                 fl_clear_combox(combox_);
217                 LyXTextClass const & tc =
218                         owner_->buffer()->params.getLyXTextClass();
219                 LyXTextClass::const_iterator end = tc.end();
220                 for (LyXTextClass::const_iterator cit = tc.begin();
221                      cit != end; ++cit) {
222                         // ignore obsolete entries
223                         if ((*cit)->obsoleted_by().empty()) {
224                                 string const & name = _((*cit)->name());
225                                 fl_addto_combox(combox_, name.c_str());
226                         }
227                 }
228         }
229         // we need to do this.
230         fl_redraw_object(combox_);
231 }
232
233
234 void Toolbar::Pimpl::clearLayoutList()
235 {
236         if (!combox_)
237                 return;
238
239         fl_clear_combox(combox_);
240         fl_redraw_object(combox_);
241 }
242
243
244 void Toolbar::Pimpl::openLayoutList()
245 {
246         if (!combox_)
247                 return;
248
249         fl_show_combox_browser(combox_);
250 }
251
252
253 namespace {
254
255 void ToolbarCB(FL_OBJECT * ob, long ac)
256 {
257         XFormsView * owner = static_cast<XFormsView *>(ob->u_vdata);
258
259         owner->getLyXFunc().dispatch(int(ac), true);
260 }
261
262
263 extern "C" {
264
265 void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
266 {
267         ToolbarCB(ob, data);
268 }
269
270 }
271
272 } // namespace anon
273
274
275 void Toolbar::Pimpl::add(ToolbarBackend::Toolbar const & tb)
276 {
277         // we can only handle one toolbar
278         if (!toollist_.empty())
279                 return;
280
281         ToolbarBackend::item_iterator it = tb.items.begin();
282         ToolbarBackend::item_iterator end = tb.items.end();
283         for (; it != end; ++it)
284                 add(it->first, it->second);
285 }
286
287
288 void Toolbar::Pimpl::add(int action, string const & tooltip)
289 {
290         toolbarItem item;
291         item.action = action;
292
293         switch (action) {
294         case ToolbarBackend::SEPARATOR:
295                 xpos += sepspace;
296                 break;
297         case ToolbarBackend::MINIBUFFER:
298                 // Not implemented
299                 break;
300         case ToolbarBackend::LAYOUTS:
301                 xpos += standardspacing;
302                 if (combox_)
303                         break;
304
305                 combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
306                                         xpos, ypos, 135, height, "");
307                 fl_set_combox_browser_height(combox_, 400);
308                 fl_set_object_boxtype(combox_, FL_DOWN_BOX);
309                 fl_set_object_color(combox_, FL_MCOL, FL_MCOL);
310                 fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
311                 fl_set_object_resize(combox_, FL_RESIZE_ALL);
312
313                 combox_->u_vdata = this;
314                 fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
315                 xpos += 135;
316                 break;
317         default: {
318                 FL_OBJECT * obj;
319
320                 xpos += standardspacing;
321                 item.icon = obj =
322                         fl_add_pixmapbutton(FL_NORMAL_BUTTON,
323                                             xpos, ypos,
324                                             buttonwidth,
325                                             height, "");
326                 fl_set_object_resize(obj, FL_RESIZE_ALL);
327                 fl_set_object_gravity(obj,
328                                       NorthWestGravity,
329                                       NorthWestGravity);
330                 fl_set_object_callback(obj, C_Toolbar_ToolbarCB,
331                                        static_cast<long>(action));
332                 // Remove the blue feedback rectangle
333                 fl_set_pixmapbutton_focus_outline(obj, 0);
334
335                 tooltip_->init(obj, tooltip);
336
337                 // The view that this object belongs to.
338                 obj->u_vdata = owner_;
339
340                 string const xpm = toolbarbackend.getIcon(action);
341                 fl_set_pixmapbutton_file(obj, xpm.c_str());
342
343                 // we must remember to update the positions
344                 xpos += buttonwidth;
345                 // ypos is constant
346                 /* Here will come a check to see if the new
347                  * pos is within the bounds of the main frame,
348                  * and perhaps wrap the toolbar if not.
349                  */
350                 break;
351         }
352         }
353
354         toollist_.push_back(item);
355 }