mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-06 09:17:42 +02:00
Rework: custom/default key bindings
Issue: macro definitions had to be synchronized for custom key bindings. That's not possible for readonly macros and breaks the architecture. Now, there is a default binding and a custom binding: the macros provide a default binding only and the custom key binding can override this. This scheme is implemented consistently, so now the "reset" function of the key binding editor simply clears the custom binding. Side effect: reset of individual key bindings is possible. Another side effect: removing a key binding from an item with a default one is not possible. Instead, redefine it.
This commit is contained in:
@@ -239,7 +239,9 @@ public:
|
||||
ActionHandle::ActionHandle (QWidget *parent)
|
||||
: mp_action (new ActionObject (parent)),
|
||||
m_ref_count (0),
|
||||
m_owned (true)
|
||||
m_owned (true),
|
||||
m_visible (true),
|
||||
m_hidden (false)
|
||||
{
|
||||
if (! sp_actionHandles) {
|
||||
sp_actionHandles = new std::set<ActionHandle *> ();
|
||||
@@ -253,7 +255,9 @@ ActionHandle::ActionHandle (QWidget *parent)
|
||||
ActionHandle::ActionHandle (QAction *action, bool owned)
|
||||
: mp_action (action),
|
||||
m_ref_count (0),
|
||||
m_owned (owned)
|
||||
m_owned (owned),
|
||||
m_visible (true),
|
||||
m_hidden (false)
|
||||
{
|
||||
if (! sp_actionHandles) {
|
||||
sp_actionHandles = new std::set<ActionHandle *> ();
|
||||
@@ -310,6 +314,89 @@ ActionHandle::destroyed (QObject * /*obj*/)
|
||||
m_owned = false;
|
||||
}
|
||||
|
||||
void
|
||||
ActionHandle::set_visible (bool v)
|
||||
{
|
||||
if (m_visible != v) {
|
||||
m_visible = v;
|
||||
if (mp_action) {
|
||||
mp_action->setVisible (is_effective_visible ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ActionHandle::set_hidden (bool h)
|
||||
{
|
||||
if (m_hidden != h) {
|
||||
m_hidden = h;
|
||||
if (mp_action) {
|
||||
mp_action->setVisible (is_effective_visible ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ActionHandle::is_visible () const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
bool
|
||||
ActionHandle::is_hidden () const
|
||||
{
|
||||
return m_hidden;
|
||||
}
|
||||
|
||||
bool
|
||||
ActionHandle::is_effective_visible () const
|
||||
{
|
||||
return m_visible && !m_hidden;
|
||||
}
|
||||
|
||||
void
|
||||
ActionHandle::set_default_shortcut (const QKeySequence &sc)
|
||||
{
|
||||
if (m_default_shortcut != sc) {
|
||||
m_default_shortcut = sc;
|
||||
if (mp_action) {
|
||||
mp_action->setShortcut (get_effective_shortcut ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ActionHandle::set_shortcut (const QKeySequence &sc)
|
||||
{
|
||||
if (m_shortcut != sc) {
|
||||
m_shortcut = sc;
|
||||
if (mp_action) {
|
||||
mp_action->setShortcut (get_effective_shortcut ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QKeySequence &
|
||||
ActionHandle::get_default_shortcut () const
|
||||
{
|
||||
return m_default_shortcut;
|
||||
}
|
||||
|
||||
const QKeySequence &
|
||||
ActionHandle::get_shortcut () const
|
||||
{
|
||||
return m_shortcut;
|
||||
}
|
||||
|
||||
QKeySequence
|
||||
ActionHandle::get_effective_shortcut () const
|
||||
{
|
||||
if (m_shortcut.isEmpty ()) {
|
||||
return m_default_shortcut;
|
||||
} else {
|
||||
return m_shortcut;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Action implementation
|
||||
@@ -338,6 +425,12 @@ Action::Action (ActionHandle *handle)
|
||||
mp_handle->add_ref ();
|
||||
}
|
||||
|
||||
Action
|
||||
Action::create_free_action (QWidget *parent)
|
||||
{
|
||||
return Action (new ActionHandle (parent));
|
||||
}
|
||||
|
||||
Action::Action (const Action &action)
|
||||
: QObject ()
|
||||
{
|
||||
@@ -422,24 +515,56 @@ Action::get_title () const
|
||||
void
|
||||
Action::set_shortcut (const QKeySequence &s)
|
||||
{
|
||||
if (qaction ()) {
|
||||
qaction ()->setShortcut (s);
|
||||
if (mp_handle) {
|
||||
mp_handle->set_shortcut (s);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
Action::set_default_shortcut (const QKeySequence &s)
|
||||
{
|
||||
if (mp_handle) {
|
||||
mp_handle->set_default_shortcut (s);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Action::set_shortcut (const std::string &s)
|
||||
{
|
||||
if (qaction () && s != get_shortcut ()) {
|
||||
qaction ()->setShortcut (QKeySequence (tl::to_qstring (s)));
|
||||
set_shortcut (QKeySequence (tl::to_qstring (s)));
|
||||
}
|
||||
|
||||
void
|
||||
Action::set_default_shortcut (const std::string &s)
|
||||
{
|
||||
set_default_shortcut (QKeySequence (tl::to_qstring (s)));
|
||||
}
|
||||
|
||||
std::string
|
||||
Action::get_effective_shortcut () const
|
||||
{
|
||||
if (mp_handle) {
|
||||
return tl::to_string (mp_handle->get_effective_shortcut ().toString ());
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
std::string
|
||||
Action::get_shortcut () const
|
||||
{
|
||||
if (qaction ()) {
|
||||
return tl::to_string (qaction ()->shortcut ().toString ());
|
||||
if (mp_handle) {
|
||||
return tl::to_string (mp_handle->get_shortcut ().toString ());
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Action::get_default_shortcut () const
|
||||
{
|
||||
if (mp_handle) {
|
||||
return tl::to_string (mp_handle->get_default_shortcut ().toString ());
|
||||
} else {
|
||||
return std::string ();
|
||||
}
|
||||
@@ -478,7 +603,19 @@ Action::is_enabled () const
|
||||
bool
|
||||
Action::is_visible () const
|
||||
{
|
||||
return qaction () && qaction ()->isVisible ();
|
||||
return mp_handle && mp_handle->is_visible ();
|
||||
}
|
||||
|
||||
bool
|
||||
Action::is_hidden () const
|
||||
{
|
||||
return mp_handle && mp_handle->is_hidden ();
|
||||
}
|
||||
|
||||
bool
|
||||
Action::is_effective_visible () const
|
||||
{
|
||||
return mp_handle && mp_handle->is_effective_visible ();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -498,8 +635,16 @@ Action::set_enabled (bool b)
|
||||
void
|
||||
Action::set_visible (bool v)
|
||||
{
|
||||
if (qaction ()) {
|
||||
qaction ()->setVisible (v);
|
||||
if (mp_handle) {
|
||||
mp_handle->set_visible (v);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Action::set_hidden (bool h)
|
||||
{
|
||||
if (mp_handle) {
|
||||
mp_handle->set_hidden (h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,7 +850,7 @@ AbstractMenu::create_action (const std::string &s)
|
||||
}
|
||||
|
||||
if (! shortcut.empty ()) {
|
||||
ah->ptr ()->setShortcut (QKeySequence (tl::to_qstring (shortcut)));
|
||||
ah->set_default_shortcut (QKeySequence (tl::to_qstring (shortcut)));
|
||||
}
|
||||
|
||||
return ah;
|
||||
@@ -1036,7 +1181,7 @@ AbstractMenu::insert_menu (const std::string &p, const std::string &name, const
|
||||
void
|
||||
AbstractMenu::insert_menu (const std::string &path, const std::string &name, const std::string &title)
|
||||
{
|
||||
insert_menu (path, name, Action (create_action (title)));
|
||||
insert_menu (path, name, create_action (title));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1324,7 +1469,7 @@ AbstractMenu::transfer (const MenuLayoutEntry *layout, AbstractMenuItem &item)
|
||||
a.set_title (title);
|
||||
|
||||
if (! shortcut.empty ()) {
|
||||
a.set_shortcut (QKeySequence (tl::to_qstring (shortcut)));
|
||||
a.set_default_shortcut (shortcut);
|
||||
}
|
||||
|
||||
if (! tool_tip.empty ()) {
|
||||
|
||||
@@ -57,7 +57,7 @@ class PluginRoot;
|
||||
/**
|
||||
* @brief A helper class that does reference counting for the QAction object
|
||||
*/
|
||||
class LAYBASIC_PUBLIC ActionHandle
|
||||
class ActionHandle
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -70,6 +70,18 @@ public:
|
||||
void remove_ref ();
|
||||
QAction *ptr () const;
|
||||
|
||||
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 QKeySequence &sc);
|
||||
void set_shortcut (const QKeySequence &sc);
|
||||
const QKeySequence &get_default_shortcut () const;
|
||||
const QKeySequence &get_shortcut () const;
|
||||
QKeySequence get_effective_shortcut () const;
|
||||
|
||||
protected slots:
|
||||
void destroyed (QObject *obj);
|
||||
|
||||
@@ -77,6 +89,10 @@ private:
|
||||
QAction *mp_action;
|
||||
int m_ref_count;
|
||||
bool m_owned;
|
||||
bool m_visible;
|
||||
bool m_hidden;
|
||||
QKeySequence m_default_shortcut;
|
||||
QKeySequence m_shortcut;
|
||||
|
||||
// no copying
|
||||
ActionHandle (const ActionHandle &);
|
||||
@@ -125,20 +141,18 @@ public:
|
||||
*/
|
||||
Action (const std::string &title);
|
||||
|
||||
/**
|
||||
* @brief Creates a new free action
|
||||
* This constructor wil create a new action with it's own QAction object
|
||||
* under the given parent.
|
||||
*/
|
||||
static Action create_free_action (QWidget *parent);
|
||||
|
||||
/**
|
||||
* @brief Assignement
|
||||
*/
|
||||
Action &operator= (const Action &action);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
@@ -155,20 +169,48 @@ public:
|
||||
std::string get_title () const;
|
||||
|
||||
/**
|
||||
* @brief Set the keyboard shortcut (as a QKeySequence object)
|
||||
* @brief Sets the keyboard shortcut (as a QKeySequence object)
|
||||
* If no shortcut is set, the default shortcut will be taken.
|
||||
*/
|
||||
void set_shortcut (const QKeySequence &s);
|
||||
|
||||
/**
|
||||
* @brief Set the keyboard shortcut
|
||||
* @brief Sets the keyboard shortcut
|
||||
* If no shortcut is set, the default shortcut will be taken.
|
||||
*/
|
||||
void set_shortcut (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Get the keyboard shortcut
|
||||
* @brief Gets the keyboard shortcut
|
||||
* To get the effective shortcut (combination of default shortcut and shortcut),
|
||||
* use "get_effective_shortcut".
|
||||
*/
|
||||
std::string get_shortcut () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the default keyboard shortcut (as a QKeySequence object)
|
||||
* This shortcut is used when no specific shortcut is set.
|
||||
*/
|
||||
void set_default_shortcut (const QKeySequence &s);
|
||||
|
||||
/**
|
||||
* @brief Sets the default keyboard shortcut
|
||||
* This shortcut is used when no specific shortcut is set.
|
||||
*/
|
||||
void set_default_shortcut (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Gets the default keyboard shortcut
|
||||
* To get the effective shortcut (combination of default shortcut and shortcut),
|
||||
* use "get_effective_shortcut".
|
||||
*/
|
||||
std::string get_default_shortcut () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the effective shortcut
|
||||
*/
|
||||
std::string get_effective_shortcut () const;
|
||||
|
||||
/**
|
||||
* @brief "is_checkable" attribute
|
||||
*/
|
||||
@@ -189,6 +231,20 @@ public:
|
||||
*/
|
||||
bool is_visible () const;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the action is intentionally hidden
|
||||
* This flag combines with the visibility. "is_effective_visible" is false
|
||||
* if hidden is true. This feature allows implementation of the menu configuration
|
||||
* feature where users can deliberately switch off and on menu items.
|
||||
*/
|
||||
bool is_hidden () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the effective visibility
|
||||
* See "is_hidden" for details.
|
||||
*/
|
||||
bool is_effective_visible () const;
|
||||
|
||||
/**
|
||||
* @brief "is_separator" attribute
|
||||
*/
|
||||
@@ -204,6 +260,12 @@ public:
|
||||
*/
|
||||
void set_visible (bool v);
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the menu item is hidden
|
||||
* See "is_hidden" for details.
|
||||
*/
|
||||
void set_hidden (bool h);
|
||||
|
||||
/**
|
||||
* @brief Make checkable or not
|
||||
*/
|
||||
@@ -295,7 +357,18 @@ public slots:
|
||||
void triggered_slot ();
|
||||
|
||||
private:
|
||||
friend class AbstractMenu;
|
||||
|
||||
ActionHandle *mp_handle;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -738,17 +811,6 @@ public:
|
||||
*/
|
||||
QMenu *detached_menu (const std::string &name);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param parent The widget to which to attach the QAction object
|
||||
* @return The ActionHandle object created
|
||||
*/
|
||||
static ActionHandle *create_action (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Creates a new exclusive action group
|
||||
*
|
||||
@@ -772,7 +834,9 @@ signals:
|
||||
*/
|
||||
void changed ();
|
||||
|
||||
private:
|
||||
private:
|
||||
friend class Action;
|
||||
|
||||
std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator> > find_item (const std::string &path);
|
||||
const AbstractMenuItem *find_item_exact (const std::string &path) const;
|
||||
AbstractMenuItem *find_item_exact (const std::string &path);
|
||||
@@ -782,6 +846,17 @@ private:
|
||||
void collect_group (std::vector<std::string> &grp, const std::string &name, const AbstractMenuItem &item) const;
|
||||
void reset_menu_objects (AbstractMenuItem &item);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param parent The widget to which to attach the QAction object
|
||||
* @return The ActionHandle object created
|
||||
*/
|
||||
static ActionHandle *create_action (const std::string &s);
|
||||
|
||||
AbstractMenuProvider *mp_provider;
|
||||
AbstractMenuItem m_root;
|
||||
tl::stable_vector<QMenu> m_helper_menu_items;
|
||||
|
||||
@@ -139,7 +139,7 @@ PluginDeclaration::init_menu ()
|
||||
title = tab + 1;
|
||||
}
|
||||
|
||||
m_editable_mode_action = AbstractMenu::create_action (title);
|
||||
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.qaction ()->setData (id ());
|
||||
m_editable_mode_action.set_checkable (true);
|
||||
@@ -163,7 +163,7 @@ PluginDeclaration::init_menu ()
|
||||
menu.insert_menu (m->insert_pos, m->menu_name, m->title);
|
||||
} else {
|
||||
|
||||
Action action (AbstractMenu::create_action (m->title));
|
||||
Action action (m->title);
|
||||
action.qaction ()->setData (QVariant (tl::to_qstring (m->symbol)));
|
||||
gtf::action_connect (action.qaction (), SIGNAL (triggered ()), this, SLOT (generic_menu ()));
|
||||
menu.insert_item (m->insert_pos, m->menu_name, action);
|
||||
@@ -189,7 +189,7 @@ PluginDeclaration::init_menu ()
|
||||
title = std::string (tab + 1);
|
||||
}
|
||||
|
||||
m_mouse_mode_action = AbstractMenu::create_action (title);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user