From 8bf7a0c57e0ea4018d8afdbf4a19f30e7d75886c Mon Sep 17 00:00:00 2001 From: mzn Date: Mon, 30 Aug 2010 10:39:00 +0000 Subject: [PATCH] Fix for imp 0020845: EDF 1376 GUI : More shortcuts. --- src/CAM/CAM_Module.cxx | 5 +- src/CAM/CAM_Module.h | 2 +- src/LightApp/LightApp_Application.cxx | 10 ++ src/LightApp/LightApp_Module.cxx | 17 ++- src/LightApp/resources/LightApp.xml | 23 +++ src/LightApp/resources/LightApp_msg_en.ts | 8 + src/OCCViewer/OCCViewer_ViewWindow.cxx | 24 ++- src/Qtx/QtxAction.cxx | 49 ++++++- src/Qtx/QtxAction.h | 12 +- src/Qtx/QtxPagePrefMgr.cxx | 10 ++ src/Qtx/QtxShortcutEdit.cxx | 87 ++++++++++- src/Qtx/QtxShortcutEdit.h | 3 + src/SUIT/Makefile.am | 9 +- src/SUIT/SUIT_Application.cxx | 19 ++- src/SUIT/SUIT_Application.h | 7 +- src/SUIT/SUIT_ShortcutMgr.cxx | 170 ++++++++++++++++++++++ src/SUIT/SUIT_ShortcutMgr.h | 71 +++++++++ src/SVTK/SVTK_ViewWindow.cxx | 21 ++- src/SalomeApp/resources/SalomeApp.xml | 23 +++ 19 files changed, 529 insertions(+), 41 deletions(-) create mode 100644 src/SUIT/SUIT_ShortcutMgr.cxx create mode 100644 src/SUIT/SUIT_ShortcutMgr.h diff --git a/src/CAM/CAM_Module.cxx b/src/CAM/CAM_Module.cxx index 39beee2d7..8e39ab66b 100755 --- a/src/CAM/CAM_Module.cxx +++ b/src/CAM/CAM_Module.cxx @@ -835,9 +835,10 @@ int CAM_Module::actionId( const QAction* a ) const */ QAction* CAM_Module::createAction( const int id, const QString& text, const QIcon& icon, const QString& menu, const QString& tip, const int key, - QObject* parent, const bool toggle, QObject* reciever, const char* member ) + QObject* parent, const bool toggle, QObject* reciever, + const char* member, const QString& shortcutAction ) { - QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle ); + QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle, shortcutAction ); a->setStatusTip( tip ); if ( reciever && member ) diff --git a/src/CAM/CAM_Module.h b/src/CAM/CAM_Module.h index 73aaf71b9..2a3022d66 100755 --- a/src/CAM/CAM_Module.h +++ b/src/CAM/CAM_Module.h @@ -128,7 +128,7 @@ protected: bool unregisterAction( QAction* ); QAction* createAction( const int, const QString&, const QIcon&, const QString&, const QString&, const int, QObject* = 0, - const bool = false, QObject* = 0, const char* = 0 ); + const bool = false, QObject* = 0, const char* = 0, const QString& = QString() ); private: CAM_Application* myApp; //!< parent application object diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index e31d40453..12b1e9c6b 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -1596,6 +1597,9 @@ void LightApp_Application::showPreferences( const QString& itemText ) if ( desktop() ) resourceMgr()->setValue( "desktop", "geometry", desktop()->storeGeometry() ); resourceMgr()->save(); + + // Update shortcuts + shortcutMgr()->updateShortcuts(); } delete prefDlg; @@ -2156,6 +2160,12 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->addPreference( tr( "PREF_RESIZE_ON_EXPAND_ITEM" ), objSetGroup, LightApp_Preferences::Bool, "ObjectBrowser", "resize_on_expand_item" ); + // Shortcuts preferences + int shortcutTab = pref->addPreference( tr( "PREF_TAB_SHORTCUTS" ), salomeCat ); + int shortcutGroup = pref->addPreference( tr( "PREF_GROUP_SHORTCUTS" ), shortcutTab ); + pref->addPreference( tr( "" ), shortcutGroup, + LightApp_Preferences::ShortcutTree, "shortcuts" ); + // MRU preferences int mruGroup = pref->addPreference( tr( "PREF_GROUP_MRU" ), genTab, LightApp_Preferences::Auto, "MRU", "show_mru" ); pref->setItemProperty( "columns", 4, mruGroup ); diff --git a/src/LightApp/LightApp_Module.cxx b/src/LightApp/LightApp_Module.cxx index 118fc9db4..ba8b641fd 100644 --- a/src/LightApp/LightApp_Module.cxx +++ b/src/LightApp/LightApp_Module.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -220,6 +221,12 @@ bool LightApp_Module::activateModule( SUIT_Study* study ) if ( mySwitchOp == 0 ) mySwitchOp = new LightApp_SwitchOp( this ); + // Enable Display and Erase actions + action(myDisplay)->setEnabled(true); + action(myErase)->setEnabled(true); + + application()->shortcutMgr()->setSectionEnabled( moduleName() ); + /* BUG 0020498 : The Entry column is always shown at module activation The registration of column is moved into LightApp_Application @@ -251,6 +258,12 @@ bool LightApp_Module::deactivateModule( SUIT_Study* study ) anIt.value()->abort(); } + // Disable Display and Erase action + action(myDisplay)->setEnabled(false); + action(myErase)->setEnabled(false); + + application()->shortcutMgr()->setSectionEnabled( moduleName(), false ); + /* BUG 0020498 : The Entry column is always shown at module activation QString EntryCol = QObject::tr( "ENTRY_COLUMN" ); LightApp_DataModel* m = dynamic_cast( dataModel() ); @@ -386,9 +399,9 @@ QtxPopupMgr* LightApp_Module::popupMgr() QAction *disp = createAction( -1, tr( "TOP_SHOW" ), p, tr( "MEN_SHOW" ), tr( "STB_SHOW" ), - 0, d, false, this, SLOT( onShowHide() ) ), + 0, d, false, this, SLOT( onShowHide() ), QString("General:Show object(s)") ), *erase = createAction( -1, tr( "TOP_HIDE" ), p, tr( "MEN_HIDE" ), tr( "STB_HIDE" ), - 0, d, false, this, SLOT( onShowHide() ) ), + 0, d, false, this, SLOT( onShowHide() ) , QString("General:Hide object(s)") ), *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ), 0, d, false, this, SLOT( onShowHide() ) ), *eraseAll = createAction( -1, tr( "TOP_ERASE_ALL" ), p, tr( "MEN_ERASE_ALL" ), tr( "STB_ERASE_ALL" ), diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index 7a54913eb..bdfbfae04 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -178,4 +178,27 @@ + +
+ +
+
+ + +
+
+ + + + + + + +
+
+ + + + +
diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index aaa62e008..cc69e4730 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -635,6 +635,14 @@ File does not exist PREFERENCES_NOT_SUPPORTED Preferences for module "%1" not supported + + PREF_TAB_SHORTCUTS + Shortcuts + + + PREF_GROUP_SHORTCUTS + Shortcuts settings + LightApp_Module diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index ee2ba5cb8..fd0992fba 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1039,46 +1039,54 @@ void OCCViewer_ViewWindow::createActions() // Projections aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ), - tr( "MNU_FRONT_VIEW" ), 0, this); + tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view"); aAction->setStatusTip(tr("DSC_FRONT_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, FrontId ); aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ), - tr( "MNU_BACK_VIEW" ), 0, this); + tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view"); aAction->setStatusTip(tr("DSC_BACK_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, BackId ); aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ), - tr( "MNU_TOP_VIEW" ), 0, this); + tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view"); aAction->setStatusTip(tr("DSC_TOP_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, TopId ); aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ), - tr( "MNU_BOTTOM_VIEW" ), 0, this); + tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view"); aAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView())); + this->addAction(aAction); + this->addAction(aAction); toolMgr()->registerAction( aAction, BottomId ); - + aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ), - tr( "MNU_LEFT_VIEW" ), 0, this); + tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view"); aAction->setStatusTip(tr("DSC_LEFT_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, LeftId ); aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ), - tr( "MNU_RIGHT_VIEW" ), 0, this); + tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view"); aAction->setStatusTip(tr("DSC_RIGHT_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, RightId ); // Reset aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ), - tr( "MNU_RESET_VIEW" ), 0, this); + tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view"); aAction->setStatusTip(tr("DSC_RESET_VIEW")); connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView())); + this->addAction(aAction); toolMgr()->registerAction( aAction, ResetId ); // Clone diff --git a/src/Qtx/QtxAction.cxx b/src/Qtx/QtxAction.cxx index 0bc9508aa..b706f850a 100755 --- a/src/Qtx/QtxAction.cxx +++ b/src/Qtx/QtxAction.cxx @@ -67,14 +67,19 @@ private: Creates an action owned by \a parent. Parameter \a toggle can be used to make the action checkable. + Parameter \a shortcutAction can be used to assign the shortcut from + preferences. This parameter value corresponds to shortcut action identifier + in shortcut preferences. \param parent parent object \param toggle if \c true the action will be a toggle action + \param shortcutAction shortcut action identifier */ -QtxAction::QtxAction( QObject* parent, bool toggle ) +QtxAction::QtxAction( QObject* parent, bool toggle, const QString& shortcutAction ) : QWidgetAction( parent ) { setCheckable( toggle ); + setShortcutActionName(shortcutAction); QApplication::instance()->installEventFilter( this ); } @@ -85,6 +90,9 @@ QtxAction::QtxAction( QObject* parent, bool toggle ) Creates an action owned by \a parent. Parameters \a text, \a icon, \a menuText and \a accel specify the action's attributes. Parameter \a toggle can be used to make the action checkable. + Parameter \a shortcutAction can be used to assign the shortcut from + preferences. This parameter value corresponds to shortcut action identifier + in shortcut preferences. \param text tooltip text \param icon iconset @@ -92,9 +100,10 @@ QtxAction::QtxAction( QObject* parent, bool toggle ) \param accel shortcut key sequence \param parent parent object \param toggle if \c true the action will be a toggle action + \param shortcutAction shortcut action identifier */ -QtxAction::QtxAction( const QString& text, const QIcon& icon, - const QString& menuText, int accel, QObject* parent, bool toggle ) +QtxAction::QtxAction( const QString& text, const QIcon& icon, const QString& menuText, + int accel, QObject* parent, bool toggle, const QString& shortcutAction ) : QWidgetAction( parent ) { setIcon( icon ); @@ -102,6 +111,7 @@ QtxAction::QtxAction( const QString& text, const QIcon& icon, setToolTip( text ); setShortcut( accel ); setCheckable( toggle ); + setShortcutActionName(shortcutAction); QApplication::instance()->installEventFilter( this ); } @@ -112,22 +122,27 @@ QtxAction::QtxAction( const QString& text, const QIcon& icon, Creates an action owned by \a parent. Parameters \a text, \a menuText and \a accel specify the action's attributes. Parameter \a toggle can be used to make the action checkable. + Parameter \a shortcutAction can be used to assign the shortcut from + preferences. This parameter value corresponds to shortcut action identifier + in shortcut preferences. \param text tooltip text \param menuText menu text \param accel shortcut key sequence \param parent parent object \param toggle if \c true the action is a toggle action + \param shortcutAction shortcut action identifier */ QtxAction::QtxAction( const QString& text, const QString& menuText, - int accel, QObject* parent, bool toggle ) + int accel, QObject* parent, bool toggle, const QString& shortcutAction ) : QWidgetAction( parent ) { setText( menuText ); setToolTip( text ); setShortcut( accel ); setCheckable( toggle ); - + setShortcutActionName(shortcutAction); + QApplication::instance()->installEventFilter( this ); } @@ -208,3 +223,27 @@ void QtxAction::customEvent( QEvent* e ) else removedFrom( ae->widget() ); } + +/*! + \brief Return shortcut action name for the action. + + \return shortcut action name + \sa setShortcutActionName() +*/ +QString QtxAction::shortcutActionName() const +{ + return myShortcutActionName; +} + +/*! + \brief Set shortcut action name to the action. + + Shortcut action name is used for shortcuts customization. + + \param shortcutAction shortcut action name + \sa shortcutActionName() +*/ +void QtxAction::setShortcutActionName( const QString& shortcutAction ) +{ + myShortcutActionName = shortcutAction; +} diff --git a/src/Qtx/QtxAction.h b/src/Qtx/QtxAction.h index c7a87293f..4536fa5ba 100755 --- a/src/Qtx/QtxAction.h +++ b/src/Qtx/QtxAction.h @@ -43,18 +43,24 @@ class QTX_EXPORT QtxAction : public QWidgetAction class ActionNotify; public: - QtxAction( QObject* = 0, bool = false ); - QtxAction( const QString&, const QString&, int, QObject*, bool = false ); - QtxAction( const QString&, const QIcon&, const QString&, int, QObject*, bool = false ); + QtxAction( QObject* = 0, bool = false, const QString& = QString() ); + QtxAction( const QString&, const QString&, int, QObject*, bool = false, const QString& = QString() ); + QtxAction( const QString&, const QIcon&, const QString&, int, QObject*, bool = false, const QString& = QString() ); virtual ~QtxAction(); virtual bool eventFilter( QObject*, QEvent* ); + QString shortcutActionName() const; + void setShortcutActionName( const QString& ); + protected: virtual void addedTo( QWidget* ); virtual void removedFrom( QWidget* ); virtual void customEvent( QEvent* ); + +private: + QString myShortcutActionName; }; #ifdef WIN32 diff --git a/src/Qtx/QtxPagePrefMgr.cxx b/src/Qtx/QtxPagePrefMgr.cxx index 28a9db0d8..67cf63beb 100644 --- a/src/Qtx/QtxPagePrefMgr.cxx +++ b/src/Qtx/QtxPagePrefMgr.cxx @@ -4245,7 +4245,17 @@ QtxPagePrefShortcutTreeItem::QtxPagePrefShortcutTreeItem( const QString& title, const QString& param ): QtxPageNamedPrefItem( title, parent, sect, "" ) { mySection = sect; + myShortcutTree = new QtxShortcutTree(); + + // Retrieve shortcuts common sections from resources + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ){ + QString generalSections = resourceMgr()->stringValue( "shortcuts_settings", "general_sections", QString() ); + QStringList sectionsList = generalSections.split( ";", QString::SkipEmptyParts ); + myShortcutTree->setGeneralSections( sectionsList ); + } + setControl( myShortcutTree ); } diff --git a/src/Qtx/QtxShortcutEdit.cxx b/src/Qtx/QtxShortcutEdit.cxx index c5aa6eaa7..efa555de1 100755 --- a/src/Qtx/QtxShortcutEdit.cxx +++ b/src/Qtx/QtxShortcutEdit.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -251,13 +252,14 @@ bool QtxShortcutTree::eventFilter(QObject* obj, QEvent* event) if ( keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace ) currentItem()->setText( 1, "" ); if ( text != "" ) { - currentItem()->setText( 1, text ); + if ( text.endsWith( "+" ) || checkUniqueness( currentItem(), text ) ) + currentItem()->setText( 1, text ); } return true; } if ( event->type() == QEvent::KeyRelease ) { if ( currentItem()->text( 1 ).endsWith( "+" ) ) - currentItem()->setText( 1, myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] ); + currentItem()->setText( 1, myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] ); else myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] = currentItem()->text( 1 ); return true; @@ -277,7 +279,6 @@ void QtxShortcutTree::onCurrentItemChanged( QTreeWidgetItem* cur, QTreeWidgetIte prev->setText( 1, myPrevBindings[ prev->parent()->text( 0 ) ][ prev->text( 0 ) ] ); } - /*! \brief Set key bindings to the tree \param title the name of top-level item @@ -286,8 +287,12 @@ void QtxShortcutTree::onCurrentItemChanged( QTreeWidgetItem* cur, QTreeWidgetIte void QtxShortcutTree::setBindings( const QString& title, const ShortcutMap& theShortcutMap ) { QTreeWidgetItem* item= new QTreeWidgetItem(); + QFont font = item->font(0); + font.setBold(true); + if ( findItems( title, Qt::MatchFixedString ).isEmpty() ) { item->setText( 0, title ); + item->setFont( 0, font ); addTopLevelItem( item ); item->setFlags( Qt::ItemIsEnabled ); } else { @@ -315,10 +320,12 @@ ShortcutMap* QtxShortcutTree::bindings( const QString& sec ) const { ShortcutMap* aMap = new ShortcutMap(); QTreeWidgetItem* item = findItems( sec, Qt::MatchFixedString ).first(); - QList< QTreeWidgetItem* > childLst = item->takeChildren(); + int nbChildren = item->childCount(); - for( int i = 0; i < childLst.size(); i++ ) - aMap->insert( childLst.at(i)->text( 0 ), childLst.at(i)->text(1) ); + for( int i = 0; i < nbChildren; i++ ) { + QTreeWidgetItem* child = item->child(i); + aMap->insert( child->text( 0 ), child->text( 1 ) ); + } return aMap; } @@ -326,6 +333,72 @@ ShortcutMap* QtxShortcutTree::bindings( const QString& sec ) const void QtxShortcutTree::focusOutEvent ( QFocusEvent* event ) { QWidget::focusOutEvent( event ); - if ( currentItem()->isSelected() ) + if ( currentItem() && currentItem()->isSelected() ) currentItem()->setText( 1, myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] ); } + +/*! + \brief Set the list of shortcuts general sections. + + Key combinations in general sections should not intersect + with any other key combinations. + + \param sectionsList list of common section names +*/ +void QtxShortcutTree::setGeneralSections( const QStringList& sectionsList ) +{ + myGeneralSections = sectionsList; +} + +/*! + \brief Check uniqueness of the shortcut. + \param item current item of the shortcut tree + \param shortcut shortcut appointed for the current item + \return \c true if the given shortcut is allowed +*/ +bool QtxShortcutTree::checkUniqueness( QTreeWidgetItem* item, const QString& shortcut ) +{ + // List of sections to check shortcut intersections + QStringList sectionsList; + + // Current section + QString currentSection = currentItem()->parent()->text( 0 ); + + // If the current section is general + if ( myGeneralSections.contains(currentSection) ) { + sectionsList = sections(); + int currentSectionIndex = sectionsList.indexOf(currentSection); + sectionsList.move( currentSectionIndex, 0); + } + else { + sectionsList = myGeneralSections; + sectionsList.prepend(currentSection); + } + + // Iterate on sections + QStringList::const_iterator it; + for( it = sectionsList.constBegin(); it != sectionsList.constEnd(); ++it ) { + QString section = *it; + + // Iterate on actual section + QTreeWidgetItem* sectionRoot = findItems( section, Qt::MatchFixedString ).first(); + int nbChildren = sectionRoot->childCount(); + + for( int i = 0; i < nbChildren; i++ ) { + QTreeWidgetItem* child = sectionRoot->child(i); + + if ( (child != item) && (shortcut == child->text( 1 )) ) { + bool res = QMessageBox::warning( parentWidget(), tr("Warning"), + tr("The \"%1\" shortcut has already used by the \"%2\" action.\n") + .arg(shortcut, section + ":" + child->text( 0 ) ) + + tr("Do you want to reassign it from that action to the current one?"), + QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes; + if (res) + child->setText( 1, "" ); + return res; + } + } + } + + return true; +} diff --git a/src/Qtx/QtxShortcutEdit.h b/src/Qtx/QtxShortcutEdit.h index 782402288..01791d761 100755 --- a/src/Qtx/QtxShortcutEdit.h +++ b/src/Qtx/QtxShortcutEdit.h @@ -69,16 +69,19 @@ public: void setBindings( const QString&, const ShortcutMap& ); ShortcutMap* bindings( const QString& ) const; QStringList sections() const; + void setGeneralSections( const QStringList& ); protected: virtual bool eventFilter( QObject*, QEvent* ); virtual void focusOutEvent( QFocusEvent* ); + virtual bool checkUniqueness( QTreeWidgetItem*, const QString& ); private slots: void onCurrentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ); private: QMap< QString, ShortcutMap > myPrevBindings; + QStringList myGeneralSections; }; #endif // QTXSHORTCUTEDIT_H diff --git a/src/SUIT/Makefile.am b/src/SUIT/Makefile.am index 0c08e6c8a..9b1df08d9 100755 --- a/src/SUIT/Makefile.am +++ b/src/SUIT/Makefile.am @@ -61,7 +61,8 @@ salomeinclude_HEADERS = \ SUIT_TreeModel.h \ SUIT_ViewManager.h \ SUIT_ViewModel.h \ - SUIT_ViewWindow.h + SUIT_ViewWindow.h \ + SUIT_ShortcutMgr.h dist_libsuit_la_SOURCES = \ SUIT_Accel.cxx \ @@ -92,7 +93,8 @@ dist_libsuit_la_SOURCES = \ SUIT_TreeModel.cxx \ SUIT_ViewManager.cxx \ SUIT_ViewModel.cxx \ - SUIT_ViewWindow.cxx + SUIT_ViewWindow.cxx \ + SUIT_ShortcutMgr.cxx MOC_FILES = \ SUIT_Accel_moc.cxx \ @@ -113,7 +115,8 @@ MOC_FILES = \ SUIT_TreeModel_moc.cxx \ SUIT_ViewManager_moc.cxx \ SUIT_ViewModel_moc.cxx \ - SUIT_ViewWindow_moc.cxx + SUIT_ViewWindow_moc.cxx \ + SUIT_ShortcutMgr_moc.cxx nodist_libsuit_la_SOURCES = $(MOC_FILES) diff --git a/src/SUIT/SUIT_Application.cxx b/src/SUIT/SUIT_Application.cxx index 7624b5c6a..e7129b5e8 100755 --- a/src/SUIT/SUIT_Application.cxx +++ b/src/SUIT/SUIT_Application.cxx @@ -26,6 +26,7 @@ #include "SUIT_Session.h" #include "SUIT_Desktop.h" #include "SUIT_ResourceMgr.h" +#include "SUIT_ShortcutMgr.h" #include #include @@ -37,6 +38,7 @@ #include #include + /*! \class StatusLabel \brief Status bar customization label. Used to workaroubd desktop resizing bug. @@ -123,6 +125,9 @@ void SUIT_Application::start() { if ( desktop() ) desktop()->show(); + + // Initialize shortcut manager + SUIT_ShortcutMgr::Init(); } /*! @@ -174,6 +179,15 @@ SUIT_ResourceMgr* SUIT_Application::resourceMgr() const return SUIT_Session::session()->resourceMgr(); } +/*! + \brief Get access to shortcut manager. + \return global shortcut manager +*/ +SUIT_ShortcutMgr* SUIT_Application::shortcutMgr() const +{ + return SUIT_ShortcutMgr::getShortcutMgr(); +} + #define DEFAULT_MESSAGE_DELAY 3000 /*! @@ -612,9 +626,10 @@ QList SUIT_Application::actionIds() const */ QAction* SUIT_Application::createAction( const int id, const QString& text, const QIcon& icon, const QString& menu, const QString& tip, const int key, - QObject* parent, const bool toggle, QObject* reciever, const char* member ) + QObject* parent, const bool toggle, QObject* reciever, + const char* member, const QString& shortcutAction ) { - QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle ); + QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle, shortcutAction ); a->setStatusTip( tip ); if ( reciever && member ) diff --git a/src/SUIT/SUIT_Application.h b/src/SUIT/SUIT_Application.h index e04cee4f5..3773977fc 100755 --- a/src/SUIT/SUIT_Application.h +++ b/src/SUIT/SUIT_Application.h @@ -37,6 +37,7 @@ class QWidget; class SUIT_Desktop; class SUIT_ViewModel; class SUIT_ResourceMgr; +class SUIT_ShortcutMgr; class SUIT_Study; #ifdef WIN32 @@ -97,6 +98,8 @@ public: SUIT_ResourceMgr* resourceMgr() const; + SUIT_ShortcutMgr* shortcutMgr() const; + //! Puts the message to the status bar void putInfo ( const QString&, const int = 0 ); @@ -164,7 +167,8 @@ protected: int registerAction( const int, QAction* ); QAction* createAction( const int, const QString&, const QIcon&, const QString&, const QString&, const int, QObject* = 0, - const bool = false, QObject* = 0, const char* = 0 ); + const bool = false, QObject* = 0, const char* = 0, + const QString& = QString() ); protected slots: virtual void onDesktopActivated(); @@ -173,6 +177,7 @@ private: SUIT_Study* myStudy; SUIT_Desktop* myDesktop; QMap myActionMap; + SUIT_ShortcutMgr* myShortcutMgr; QLabel* myStatusLabel; }; diff --git a/src/SUIT/SUIT_ShortcutMgr.cxx b/src/SUIT/SUIT_ShortcutMgr.cxx new file mode 100644 index 000000000..ab5afccbc --- /dev/null +++ b/src/SUIT/SUIT_ShortcutMgr.cxx @@ -0,0 +1,170 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SUIT_ShortcutMgr.h" + +#include "SUIT_Session.h" +#include "SUIT_ResourceMgr.h" + +#include + +#include +#include + +SUIT_ShortcutMgr* SUIT_ShortcutMgr::myShortcutMgr = NULL; + +/*! + \brief Constructor +*/ +SUIT_ShortcutMgr::SUIT_ShortcutMgr() +: QObject() +{ + qApp->installEventFilter( this ); +} + +/*! + \brief Destructor +*/ +SUIT_ShortcutMgr::~SUIT_ShortcutMgr() +{ + qApp->removeEventFilter( this ); +} + +/*! + \brief Create new instance of shortcut manager. +*/ +void SUIT_ShortcutMgr::Init() +{ + if( myShortcutMgr==NULL ) + myShortcutMgr = new SUIT_ShortcutMgr(); +} + +/*! + \brief Return shortcut manager. +*/ +SUIT_ShortcutMgr* SUIT_ShortcutMgr::getShortcutMgr() +{ + Init(); + + return myShortcutMgr; +} + +/*! + \brief Custom event filter for qapplication . + + Redefined from QObject::eventFilter(); +*/ +bool SUIT_ShortcutMgr::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == QEvent::ActionAdded ) { + QActionEvent* anActionEvent = (QActionEvent*)e; + if (anActionEvent) { + QtxAction* anAction = qobject_cast( anActionEvent->action() ); + if ( anAction ) + processAction( anAction ); + } + } + + return QObject::eventFilter( o, e ); +} + +/*! + \brief Return key sequence for shortcut action name. + \param actionName name of shortcut action in preferences + \return key sequence defined in preferences or empty sequence +*/ +QKeySequence SUIT_ShortcutMgr::getShortcutByActionName( const QString& actionName ) const +{ + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + + QString section = actionName.section( resMgr->sectionsToken(), 0, 0 ); + section.prepend( QString("shortcuts") + resMgr->sectionsToken() ); + QString parameter = actionName.section( resMgr->sectionsToken(), 1, 1 ); + + QString shortcutValue; + bool hasValue = resMgr->value( section, parameter, shortcutValue, false ); + + if ( !hasValue ) + return QKeySequence(); + + return QKeySequence::fromString( shortcutValue ); +} + +/*! + \brief Set shortcut to the given action if the shortcut is defined. + \param action action to process + */ +void SUIT_ShortcutMgr::processAction( QtxAction* action ) +{ + QString shortcutActionName = action->shortcutActionName(); + + if ( !shortcutActionName.isEmpty() ) { + // Add action to the actions map + QList actions = myShortcutActions.values( shortcutActionName ); + if ( !actions.contains(action) ) + myShortcutActions.insertMulti( shortcutActionName, action ); + + QKeySequence keySeq = getShortcutByActionName( shortcutActionName ); + action->setShortcut( keySeq ); + } +} + +/*! + \brief Enable/disable a shortcuts section. + + Enables or disables actions which belong to the given shortcuts section. + Only actions which have an active desktop as a parent widget + are taken into account. + + \param section shorcuts section + \param on if \c true - action will be enabled, otherwise - disabled +*/ +void SUIT_ShortcutMgr::setSectionEnabled( const QString& section, const bool on ) +{ + QMap::ConstIterator it; + for ( it = myShortcutActions.constBegin(); it != myShortcutActions.constEnd(); ++it ) { + QtxAction* action = it.value(); + QString shortcutActionName = action->shortcutActionName(); + QString actionSection = shortcutActionName.section( ":", 0, 0 ); + if ( actionSection == section ) { + // Check if the action parent widget equals to the active desktop + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( !app ) + return; + if ( action->parentWidget() == (QWidget*)app->desktop() ) + action->setEnabled( on ); + } + } +} + +/*! + \brief Update shortcuts from preferences. +*/ +void SUIT_ShortcutMgr::updateShortcuts() +{ + QMap::ConstIterator it; + for ( it = myShortcutActions.constBegin(); it != myShortcutActions.constEnd(); ++it ) { + QtxAction* action = it.value(); + QKeySequence keySeq = getShortcutByActionName( action->shortcutActionName() ); + action->setShortcut( keySeq ); + } +} diff --git a/src/SUIT/SUIT_ShortcutMgr.h b/src/SUIT/SUIT_ShortcutMgr.h new file mode 100644 index 000000000..e620db8e6 --- /dev/null +++ b/src/SUIT/SUIT_ShortcutMgr.h @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef SUIT_SHORTCUTMGR_H +#define SUIT_SHORTCUTMGR_H + +#include "SUIT.h" + +#include +#include + +class QtxAction; + +class QKeySequence; + +#if defined WIN32 +#pragma warning( disable: 4251 ) +#endif + +/*! + \class SUIT_ShortcutMgr + \brief Class which manages shortcuts customization. +*/ +class SUIT_EXPORT SUIT_ShortcutMgr: public QObject +{ +public: + static void Init(); + static SUIT_ShortcutMgr* getShortcutMgr(); + + void setSectionEnabled( const QString&, const bool = true ); + void updateShortcuts(); + +protected: + SUIT_ShortcutMgr(); + virtual ~SUIT_ShortcutMgr(); + +private: + virtual bool eventFilter( QObject* o, QEvent* e ); + + void processAction( QtxAction* ); + QKeySequence getShortcutByActionName( const QString& ) const; + +private: + static SUIT_ShortcutMgr* myShortcutMgr; + QMap myShortcutActions; +}; + +#if defined WIN32 +#pragma warning( default: 4251 ) +#endif + +#endif diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 10c16646e..a8fa48f19 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -1634,52 +1634,59 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) // Projections anAction = new QtxAction(tr("MNU_FRONT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_FRONT" ) ), - tr( "MNU_FRONT_VIEW" ), 0, this); + tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view"); anAction->setStatusTip(tr("DSC_FRONT_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onFrontView())); + this->addAction(anAction); mgr->registerAction( anAction, FrontId ); anAction = new QtxAction(tr("MNU_BACK_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BACK" ) ), - tr( "MNU_BACK_VIEW" ), 0, this); + tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view"); anAction->setStatusTip(tr("DSC_BACK_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onBackView())); + this->addAction(anAction); mgr->registerAction( anAction, BackId ); anAction = new QtxAction(tr("MNU_TOP_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TOP" ) ), - tr( "MNU_TOP_VIEW" ), 0, this); + tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view"); anAction->setStatusTip(tr("DSC_TOP_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onTopView())); + this->addAction(anAction); mgr->registerAction( anAction, TopId ); anAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BOTTOM" ) ), - tr( "MNU_BOTTOM_VIEW" ), 0, this); + tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view"); anAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onBottomView())); + this->addAction(anAction); mgr->registerAction( anAction, BottomId ); anAction = new QtxAction(tr("MNU_LEFT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_LEFT" ) ), - tr( "MNU_LEFT_VIEW" ), 0, this); + tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view"); anAction->setStatusTip(tr("DSC_LEFT_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onLeftView())); + this->addAction(anAction); mgr->registerAction( anAction, LeftId ); anAction = new QtxAction(tr("MNU_RIGHT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RIGHT" ) ), - tr( "MNU_RIGHT_VIEW" ), 0, this); + tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view"); anAction->setStatusTip(tr("DSC_RIGHT_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onRightView())); + this->addAction(anAction); mgr->registerAction( anAction, RightId ); // Reset anAction = new QtxAction(tr("MNU_RESET_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RESET" ) ), - tr( "MNU_RESET_VIEW" ), 0, this); + tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view"); anAction->setStatusTip(tr("DSC_RESET_VIEW")); connect(anAction, SIGNAL(activated()), this, SLOT(onResetView())); + this->addAction(anAction); mgr->registerAction( anAction, ResetId ); // onViewTrihedron: Shows - Hides Trihedron diff --git a/src/SalomeApp/resources/SalomeApp.xml b/src/SalomeApp/resources/SalomeApp.xml index f41407f58..542811fc7 100644 --- a/src/SalomeApp/resources/SalomeApp.xml +++ b/src/SalomeApp/resources/SalomeApp.xml @@ -226,4 +226,27 @@ + +
+ +
+
+ + +
+
+ + + + + + + +
+
+ + + + +
-- 2.39.2