2002-08-25 18:26:45 +00:00
|
|
|
/**
|
2003-06-28 01:23:11 +00:00
|
|
|
* \file QLPopupMenu.C
|
2002-09-24 13:57:09 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-08-25 18:26:45 +00:00
|
|
|
*
|
2002-10-20 01:48:28 +00:00
|
|
|
* \author John Levon
|
2002-09-24 13:57:09 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2002-08-25 18:26:45 +00:00
|
|
|
*/
|
|
|
|
|
2002-09-24 13:57:09 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2004-05-20 09:36:28 +00:00
|
|
|
// Qt defines a macro 'signals' that clashes with a boost namespace.
|
|
|
|
// All is well if the namespace is visible first.
|
2002-08-25 18:26:45 +00:00
|
|
|
#include "QtView.h"
|
2002-10-20 01:48:28 +00:00
|
|
|
|
2002-08-25 18:26:45 +00:00
|
|
|
#include "QLPopupMenu.h"
|
2004-05-20 09:36:28 +00:00
|
|
|
#include "QLMenubar.h"
|
2002-12-17 20:37:13 +00:00
|
|
|
#include "qt_helpers.h"
|
2002-08-25 18:26:45 +00:00
|
|
|
|
2004-05-20 09:36:28 +00:00
|
|
|
#include "MenuBackend.h"
|
|
|
|
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
|
2004-07-07 09:32:19 +00:00
|
|
|
#ifdef Q_WS_MACX
|
|
|
|
#include "kbmap.h"
|
|
|
|
#include "QLyXKeySym.h"
|
|
|
|
extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
|
|
|
|
#endif
|
|
|
|
|
2004-08-13 15:45:51 +00:00
|
|
|
#include <qapplication.h>
|
|
|
|
|
2004-01-28 16:21:29 +00:00
|
|
|
using std::distance;
|
2003-09-09 22:13:45 +00:00
|
|
|
using std::make_pair;
|
2003-10-06 15:43:21 +00:00
|
|
|
using std::string;
|
2002-09-10 19:23:38 +00:00
|
|
|
using std::pair;
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2004-05-19 15:11:37 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
using support::subst;
|
|
|
|
|
|
|
|
namespace frontend {
|
2002-11-27 10:30:28 +00:00
|
|
|
|
2002-08-25 18:26:45 +00:00
|
|
|
namespace {
|
2002-10-20 01:48:28 +00:00
|
|
|
|
2002-08-25 18:26:45 +00:00
|
|
|
string const getLabel(MenuItem const & mi)
|
|
|
|
{
|
|
|
|
string const shortcut = mi.shortcut();
|
2002-10-20 01:48:28 +00:00
|
|
|
string label = subst(mi.label(), "&", "&&");
|
2002-08-25 18:26:45 +00:00
|
|
|
|
2003-09-21 23:00:47 +00:00
|
|
|
if (!shortcut.empty()) {
|
|
|
|
string::size_type pos = label.find(shortcut);
|
|
|
|
if (pos != string::npos)
|
|
|
|
label.insert(pos, 1, '&');
|
|
|
|
}
|
2002-11-27 10:30:28 +00:00
|
|
|
|
2002-08-25 18:26:45 +00:00
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2004-08-14 18:06:10 +00:00
|
|
|
#ifdef Q_WS_MACX
|
|
|
|
// The offset added to the special Mac menu entries
|
|
|
|
const int indexOffset = 5000;
|
|
|
|
#endif
|
|
|
|
|
2002-10-20 01:48:28 +00:00
|
|
|
} // namespace anon
|
2002-08-25 18:26:45 +00:00
|
|
|
|
|
|
|
|
2002-10-20 01:48:28 +00:00
|
|
|
pair<int, QLPopupMenu *>
|
2003-07-25 21:34:45 +00:00
|
|
|
createMenu(QMenuData * parent, MenuItem const * item, QLMenubar * owner,
|
2003-02-15 21:03:40 +00:00
|
|
|
bool is_toplevel)
|
2002-08-25 18:26:45 +00:00
|
|
|
{
|
2002-09-10 19:23:38 +00:00
|
|
|
QLPopupMenu * pm = new QLPopupMenu(owner, item->submenuname(), is_toplevel);
|
2003-09-21 18:57:15 +00:00
|
|
|
int const id = parent->insertItem(toqstr(getLabel(*item)), pm);
|
2002-09-10 19:23:38 +00:00
|
|
|
return make_pair(id, pm);
|
2002-08-25 18:26:45 +00:00
|
|
|
}
|
2002-10-20 01:48:28 +00:00
|
|
|
|
|
|
|
|
2003-07-25 21:34:45 +00:00
|
|
|
QLPopupMenu::QLPopupMenu(QLMenubar * owner,
|
2002-10-20 01:48:28 +00:00
|
|
|
string const & name, bool toplevel)
|
2002-08-25 18:26:45 +00:00
|
|
|
: owner_(owner), name_(name)
|
|
|
|
{
|
2002-09-10 19:23:38 +00:00
|
|
|
if (toplevel)
|
|
|
|
connect(this, SIGNAL(aboutToShow()), this, SLOT(showing()));
|
2002-09-13 00:04:22 +00:00
|
|
|
connect(this, SIGNAL(activated(int)),
|
2003-09-21 18:57:15 +00:00
|
|
|
this, SLOT(fire(int)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void QLPopupMenu::fire(int index)
|
|
|
|
{
|
2004-08-14 18:06:10 +00:00
|
|
|
#ifdef Q_WS_MACX
|
|
|
|
if (index >= indexOffset) {
|
|
|
|
MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset];
|
|
|
|
owner_->view()->activated(mi.func());
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
owner_->view()->activated(funcs_[index]);
|
2002-08-25 18:26:45 +00:00
|
|
|
}
|
2002-10-20 01:48:28 +00:00
|
|
|
|
2002-08-25 18:26:45 +00:00
|
|
|
|
2002-09-10 19:23:38 +00:00
|
|
|
void QLPopupMenu::populate(Menu * menu)
|
2002-08-25 18:26:45 +00:00
|
|
|
{
|
2003-09-21 18:57:15 +00:00
|
|
|
funcs_.clear();
|
|
|
|
|
2002-09-10 19:23:38 +00:00
|
|
|
Menu::const_iterator m = menu->begin();
|
|
|
|
Menu::const_iterator end = menu->end();
|
2002-08-25 18:26:45 +00:00
|
|
|
for (; m != end; ++m) {
|
|
|
|
if (m->kind() == MenuItem::Separator) {
|
2003-02-15 21:03:40 +00:00
|
|
|
insertSeparator();
|
2002-08-25 18:26:45 +00:00
|
|
|
} else if (m->kind() == MenuItem::Submenu) {
|
2002-09-14 20:10:10 +00:00
|
|
|
pair<int, QLPopupMenu *> res = createMenu(this, &(*m), owner_);
|
2004-03-18 13:57:20 +00:00
|
|
|
setItemEnabled(res.first, m->status().enabled());
|
2002-09-10 19:23:38 +00:00
|
|
|
res.second->populate(m->submenu());
|
2004-08-14 18:06:10 +00:00
|
|
|
} else { // we have a MenuItem::Command
|
2004-10-07 08:03:18 +00:00
|
|
|
FuncStatus status = m->status();
|
2003-02-25 13:35:26 +00:00
|
|
|
|
2003-09-21 18:57:15 +00:00
|
|
|
Funcs::iterator fit =
|
|
|
|
funcs_.insert(funcs_.end(), m->func());
|
2004-01-28 16:21:29 +00:00
|
|
|
int const index = distance(funcs_.begin(), fit);
|
2003-09-21 18:57:15 +00:00
|
|
|
|
2004-07-07 09:32:19 +00:00
|
|
|
QString label = toqstr(getLabel(*m));
|
|
|
|
#ifdef Q_WS_MACX
|
|
|
|
/* There are two constraints on Qt/Mac: (1)
|
|
|
|
the bindings require a unicode string to be
|
|
|
|
represented meaningfully and std::string
|
|
|
|
does not work (2) only 1-key bindings can
|
|
|
|
be represented in menus.
|
2004-10-05 10:11:42 +00:00
|
|
|
|
2004-07-07 09:32:19 +00:00
|
|
|
This is why the unpleasant hack bellow is
|
|
|
|
needed (JMarc)
|
|
|
|
*/
|
|
|
|
pair<LyXKeySym const *, key_modifier::state>
|
|
|
|
binding = toplevel_keymap->find1keybinding(m->func());
|
|
|
|
if (binding.first) {
|
|
|
|
QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
|
|
|
|
label += '\t' + key->qprint(binding.second);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
string const binding(m->binding());
|
|
|
|
if (!binding.empty()) {
|
|
|
|
label += '\t' + toqstr(binding);
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-14 18:06:10 +00:00
|
|
|
|
|
|
|
// Actually insert the menu item
|
2004-07-07 09:32:19 +00:00
|
|
|
insertItem(label, index);
|
2004-03-18 13:57:20 +00:00
|
|
|
setItemEnabled(index, status.enabled());
|
2003-09-21 18:57:15 +00:00
|
|
|
setItemChecked(index, status.onoff(true));
|
2002-08-25 18:26:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-09-10 19:23:38 +00:00
|
|
|
|
2002-10-20 01:48:28 +00:00
|
|
|
|
2002-09-10 19:23:38 +00:00
|
|
|
void QLPopupMenu::showing()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
Menu tomenu;
|
|
|
|
Menu const frommenu = owner_->backend().getMenu(name_);
|
2003-02-15 21:03:40 +00:00
|
|
|
owner_->backend().expand(frommenu, tomenu, owner_->view());
|
2002-10-20 01:48:28 +00:00
|
|
|
populate(&tomenu);
|
2004-08-14 18:06:10 +00:00
|
|
|
#ifdef Q_WS_MACX
|
|
|
|
/* The qt/mac menu code has a very silly hack that
|
|
|
|
moves some menu entries that it recognizes by name
|
|
|
|
(e.g. "Preferences...") to the "LyX" menu. This
|
|
|
|
feature can only work if the menu entries are
|
|
|
|
always available. Since we build menus on demand,
|
|
|
|
we add some dummy contents to one of the menus (JMarc)
|
|
|
|
*/
|
|
|
|
static QLPopupMenu * themenu = this;
|
|
|
|
if (themenu == this && owner_->backend().hasMenu("LyX")) {
|
|
|
|
Menu special = owner_->backend().getMenu("LyX");
|
|
|
|
Menu::const_iterator end = special.end();
|
|
|
|
Menu::size_type i = 0;
|
|
|
|
for (Menu::const_iterator cit = special.begin();
|
|
|
|
cit != end ; ++cit, ++i)
|
|
|
|
insertItem(toqstr(cit->label()), indexOffset + i);
|
|
|
|
}
|
|
|
|
#endif
|
2002-09-10 19:23:38 +00:00
|
|
|
}
|
2004-05-19 15:11:37 +00:00
|
|
|
|
|
|
|
} // namespace frontend
|
|
|
|
} // namespace lyx
|