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