]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/XFormsToolbar.C
If I ever see another licence blurb again, it'll be too soon...
[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
17 #include "XFormsToolbar.h"
18 #include "debug.h"
19 #include "XFormsView.h"
20 #include "lyxfunc.h"
21 #include "FuncStatus.h"
22 #include "buffer.h"
23 #include "funcrequest.h"
24 #include "gettext.h"
25 #include "Tooltips.h"
26 #include "lyx_forms.h"
27 #include "combox.h"
28 #include "xforms_helpers.h"
29
30 #include "LyXAction.h"
31
32 #include "support/LAssert.h"
33 #include "support/filetools.h"
34 #include "support/lstrings.h"
35
36 using std::endl;
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         : action(LFUN_NOACTION), 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         action = ti.action;
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->action == ToolbarBackend::LAYOUTS && combox_) {
119                         LyXFunc const & lf = owner_->getLyXFunc();
120                         bool const disable =
121                                 lf.getStatus(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->action);
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         XFormsView * owner = static_cast<XFormsView *>(ob->u_vdata);
255
256         owner->getLyXFunc().dispatch(int(ac), true);
257 }
258
259
260 extern "C" {
261
262 void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
263 {
264         ToolbarCB(ob, data);
265 }
266
267 }
268
269 } // namespace anon
270
271
272 void XFormsToolbar::add(ToolbarBackend::Toolbar const & tb)
273 {
274         // we can only handle one toolbar
275         if (!toollist_.empty())
276                 return;
277
278         ToolbarBackend::item_iterator it = tb.items.begin();
279         ToolbarBackend::item_iterator end = tb.items.end();
280         for (; it != end; ++it)
281                 add(it->first, it->second);
282 }
283
284
285 void XFormsToolbar::add(int action, string const & tooltip)
286 {
287         toolbarItem item;
288         item.action = action;
289
290         switch (action) {
291         case ToolbarBackend::SEPARATOR:
292                 xpos += sepspace;
293                 break;
294         case ToolbarBackend::MINIBUFFER:
295                 // Not implemented
296                 break;
297         case ToolbarBackend::LAYOUTS:
298                 xpos += standardspacing;
299                 if (combox_)
300                         break;
301
302                 combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
303                                         xpos, ypos, 135, height, "");
304                 fl_set_combox_browser_height(combox_, 400);
305                 fl_set_object_boxtype(combox_, FL_DOWN_BOX);
306                 fl_set_object_color(combox_, FL_MCOL, FL_MCOL);
307                 fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
308                 fl_set_object_resize(combox_, FL_RESIZE_ALL);
309
310                 combox_->u_vdata = this;
311                 fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
312                 xpos += 135;
313                 break;
314         default: {
315                 FL_OBJECT * obj;
316
317                 xpos += standardspacing;
318                 item.icon = obj =
319                         fl_add_pixmapbutton(FL_NORMAL_BUTTON,
320                                             xpos, ypos,
321                                             buttonwidth,
322                                             height, "");
323                 fl_set_object_resize(obj, FL_RESIZE_ALL);
324                 fl_set_object_gravity(obj,
325                                       NorthWestGravity,
326                                       NorthWestGravity);
327                 fl_set_object_callback(obj, C_Toolbar_ToolbarCB,
328                                        static_cast<long>(action));
329                 // Remove the blue feedback rectangle
330                 fl_set_pixmapbutton_focus_outline(obj, 0);
331
332                 tooltip_->init(obj, tooltip);
333
334                 // The view that this object belongs to.
335                 obj->u_vdata = owner_;
336
337                 string const xpm = toolbarbackend.getIcon(action);
338                 fl_set_pixmapbutton_file(obj, xpm.c_str());
339
340                 // we must remember to update the positions
341                 xpos += buttonwidth;
342                 // ypos is constant
343                 /* Here will come a check to see if the new
344                  * pos is within the bounds of the main frame,
345                  * and perhaps wrap the toolbar if not.
346                  */
347                 break;
348         }
349         }
350
351         toollist_.push_back(item);
352 }