From a0e673aa61b409329bdde325455251eb9b84f30a Mon Sep 17 00:00:00 2001 From: Dirk Wilden Date: Wed, 17 Sep 2008 11:32:25 +0000 Subject: [PATCH] updated keyInterface key registration added git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@2826 383ad7c9-94d9-4d36-a494-682f7c89f535 --- BasePlugin/KeyInterface.hh | 26 +++-- Core/Core.cc | 16 +++ Core/Core.hh | 4 +- Core/PluginInfo.hh | 45 ++++++++ Core/PluginLoader.cc | 15 ++- widgets/coreWidget/CoreWidget.cc | 124 ++++++++++++++++++++-- widgets/coreWidget/CoreWidget.hh | 52 ++++----- widgets/optionsWidget/optionsWidget.cc | 54 +++++++++- widgets/optionsWidget/optionsWidget.hh | 9 +- widgets/optionsWidget/ui_optionsWidget.ui | 20 +++- 10 files changed, 315 insertions(+), 50 deletions(-) create mode 100644 Core/PluginInfo.hh diff --git a/BasePlugin/KeyInterface.hh b/BasePlugin/KeyInterface.hh index e336c0bc..c5496cd9 100644 --- a/BasePlugin/KeyInterface.hh +++ b/BasePlugin/KeyInterface.hh @@ -49,13 +49,25 @@ /** \brief Interface class for plugins which have to react on keyboard events * - * Using this interface you can react on key events. The key events are emitted to all plugins - * implementing this interface. So a key event may be handled by multiple plugins. - * Use keys with care!! - * @todo : implement core handling of key events and warn on multiple definitions for the same key. - */ + * Using this interface you can react on key events. You first have to register + * a key (or key combination). For each registered key you will receive a keyEvent when + * the key was pressed and a keyReleaseEvent when the key was released. + * + */ class KeyInterface { - private slots : + signals: + /** \brief Register a key-combination for your plugin + * + * To obtain key events from the viewer for a certain key-combination, you have + * to register that combination first + * + * @param _key the key that should be registered + * @param _modifiers the keyboard modifiers + * @param _description a short description about the functionality + */ + virtual void registerKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description) {}; + + public slots : /** \brief Key Event from Main App * @@ -78,6 +90,6 @@ class KeyInterface { }; -Q_DECLARE_INTERFACE(KeyInterface,"OpenFlipper.KeyInterface/1.0") +Q_DECLARE_INTERFACE(KeyInterface,"OpenFlipper.KeyInterface/1.1") #endif // KEYINTERFACE_HH diff --git a/Core/Core.cc b/Core/Core.cc index 9ad2a5d1..f39e7d44 100644 --- a/Core/Core.cc +++ b/Core/Core.cc @@ -198,7 +198,23 @@ Core::init() { connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection); connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection); + + + // ====================================================================== + // Create a logger class for CoreWidget + // ====================================================================== + + if ( OpenFlipper::Options::gui() ){ + PluginLogger* widgetlog = new PluginLogger("CoreWidget"); + + loggers_.push_back(widgetlog); + connect(coreWidget_,SIGNAL(log(Logtype, QString )),widgetlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection); + connect(coreWidget_,SIGNAL(log(QString )),widgetlog,SLOT(slotLog(QString )),Qt::DirectConnection); + // Connect it to the Master logger + connect(widgetlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection); + connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection); + } // ====================================================================== // Catch OpenMesh Error logs with an own Logger diff --git a/Core/Core.hh b/Core/Core.hh index 430604ce..bd285b3e 100644 --- a/Core/Core.hh +++ b/Core/Core.hh @@ -89,6 +89,8 @@ #include +#include + //== CLASS DEFINITION ========================================================= struct fileTypes { @@ -494,7 +496,7 @@ private: private: /// List of all loaded plugins - std::vector plugins; + std::vector plugins; /// List of Plugins that should not be loaded QStringList dontLoadPlugins_; diff --git a/Core/PluginInfo.hh b/Core/PluginInfo.hh new file mode 100644 index 00000000..9e10f6f2 --- /dev/null +++ b/Core/PluginInfo.hh @@ -0,0 +1,45 @@ +#ifndef PLUGININFO_HH +#define PLUGININFO_HH + +#include +#include +#include +#include +#include +#include + +struct KeyBinding{ + int key; + Qt::KeyboardModifiers modifiers; + QString description; +}; + +/** Type defining a currently loaded Plugin */ +struct PluginInfo{ + + /// Pointer to the loaded plugin (Already casted when loading it) + QObject* plugin; + + /// Name of the plugin ( requested from the plugin on load) + QString name; + + /// Description of the plugin ( requested from the plugin on load) + QString description; + + /// Path to the plugin ( set on load ) + QString path; + + /// Clean rpc name of the plugin + QString rpcName; + + /// List of exported rpc slots + QStringList rpcFunctions; + + /// List of registered keys with description + QList< KeyBinding > keys; + + /// Pointer to plugins toolbar widget (if available) + QDockWidget* widget; +}; + +#endif //PLUGININFO_HH diff --git a/Core/PluginLoader.cc b/Core/PluginLoader.cc index 67fa0e6c..7bd740a9 100644 --- a/Core/PluginLoader.cc +++ b/Core/PluginLoader.cc @@ -329,7 +329,7 @@ void Core::loadPlugin(QString filename, bool silent){ // Check if a plugin has been loaded if (plugin) { - PluginInfoT info; + PluginInfo info; QString supported; // Check if it is a BasePlugin @@ -572,11 +572,16 @@ void Core::loadPlugin(QString filename, bool silent){ KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugin); if ( keyPlugin && OpenFlipper::Options::gui() ) { supported = supported + "KeyboardEvents "; - if ( checkSlot( plugin , "slotKeyEvent(QKeyEvent*)" ) ) - connect(coreWidget_,SIGNAL(PluginKeyEvent(QKeyEvent* )), plugin,SLOT(slotKeyEvent(QKeyEvent*))); - if ( checkSlot( plugin , "slotKeyReleaseEvent(QKeyEvent*)" ) ) - connect(coreWidget_,SIGNAL(PluginKeyReleaseEvent(QKeyEvent* )), plugin,SLOT(slotKeyReleaseEvent(QKeyEvent*))); + if ( checkSignal(plugin,"registerKey(int,Qt::KeyboardModifiers,QString)") ) + connect(plugin,SIGNAL( registerKey(int, Qt::KeyboardModifiers, QString) ), + coreWidget_,SLOT(slotRegisterKey(int, Qt::KeyboardModifiers, QString)) ); + +// if ( checkSlot( plugin , "slotKeyEvent(QKeyEvent*)" ) ) +// connect(coreWidget_,SIGNAL(PluginKeyEvent(QKeyEvent* )), plugin,SLOT(slotKeyEvent(QKeyEvent*))); +// +// if ( checkSlot( plugin , "slotKeyReleaseEvent(QKeyEvent*)" ) ) +// connect(coreWidget_,SIGNAL(PluginKeyReleaseEvent(QKeyEvent* )), plugin,SLOT(slotKeyReleaseEvent(QKeyEvent*))); } //Check if the plugin supports Mouse-Interface diff --git a/widgets/coreWidget/CoreWidget.cc b/widgets/coreWidget/CoreWidget.cc index 516803b4..81d610ce 100644 --- a/widgets/coreWidget/CoreWidget.cc +++ b/widgets/coreWidget/CoreWidget.cc @@ -48,6 +48,8 @@ #include #include #include +#include +#include #define WIDGET_HEIGHT 800 #define WIDGET_WIDTH 800 @@ -59,7 +61,7 @@ */ CoreWidget:: CoreWidget( QVector& _viewModes, - std::vector& _plugins ) : + std::vector& _plugins ) : QMainWindow(), viewModes_(_viewModes), dockViewMode_(0), @@ -251,6 +253,13 @@ CoreWidget( QVector& _viewModes, updateRecent(); statusBar_->showMessage("Ready", 5000); + + //register keys for coreWidget + connect(this,SIGNAL( registerKey(int, Qt::KeyboardModifiers, QString) ), + this,SLOT(slotRegisterKey(int, Qt::KeyboardModifiers, QString)) ); + + emit registerKey(Qt::Key_S,Qt::ControlModifier, "Save Object"); + emit registerKey(Qt::Key_O,Qt::ControlModifier, "Open Object"); } @@ -356,7 +365,7 @@ CoreWidget::keyPressEvent(QKeyEvent* _e) // Send remaining events to plugins default: - emit PluginKeyEvent(_e); + mapKeyPressEvent(_e); return; } } @@ -365,7 +374,7 @@ CoreWidget::keyPressEvent(QKeyEvent* _e) { // Send remaining events to plugins default: - emit PluginKeyEvent(_e); + mapKeyPressEvent(_e); break; } } @@ -375,7 +384,109 @@ CoreWidget::keyPressEvent(QKeyEvent* _e) /** Handle Key Release Events */ void CoreWidget::keyReleaseEvent(QKeyEvent* _e) { - emit PluginKeyReleaseEvent(_e); + mapKeyReleaseEvent(_e); +} + +//----------------------------------------------------------------------------- + +/** Map Key Press Events to Plugins */ +void +CoreWidget::mapKeyPressEvent(QKeyEvent* _e){ + //find the first plugin which wants to handle that key + for (uint i=0; i < plugins_.size(); i++) + for (int k=0; k < plugins_[i].keys.count(); k++) + if ( plugins_[i].keys[k].key == _e->key() + && plugins_[i].keys[k].modifiers == _e->modifiers() ){ + + KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugins_[i].plugin); + + if (keyPlugin){ +// if ( checkSlot( plugins_[i].plugin , "slotKeyEvent(QKeyEvent*)" ) ) + keyPlugin->slotKeyEvent(_e); + + return; + } + } +} + +//----------------------------------------------------------------------------- + +/** Map Key Release Events to Plugins */ +void +CoreWidget::mapKeyReleaseEvent(QKeyEvent* _e){ + + if (_e->isAutoRepeat()) return; //consider only "real" release events + + //find the first plugin which wants to handle that key + for (uint i=0; i < plugins_.size(); i++) + for (int k=0; k < plugins_[i].keys.count(); k++) + if ( plugins_[i].keys[k].key == _e->key() + && plugins_[i].keys[k].modifiers == _e->modifiers() ){ + + KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugins_[i].plugin); + + if (keyPlugin){ +// if ( checkSlot( plugins_[i].plugin , "slotKeyReleaseEvent(QKeyEvent*)" ) ) + keyPlugin->slotKeyReleaseEvent(_e); + + return; + } + } +} + +//----------------------------------------------------------------------------- + +/** Register a key to a plugin */ +void +CoreWidget::slotRegisterKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description){ + + //first check if the key is already registered by the coreWidget + bool found = false; + for (uint i=0; i < coreKeys_.size(); i++) + if (coreKeys_[i].key == _key && coreKeys_[i].modifiers == _modifiers){ + found = true; + break; + } + + //then check if the key is already registered by a different plugin + if (!found) + for (uint i=0; i < plugins_.size(); i++) + for (int k=0; k < plugins_[i].keys.count(); k++) + if (plugins_[i].keys[k].key == _key + && plugins_[i].keys[k].modifiers == _modifiers) + found = true; + + if (found) + emit log(LOGERR, "Key already registered elsewhere."); + + //check if its a key for the core + if (sender() == this){ + KeyBinding kb; + kb.key = _key; + kb.modifiers = _modifiers; + kb.description = _description; + coreKeys_.push_back( kb ); + return; + } + + //find plugin + PluginInfo* pluginInfo = 0; + + for (uint i=0; i < plugins_.size(); i++) + if (plugins_[i].plugin == sender()) + pluginInfo = &plugins_[i]; + + if (pluginInfo == 0){ + emit log(LOGERR, "Unable to register key. Plugin not found!"); + return; + } + + KeyBinding kb; + kb.key = _key; + kb.modifiers = _modifiers; + kb.description = _description; + + pluginInfo->keys.append( kb ); } //============================================================================= @@ -432,7 +543,7 @@ void CoreWidget::showOptionsWidget() { return; if ( optionsWidget_ == 0 ) { - optionsWidget_ = new OptionsWidget(0); + optionsWidget_ = new OptionsWidget(plugins_, coreKeys_, 0); connect(optionsWidget_,SIGNAL(applyOptions()),this,SIGNAL(applyOptions())); connect(optionsWidget_,SIGNAL(saveOptions()),this,SIGNAL(saveOptions())); } @@ -442,7 +553,8 @@ void CoreWidget::showOptionsWidget() { center.setX( x() + width() / 2 ); center.setY( y() + height() / 2 ); - optionsWidget_->setGeometry(center.x() - optionsWidget_->width() / 2, center.y() - optionsWidget_->height() / 2, optionsWidget_->width(), optionsWidget_->height()); + optionsWidget_->setGeometry(center.x() - optionsWidget_->width() / 2, + center.y() - optionsWidget_->height()/ 2, optionsWidget_->width(), optionsWidget_->height()); optionsWidget_->show(); diff --git a/widgets/coreWidget/CoreWidget.hh b/widgets/coreWidget/CoreWidget.hh index dceaf1e9..a15bb8b1 100644 --- a/widgets/coreWidget/CoreWidget.hh +++ b/widgets/coreWidget/CoreWidget.hh @@ -70,30 +70,7 @@ #include #include -/** Type defining a currently loaded Plugin */ -struct PluginInfoT{ - - /// Pointer to the loaded plugin (Already casted when loading it) - QObject* plugin; - - /// Name of the plugin ( requested from the plugin on load) - QString name; - - /// Description of the plugin ( requested from the plugin on load) - QString description; - - /// Path to the plugin ( set on load ) - QString path; - - /// Clean rpc name of the plugin - QString rpcName; - - /// List of exported rpc slots - QStringList rpcFunctions; - - /// Pointer to plugins toolbar widget (if available) - QDockWidget* widget; -}; +#include struct ViewMode{ QString name; @@ -132,7 +109,7 @@ class CoreWidget : public QMainWindow public: /// constructor - CoreWidget( QVector& _viewModes, std::vector& _plugins ); + CoreWidget( QVector& _viewModes, std::vector& _plugins ); /// destructor ~CoreWidget(); @@ -156,6 +133,17 @@ public: /// Called on applications close void closeEvent ( QCloseEvent * event ); + //=========================================================================== + /** @name Logger + * @{ */ + //=========================================================================== + + signals : + void log(Logtype _type, QString _message); + void log(QString _message); + + /** @} */ + //=========================================================================== /** @name Keys * @{ */ @@ -174,6 +162,18 @@ public: /// When this Signal is emitted when a key release event event occures void PluginKeyReleaseEvent(QKeyEvent* ); + /// internal signal to register CoreWidget keys + void registerKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description); + + private: + void mapKeyPressEvent(QKeyEvent* _e); + void mapKeyReleaseEvent(QKeyEvent* _e); + + std::vector coreKeys_; + + private slots: + void slotRegisterKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description); + /** @} */ //=========================================================================== @@ -499,7 +499,7 @@ public: private : - std::vector& plugins_; + std::vector& plugins_; }; diff --git a/widgets/optionsWidget/optionsWidget.cc b/widgets/optionsWidget/optionsWidget.cc index 06b806db..d5be3954 100644 --- a/widgets/optionsWidget/optionsWidget.cc +++ b/widgets/optionsWidget/optionsWidget.cc @@ -36,10 +36,15 @@ #include #include -OptionsWidget::OptionsWidget( QWidget *parent) - : QWidget(parent) + + +OptionsWidget::OptionsWidget(std::vector& _plugins, std::vector& _core, QWidget *parent) + : plugins_(_plugins), + coreKeys_(_core), + QWidget(parent) { setupUi(this); + connect(applyButton,SIGNAL(clicked()),this,SLOT(slotApply())); connect(cancelButton,SIGNAL(clicked()),this,SLOT(slotCancel())); } @@ -57,6 +62,50 @@ void OptionsWidget::showEvent ( QShowEvent * event ) { wZoomFactor->setText( QString::number(OpenFlipper::Options::wheelZoomFactor(), 'f') ); wZoomFactorShift->setText( QString::number(OpenFlipper::Options::wheelZoomFactorShift(), 'f') ); + //keyBindings + keyTree->setColumnCount ( 2 ); + + QStringList headerdata; + headerdata << "Action" << "Shortcut"; + keyTree->setHeaderLabels(headerdata); + + //add Core Keys + QTreeWidgetItem * core = new QTreeWidgetItem(keyTree, QStringList("CoreWidget")); + + QList keys; + + for (uint i=0; i < coreKeys_.size(); i++){ + QStringList row; + row << coreKeys_[i].description << QString::number(coreKeys_[i].key); + keys.append(new QTreeWidgetItem(core, row)); + } + + core->addChildren(keys); + keyTree->addTopLevelItem( core ); + + + + QList plugins; + + for (uint i=0; i < plugins_.size(); i++){ + plugins.append(new QTreeWidgetItem(keyTree, QStringList( plugins_[i].name ))); + + QList keys; + + for (int k=0; k < plugins_[i].keys.count(); k++){ + QStringList row; + row << plugins_[i].keys[k].description << QString::number(plugins_[i].keys[k].key); + keys.append(new QTreeWidgetItem(plugins[i], row)); + } + + plugins[i]->addChildren(keys); + + } + + keyTree->addTopLevelItems( plugins ); + + keyTree->resizeColumnToContents(0); + keyTree->resizeColumnToContents(1); } void OptionsWidget::slotApply() { @@ -80,4 +129,3 @@ void OptionsWidget::slotApply() { void OptionsWidget::slotCancel() { hide(); } - diff --git a/widgets/optionsWidget/optionsWidget.hh b/widgets/optionsWidget/optionsWidget.hh index 4a645ae7..5c9cbcdd 100644 --- a/widgets/optionsWidget/optionsWidget.hh +++ b/widgets/optionsWidget/optionsWidget.hh @@ -39,12 +39,14 @@ #include #include +#include + class OptionsWidget : public QWidget, public Ui::OptionsWidget { Q_OBJECT public: - OptionsWidget(QWidget *parent = 0 ); + OptionsWidget(std::vector& _plugins, std::vector& _core, QWidget *parent = 0 ); signals: void applyOptions(); @@ -59,6 +61,11 @@ class OptionsWidget : public QWidget, public Ui::OptionsWidget protected: void showEvent ( QShowEvent * event ); + + private: + //key-bindings + std::vector& plugins_; + std::vector& coreKeys_; }; diff --git a/widgets/optionsWidget/ui_optionsWidget.ui b/widgets/optionsWidget/ui_optionsWidget.ui index e21b9c4a..8d07dfa5 100644 --- a/widgets/optionsWidget/ui_optionsWidget.ui +++ b/widgets/optionsWidget/ui_optionsWidget.ui @@ -22,7 +22,7 @@ - 1 + 2 true @@ -187,6 +187,24 @@ + + + + 0 + 0 + 545 + 409 + + + + Key Bindings + + + + + + + -- GitLab