]> git.lyx.org Git - features.git/blob - src/frontends/xforms/XFormsToolbar.C
towards saner frontends (?). Part II: the menubar (now it is possible to switch front...
[features.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         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         XFormsView * owner = static_cast<XFormsView *>(ob->u_vdata);
254
255         owner->getLyXFunc().dispatch(int(ac), true);
256 }
257
258
259 extern "C" {
260
261 void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
262 {
263         ToolbarCB(ob, data);
264 }
265
266 }
267
268 } // namespace anon
269
270
271 void XFormsToolbar::add(ToolbarBackend::Toolbar const & tb)
272 {
273         // we can only handle one toolbar
274         if (!toollist_.empty())
275                 return;
276
277         ToolbarBackend::item_iterator it = tb.items.begin();
278         ToolbarBackend::item_iterator end = tb.items.end();
279         for (; it != end; ++it)
280                 add(it->first, it->second);
281 }
282
283
284 void XFormsToolbar::add(int action, string const & tooltip)
285 {
286         toolbarItem item;
287         item.action = action;
288
289         switch (action) {
290         case ToolbarBackend::SEPARATOR:
291                 xpos += sepspace;
292                 break;
293         case ToolbarBackend::MINIBUFFER:
294                 // Not implemented
295                 break;
296         case ToolbarBackend::LAYOUTS:
297                 xpos += standardspacing;
298                 if (combox_)
299                         break;
300
301                 combox_ = fl_add_combox(FL_DROPLIST_COMBOX,
302                                         xpos, ypos, 135, height, "");
303                 fl_set_combox_browser_height(combox_, 400);
304                 fl_set_object_boxtype(combox_, FL_DOWN_BOX);
305                 fl_set_object_color(combox_, FL_MCOL, FL_MCOL);
306                 fl_set_object_gravity(combox_, FL_NorthWest, FL_NorthWest);
307                 fl_set_object_resize(combox_, FL_RESIZE_ALL);
308
309                 combox_->u_vdata = this;
310                 fl_set_object_callback(combox_, C_layoutSelectedCB, 0);
311                 xpos += 135;
312                 break;
313         default: {
314                 FL_OBJECT * obj;
315
316                 xpos += standardspacing;
317                 item.icon = obj =
318                         fl_add_pixmapbutton(FL_NORMAL_BUTTON,
319                                             xpos, ypos,
320                                             buttonwidth,
321                                             height, "");
322                 fl_set_object_resize(obj, FL_RESIZE_ALL);
323                 fl_set_object_gravity(obj,
324                                       NorthWestGravity,
325                                       NorthWestGravity);
326                 fl_set_object_callback(obj, C_Toolbar_ToolbarCB,
327                                        static_cast<long>(action));
328                 // Remove the blue feedback rectangle
329                 fl_set_pixmapbutton_focus_outline(obj, 0);
330
331                 tooltip_->init(obj, tooltip);
332
333                 // The view that this object belongs to.
334                 obj->u_vdata = owner_;
335
336                 string const xpm = toolbarbackend.getIcon(action);
337                 fl_set_pixmapbutton_file(obj, xpm.c_str());
338
339                 // we must remember to update the positions
340                 xpos += buttonwidth;
341                 // ypos is constant
342                 /* Here will come a check to see if the new
343                  * pos is within the bounds of the main frame,
344                  * and perhaps wrap the toolbar if not.
345                  */
346                 break;
347         }
348         }
349
350         toollist_.push_back(item);
351 }