Basic refactoring: Action -> Action*

This commit is contained in:
Matthias Koefferlein 2020-02-13 00:16:37 +01:00
parent c801df7f7b
commit 0059d1bf24
23 changed files with 787 additions and 1068 deletions

View File

@ -218,8 +218,8 @@ PluginDeclaration::update_current_template ()
std::vector<std::string> menu_entries = mp->menu ()->group ("ruler_mode_group");
for (std::vector<std::string>::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
lay::Action action = mp->menu ()->action (*m);
action.set_title (m_templates [m_current_template].title ());
lay::Action *action = mp->menu ()->action (*m);
action->set_title (m_templates [m_current_template].title ());
}
if (m_templates.size () > 1) {
@ -251,8 +251,8 @@ PluginDeclaration::update_menu ()
if (m_current_template >= 0 && m_current_template < int (m_templates.size ())) {
std::vector<std::string> menu_entries = mp->menu ()->group ("ruler_mode_group");
for (std::vector<std::string>::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
lay::Action action = mp->menu ()->action (*m);
action.set_title (m_templates [m_current_template].title ());
lay::Action *action = mp->menu ()->action (*m);
action->set_title (m_templates [m_current_template].title ());
}
}
@ -269,12 +269,12 @@ PluginDeclaration::update_menu ()
if (m_templates.size () > 1) {
int it = 0;
for (std::vector<Template>::const_iterator tt = m_templates.begin (); tt != m_templates.end (); ++tt, ++it) {
lay::ConfigureAction *action = mp->create_config_action (tt->title (), cfg_current_ruler_template, tl::to_string (it));
lay::ConfigureAction *action = new lay::ConfigureAction (tt->title (), cfg_current_ruler_template, tl::to_string (it));
m_actions.push_back (action);
action->set_checkable (true);
action->set_checked (it == m_current_template);
for (std::vector<std::string>::const_iterator t = tmpl_group.begin (); t != tmpl_group.end (); ++t) {
mp->menu ()->insert_item (*t + ".end", "ruler_template_" + tl::to_string (it), *action);
mp->menu ()->insert_item (*t + ".end", "ruler_template_" + tl::to_string (it), action);
}
}
}

View File

@ -297,13 +297,11 @@ public:
}
// add entries to the combine mode dialog
lay::Action combine_menu = mp->menu ()->action ("@toolbar.combine_mode");
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_add", *mp->create_config_action (tl::to_string (QObject::tr ("Add<:/cm_add.png>{Add shapes}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Add)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_merge", *mp->create_config_action (tl::to_string (QObject::tr ("Merge<:/cm_merge.png>{Merge shapes with background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Merge)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_erase", *mp->create_config_action (tl::to_string (QObject::tr ("Erase<:/cm_erase.png>{Erase shape from background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Erase)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_mask", *mp->create_config_action (tl::to_string (QObject::tr ("Mask<:/cm_mask.png>{Mask background with shape}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Mask)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_diff", *mp->create_config_action (tl::to_string (QObject::tr ("Diff<:/cm_diff.png>{Compute difference of shape with background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Diff)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_add", new lay::ConfigureAction (tl::to_string (QObject::tr ("Add<:/cm_add.png>{Add shapes}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Add)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_merge", new lay::ConfigureAction (tl::to_string (QObject::tr ("Merge<:/cm_merge.png>{Merge shapes with background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Merge)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_erase", new lay::ConfigureAction (tl::to_string (QObject::tr ("Erase<:/cm_erase.png>{Erase shape from background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Erase)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_mask", new lay::ConfigureAction (tl::to_string (QObject::tr ("Mask<:/cm_mask.png>{Mask background with shape}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Mask)));
mp->menu ()->insert_item ("@toolbar.combine_mode.end", "combine_mode_diff", new lay::ConfigureAction (tl::to_string (QObject::tr ("Diff<:/cm_diff.png>{Compute difference of shape with background}")), cfg_edit_combine_mode, CMConverter ().to_string (CM_Diff)));
update_menu (CM_Add);
}
@ -315,23 +313,23 @@ public:
return;
}
lay::Action combine_menu = mp->menu ()->action ("@toolbar.combine_mode");
lay::Action *combine_menu = mp->menu ()->action ("@toolbar.combine_mode");
if (cm == CM_Add) {
combine_menu.set_title (tl::to_string (QObject::tr ("Add")));
combine_menu.set_icon (":/cm_add.png");
combine_menu->set_title (tl::to_string (QObject::tr ("Add")));
combine_menu->set_icon (":/cm_add.png");
} else if (cm == CM_Merge) {
combine_menu.set_title (tl::to_string (QObject::tr ("Merge")));
combine_menu.set_icon (":/cm_merge.png");
combine_menu->set_title (tl::to_string (QObject::tr ("Merge")));
combine_menu->set_icon (":/cm_merge.png");
} else if (cm == CM_Erase) {
combine_menu.set_title (tl::to_string (QObject::tr ("Erase")));
combine_menu.set_icon (":/cm_erase.png");
combine_menu->set_title (tl::to_string (QObject::tr ("Erase")));
combine_menu->set_icon (":/cm_erase.png");
} else if (cm == CM_Mask) {
combine_menu.set_title (tl::to_string (QObject::tr ("Mask")));
combine_menu.set_icon (":/cm_mask.png");
combine_menu->set_title (tl::to_string (QObject::tr ("Mask")));
combine_menu->set_icon (":/cm_mask.png");
} else if (cm == CM_Diff) {
combine_menu.set_title (tl::to_string (QObject::tr ("Diff")));
combine_menu.set_icon (":/cm_diff.png");
combine_menu->set_title (tl::to_string (QObject::tr ("Diff")));
combine_menu->set_icon (":/cm_diff.png");
}
}
@ -378,13 +376,13 @@ public:
return;
}
lay::Action combine_menu = mp->menu ()->action ("@toolbar.combine_mode");
lay::Action *combine_menu = mp->menu ()->action ("@toolbar.combine_mode");
// Do some more initialization here.
combine_mode_type cm = CM_Add;
root->config_get (cfg_edit_combine_mode, cm, CMConverter ());
if (cm != CM_Add && combine_menu.is_visible ()) {
if (cm != CM_Add && combine_menu->is_visible ()) {
lay::TipDialog td (QApplication::activeWindow (),
tl::to_string (QObject::tr ("The background combination mode of the shape editor is set to some other mode than 'Add'.\n"
"This can be confusing, because a shape may not be drawn as expected.\n\nTo switch back to normal mode, choose 'Add' for the background combination mode in the toolbar.")),

View File

@ -666,6 +666,40 @@ static std::string menu_name (std::set<std::string> &used_names, const std::stri
return name;
}
namespace {
class RunMacroAction
: public lay::Action
{
public:
RunMacroAction (lym::Macro *lym)
: lay::Action (), mp_lym (lym)
{
if (lym->description ().empty ()) {
set_title (lym->path ());
} else {
set_title (lym->description ());
}
}
void triggered ()
{
if (mp_lym.get ()) {
mp_lym->run ();
}
}
lym::Macro *macro () const
{
return const_cast<lym::Macro *> (mp_lym.get ());
}
private:
tl::weak_ptr<lym::Macro> mp_lym;
};
}
void
MacroController::add_macro_items_to_menu (lym::MacroCollection &collection, std::set<std::string> &used_names, std::set<std::string> &groups, const db::Technology *tech)
{
@ -702,62 +736,32 @@ MacroController::add_macro_items_to_menu (lym::MacroCollection &collection, std:
std::string gn = tl::trim (c->second->group_name ());
if (! gn.empty () && groups.find (gn) == groups.end ()) {
groups.insert (gn);
lay::Action as;
as.set_separator (true);
lay::Action *as = new lay::Action ();
as->set_separator (true);
m_macro_actions.push_back (as);
mp_mw->menu ()->insert_item (mp, menu_name (used_names, std::string ()), as);
}
lay::Action a;
if (c->second->description ().empty ()) {
a.set_title (c->second->path ());
} else {
a.set_title (c->second->description ());
}
a.set_default_shortcut (sc);
lay::Action *a = new RunMacroAction (c->second);
a->set_default_shortcut (sc);
m_macro_actions.push_back (a);
mp_mw->menu ()->insert_item (mp, menu_name (used_names, c->second->name ()), a);
m_action_to_macro.insert (std::make_pair (a.qaction (), c->second));
lym::MacroSignalAdaptor *adaptor = new lym::MacroSignalAdaptor (a.qaction (), c->second);
QObject::connect (a.qaction (), SIGNAL (triggered ()), adaptor, SLOT (run ()));
} else if (! sc.empty ()) {
// Create actions for shortcut-only actions too and add them to the main window
// to register their shortcut.
lay::Action a;
if (c->second->description ().empty ()) {
a.set_title (c->second->path ());
} else {
a.set_title (c->second->description ());
}
a.set_shortcut (sc);
lay::Action *a = new RunMacroAction (c->second);
a->set_shortcut (sc);
m_macro_actions.push_back (a);
mp_mw->addAction (a.qaction ());
lym::MacroSignalAdaptor *adaptor = new lym::MacroSignalAdaptor (a.qaction (), c->second);
QObject::connect (a.qaction (), SIGNAL (triggered ()), adaptor, SLOT (run ()));
mp_mw->addAction (a->qaction ());
}
}
}
lym::Macro *
MacroController::macro_for_action (const lay::Action *action)
{
if (action) {
std::map<QAction *, lym::Macro *>::const_iterator a2m = m_action_to_macro.find (action->qaction ());
if (a2m != m_action_to_macro.end ()) {
return a2m->second;
}
}
return 0;
}
void
MacroController::sync_with_external_sources ()
{
@ -778,7 +782,6 @@ void
MacroController::macro_collection_changed ()
{
// empty action to macro table now we know it's invalid
m_action_to_macro.clear ();
dm_do_update_menu_with_macros ();
dm_sync_file_watcher ();
}
@ -796,11 +799,16 @@ MacroController::do_update_menu_with_macros ()
}
// delete all existing items
for (std::vector<lay::Action>::iterator a = m_macro_actions.begin (); a != m_macro_actions.end (); ++a) {
std::vector<lay::Action *> actions;
for (tl::weak_collection<lay::Action>::iterator a = m_macro_actions.begin (); a != m_macro_actions.end (); ++a) {
if (a.operator-> ()) {
actions.push_back (a.operator-> ());
}
}
for (std::vector<lay::Action *>::const_iterator a = actions.begin (); a != actions.end (); ++a) {
mp_mw->menu ()->delete_items (*a);
}
m_macro_actions.clear ();
m_action_to_macro.clear ();
std::set<std::string> groups;
std::set<std::string> used_names;
@ -810,16 +818,16 @@ MacroController::do_update_menu_with_macros ()
// apply the custom keyboard shortcuts
for (std::vector<std::pair<std::string, std::string> >::const_iterator kb = m_key_bindings.begin (); kb != m_key_bindings.end (); ++kb) {
if (mp_mw->menu ()->is_valid (kb->first)) {
lay::Action a = mp_mw->menu ()->action (kb->first);
a.set_shortcut (kb->second);
lay::Action *a = mp_mw->menu ()->action (kb->first);
a->set_shortcut (kb->second);
}
}
// apply the custom hidden flags
for (std::vector<std::pair<std::string, bool> >::const_iterator hf = m_menu_items_hidden.begin (); hf != m_menu_items_hidden.end (); ++hf) {
if (mp_mw->menu ()->is_valid (hf->first)) {
lay::Action a = mp_mw->menu ()->action (hf->first);
a.set_hidden (hf->second);
lay::Action *a = mp_mw->menu ()->action (hf->first);
a->set_hidden (hf->second);
}
}
}
@ -876,7 +884,8 @@ static tl::RegisteredClass<lay::PluginDeclaration> macro_controller_decl (new la
static lym::Macro *macro_for_action (const lay::Action *action)
{
return MacroController::instance () ? MacroController::instance ()->macro_for_action (action) : 0;
const RunMacroAction *rma = dynamic_cast<const RunMacroAction *> (action);
return rma ? rma->macro () : 0;
}
// extend lay::Action with the ability to associate a macro with it

View File

@ -162,11 +162,6 @@ public:
*/
void add_temp_macro (lym::Macro *m);
/**
* @brief Gets the macro associated with an Action or nil if there is none
*/
lym::Macro *macro_for_action (const lay::Action *action);
/**
* @brief Obtain the list of macro categories
*/
@ -236,8 +231,7 @@ private:
lay::MacroEditorDialog *mp_macro_editor;
lay::MainWindow *mp_mw;
bool m_no_implicit_macros;
std::vector<lay::Action> m_macro_actions;
std::map<QAction *, lym::Macro *> m_action_to_macro;
tl::weak_collection<lay::Action> m_macro_actions;
lym::MacroCollection m_temp_macros;
std::vector<MacroCategory> m_macro_categories;
std::vector<InternalPathDescriptor> m_internal_paths;

View File

@ -329,7 +329,7 @@ MainConfigPage5::commit (lay::Dispatcher *root)
// The "key bindings" config page
CustomizeMenuConfigPage::CustomizeMenuConfigPage (QWidget *parent)
: lay::ConfigPage (parent), m_enable_event (true)
: lay::ConfigPage (parent), m_enable_event (true), mp_dispatcher (0)
{
mp_ui = new Ui::CustomizeMenuConfigPage ();
mp_ui->setupUi (this);
@ -357,7 +357,7 @@ static void get_shortcuts (const lay::AbstractMenu &menu, const std::string &roo
std::vector<std::string> items = menu.items (root);
for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) {
if (i->size () > 0) {
if (menu.is_valid (*i) && menu.action (*i).is_visible ()) {
if (menu.is_valid (*i) && menu.action (*i)->is_visible ()) {
if (menu.is_menu (*i)) {
// a menu must be listed (so it can be hidden), but does not have a shortcut
// but we don't include special menus
@ -366,7 +366,7 @@ static void get_shortcuts (const lay::AbstractMenu &menu, const std::string &roo
}
get_shortcuts (menu, *i, bindings, with_defaults);
} else if (! menu.is_separator (*i)) {
bindings.insert (std::make_pair (*i, with_defaults ? menu.action (*i).get_default_shortcut () : menu.action (*i).get_effective_shortcut ()));
bindings.insert (std::make_pair (*i, with_defaults ? menu.action (*i)->get_default_shortcut () : menu.action (*i)->get_effective_shortcut ()));
}
}
}
@ -402,11 +402,11 @@ CustomizeMenuConfigPage::apply (const std::vector<std::pair<std::string, std::st
// get the current bindings
m_current_bindings.clear ();
get_shortcuts (*lay::Dispatcher::instance ()->menu (), std::string (), m_current_bindings, false);
get_shortcuts (*mp_dispatcher->menu (), std::string (), m_current_bindings, false);
// get the default bindings
std::map<std::string, std::string> default_bindings;
get_shortcuts (*lay::Dispatcher::instance ()->menu (), std::string (), default_bindings, true);
get_shortcuts (*mp_dispatcher->menu (), std::string (), default_bindings, true);
m_enable_event = false;
@ -416,8 +416,8 @@ CustomizeMenuConfigPage::apply (const std::vector<std::pair<std::string, std::st
for (std::map<std::string, std::string>::iterator kb = m_current_bindings.begin (); kb != m_current_bindings.end (); ++kb) {
std::map<std::string, std::string>::iterator bb = b.find (kb->first);
if (bb != b.end ()) {
lay::Action a = lay::Dispatcher::instance ()->menu ()->action (kb->first);
kb->second = a.get_effective_shortcut_for (bb->second);
lay::Action *a = mp_dispatcher->menu ()->action (kb->first);
kb->second = a->get_effective_shortcut_for (bb->second);
} else {
kb->second.clear ();
}
@ -470,11 +470,11 @@ CustomizeMenuConfigPage::apply (const std::vector<std::pair<std::string, std::st
if (t->first == tl_menu) {
QTreeWidgetItem *item = new QTreeWidgetItem (top_level_item);
lay::Action action = lay::Dispatcher::instance ()->menu ()->action (cb->first);
lay::Action *action = mp_dispatcher->menu ()->action (cb->first);
item->setData (0, Qt::ToolTipRole, tl::to_qstring (rem_path));
item->setData (0, Qt::DisplayRole, tl::to_qstring (rem_path));
item->setData (1, Qt::ToolTipRole, tl::to_qstring (action.get_title ()));
item->setData (1, Qt::DisplayRole, tl::to_qstring (action.get_title ()));
item->setData (1, Qt::ToolTipRole, tl::to_qstring (action->get_title ()));
item->setData (1, Qt::DisplayRole, tl::to_qstring (action->get_title ()));
item->setData (2, Qt::DisplayRole, tl::to_qstring (sc));
item->setData (2, Qt::ForegroundRole, palette ().color (is_default ? QPalette::Disabled : QPalette::Normal, QPalette::Text));
item->setData (0, Qt::UserRole, tl::to_qstring (path));
@ -482,8 +482,8 @@ CustomizeMenuConfigPage::apply (const std::vector<std::pair<std::string, std::st
item->setCheckState (0, hidden ? Qt::Unchecked : Qt::Checked);
item->setHidden (false);
m_item_for_path[path] = item;
if (action.qaction ()) {
m_paths_for_action[action.qaction ()].push_back (path);
if (action->qaction ()) {
m_paths_for_action[action->qaction ()].push_back (path);
}
}
}
@ -502,21 +502,23 @@ CustomizeMenuConfigPage::apply (const std::vector<std::pair<std::string, std::st
}
void
CustomizeMenuConfigPage::setup (lay::Dispatcher *root)
CustomizeMenuConfigPage::setup (lay::Dispatcher *dispatcher)
{
mp_dispatcher = dispatcher;
std::string packed_key_bindings;
root->config_get (cfg_key_bindings, packed_key_bindings);
dispatcher->config_get (cfg_key_bindings, packed_key_bindings);
std::vector<std::pair<std::string, std::string> > key_bindings = unpack_key_binding (packed_key_bindings);
std::string packed_menu_items_hidden;
root->config_get (cfg_menu_items_hidden, packed_menu_items_hidden);
dispatcher->config_get (cfg_menu_items_hidden, packed_menu_items_hidden);
std::vector<std::pair<std::string, bool> > menu_items_hidden = unpack_menu_items_hidden (packed_menu_items_hidden);
apply (key_bindings, menu_items_hidden);
}
void
CustomizeMenuConfigPage::commit (lay::Dispatcher *root)
CustomizeMenuConfigPage::commit (lay::Dispatcher *dispatcher)
{
current_changed (0, mp_ui->bindings_list->currentItem ());
@ -524,14 +526,14 @@ CustomizeMenuConfigPage::commit (lay::Dispatcher *root)
// but never reduce them.
std::string packed_key_bindings;
root->config_get (cfg_key_bindings, packed_key_bindings);
dispatcher->config_get (cfg_key_bindings, packed_key_bindings);
std::vector<std::pair<std::string, std::string> > key_bindings = unpack_key_binding (packed_key_bindings);
for (std::vector<std::pair<std::string, std::string> >::iterator kb = key_bindings.begin (); kb != key_bindings.end (); ++kb) {
std::map<std::string, std::string>::iterator cb = m_current_bindings.find (kb->first);
if (cb != m_current_bindings.end ()) {
lay::Action a = lay::Dispatcher::instance ()->menu ()->action (kb->first);
if (cb->second != a.get_default_shortcut ()) {
lay::Action *a = dispatcher->menu ()->action (kb->first);
if (cb->second != a->get_default_shortcut ()) {
if (cb->second.empty ()) {
kb->second = lay::Action::no_shortcut ();
} else {
@ -549,10 +551,10 @@ CustomizeMenuConfigPage::commit (lay::Dispatcher *root)
}
packed_key_bindings = pack_key_binding (key_bindings);
root->config_set (cfg_key_bindings, packed_key_bindings);
dispatcher->config_set (cfg_key_bindings, packed_key_bindings);
std::string packed_hidden_flags;
root->config_get (cfg_menu_items_hidden, packed_hidden_flags);
dispatcher->config_get (cfg_menu_items_hidden, packed_hidden_flags);
std::vector<std::pair<std::string, bool> > hidden = unpack_menu_items_hidden (packed_hidden_flags);
for (std::vector<std::pair<std::string, bool> >::iterator hf = hidden.begin (); hf != hidden.end (); ++hf) {
@ -568,7 +570,7 @@ CustomizeMenuConfigPage::commit (lay::Dispatcher *root)
}
packed_hidden_flags = pack_menu_items_hidden (hidden);
root->config_set (cfg_menu_items_hidden, packed_hidden_flags);
dispatcher->config_set (cfg_menu_items_hidden, packed_hidden_flags);
}
void
@ -580,10 +582,10 @@ CustomizeMenuConfigPage::text_cleared ()
}
std::string path = tl::to_string (item->data (0, Qt::UserRole).toString ());
lay::Action a = lay::Dispatcher::instance ()->menu ()->action (path);
lay::Action *a = mp_dispatcher->menu ()->action (path);
// "clear" reverts to default
mp_ui->binding_le->setText (tl::to_qstring (a.get_default_shortcut ()));
mp_ui->binding_le->setText (tl::to_qstring (a->get_default_shortcut ()));
}
void
@ -634,8 +636,8 @@ CustomizeMenuConfigPage::update_list_item (QTreeWidgetItem *item)
bool is_default = false;
lay::Action a = lay::Dispatcher::instance ()->menu ()->action (path);
std::string def_shortcut = a.get_default_shortcut ();
lay::Action *a = mp_dispatcher->menu ()->action (path);
std::string def_shortcut = a->get_default_shortcut ();
is_default = (def_shortcut == shortcut);
@ -643,9 +645,9 @@ CustomizeMenuConfigPage::update_list_item (QTreeWidgetItem *item)
item->setData (2, Qt::ForegroundRole, palette ().color (is_default ? QPalette::Disabled : QPalette::Normal, QPalette::Text));
// Set the aliases too
const lay::AbstractMenu &menu = *lay::Dispatcher::instance ()->menu ();
const lay::AbstractMenu &menu = *mp_dispatcher->menu ();
if (menu.is_valid (path)) {
QAction *qaction = menu.action (path).qaction ();
QAction *qaction = menu.action (path)->qaction ();
std::map<QAction *, std::vector<std::string> >::const_iterator a = m_paths_for_action.find (qaction);
if (a != m_paths_for_action.end ()) {
for (std::vector<std::string>::const_iterator p = a->second.begin (); p != a->second.end (); ++p) {
@ -688,7 +690,7 @@ CustomizeMenuConfigPage::current_changed (QTreeWidgetItem *current, QTreeWidgetI
if (current && !current->data (0, Qt::UserRole).isNull ()) {
std::string path = tl::to_string (current->data (0, Qt::UserRole).toString ());
if (lay::Dispatcher::instance ()->menu ()->is_menu (path)) {
if (mp_dispatcher->menu ()->is_menu (path)) {
mp_ui->binding_le->setText (QString ());
#if QT_VERSION >= 0x40700
@ -700,9 +702,9 @@ CustomizeMenuConfigPage::current_changed (QTreeWidgetItem *current, QTreeWidgetI
std::string shortcut = m_current_bindings[path];
lay::Action a = lay::Dispatcher::instance ()->menu ()->action (path);
lay::Action *a = mp_dispatcher->menu ()->action (path);
std::string def_shortcut = a.get_default_shortcut ();
std::string def_shortcut = a->get_default_shortcut ();
mp_ui->binding_le->setText (tl::to_qstring (shortcut));
#if QT_VERSION >= 0x40700

View File

@ -189,6 +189,7 @@ private:
std::map<std::string, QTreeWidgetItem *> m_item_for_path;
std::map<QAction *, std::vector<std::string> > m_paths_for_action;
bool m_enable_event;
lay::Dispatcher *mp_dispatcher;
void apply (const std::vector<std::pair<std::string, std::string> > &bindings, const std::vector<std::pair<std::string, bool> > &menu_items_hidden);
void update_list_item (QTreeWidgetItem *item);

View File

@ -694,10 +694,6 @@ MainWindow::~MainWindow ()
{
lay::register_help_handler (0, 0, 0);
// since the configuration actions unregister themselves, we need to do this before the main
// window is gone:
clear_configuration_actions ();
mw_instance = 0;
// explicitly delete the views here. Otherwise they
@ -734,7 +730,7 @@ MainWindow::init_menu ()
if ((lay::ApplicationBase::instance () && lay::ApplicationBase::instance ()->is_vo_mode ())) {
std::vector<std::string> hide_vo_grp = menu ()->group ("hide_vo");
for (std::vector<std::string>::const_iterator g = hide_vo_grp.begin (); g != hide_vo_grp.end (); ++g) {
menu ()->action (*g).set_visible (false);
menu ()->action (*g)->set_visible (false);
}
}
@ -744,12 +740,12 @@ MainWindow::init_menu ()
std::vector<std::string> edit_mode_grp = menu ()->group ("edit_mode");
for (std::vector<std::string>::const_iterator g = edit_mode_grp.begin (); g != edit_mode_grp.end (); ++g) {
menu ()->action (*g).set_visible (! view_mode);
menu ()->action (*g)->set_visible (! view_mode);
}
std::vector<std::string> view_mode_grp = menu ()->group ("view_mode");
for (std::vector<std::string>::const_iterator g = view_mode_grp.begin (); g != view_mode_grp.end (); ++g) {
menu ()->action (*g).set_visible (view_mode);
menu ()->action (*g)->set_visible (view_mode);
}
}
@ -1136,13 +1132,13 @@ MainWindow::config_finalize ()
std::string name = "default_grid_" + tl::to_string (i);
m_default_grid_actions.push_back (create_config_action (tl::to_string (*g) + tl::to_string (QObject::tr (" um")), cfg_grid, tl::to_string (*g)));
m_default_grid_actions.push_back (new lay::ConfigureAction (tl::to_string (*g) + tl::to_string (QObject::tr (" um")), cfg_grid, tl::to_string (*g)));
m_default_grid_actions.back ()->set_checkable (true);
m_default_grid_actions.back ()->set_checked (fabs (*g - m_grid_micron) < 1e-10);
for (std::vector<std::string>::const_iterator t = group.begin (); t != group.end (); ++t) {
menu ()->insert_item (*t + ".end", name, *m_default_grid_actions.back ());
menu ()->insert_item (*t + ".end", name, m_default_grid_actions.back ());
}
}
@ -1448,8 +1444,8 @@ MainWindow::apply_hidden (const std::vector<std::pair<std::string, bool> > &hidd
{
for (std::vector<std::pair<std::string, bool> >::const_iterator hf = hidden.begin (); hf != hidden.end (); ++hf) {
if (menu ()->is_valid (hf->first)) {
lay::Action a = menu ()->action (hf->first);
a.set_hidden (hf->second);
lay::Action *a = menu ()->action (hf->first);
a->set_hidden (hf->second);
}
}
}
@ -1459,8 +1455,8 @@ MainWindow::apply_key_bindings ()
{
for (std::vector<std::pair<std::string, std::string> >::const_iterator kb = m_key_bindings.begin (); kb != m_key_bindings.end (); ++kb) {
if (menu ()->is_valid (kb->first)) {
lay::Action a = menu ()->action (kb->first);
a.set_shortcut (kb->second);
lay::Action *a = menu ()->action (kb->first);
a->set_shortcut (kb->second);
}
}
}
@ -1481,7 +1477,7 @@ MainWindow::edits_enabled_changed ()
std::vector<std::string> edit_grp = menu ()->group ("edit");
for (std::vector<std::string>::const_iterator g = edit_grp.begin (); g != edit_grp.end (); ++g) {
menu ()->action (*g).set_enabled (enable);
menu ()->action (*g)->set_enabled (enable);
}
}
@ -1859,9 +1855,9 @@ MainWindow::select_mode (int m)
// Plugin's yet (selection, move).
std::vector<std::string> items = menu ()->items ("@toolbar");
for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) {
Action a = menu ()->action (*i);
if (a.qaction ()->isCheckable() && a.qaction ()->data ().toInt () == m_mode) {
a.set_checked (true);
Action *a = menu ()->action (*i);
if (a->qaction ()->isCheckable() && a->qaction ()->data ().toInt () == m_mode) {
a->set_checked (true);
break;
}
}
@ -2029,7 +2025,7 @@ MainWindow::update_action_states ()
if (menu ()->is_valid ("edit_menu.undo")) {
Action undo_action = menu ()->action ("edit_menu.undo");
Action *undo_action = menu ()->action ("edit_menu.undo");
std::string undo_txt (tl::to_string (QObject::tr ("&Undo")));
bool undo_enable = false;
@ -2037,14 +2033,14 @@ MainWindow::update_action_states ()
undo_txt += " - " + m_manager.available_undo ().second;
undo_enable = true;
}
undo_action.set_title (undo_txt);
undo_action.set_enabled (undo_enable && edits_enabled ());
undo_action->set_title (undo_txt);
undo_action->set_enabled (undo_enable && edits_enabled ());
}
if (menu ()->is_valid ("edit_menu.redo")) {
Action redo_action = menu ()->action ("edit_menu.redo");
Action *redo_action = menu ()->action ("edit_menu.redo");
std::string redo_txt (tl::to_string (QObject::tr ("&Redo")));
bool redo_enable = false;
@ -2052,24 +2048,24 @@ MainWindow::update_action_states ()
redo_txt += " - " + m_manager.available_redo ().second;
redo_enable = true;
}
redo_action.set_title (redo_txt);
redo_action.set_enabled (redo_enable && edits_enabled ());
redo_action->set_title (redo_txt);
redo_action->set_enabled (redo_enable && edits_enabled ());
}
if (menu ()->is_valid ("edit_menu.paste")) {
Action paste_action = menu ()->action ("edit_menu.paste");
paste_action.set_enabled (! db::Clipboard::instance ().empty () && edits_enabled ());
Action *paste_action = menu ()->action ("edit_menu.paste");
paste_action->set_enabled (! db::Clipboard::instance ().empty () && edits_enabled ());
}
if (menu ()->is_valid ("zoom_menu.next_display_state")) {
Action next_display_state_action = menu ()->action ("zoom_menu.next_display_state");
next_display_state_action.set_enabled (has_next_display_state ());
Action *next_display_state_action = menu ()->action ("zoom_menu.next_display_state");
next_display_state_action->set_enabled (has_next_display_state ());
}
if (menu ()->is_valid ("zoom_menu.prev_display_state")) {
Action prev_display_state_action = menu ()->action ("zoom_menu.prev_display_state");
prev_display_state_action.set_enabled (has_prev_display_state ());
Action *prev_display_state_action = menu ()->action ("zoom_menu.prev_display_state");
prev_display_state_action->set_enabled (has_prev_display_state ());
}
} catch (...) {
@ -3069,6 +3065,29 @@ MainWindow::add_mru (const std::string &fn_rel, const std::string &tech)
dispatcher ()->config_set (cfg_mru, config_str);
}
namespace
{
class OpenRecentAction
: public lay::Action
{
public:
OpenRecentAction (lay::MainWindow *mw, size_t n)
: lay::Action (), mp_mw (mw), m_n (n)
{ }
void triggered ()
{
mp_mw->open_recent (m_n);
}
private:
lay::MainWindow *mp_mw;
size_t m_n;
};
}
void
MainWindow::do_update_file_menu ()
{
@ -3076,8 +3095,8 @@ MainWindow::do_update_file_menu ()
if (menu ()->is_valid (mru_menu)) {
Action open_recent_action = menu ()->action (mru_menu);
open_recent_action.set_enabled (true);
Action *open_recent_action = menu ()->action (mru_menu);
open_recent_action->set_enabled (true);
if (m_mru.size () > 0 && edits_enabled ()) {
@ -3086,29 +3105,24 @@ MainWindow::do_update_file_menu ()
for (std::vector<std::pair<std::string, std::string> >::iterator mru = m_mru.end (); mru != m_mru.begin (); ) {
--mru;
unsigned int i = std::distance (m_mru.begin (), mru);
Action action;
gtf::action_connect (action.qaction (), SIGNAL (triggered ()), this, SLOT (open_recent ()));
action.set_title (mru->first);
action.qaction ()->setData (QVariant (int (i)));
size_t i = std::distance (m_mru.begin (), mru);
Action *action = new OpenRecentAction (this, i);
action->set_title (mru->first);
menu ()->insert_item (mru_menu + ".end", tl::sprintf ("open_recent_%d", i + 1), action);
}
} else {
open_recent_action.set_enabled (false);
open_recent_action->set_enabled (false);
}
}
}
void
MainWindow::open_recent ()
MainWindow::open_recent (size_t n)
{
BEGIN_PROTECTED
QAction *action = dynamic_cast <QAction *> (sender ());
tl_assert (action);
size_t n = size_t (action->data ().toInt ());
if (n >= m_mru.size ()) {
return;
}

View File

@ -638,7 +638,7 @@ public slots:
void tab_close_requested (int);
void enable_all ();
void disable_all ();
void open_recent ();
void open_recent (size_t n);
void view_selected (int index);
void view_title_changed ();

View File

@ -541,11 +541,11 @@ Navigator::all_hier_levels (bool f)
void
Navigator::freeze_clicked ()
{
Action freeze_action = mp_main_window->menu ()->action (freeze_action_path);
Action *freeze_action = mp_main_window->menu ()->action (freeze_action_path);
m_frozen_list.erase (mp_source_view);
if (freeze_action.is_checked () && mp_source_view) {
if (freeze_action->is_checked () && mp_source_view) {
NavigatorFrozenViewInfo &info = m_frozen_list.insert (std::make_pair (mp_source_view, NavigatorFrozenViewInfo ())).first->second;
info.layer_properties = mp_source_view->get_properties ();
info.hierarchy_levels = mp_source_view->get_hier_levels ();
@ -690,8 +690,8 @@ Navigator::attach_view (LayoutView *view)
all_views.erase (*v);
}
Action freeze_action = mp_main_window->menu ()->action (freeze_action_path);
freeze_action.set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ());
Action *freeze_action = mp_main_window->menu ()->action (freeze_action_path);
freeze_action->set_checked (m_frozen_list.find (mp_source_view) != m_frozen_list.end ());
// Hint: this must happen before update ()
mp_service->attach_view (mp_source_view);

View File

@ -50,7 +50,7 @@ std::string tech_string_from_name (const std::string &tn)
}
TechnologyController::TechnologyController ()
: PluginDeclaration (), mp_editor (0), mp_mw (0), mp_plugin_root (0), mp_active_technology (0)
: PluginDeclaration (), mp_editor (0), mp_mw (0), mp_dispatcher (0), mp_active_technology (0)
{
m_configure_enabled = true;
m_current_technology_updated = false;
@ -70,9 +70,9 @@ TechnologyController::instance ()
}
void
TechnologyController::initialize (lay::Dispatcher *root)
TechnologyController::initialize (lay::Dispatcher *dispatcher)
{
mp_plugin_root = root;
mp_dispatcher = dispatcher;
mp_mw = lay::MainWindow::instance ();
if (mp_mw) {
mp_editor = new lay::TechSetupDialog (mp_mw);
@ -81,9 +81,11 @@ TechnologyController::initialize (lay::Dispatcher *root)
}
void
TechnologyController::initialized (lay::Dispatcher * /*root*/)
TechnologyController::initialized (lay::Dispatcher *dispatcher)
{
update_menu ();
tl_assert (dispatcher == mp_dispatcher);
update_menu (mp_dispatcher);
connect_events ();
if (lay::SaltController::instance ()) {
@ -92,8 +94,10 @@ TechnologyController::initialized (lay::Dispatcher * /*root*/)
}
void
TechnologyController::uninitialize (lay::Dispatcher * /*root*/)
TechnologyController::uninitialize (lay::Dispatcher *dispatcher)
{
tl_assert (dispatcher == mp_dispatcher);
m_tech_actions.clear ();
tl::Object::detach_from_all_events ();
@ -204,11 +208,11 @@ void
TechnologyController::technologies_changed ()
{
// update the configuration to reflect the persisted technologies
lay::Dispatcher *pr = mp_plugin_root;
if (pr) {
lay::Dispatcher *dispatcher = mp_dispatcher;
if (dispatcher) {
m_configure_enabled = false;
try {
pr->config_set (cfg_technologies, db::Technologies::instance ()->to_xml ());
dispatcher->config_set (cfg_technologies, db::Technologies::instance ()->to_xml ());
m_configure_enabled = true;
} catch (...) {
m_configure_enabled = true;
@ -216,7 +220,7 @@ TechnologyController::technologies_changed ()
}
}
update_menu ();
update_menu (dispatcher);
emit technologies_edited ();
}
@ -266,13 +270,13 @@ void
TechnologyController::config_finalize ()
{
if (m_technologies_configured) {
update_menu ();
update_menu (mp_dispatcher);
emit technologies_edited ();
m_technologies_configured = false;
}
if (m_current_technology_updated) {
update_current_technology ();
update_current_technology (mp_dispatcher);
m_current_technology_updated = false;
}
}
@ -296,19 +300,18 @@ TechnologyController::menu_activated (const std::string &symbol) const
}
void
TechnologyController::update_current_technology ()
TechnologyController::update_current_technology (lay::Dispatcher *dispatcher)
{
lay::Dispatcher *pr = lay::Dispatcher::instance ();
if (! pr || ! pr->has_ui ()) {
if (! dispatcher || ! dispatcher->has_ui ()) {
return;
}
std::string title = tech_string_from_name (m_current_technology);
std::vector<std::string> menu_entries = pr->menu ()->group ("tech_selector_group");
std::vector<std::string> menu_entries = dispatcher->menu ()->group ("tech_selector_group");
for (std::vector<std::string>::const_iterator m = menu_entries.begin (); m != menu_entries.end (); ++m) {
lay::Action action = pr->menu ()->action (*m);
action.set_title (title);
lay::Action *action = dispatcher->menu ()->action (*m);
action->set_title (title);
}
std::map<std::string, const db::Technology *> tech_by_name;
@ -318,15 +321,14 @@ TechnologyController::update_current_technology ()
size_t it = 0;
for (std::map<std::string, const db::Technology *>::const_iterator t = tech_by_name.begin (); t != tech_by_name.end () && it < m_tech_actions.size (); ++t, ++it) {
m_tech_actions[it].set_checked (t->second->name () == m_current_technology);
m_tech_actions[it]->set_checked (t->second->name () == m_current_technology);
}
}
void
TechnologyController::update_menu ()
TechnologyController::update_menu (lay::Dispatcher *dispatcher)
{
lay::Dispatcher *pr = lay::Dispatcher::instance ();
if (! pr || ! pr->has_ui ()) {
if (! dispatcher || ! dispatcher->has_ui ()) {
return;
}
@ -345,15 +347,15 @@ TechnologyController::update_menu ()
++ntech;
}
std::vector<std::string> tech_group = pr->menu ()->group ("tech_selector_group");
std::vector<std::string> tech_group = dispatcher->menu ()->group ("tech_selector_group");
for (std::vector<std::string>::const_iterator t = tech_group.begin (); t != tech_group.end (); ++t) {
lay::Action action = pr->menu ()->action (*t);
action.set_title (title);
action.set_enabled (ntech > 1);
std::vector<std::string> items = pr->menu ()->items (*t);
lay::Action *action = dispatcher->menu ()->action (*t);
action->set_title (title);
action->set_enabled (ntech > 1);
std::vector<std::string> items = dispatcher->menu ()->items (*t);
for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) {
pr->menu ()->delete_item (*i);
dispatcher->menu ()->delete_item (*i);
}
}
@ -372,7 +374,7 @@ TechnologyController::update_menu ()
std::string tp = *tg;
if (! g->first.empty ()) {
std::string gn = "techgroup_" + tl::to_string (++ig);
pr->menu ()->insert_menu (*tg + ".end", gn, g->first);
dispatcher->menu ()->insert_menu (*tg + ".end", gn, g->first);
tp = *tg + "." + gn;
}
tp += ".end";
@ -382,11 +384,11 @@ TechnologyController::update_menu ()
std::string title = tech_string_from_name (t->first);
m_tech_actions.push_back (pr->create_config_action ("", cfg_initial_technology, t->first));
m_tech_actions.back ().set_title (title); // setting the title here avoids interpretation of '(...)' etc.
m_tech_actions.back ().set_checkable (true);
m_tech_actions.back ().set_checked (t->first == m_current_technology);
pr->menu ()->insert_item (tp, "technology_" + tl::to_string (it), m_tech_actions.back ());
m_tech_actions.push_back (new lay::ConfigureAction ("", cfg_initial_technology, t->first));
m_tech_actions.back ()->set_title (title); // setting the title here avoids interpretation of '(...)' etc.
m_tech_actions.back ()->set_checkable (true);
m_tech_actions.back ()->set_checked (t->first == m_current_technology);
dispatcher->menu ()->insert_item (tp, "technology_" + tl::to_string (it), m_tech_actions.back ());
}
@ -490,7 +492,7 @@ TechnologyController::show_editor ()
}
mp_plugin_root->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor));
mp_dispatcher->config_set (cfg_tech_editor_window_state, lay::save_dialog_state (mp_editor));
}
const std::string &

View File

@ -125,14 +125,14 @@ private slots:
void sync_with_external_sources ();
private:
tl::stable_vector <lay::Action> m_tech_actions;
std::vector <lay::Action *> m_tech_actions;
std::string m_current_technology;
bool m_configure_enabled;
bool m_current_technology_updated;
bool m_technologies_configured;
lay::TechSetupDialog *mp_editor;
lay::MainWindow *mp_mw;
lay::Dispatcher *mp_plugin_root;
lay::Dispatcher *mp_dispatcher;
std::vector<std::string> m_paths;
std::vector<db::Technology> m_temp_tech;
db::Technology *mp_active_technology;
@ -144,8 +144,8 @@ private:
bool configure (const std::string &name, const std::string &value);
void config_finalize ();
bool menu_activated (const std::string &symbol) const;
void update_current_technology ();
void update_menu ();
void update_current_technology (Dispatcher *dispatcher);
void update_menu (lay::Dispatcher *dispatcher);
void replace_technologies (const db::Technologies &technologies);
};

View File

@ -25,6 +25,34 @@
#include "gsiSignals.h"
#include "layAbstractMenu.h"
namespace {
// The Action stub to allow reimplementation of the triggered method
class ActionStub
: public lay::Action
{
public:
virtual void triggered ()
{
if (triggered_cb.can_issue ()) {
triggered_cb.issue<lay::Action> (&lay::Action::triggered);
}
on_triggered_event ();
}
gsi::Callback triggered_cb;
tl::Event on_triggered_event;
};
}
namespace tl
{
template <> struct type_traits<ActionStub> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
}
namespace gsi
{
@ -87,7 +115,7 @@ Class<lay::AbstractMenu> decl_AbstractMenu ("lay", "AbstractMenu",
"\n"
"This method has been introduced in version 0.26."
) +
method ("action", &lay::AbstractMenu::action,
method ("action", (lay::Action *(lay::AbstractMenu::*) (const std::string &path)) &lay::AbstractMenu::action,
"@brief Get the reference to a Action object associated with the given path\n"
"@args path\n"
"\n"
@ -359,23 +387,6 @@ Class<lay::Action> decl_ActionBase ("lay", "ActionBase",
"@alias Action\n"
);
// The Action stub to allow reimplementation of the triggered method
class ActionStub
: public lay::Action
{
public:
virtual void triggered ()
{
if (triggered_cb.can_issue ()) {
triggered_cb.issue<lay::Action> (&lay::Action::triggered);
}
on_triggered_event ();
}
gsi::Callback triggered_cb;
tl::Event on_triggered_event;
};
Class<ActionStub> decl_Action (decl_ActionBase, "lay", "Action",
gsi::callback ("triggered", &ActionStub::triggered, &ActionStub::triggered_cb,
"@brief This method is called if the menu item is selected"

File diff suppressed because it is too large Load Diff

View File

@ -75,83 +75,14 @@ LAYBASIC_PUBLIC std::vector<std::pair<std::string, bool> > unpack_menu_items_hid
LAYBASIC_PUBLIC std::string pack_menu_items_hidden (const std::vector<std::pair<std::string, bool> > &unpacked);
/**
* @brief A helper class that does reference counting for the QAction object
*/
class ActionHandle
: public QObject
{
Q_OBJECT
public:
ActionHandle ();
ActionHandle (QAction *action, bool owned = true);
ActionHandle (QMenu *menu, bool owned = true);
~ActionHandle ();
void add_ref ();
void remove_ref ();
QAction *ptr () const;
QMenu *menu () const;
Dispatcher *dispatcher () { return mp_dispatcher; }
void set_symbol (const std::string &s) { m_symbol = s; }
const std::string &symbol () const { return m_symbol; }
void set_visible (bool v);
void set_hidden (bool h);
bool is_visible () const;
bool is_hidden () const;
bool is_effective_visible () const;
void set_default_shortcut (const std::string &sc);
void set_shortcut (const std::string &sc);
std::string get_default_shortcut () const;
std::string get_shortcut() const;
QKeySequence get_key_sequence () const;
QKeySequence get_key_sequence_for (const std::string &sc) const;
signals:
void triggered ();
protected slots:
void destroyed (QObject *obj);
void qaction_triggered ();
private:
friend struct AbstractMenuItem;
QMenu *mp_menu;
QAction *mp_action;
lay::Dispatcher *mp_dispatcher;
int m_ref_count;
bool m_owned;
bool m_visible;
bool m_hidden;
std::string m_default_shortcut;
QKeySequence m_default_key_sequence;
std::string m_shortcut;
std::string m_symbol;
QKeySequence m_key_sequence;
bool m_no_key_sequence;
void set_dispatcher (Dispatcher *dispatcher);
// no copying
ActionHandle (const ActionHandle &);
ActionHandle &operator= (const ActionHandle &);
};
/**
* @brief A QAction proxy
* @brief The basic Action object
*
* This class is provided to be better suited to automation because it provides the corresponding interfaces
* and allows implementing the "trigger" event by reimplementation of the slot (after being connected).
* In addition, by acting as a proxy, it can act as a reference to a QAction object created by Qt itself (i.e.
* within a QMenu).
* To reimplement the "triggered" method, derive a class from Action and reimplement "triggered". Then
* pass a reference to this object to "insert_item" of AbstractMenu and store away the derived object.
* This object then will receive the triggered events, although the menu holds a pure Action object.
* This works since the basic object is the QAction to which both the derived object and the Action
* point to. A triggered event will be forwarded from this QAction to all referencing Action objects.
* An "action" is the target of a menu action. It allows reimplementing the "triggered" method
* to implement a specific action. The action encapsulates a QAction object.
*
* Use this object in "insert_item" of AbstractMenu.
*
* This object is typically owned by the AbstractMenu and cannot be copied or assigned.
*/
class LAYBASIC_PUBLIC Action
: public QObject,
@ -162,21 +93,25 @@ Q_OBJECT
public:
/**
* @brief The main constructor
*
* This constructor creates an QAction object internally which is owned by the Action object.
*/
Action ();
/**
* @brief The copy constructor
*
* This constructor creates an QAction object internally which is owned by the Action object.
* @brief Creates an action from the given QAction
* If "owned" is true, the QAction will become owned by the Action object.
*/
Action (const Action &action);
Action (QAction *action, bool owned = true);
/**
* @brief Creates an action from the given QMenu
* If "owned" is true, the QAction will become owned by the Action object.
*/
Action (QMenu *menu, bool owned = true);
/**
* @brief Creates an action with the given title (icon, keyboard shortcut)
*
* The title will optionally encode the shortcut and/or icon resource.
* The format of the title string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param title The title string encoding icon and keyboard shortcut if applicable.
@ -184,14 +119,9 @@ public:
Action (const std::string &title);
/**
* @brief Assignement
* @brief Destructor
*/
Action &operator= (const Action &action);
/**
* @brief The destructor
*/
~Action ();
~Action ();
/**
* @brief Set the title
@ -316,7 +246,7 @@ public:
void set_separator (bool s);
/**
* @brief Set the tool tip text
* @brief Set the tool tip text
*
* @param text The text to display in the tool tip
*/
@ -332,7 +262,7 @@ public:
void set_icon (const std::string &filename);
/**
* @brief Set the icon's text
* @brief Set the icon's text
*
* If an icon text is set, this will be used for the text below the icon.
* If no icon text is set, the normal text will be used for the icon.
@ -340,7 +270,7 @@ public:
*/
void set_icon_text (const std::string &icon_text);
/**
/**
* @brief Set the action's QObject name (for testing for example)
*/
void set_object_name (const std::string &name);
@ -351,12 +281,12 @@ public:
void add_to_exclusive_group (lay::AbstractMenu *menu, const std::string &group_name);
/**
* @brief Get the tool tip text
* @brief Get the tool tip text
*/
std::string get_tool_tip () const;
/**
* @brief Get the icon's text
* @brief Get the icon's text
*/
std::string get_icon_text () const;
@ -382,50 +312,41 @@ public:
*/
QMenu *menu () const;
/**
* @brief Gets the handle
* The handle is the representative of the menu entry which is shared
* by all Action copies.
*/
ActionHandle *handle ()
{
return mp_handle;
}
/**
* @brief Gets the dispatcher object this action is connected to
*/
Dispatcher *dispatcher () const
{
return mp_handle->dispatcher ();
return mp_dispatcher;
}
/**
* @brief Compares two action objects
*
* Two action objects are equal when they refer to the same ActionHandle.
*/
bool operator== (const Action &other) const
{
return mp_handle == other.mp_handle;
}
public slots:
void triggered_slot ();
protected slots:
void destroyed (QObject *obj);
void qaction_triggered ();
private:
friend class AbstractMenu;
friend struct AbstractMenuItem;
ActionHandle *mp_handle;
QMenu *mp_menu;
QAction *mp_action;
lay::Dispatcher *mp_dispatcher;
bool m_owned;
bool m_visible;
bool m_hidden;
std::string m_default_shortcut;
QKeySequence m_default_key_sequence;
std::string m_shortcut;
std::string m_symbol;
QKeySequence m_key_sequence;
bool m_no_key_sequence;
/**
* @brief The proxy constructor
*
* This constructor takes a QAction object that it will refer to.
* If the Action is copied, the copy will refer to the same QAction.
* The QAction object is deleted if the last Action referring to QAction is deleted.
*/
Action (ActionHandle *action);
void set_dispatcher (Dispatcher *dispatcher);
QKeySequence get_key_sequence () const;
QKeySequence get_key_sequence_for (const std::string &sc) const;
// no copying
Action (const Action &);
Action &operator= (const Action &);
};
/**
@ -444,7 +365,7 @@ public:
/**
* @brief The default constructor
*/
ConfigureAction (lay::Dispatcher *dispatcher);
ConfigureAction ();
/**
* @brief Create an configure action with the given name and value
@ -455,14 +376,13 @@ public:
* The value can be "?" in which case the configuration action describes
* a boolean parameter which is mapped to a checkable action.
*/
ConfigureAction (lay::Dispatcher *dispatcher, const std::string &cname, const std::string &value);
ConfigureAction (const std::string &cname, const std::string &value);
/**
* @brief Create an configure action with the given title (icon, keyboard shortcut), name and value
*
* The format of the title string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param pr The reference to the plugin root object which receives the configure request
* @param title The title string encoding icon and keyboard shortcut if applicable.
* @param cname The name of the configuration parameter to set
* @param cvalue The value to set "cname" to
@ -470,7 +390,7 @@ public:
* The value can be "?" in which case the configuration action describes
* a boolean parameter which is mapped to a checkable action.
*/
ConfigureAction (lay::Dispatcher *dispatcher, const std::string &title, const std::string &cname, const std::string &value);
ConfigureAction (const std::string &title, const std::string &cname, const std::string &value);
/**
* @brief Destructor
@ -519,14 +439,10 @@ public:
protected:
virtual void triggered ();
void reg ();
void unreg ();
private:
ConfigureAction (const ConfigureAction &action);
ConfigureAction &operator= (const ConfigureAction &action);
lay::Dispatcher *mp_dispatcher;
std::string m_cname, m_cvalue;
type m_type;
};
@ -544,7 +460,7 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
/**
* @brief Internal method used to set up the item
*/
void setup_item (const std::string &pn, const std::string &n, const Action &a);
void setup_item (const std::string &pn, const std::string &n, Action *a);
Dispatcher *dispatcher () const
{
@ -561,18 +477,23 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
return m_groups;
}
void set_action (const Action &a, bool copy_properties);
void set_action (Action *a, bool copy_properties);
void set_action_title (const std::string &t);
const Action &action () const
Action *action ()
{
return m_action;
return mp_action.get ();
}
QMenu *menu () const
const Action *action () const
{
return m_action.menu ();
return mp_action.get ();
}
QMenu *menu ()
{
return mp_action->menu ();
}
void set_has_submenu ();
@ -592,7 +513,7 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
std::list <AbstractMenuItem> children;
private:
Action m_action;
tl::shared_ptr<Action> mp_action;
Dispatcher *mp_dispatcher;
bool m_has_submenu;
bool m_remove_on_empty;
@ -694,7 +615,12 @@ public:
* @param path The path to the item. This must be a valid path.
* @return The action object
*/
Action action (const std::string &path) const;
Action *action (const std::string &path);
/**
* @brief Get the Action object for a given item (const version)
*/
const Action *action(const std::string &path) const;
/**
* @brief Get the subitems for a given submenu
@ -737,8 +663,10 @@ public:
* @param path The path to the item before which to insert the new item
* @param name The name of the item to insert
* @param action The action associated with the item
*
* NOTE: the abstract menu will take ownership of the Action object.
*/
void insert_item (const std::string &path, const std::string &name, const Action &action);
void insert_item (const std::string &path, const std::string &name, Action *action);
/**
* @brief Insert a new separator before the one item by the path
@ -758,7 +686,7 @@ public:
* @param name The name of the submenu to insert
* @param action The action associated with the submenu
*/
void insert_menu (const std::string &path, const std::string &name, const Action &action);
void insert_menu (const std::string &path, const std::string &name, Action *action);
/**
* @brief Insert a new submenu before the item given by the path
@ -789,7 +717,7 @@ public:
/**
* @brief Delete the items referring to the given action
*/
void delete_items (const Action &action);
void delete_items (Action *action);
/**
* @brief Get the group members
@ -805,7 +733,14 @@ public:
* @param group The group name
* @param A vector of all members (as actions) of the group
*/
std::vector<lay::Action> group_actions (const std::string &name) const;
std::vector<Action *> group_actions(const std::string &name);
/**
* @brief Get the configure actions for a given configuration name
*
* @param The configuration actions for this given configuration name
*/
std::vector<lay::ConfigureAction *> configure_actions (const std::string &name);
/**
* @brief Get the detached menu
@ -852,21 +787,15 @@ private:
void build (QMenu *menu, std::list<AbstractMenuItem> &items);
void build (QToolBar *tbar, std::list<AbstractMenuItem> &items);
void collect_group (std::vector<std::string> &grp, const std::string &name, const AbstractMenuItem &item) const;
/**
* @brief Create a action from a string
*
* The format of the string is: <text>["("shortcut")"]["<"icon-resource">"]
*
* @param s The title, key and icon resource string in the format given above
* @return The ActionHandle object created
*/
static ActionHandle *create_action (const std::string &s);
void collect_configure_actions (std::vector<ConfigureAction *> &ca, AbstractMenuItem &item);
void emit_changed ();
Dispatcher *mp_dispatcher;
AbstractMenuItem m_root;
tl::stable_vector<QMenu> m_helper_menu_items;
std::map<std::string, QActionGroup *> m_action_groups;
std::map<std::string, std::vector<ConfigureAction *> > m_config_action_by_name;
bool m_config_actions_valid;
};
}
@ -877,6 +806,15 @@ namespace tl
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
template <> struct type_traits<lay::AbstractMenuItem> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_default_constructor;
};
template <> struct type_traits<lay::Action> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
}
#endif

View File

@ -50,66 +50,13 @@ Dispatcher::~Dispatcher ()
}
}
lay::ConfigureAction *
Dispatcher::create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue)
{
lay::ConfigureAction *ca = new lay::ConfigureAction (this, title, cname, cvalue);
m_ca_collection.push_back (ca);
return ca;
}
lay::ConfigureAction *
Dispatcher::create_config_action (const std::string &cname, const std::string &cvalue)
{
lay::ConfigureAction *ca = new lay::ConfigureAction (this, std::string (), cname, cvalue);
m_ca_collection.push_back (ca);
return ca;
}
void
Dispatcher::register_config_action (const std::string &name, lay::ConfigureAction *action)
{
std::map<std::string, std::vector<lay::ConfigureAction *> >::iterator ca = m_configuration_actions.insert (std::make_pair (name, std::vector<lay::ConfigureAction *> ())).first;
for (std::vector<lay::ConfigureAction *>::iterator a = ca->second.begin (); a != ca->second.end (); ++a) {
if (*a == action) {
return; // already registered
}
}
ca->second.push_back (action);
}
void
Dispatcher::unregister_config_action (const std::string &name, lay::ConfigureAction *action)
{
std::map<std::string, std::vector<lay::ConfigureAction *> >::iterator ca = m_configuration_actions.find (name);
if (ca != m_configuration_actions.end ()) {
for (std::vector<lay::ConfigureAction *>::iterator a = ca->second.begin (); a != ca->second.end (); ++a) {
if (*a == action) {
ca->second.erase (a);
return;
}
}
}
}
void
Dispatcher::clear_configuration_actions ()
{
m_ca_collection.clear ();
m_configuration_actions.clear ();
}
bool
Dispatcher::configure (const std::string &name, const std::string &value)
{
std::map<std::string, std::vector<lay::ConfigureAction *> >::iterator ca = m_configuration_actions.find (name);
if (ca != m_configuration_actions.end ()) {
for (std::vector<lay::ConfigureAction *>::const_iterator a = ca->second.begin (); a != ca->second.end (); ++a) {
(*a)->configure (value);
}
std::vector<lay::ConfigureAction *> ca = m_menu.configure_actions (name);
for (std::vector<lay::ConfigureAction *>::const_iterator a = ca.begin (); a != ca.end (); ++a) {
(*a)->configure (value);
}
return false;
}

View File

@ -129,44 +129,15 @@ public:
return (dispatcher () == this) ? &m_menu : dispatcher ()->menu ();
}
/**
* @brief Creates a configuration action with the given title, parameter name and value
*
* The action will be owned by the abstract menu provider but can be deleted to remove it from there.
*/
lay::ConfigureAction *create_config_action (const std::string &title, const std::string &cname, const std::string &cvalue);
/**
* @brief Creates a configuration action with the given parameter name and value
*
* The action will be owned by the abstract menu provider but can be deleted to remove it from there.
* This version is provided for applications, where the title is set later.
*/
lay::ConfigureAction *create_config_action (const std::string &cname, const std::string &cvalue);
/**
* @brief Registers a configuration action with the given name
*/
void register_config_action (const std::string &name, lay::ConfigureAction *action);
/**
* @brief Unregisters a configuration action with the given name
*/
void unregister_config_action (const std::string &name, lay::ConfigureAction *action);
protected:
// capture the configuration events so we can change the value of the configuration actions
virtual bool configure (const std::string &name, const std::string &value);
void clear_configuration_actions ();
private:
Dispatcher (const Dispatcher &);
Dispatcher &operator= (const Dispatcher &);
lay::AbstractMenu m_menu;
std::map<std::string, std::vector<lay::ConfigureAction *> > m_configuration_actions;
tl::shared_collection<lay::ConfigureAction> m_ca_collection;
};
}

View File

@ -366,11 +366,11 @@ LayoutView::init_menu ()
// if not in editable mode, hide all entries from "edit_mode" group and show all from the "view_mode" group and vice versa
std::vector<std::string> edit_mode_grp = menu ()->group ("edit_mode");
for (std::vector<std::string>::const_iterator g = edit_mode_grp.begin (); g != edit_mode_grp.end (); ++g) {
menu ()->action (*g).set_visible (is_editable ());
menu ()->action (*g)->set_visible (is_editable ());
}
std::vector<std::string> view_mode_grp = menu ()->group ("view_mode");
for (std::vector<std::string>::const_iterator g = view_mode_grp.begin (); g != view_mode_grp.end (); ++g) {
menu ()->action (*g).set_visible (! is_editable ());
menu ()->action (*g)->set_visible (! is_editable ());
}
}
@ -896,6 +896,32 @@ Plugin *LayoutView::get_plugin_by_name (const std::string &name) const
return 0;
}
namespace {
class GotoBookmarkAction
: public lay::Action
{
public:
GotoBookmarkAction (lay::LayoutView *view, size_t id, const std::string &title)
: Action (), mp_view (view), m_id (id)
{
set_title (title);
}
void triggered ()
{
if (mp_view) {
mp_view->goto_view (mp_view->bookmarks ().state (m_id));
}
}
private:
tl::weak_ptr<lay::LayoutView> mp_view;
size_t m_id;
};
}
void
LayoutView::update_menu (lay::LayoutView *view, lay::AbstractMenu &menu)
{
@ -905,23 +931,20 @@ LayoutView::update_menu (lay::LayoutView *view, lay::AbstractMenu &menu)
menu.clear_menu (bm_menu);
Action goto_bookmark_action = menu.action (bm_menu);
Action *goto_bookmark_action = menu.action (bm_menu);
if (view && view->bookmarks ().size () > 0) {
goto_bookmark_action.set_enabled (true);
goto_bookmark_action->set_enabled (true);
const lay::BookmarkList &bookmarks = view->bookmarks ();
for (size_t i = 0; i < bookmarks.size (); ++i) {
Action action;
gtf::action_connect (action.qaction (), SIGNAL (triggered ()), view, SLOT (goto_bookmark ()));
action.set_title (bookmarks.name (i));
action.qaction ()->setData (QVariant (int (i)));
Action *action = new GotoBookmarkAction (view, i, bookmarks.name (i));
menu.insert_item (bm_menu + ".end", tl::sprintf ("bookmark_%d", i + 1), action);
}
} else {
goto_bookmark_action.set_enabled (false);
goto_bookmark_action->set_enabled (false);
}
}
@ -3917,21 +3940,6 @@ LayoutView::bookmark_view (const std::string &name)
emit menu_needs_update ();
}
void
LayoutView::goto_bookmark ()
{
BEGIN_PROTECTED
QAction *action = dynamic_cast <QAction *> (sender ());
tl_assert (action);
size_t id = size_t (action->data ().toInt ());
if (bookmarks ().size () > id) {
goto_view (bookmarks ().state (id));
}
END_PROTECTED
}
void
LayoutView::goto_view (const DisplayState &state)
{

View File

@ -2684,7 +2684,6 @@ public slots:
private slots:
void active_cellview_changed (int index);
void active_library_changed (int index);
void goto_bookmark ();
void side_panel_destroyed ();
signals:

View File

@ -56,8 +56,6 @@ PluginDeclaration::PluginDeclaration ()
PluginDeclaration::~PluginDeclaration ()
{
clear_menu_items ();
if (Dispatcher::instance ()) {
Dispatcher::instance ()->plugin_removed (this);
}
@ -95,60 +93,58 @@ PluginDeclaration::menu_symbols ()
return symbols;
}
void
PluginDeclaration::generic_menu ()
namespace {
class GenericMenuAction
: public Action
{
BEGIN_PROTECTED
public:
GenericMenuAction (Dispatcher *dispatcher, const std::string &title, const std::string &symbol)
: Action (title), mp_dispatcher (dispatcher), m_symbol (symbol)
{ }
ActionHandle *action_handle = dynamic_cast <ActionHandle *> (sender ());
tl_assert (action_handle);
tl_assert (action_handle->dispatcher () != 0);
// Global handler: give the declaration a chance to handle the menu request globally
if (menu_activated (action_handle->symbol ())) {
return;
void triggered ()
{
if (mp_dispatcher) {
mp_dispatcher->menu_activated (m_symbol);
}
}
// Forward the request to the plugin root which will propagate it down to the plugins
action_handle->dispatcher ()->menu_activated (action_handle->symbol ());
private:
Dispatcher *mp_dispatcher;
std::string m_symbol;
};
END_PROTECTED
}
void
PluginDeclaration::mode_triggered ()
class ModeAction
: public Action
{
BEGIN_PROTECTED
public:
ModeAction (Dispatcher *dispatcher, const std::string &title, int mode)
: Action (title), mp_dispatcher (dispatcher), m_mode (mode)
{ }
ActionHandle *action_handle = dynamic_cast<ActionHandle *> (sender ());
tl_assert (action_handle != 0);
tl_assert (action_handle->dispatcher () != 0);
void triggered ()
{
if (mp_dispatcher) {
mp_dispatcher->select_mode (m_mode);
set_checked (true);
}
}
int mode = 0;
tl::from_string (action_handle->symbol (), mode);
private:
Dispatcher *mp_dispatcher;
int m_mode;
};
action_handle->dispatcher ()->select_mode (mode);
action_handle->ptr ()->setChecked (true);
END_PROTECTED
}
void
PluginDeclaration::clear_menu_items ()
{
m_menu_actions.clear ();
m_our_menu_actions.clear ();
}
void
PluginDeclaration::init_menu (lay::Dispatcher *dispatcher)
{
lay::AbstractMenu &menu = *dispatcher->menu ();
// pre-initialize to allow multiple init_menu calls
m_editable_mode_action = lay::Action ();
m_mouse_mode_action = lay::Action ();
clear_menu_items ();
mp_editable_mode_action.reset ((Action *) 0);
mp_mouse_mode_action.reset ((Action *) 0);
std::string title;
@ -166,12 +162,12 @@ PluginDeclaration::init_menu (lay::Dispatcher *dispatcher)
title = tab + 1;
}
m_editable_mode_action = Action (title);
gtf::action_connect (m_editable_mode_action.qaction (), SIGNAL (triggered ()), this, SLOT (toggle_editable_enabled ()));
m_editable_mode_action.set_checkable (true);
m_editable_mode_action.set_checked (m_editable_enabled);
mp_editable_mode_action.reset (new Action (title));
gtf::action_connect (mp_editable_mode_action->qaction (), SIGNAL (triggered ()), this, SLOT (toggle_editable_enabled ()));
mp_editable_mode_action->set_checkable (true);
mp_editable_mode_action->set_checked (m_editable_enabled);
menu.insert_item ("edit_menu.select_menu.end", name, m_editable_mode_action);
menu.insert_item ("edit_menu.select_menu.end", name, mp_editable_mode_action.get ());
}
@ -198,20 +194,13 @@ PluginDeclaration::init_menu (lay::Dispatcher *dispatcher)
Action *action = 0;
if (! m->cname.empty ()) {
action = dispatcher->create_config_action (m->title, m->cname, m->cvalue);
action = new ConfigureAction (m->title, m->cname, m->cvalue);
} else {
action = new Action (m->title);
action->handle ()->set_symbol (m->symbol);
connect (action->handle (), SIGNAL (triggered ()), this, SLOT (generic_menu ()));
m_our_menu_actions.push_back (action);
action = new GenericMenuAction (dispatcher, m->title, m->symbol);
}
m_menu_actions.push_back (action);
menu.insert_item (m->insert_pos, m->menu_name, *action);
menu.insert_item (m->insert_pos, m->menu_name, action);
if (! m->exclusive_group.empty ()) {
action->add_to_exclusive_group (&menu, m->exclusive_group);
@ -254,14 +243,11 @@ PluginDeclaration::init_menu (lay::Dispatcher *dispatcher)
title = std::string (tab + 1);
}
m_mouse_mode_action = Action (title);
m_mouse_mode_action.add_to_exclusive_group (&menu, "mouse_mode_exclusive_group");
m_mouse_mode_action.set_checkable (true);
m_mouse_mode_action.handle ()->set_symbol (tl::to_string (m->second.second));
mp_mouse_mode_action.reset (new ModeAction (dispatcher, title, m->second.second));
mp_mouse_mode_action->add_to_exclusive_group (&menu, "mouse_mode_exclusive_group");
mp_mouse_mode_action->set_checkable (true);
menu.insert_item (m->second.first, name + ":mode_group", m_mouse_mode_action);
connect (m_mouse_mode_action.handle (), SIGNAL (triggered ()), this, SLOT (mode_triggered ()));
menu.insert_item (m->second.first, name + ":mode_group", mp_mouse_mode_action.get ());
}
}
@ -270,13 +256,19 @@ void
PluginDeclaration::remove_menu_items (Dispatcher *dispatcher)
{
lay::AbstractMenu *menu = dispatcher->menu ();
menu->delete_items (m_editable_mode_action);
menu->delete_items (m_mouse_mode_action);
menu->delete_items (mp_editable_mode_action.get ());
menu->delete_items (mp_mouse_mode_action.get ());
std::vector<lay::Action *> actions;
for (tl::weak_collection <lay::Action>::iterator a = m_menu_actions.begin (); a != m_menu_actions.end (); ++a) {
if (a.operator-> ()) {
menu->delete_items (*a);
actions.push_back (a.operator-> ());
}
}
for (std::vector<lay::Action *>::const_iterator a = actions.begin (); a != actions.end (); ++a) {
menu->delete_items (*a);
}
m_menu_actions.clear ();
}
void
@ -284,7 +276,9 @@ PluginDeclaration::set_editable_enabled (bool f)
{
if (f != m_editable_enabled) {
m_editable_enabled = f;
m_editable_mode_action.set_checked (f);
if (mp_editable_mode_action.get ()) {
mp_editable_mode_action->set_checked (f);
}
editable_enabled_changed_event ();
}
}

View File

@ -471,18 +471,13 @@ public:
private slots:
void toggle_editable_enabled ();
void generic_menu ();
void mode_triggered ();
private:
int m_id;
tl::weak_collection <lay::Action> m_menu_actions;
tl::shared_collection <lay::Action> m_our_menu_actions;
lay::Action m_editable_mode_action;
lay::Action m_mouse_mode_action;
tl::weak_ptr<lay::Action> mp_editable_mode_action;
tl::weak_ptr<lay::Action> mp_mouse_mode_action;
tl::weak_collection<lay::Action> m_menu_actions;
bool m_editable_enabled;
void clear_menu_items ();
};
/**

View File

@ -51,57 +51,57 @@ TEST(1)
EXPECT_EQ (menu_to_string (menu), "");
try {
EXPECT_EQ (menu.action ("n1").get_title (), "");
EXPECT_EQ (menu.action ("n1")->get_title (), "");
EXPECT_EQ (true, false);
} catch (...) {
}
EXPECT_EQ (menu.is_valid ("n1"), false);
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
EXPECT_EQ (menu_to_string (menu), "(n1)");
EXPECT_EQ (tl::join (menu.items (""), ","), "n1");
EXPECT_EQ (menu.is_menu ("n1"), true);
EXPECT_EQ (menu.action ("n1").get_title (), "title:n1");
EXPECT_EQ (menu.action ("n1")->get_title (), "title:n1");
EXPECT_EQ (menu.is_valid ("n1"), true);
EXPECT_EQ (menu.is_valid ("n2"), false);
menu.insert_menu ("end", "n2", lay::Action ("title:n2"));
menu.insert_menu ("end", "n2", new lay::Action ("title:n2"));
EXPECT_EQ (menu_to_string (menu), "(n1,n2)");
EXPECT_EQ (tl::join (menu.items (""), ","), "n1,n2");
EXPECT_EQ (menu.is_menu ("n2"), true);
EXPECT_EQ (menu.action ("n2").get_title (), "title:n2");
EXPECT_EQ (menu.action ("n2")->get_title (), "title:n2");
EXPECT_EQ (menu.is_valid ("n2"), true);
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1)");
EXPECT_EQ (menu.is_menu ("n1"), true);
EXPECT_EQ (menu.action ("n1").get_title (), "title:n1");
EXPECT_EQ (menu.action ("n1")->get_title (), "title:n1");
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1");
menu.insert_item ("n1.end", "c2", lay::Action ("title:c2"));
menu.insert_item ("n1.end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1,n1.c2");
EXPECT_EQ (menu.is_menu ("n1.c2"), false);
EXPECT_EQ (menu.action ("n1.c2").get_title (), "title:c2");
EXPECT_EQ (menu.action ("n1.c2")->get_title (), "title:c2");
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1a"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1a"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
EXPECT_EQ (tl::join (menu.items ("n1"), ","), "n1.c1,n1.c2");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1a");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1a");
menu.insert_item ("n1.c1", "c3", lay::Action ("title:c3"));
menu.insert_item ("n1.c1", "c3", new lay::Action ("title:c3"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c1,n1.c2))");
menu.insert_item ("n1.c1+", "c4", lay::Action ("title:c4"));
menu.insert_item ("n1.c1+", "c4", new lay::Action ("title:c4"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c1,n1.c4,n1.c2))");
EXPECT_EQ (menu.action ("n1.c4").get_title (), "title:c4");
EXPECT_EQ (menu.action ("n1.c4")->get_title (), "title:c4");
menu.delete_item ("n1.c1");
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c3,n1.c4,n1.c2))");
@ -109,11 +109,11 @@ TEST(1)
menu.delete_item ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2)");
menu.insert_item ("n1>end(title).end", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1>end(title).end", "c1", new lay::Action ("title:c1"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1))");
EXPECT_EQ (menu.action ("n1.c1").get_title (), "title:c1");
EXPECT_EQ (menu.action ("n1.c1")->get_title (), "title:c1");
menu.insert_item ("n1>end(title).end", "c2", lay::Action ("title:c2"));
menu.insert_item ("n1>end(title).end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
menu.delete_item ("n1.c1");
@ -128,9 +128,9 @@ TEST(1)
menu.clear_menu ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2)");
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1"));
menu.insert_item ("n1.end", "c2", lay::Action ("title:c2"));
menu.insert_menu ("end", "n1", new lay::Action ("title:n1"));
menu.insert_item ("n1.begin", "c1", new lay::Action ("title:c1"));
menu.insert_item ("n1.end", "c2", new lay::Action ("title:c2"));
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
menu.clear_menu ("n1");
EXPECT_EQ (menu_to_string (menu), "(n2,n1)");

View File

@ -1903,22 +1903,5 @@ void MacroCollection::dump (int l)
}
}
// ----------------------------------------------------------------------
MacroSignalAdaptor::MacroSignalAdaptor (QObject *parent, Macro *macro)
: QObject (parent), mp_macro (macro)
{
// .. nothing yet ..
}
void MacroSignalAdaptor::run ()
{
BEGIN_PROTECTED
if (mp_macro) {
mp_macro->run ();
}
END_PROTECTED
}
}

View File

@ -25,6 +25,7 @@
#define HDR_lymMacro
#include "lymCommon.h"
#include "tlObject.h"
#include <string>
#include <map>
@ -55,7 +56,8 @@ class MacroCollection;
* by itself which interpreter to use.
*/
class LYM_PUBLIC Macro
: public QObject
: public QObject,
public tl::Object
{
Q_OBJECT
@ -1128,26 +1130,6 @@ private:
MacroCollection &operator= (const MacroCollection &d);
};
/**
* @brief A signal to macro adaptor
*
* This class allows calling a macro from a signal
*/
class LYM_PUBLIC MacroSignalAdaptor
: public QObject
{
Q_OBJECT
public:
MacroSignalAdaptor (QObject *parent, Macro *macro);
public slots:
void run ();
private:
Macro *mp_macro;
};
}
#endif