1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * This file is Copyright 1996-1998
12 * ====================================================== */
14 // Added pseudo-action handling, asierra 180296
19 #pragma implementation "toolbar.h"
23 #include "lyx_gui_misc.h"
31 #include "LyXAction.h"
32 #include "support/lstrings.h"
35 #ifdef TWO_COLOR_ICONS
37 #include "emph_bw.xpm"
39 #include "foot_bw.xpm"
40 #include "math_bw.xpm"
41 #include "depth_bw.xpm"
42 #include "margin_bw.xpm"
43 #include "melt_bw.xpm"
44 #include "copy_bw.xpm"
45 #include "noun_bw.xpm"
46 #include "paste_bw.xpm"
47 #include "free_bw.xpm"
50 #include "open_bw.xpm"
51 #include "close_bw.xpm"
52 #include "save_bw.xpm"
53 #include "print1_bw.xpm"
54 #include "quit_bw.xpm"
55 #include "typeset_ps_bw.xpm"
56 #include "unknown_bw.xpm"
77 #include "typeset_ps.xpm"
78 #include "unknown.xpm"
81 // These pixmaps are the same regardless of color:
82 #include "bold_bw.xpm"
83 #include "make_ascii_bw.xpm"
84 #include "make_latex_bw.xpm"
85 #include "run_latex_bw.xpm"
86 #include "sans_bw.xpm"
87 #include "view_dvi_bw.xpm"
88 #include "view_ps_bw.xpm"
89 #include "layout_code.xpm"
90 #include "layout_latex.xpm"
91 #include "layout_scrap.xpm"
92 #include "layout_sec.xpm"
93 #include "layout_std.xpm"
98 // this one is not "C" because combox callbacks are really C++ %-|
99 extern void LayoutsCB(int, void *);
100 extern char const ** get_pixmap_from_symbol(char const * arg, int, int);
101 extern LyXAction lyxaction;
104 Toolbar::Toolbar(LyXView * o, int x, int y)
105 : owner(o), sxpos(x), sypos(y)
113 // extracts the default toolbar actions from LyXRC
114 for (ToolbarDefaults::const_iterator cit =
115 lyxrc.toolbardefaults.begin();
116 cit != lyxrc.toolbardefaults.end(); ++cit) {
118 lyxerr[Debug::TOOLBAR] << "tool action: "
125 // timer-cb for bubble-help (Matthias)
126 void Toolbar::BubbleTimerCB(FL_OBJECT *, long data)
128 FL_OBJECT * ob = reinterpret_cast<FL_OBJECT*>(data);
129 char * help = static_cast<char*>(ob->u_vdata);
130 fl_show_oneliner(help, ob->form->x + ob->x,
131 ob->form->y + ob->y + ob->h);
135 extern "C" void C_Toolbar_BubbleTimerCB(FL_OBJECT * ob, long data)
137 Toolbar::BubbleTimerCB(ob, data);
141 // post_handler for bubble-help (Matthias)
142 int Toolbar::BubblePost(FL_OBJECT *ob, int event,
143 FL_Coord /*mx*/, FL_Coord /*my*/,
144 int /*key*/, void */*xev*/)
146 string help = static_cast<char *>(ob->u_vdata);
147 Toolbar * t = reinterpret_cast<Toolbar*>(ob->u_ldata);
149 if(event == FL_ENTER && !help.empty()){
150 fl_set_object_callback(t->bubble_timer,
151 C_Toolbar_BubbleTimerCB,
152 reinterpret_cast<long>(ob));
153 fl_set_timer(t->bubble_timer, 1);
155 else if(event != FL_MOTION){
156 fl_set_timer(t->bubble_timer, 0);
163 extern "C" int C_Toolbar_BubblePost(FL_OBJECT * ob, int event,
164 FL_Coord /*mx*/, FL_Coord /*my*/,
167 return Toolbar::BubblePost(ob, event, 0, 0, key, xev);
172 void Toolbar::activate()
174 toolbarItem * tmp= 0;
175 toolbarItem * item = toollist;
179 fl_activate_object(item->icon);
186 void Toolbar::deactivate()
188 toolbarItem * tmp= 0;
189 toolbarItem * item = toollist;
193 fl_deactivate_object(item->icon);
200 void Toolbar::ToolbarCB(FL_OBJECT * ob, long ac)
202 #if FL_REVISION >= 89
203 Toolbar * t = static_cast<Toolbar*>(ob->u_vdata);
205 Toolbar * t = reinterpret_cast<Toolbar*>(ob->u_ldata);
208 string res = t->owner->getLyXFunc()->Dispatch(int(ac));
210 lyxerr[Debug::TOOLBAR] << res << endl;
214 extern "C" void C_Toolbar_ToolbarCB(FL_OBJECT * ob, long data)
216 Toolbar::ToolbarCB(ob, data);
220 int Toolbar::get_toolbar_func(string const & func)
222 int action = lyxaction.LookupFunc(func.c_str());
224 if (func == "separator"){
225 action = TOOL_SEPARATOR;
226 } else if (func == "layouts"){
227 action = TOOL_LAYOUTS;
234 void Toolbar::set(bool doingmain)
236 // we shouldn't set if we have not cleaned
237 if (!cleaned) return;
240 toolbarItem * item = toollist;
243 fl_freeze_form(owner->getForm());
244 fl_addto_form(owner->getForm());
248 // add the time if it don't exist
249 if (bubble_timer == 0)
250 bubble_timer = fl_add_timer(FL_HIDDEN_TIMER,
251 xpos, ypos, 0, 0, "Timer");
255 switch(item->action){
261 xpos += standardspacing;
263 combox = new Combox(FL_COMBOX_DROPLIST);
264 combox->add(xpos, ypos, 135, height, 400);
265 combox->setcallback(LayoutsCB);
266 combox->resize(FL_RESIZE_ALL);
267 combox->gravity(NorthWestGravity, NorthWestGravity);
272 xpos += standardspacing;
274 fl_add_pixmapbutton(FL_NORMAL_BUTTON,
278 fl_set_object_boxtype(obj, FL_UP_BOX);
279 fl_set_object_color(obj, FL_MCOL, FL_BLUE);
280 fl_set_object_resize(obj, FL_RESIZE_ALL);
281 fl_set_object_gravity(obj,
284 fl_set_object_callback(obj, C_Toolbar_ToolbarCB,
285 static_cast<long>(item->action));
286 // Remove the blue feedback rectangle
287 fl_set_pixmapbutton_focus_outline(obj, 0);
289 // set the bubble-help (Matthias)
290 #if FL_REVISION >= 89
292 fl_set_object_helper(obj, item->help.c_str());
293 // The toolbar that this object belongs too.
299 #warning This is dangerous!
301 obj->u_vdata = const_cast<char*>(item->help.c_str());
302 // we need to know what toolbar this item
303 // belongs too. (Lgb)
304 obj->u_ldata = reinterpret_cast<long>(this);
306 fl_set_object_posthandler(obj, C_Toolbar_BubblePost);
309 fl_set_pixmapbutton_data(obj, const_cast<char**>(item->pixmap));
311 // we must remember to update the positions
314 /* Here will come a check to see if the new
315 * pos is within the bounds of the main frame,
316 * and perhaps wrap the toolbar if not.
324 fl_unfreeze_form(owner->getForm());
325 // Should be safe to do this here.
326 owner->updateLayoutChoice();
333 char const ** Toolbar::getPixmap(kb_action action, string const & arg)
335 char const ** pixmap = unknown_xpm; //0
337 case LFUN_MENUOPEN: pixmap = open_xpm; break;
338 case LFUN_CLOSEBUFFER: pixmap = close_xpm; break;
339 case LFUN_MENUPRINT: pixmap = print1_xpm; break;
340 case LFUN_MENUWRITE: pixmap = save_xpm; break;
341 case LFUN_EMPH: pixmap = emph_xpm; break;
342 case LFUN_NOUN: pixmap = noun_xpm; break;
343 case LFUN_FREE: pixmap = free_xpm; break;
344 case LFUN_FOOTMELT: pixmap = foot_xpm; break;
345 case LFUN_DEPTH: pixmap = depth_xpm; break;
346 case LFUN_COPY: pixmap = copy_xpm; break;
347 case LFUN_CUT: pixmap = cut_xpm; break;
348 case LFUN_PASTE: pixmap = paste_xpm; break;
349 case LFUN_TEX: pixmap = tex_xpm; break;
350 case LFUN_MATH_MODE: pixmap = math_xpm; break;
351 case LFUN_MARGINMELT: pixmap = margin_xpm; break;
352 case LFUN_FIGURE: pixmap = fig_xpm; break;
353 case LFUN_TABLE: pixmap = tab_xpm; break;
354 case LFUN_MELT: pixmap = melt_xpm; break;
355 case LFUN_QUIT: pixmap = quit_xpm; break;
356 case LFUN_RUNDVIPS: pixmap = update_ps_xpm; break;
360 pixmap = make_ascii_xpm;
361 else if (arg == "latex")
362 pixmap = make_latex_xpm;
367 if (arg == "Section")
368 pixmap = layout_sec_xpm;
369 else if (arg == "LaTeX")
370 pixmap = layout_latex_xpm;
371 else if (arg == "LyX-Code")
372 pixmap = layout_code_xpm;
373 else if (arg == "Scrap")
374 pixmap = layout_scrap_xpm;
376 pixmap = layout_std_xpm;
380 case LFUN_BOLD : pixmap = bold_xpm; break;
381 case LFUN_SANS: pixmap = sans_xpm; break;
382 case LFUN_RUNLATEX: pixmap = run_latex_xpm; break;
383 case LFUN_BUILDPROG: pixmap = build_xpm; break;
384 case LFUN_PREVIEWPS: pixmap = view_ps_xpm; break;
385 case LFUN_PREVIEW: pixmap = view_dvi_xpm; break;
386 case LFUN_INSERT_MATH:
389 pixmap = get_pixmap_from_symbol(arg.c_str(),
395 //pixmap = unknown_xpm;
402 void Toolbar::add(int action, bool doclean)
404 if (doclean && !cleaned) clean();
406 // this is what we do if we want to add to an existing
408 if (!doclean && owner) {
409 // first «hide» the toolbar buttons. This is not a real hide
410 // actually it deletes and frees the button altogether.
411 lyxerr << "Toolbar::add: «hide» the toolbar buttons." << endl;
412 toolbarItem * tmp= 0;
413 toolbarItem * item = toollist;
417 fl_freeze_form(owner->getForm());
421 fl_delete_object(item->icon);
422 fl_free_object(item->icon);
430 fl_unfreeze_form(owner->getForm());
431 cleaned = true; // this is not completely true, but OK anyway
434 // there exist some special actions not part of
435 // kb_action: SEPARATOR, LAYOUTS
436 char const ** pixmap = 0;
439 toolbarItem * newItem, * tmp;
441 if (lyxaction.isPseudoAction(action)) {
443 kb_action act = static_cast<kb_action>
444 (lyxaction.retrieveActionArg(action, arg));
445 pixmap = getPixmap(act, arg);
446 help = lyxaction.helpText(act);
449 lyxerr.debug() << "Pseudo action " << action << endl;
451 pixmap = getPixmap(static_cast<kb_action>(action));
452 help = lyxaction.helpText(static_cast<kb_action>(action));
455 // adds an item to the list
457 || action == TOOL_SEPARATOR
458 || action == TOOL_LAYOUTS) {
459 newItem = new toolbarItem;
460 newItem->action = action;
461 newItem->pixmap = pixmap;
462 newItem->help = help;
463 // the new item is placed at the end of the list
466 while(tmp->next != 0)
468 // here is tmp->next == 0
476 void Toolbar::clean()
478 toolbarItem * tmp = 0;
479 toolbarItem * item = toollist;
483 //now delete all the objects..
485 fl_freeze_form(owner->getForm());
491 lyxerr[Debug::TOOLBAR] << "Combox: " << combox << endl;
497 fl_unfreeze_form(owner->getForm());
498 lyxerr[Debug::TOOLBAR] << "toolbar cleaned" << endl;
503 void Toolbar::push(int nth)
505 lyxerr[Debug::TOOLBAR] << "Toolbar::push: trying to trigger no `"
506 << nth << '\'' << endl;
508 if (nth == 0) return;
511 toolbarItem * tmp = toollist;
515 fl_trigger_object(tmp->icon);
520 // item nth not found...
525 void Toolbar::add(string const & func, bool doclean)
527 int tf = lyxaction.LookupFunc(func);
530 lyxerr << "Toolbar::add: no LyX command called`"
531 << func << "'exists!" << endl;