summaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
commit7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch)
treea35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h254
1 files changed, 254 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h b/SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h
new file mode 100644
index 0000000..808af3e
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/common/extactioncontainer.h
@@ -0,0 +1,254 @@
+#ifndef extactionCONTAINER_H
+#define extactionCONTAINER_H
+
+#include "iconmanager.h"
+#include "config_builder.h"
+#include "extactionprototype.h"
+#include <QString>
+#include <QHash>
+#include <QSet>
+#include <QKeySequence>
+#include <QShortcut>
+#include <QMetaEnum>
+
+class QAction;
+class QObject;
+class QWidget;
+class QActionGroup;
+class QToolBar;
+class QSignalMapper;
+
+#define CFG_SHORTCUTS_METANAME "Shortcuts"
+
+#define CFG_KEY_LIST(Type, Title, Entries) \
+ _CFG_CATEGORIES_WITH_METANAME(Shortcuts##Type, \
+ _CFG_CATEGORY_WITH_TITLE(ShortcutsCategory##Type, Entries, Title), \
+ CFG_SHORTCUTS_METANAME\
+ )
+
+#define CFG_KEY_ENTRY(Name, KeyStr, Title) CFG_ENTRY(QString, Name, QKeySequence(KeyStr).toString(), Title)
+
+#define CFG_KEYS_DEFINE(Type) CFG_DEFINE_LAZY(Shortcuts##Type)
+
+/**
+ * @def Declares access object for defined shortuts.
+ *
+ * This is the same as CFG_INSTANCE for regular config values.
+ * It's optional. It doesn't need to be declared, but if you want to refer
+ * to keys as to configuration values, then you will need this.
+ */
+#define CFG_KEYS_INSTANCE(Type) (*Cfg::getShortcuts##Type##Instance())
+
+/**
+ * @def Binds shortcuts configuration with actions enumerator.
+ * @param Type Shortcuts category type that was passed to CFG_KEY_LIST.
+ * @param EnumName Enumerator type which lists actions that you want bind shortcuts to.
+ *
+ * Names of shortcut entries have to match names of enumerator literals in order to bind shortcuts
+ * to proper actions.
+ */
+#define BIND_SHORTCUTS(Type, EnumName) \
+ for (int _enumCounter = 0, _totalEnums = staticMetaObject.enumeratorCount(); _enumCounter < _totalEnums; _enumCounter++) \
+ { \
+ if (QString::fromLatin1(staticMetaObject.enumerator(_enumCounter).name()) == #EnumName) \
+ { \
+ bindShortcutsToEnum(Cfg::getShortcuts##Type##Instance()->ShortcutsCategory##Type, staticMetaObject.enumerator(_enumCounter)); \
+ break; \
+ } \
+ }
+
+#define GET_SHORTCUTS(Type) ExtActionContainer::getAllShortcutSequences(Cfg::getShortcuts##Type##Instance()->ShortcutsCategory##Type)
+
+class GUI_API_EXPORT ExtActionContainer
+{
+ private:
+ struct GUI_API_EXPORT ActionDetails
+ {
+ ActionDetails();
+ ActionDetails(ExtActionPrototype* action, int position, bool after);
+
+ ExtActionPrototype* action = nullptr;
+ int position = -1;
+ bool after = false;
+ };
+
+ typedef QList<ActionDetails*> ExtraActions;
+ typedef QHash<int,ExtraActions> ToolBarToAction;
+ typedef QHash<QString,ToolBarToAction> ClassNameToToolBarAndAction;
+
+ public:
+ ExtActionContainer();
+ virtual ~ExtActionContainer();
+
+ QAction* getAction(int action);
+ virtual const QMetaObject* metaObject() const = 0;
+
+ template <class T>
+ static void insertAction(ExtActionPrototype* action, int toolbar = -1);
+
+ template <class T>
+ static void insertActionBefore(ExtActionPrototype* action, int beforeAction, int toolbar = -1);
+
+ template <class T>
+ static void insertActionAfter(ExtActionPrototype* action, int afterAction, int toolbar = -1);
+
+ template <class T>
+ static void removeAction(ExtActionPrototype* action, int toolbar = -1);
+
+ protected:
+ QHash<int,QAction*> actionMap;
+ QHash<int,CfgStringEntry*> shortcuts;
+ QSet<int> noConfigShortcutActions;
+
+ virtual void createActions() = 0;
+ virtual void setupDefShortcuts() = 0;
+
+ void initActions();
+ void createAction(int action, const Icon& icon, const QString& text, const QObject* receiver, const char* slot, QWidget* container,
+ QWidget* owner = 0);
+ void createAction(int action, const QString& text, const QObject* receiver, const char* slot, QWidget* container, QWidget* owner = 0);
+
+ /**
+ * @brief Binds config shortcut entries with action enumerator.
+ * @param cfgCategory Config category with QString entries that have shortcut definitions.
+ * @param actionsEnum Enumerator with actions.
+ *
+ * Binds shortcuts defined in given config category to actions listed by the enumerator.
+ * Binding is done by name, that is name of the config entry (in the category) is matched against enumeration name,
+ *
+ * You don't normally use this method, but instead use BIND_SHORTCUTS.
+ */
+ void bindShortcutsToEnum(CfgCategory &cfgCategory, const QMetaEnum& actionsEnum);
+ void defShortcut(int action, CfgStringEntry* cfgEntry);
+ void setShortcutContext(const QList<qint32> actions, Qt::ShortcutContext context);
+
+ /**
+ * @brief attachActionInMenu
+ * @param parentAction Action that will have a submenu. Must already exist.
+ * @param childAction Action to add to the submenu. Must already exist.
+ * @param toolbar Toolbar that parentAction is already added to.
+ * Puts childAction into submenu of parentAction.
+ */
+ void attachActionInMenu(int parentAction, int childAction, QToolBar* toolbar);
+ void attachActionInMenu(int parentAction, QAction* childAction, QToolBar* toolbar);
+ void attachActionInMenu(QAction* parentAction, QAction* childAction, QToolBar* toolbar);
+ void updateShortcutTips();
+
+ /**
+ * @brief Tells the toolbar object for given toolbar enum value.
+ * @param toolbar Toolbar enum value for specific implementation of MdiChild.
+ * @return Toolbar object or null of there's no toolbar for given value, or no toolbar at all.
+ *
+ * The \p toolbar argument should be enum value from the specific implementation of MdiChild,
+ * for example for TableWindow it could be TOOLBAR_GRID_DATA, which refers to grid data tab toolbar.
+ *
+ * For classes with no toolbar this function will always return null;
+ *
+ * For classes with only one toolbar this method will always return that toolbar, no matter
+ * if the \p toolbar argument was correct.
+ *
+ * For classes with more than one toolbar this method will return proper toolbar objects only
+ * when the \p toolbar argument was correct, otherwise it returns null (assuming correct implementation
+ * of this method).
+ */
+ virtual QToolBar* getToolBar(int toolbar) const = 0;
+
+ void handleActionInsert(int toolbar, ActionDetails* details);
+ void handleActionRemoval(int toolbar, ActionDetails* details);
+
+ private:
+ typedef QPair<int,ActionDetails*> ToolbarAndProto;
+
+ void refreshShortcuts();
+ void refreshShortcut(int action);
+ void deleteActions();
+ void createAction(int action, QAction* qAction, const QObject* receiver, const char* slot, QWidget* container, QWidget* owner);
+ void handleExtraActions();
+
+ template <class T>
+ static QList<T*> getInstances();
+
+ template <class T>
+ static void insertAction(ExtActionPrototype* action, int pos, bool after, int toolbar);
+
+ static ClassNameToToolBarAndAction extraActions;
+ static QList<ExtActionContainer*> instances;
+
+ QSignalMapper* actionIdMapper = nullptr;
+ QHash<QAction*,ToolbarAndProto> extraActionToToolbarAndProto;
+ QHash<ToolbarAndProto,QAction*> toolbarAndProtoToAction;
+};
+
+template <class T>
+void ExtActionContainer::insertAction(ExtActionPrototype* action, int pos, bool after, int toolbar)
+{
+ ActionDetails* dets = new ActionDetails(action, pos, after);
+ QString clsName = T::staticMetaObject.className();
+ extraActions[clsName][toolbar] << dets;
+ for (T* instance : getInstances<T>())
+ instance->handleActionInsert(toolbar, dets);
+}
+
+template <class T>
+void ExtActionContainer::insertAction(ExtActionPrototype* action, int toolbar)
+{
+ insertAction<T>(action, -1, false, toolbar);
+}
+
+template <class T>
+void ExtActionContainer::insertActionAfter(ExtActionPrototype* action, int afterAction, int toolbar)
+{
+ insertAction<T>(action, afterAction, true, toolbar);
+}
+
+template <class T>
+void ExtActionContainer::insertActionBefore(ExtActionPrototype* action, int beforeAction, int toolbar)
+{
+ insertAction<T>(action, beforeAction, false, toolbar);
+}
+
+template <class T>
+void ExtActionContainer::removeAction(ExtActionPrototype* action, int toolbar)
+{
+ QString clsName = T::staticMetaObject.className();
+ if (!extraActions.contains(clsName))
+ return;
+
+ if (!extraActions[clsName].contains(toolbar))
+ return;
+
+ ActionDetails* dets = nullptr;
+ for (ActionDetails* d : extraActions[clsName][toolbar])
+ {
+ if (d->action == action)
+ {
+ dets = d;
+ break;
+ }
+ }
+
+ if (!dets)
+ return;
+
+ for (T* instance : getInstances<T>())
+ instance->handleActionRemoval(toolbar, dets);
+
+ extraActions[clsName][toolbar].removeOne(dets);
+ delete dets;
+}
+
+template <class T>
+QList<T*> ExtActionContainer::getInstances()
+{
+ QList<T*> typedInstances;
+ T* typedInstance = nullptr;
+ for (ExtActionContainer* instance : instances)
+ {
+ typedInstance = dynamic_cast<T*>(instance);
+ if (typedInstance)
+ typedInstances << typedInstance;
+ }
+ return typedInstances;
+}
+
+#endif // extactionCONTAINER_H