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