/**
- * \file Menubar_pimpl.C
- * Copyright 1999-2001 The LyX Team.
- * See the file COPYING.
+ * \file xforms/Menubar_pimpl.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
- * \author Lars Gullik Bjønnes, larsbj@lyx.org
+ * \author Lars Gullik Bjønnes
+ * \author Jean-Marc Lasgouttes
+ *
+ * Full author contact details are available in file CREDITS
*/
#include <config.h>
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
#include "Menubar_pimpl.h"
#include "MenuBackend.h"
-#include "LyXAction.h"
-#include "kbmap.h"
-#include "Dialogs.h"
#include "XFormsView.h"
#include "lyxfunc.h"
#include "support/lstrings.h"
#include "debug.h"
#include FORMS_H_LOCATION
-#include <boost/scoped_ptr.hpp>
+//#include <boost/scoped_ptr.hpp>
#include <algorithm>
typedef vector<int>::size_type size_type;
-extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
-extern LyXAction lyxaction;
-
namespace {
// Some constants
}
+Menubar::Pimpl::~Pimpl()
+{}
+
+
void Menubar::Pimpl::makeMenubar(Menu const & menu)
{
FL_FORM * form = owner_->getForm();
continue;
}
string const label = i->label();
- string const shortcut = "#" + i->shortcut();
+ string const shortcut = '#' + i->shortcut();
int const width = string_width(label);
obj = fl_add_button(FL_MENU_BUTTON,
air + moffset, yloc,
int menu = fl_newpup(win);
fl_setpup_softedge(menu, true);
fl_setpup_bw(menu, -1);
- lyxerr[Debug::GUI] << "Adding menu " << menu
- << " in deletion list" << endl;
smn.push_back(menu);
return menu;
}
string const fixlabel(string const & str)
{
-#if FL_VERSION < 1 && FL_REVISION < 89
- return subst(str, '%', '?');
-#else
return subst(str, "%", "%%");
-#endif
}
int Menubar::Pimpl::create_submenu(Window win, XFormsView * view,
- Menu const & menu, vector<int> & smn,
- bool & all_disabled)
+ Menu const & menu, vector<int> & smn)
{
const int menuid = get_new_submenu(smn, win);
lyxerr[Debug::GUI] << "Menubar::Pimpl::create_submenu: creating "
}
}
lyxerr[Debug::GUI] << "max_width=" << max_width
- << ", widest_label=`" << widest_label
- << "'" << endl;
-
- // Compute where to put separators
- vector<string> extra_labels(menu.size());
- vector<string>::iterator it = extra_labels.begin();
- vector<string>::iterator last = it;
- for (Menu::const_iterator i = menu.begin(); i != end; ++i, ++it)
- if (i->kind() == MenuItem::Separator)
- *last = "%l";
- else if (!i->optional() ||
- !(view->getLyXFunc()->getStatus(i->action()).disabled()))
- last = it;
-
- it = extra_labels.begin();
+ << ", widest_label=\"" << widest_label
+ << '"' << endl;
+
size_type count = 0;
int curmenuid = menuid;
- for (Menu::const_iterator i = menu.begin(); i != end; ++i, ++it) {
+ for (Menu::const_iterator i = menu.begin(); i != end; ++i) {
MenuItem const & item = (*i);
- string & extra_label = *it;
++count;
- if (count > max_number_of_items) {
+ // add a More... submenu if the menu is too long (but
+ // not just for one extra entry!)
+ if (count > max_number_of_items && (i+1) != end) {
int tmpmenuid = get_new_submenu(smn, win);
lyxerr[Debug::GUI] << "Too many items, creating "
<< "new menu " << tmpmenuid << endl;
string label = _("More");
label += "...%m";
fl_addtopup(curmenuid, label.c_str(), tmpmenuid);
- count = 1;
+ count = 0;
curmenuid = tmpmenuid;
}
switch (item.kind()) {
- case MenuItem::Command: {
- FuncStatus const flag =
- view->getLyXFunc()->getStatus(item.action());
- // handle optional entries.
- if (item.optional()
- && (flag.disabled())) {
- lyxerr[Debug::GUI]
- << "Skipping optional item "
- << item.label() << endl;
- break;
- }
-
- // Get the keys bound to this action, but keep only the
- // first one later
- string const accel =
- toplevel_keymap->findbinding(item.action());
+ case MenuItem::Command:
+ case MenuItem::Submenu:
+ {
// Build the menu label from all the info
string label = fixlabel(item.label());
+ FuncStatus const flag = item.status();
+ int submenuid;
- if (!accel.empty()) {
+ // Is there a key binding?
+ string const binding = item.binding();
+ if (!binding.empty()) {
// Try to be clever and add just enough
// tabs to align shortcuts.
do
label += '\t';
while (string_width(label) < max_width + 5);
- label += accel.substr(1,accel.find(']') - 1);
+ label += binding;
}
- label += "%x" + tostr(item.action() + action_offset)
- + extra_label;
+
+ // Is there a separator after the item?
+ if ((i+1) != end
+ && (i + 1)->kind() == MenuItem::Separator)
+ label += "%l";
// Modify the entry using the function status
- string pupmode;
if (flag.onoff(true))
- pupmode += "%B";
+ label += "%B";
if (flag.onoff(false))
- pupmode += "%b";
- if (flag.disabled() || flag.unknown())
- pupmode += "%i";
- else
- all_disabled = false;
- label += pupmode;
-
- // Finally the menu shortcut
- string shortcut = item.shortcut();
-
- if (!shortcut.empty()) {
- shortcut += lowercase(shortcut[0]);
- label += "%h";
- fl_addtopup(curmenuid, label.c_str(),
- shortcut.c_str());
- } else
- fl_addtopup(curmenuid, label.c_str());
-
- lyxerr[Debug::GUI] << "Command: \""
- << lyxaction.getActionName(item.action())
- << "\", binding \"" << accel
- << "\", shortcut \"" << shortcut
- << "\" (added to menu"
- << curmenuid << ")" << endl;
- break;
- }
-
- case MenuItem::Submenu: {
- int submenuid = create_submenu(win, view,
- *item.submenu(), smn,
- all_disabled);
- if (submenuid == -1)
- return -1;
- string label = fixlabel(item.label());
- label += extra_label + "%m";
- if (all_disabled)
+ label += "%b";
+ if (flag.disabled())
label += "%i";
+
+ // Add the shortcut
string shortcut = item.shortcut();
if (!shortcut.empty()) {
shortcut += lowercase(shortcut[0]);
label += "%h";
- fl_addtopup(curmenuid, label.c_str(),
- submenuid, shortcut.c_str());
+ }
+
+ // Finally add the action/submenu
+ if (item.kind() == MenuItem::Submenu) {
+ // create the submenu
+ submenuid =
+ create_submenu(win, view,
+ *item.submenu(), smn);
+ if (submenuid == -1)
+ return -1;
+ label += "%x" + tostr(smn.size());
+ lyxerr[Debug::GUI]
+ << "Menu: " << submenuid
+ << " (at index " << smn.size()
+ << "), ";
} else {
- fl_addtopup(curmenuid, label.c_str(),
- submenuid);
+ // Add the action
+ label += "%x" + tostr(item.action()
+ + action_offset);
+ lyxerr[Debug::GUI] << "Action: \""
+ << item.action() << "\", ";
}
+
+ // Add everything to the menu
+ fl_addtopup(curmenuid, label.c_str(),
+ shortcut.c_str());
+ if (item.kind() == MenuItem::Submenu)
+ fl_setpup_submenu(curmenuid, smn.size(),
+ submenuid);
+
+ lyxerr[Debug::GUI] << "label \"" << label
+ << "\", binding \"" << binding
+ << "\", shortcut \"" << shortcut
+ << "\" (added to menu "
+ << curmenuid << ')' << endl;
break;
}
case MenuItem::Separator:
// already done, and if it was the first one,
// we just ignore it.
+ --count;
break;
MenuBackend const * menubackend_ = iteminfo->pimpl_->menubackend_;
Menu tomenu;
Menu const frommenu = menubackend_->getMenu(item->submenuname());
- menubackend_->expand(frommenu, tomenu, view->buffer());
+ menubackend_->expand(frommenu, tomenu, view);
vector<int> submenus;
- bool all_disabled = true;
- int menu = iteminfo->pimpl_->
- create_submenu(FL_ObjWin(ob), view, tomenu,
- submenus, all_disabled);
+ int menu = iteminfo->pimpl_->create_submenu(FL_ObjWin(ob), view,
+ tomenu, submenus);
if (menu != -1) {
// place popup
fl_setpup_position(view->getForm()->x + ob->x,
// If the action value is too low, then it is not a
// valid action, but something else.
if (choice >= action_offset + 1) {
- view->getLyXFunc()->dispatch(choice - action_offset, true);
+ view->getLyXFunc().dispatch(choice - action_offset, true);
} else {
lyxerr[Debug::GUI]
<< "MenuCallback: ignoring bogus action "
fl_set_tabstop(default_tabstop);
}
+
+
+Menubar::Pimpl::ItemInfo::ItemInfo
+ (Menubar::Pimpl * p, MenuItem const * i, FL_OBJECT * o)
+ : pimpl_(p), obj_(o)
+{
+ item_.reset(i);
+}
+
+
+Menubar::Pimpl::ItemInfo::~ItemInfo()
+{}