From 053bed33433b464fc9dc4f876310cb7b344b3031 Mon Sep 17 00:00:00 2001 From: sbh Date: Fri, 13 Feb 2015 16:39:14 +0300 Subject: [PATCH] History menu: improvments and bugfixes --- src/Model/Model_Session.h | 2 +- src/ModelAPI/ModelAPI_Session.h | 2 +- src/ModuleBase/ModuleBase_Operation.cpp | 3 ++ src/ModuleBase/ModuleBase_Operation.h | 3 ++ src/PartSet/PartSet_Module.cpp | 4 +- src/XGUI/XGUI_ActionsMgr.cpp | 20 ++++++++- src/XGUI/XGUI_ActionsMgr.h | 4 ++ src/XGUI/XGUI_HistoryMenu.cpp | 13 +++--- src/XGUI/XGUI_HistoryMenu.h | 4 ++ src/XGUI/XGUI_ObjectsBrowser.cpp | 2 +- src/XGUI/XGUI_Workshop.cpp | 54 +++++++++++++++---------- src/XGUI/XGUI_Workshop.h | 3 ++ 12 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/Model/Model_Session.h b/src/Model/Model_Session.h index 0ae8bc46a..ac1e4e1b0 100644 --- a/src/Model/Model_Session.h +++ b/src/Model/Model_Session.h @@ -48,7 +48,7 @@ class Model_Session : public ModelAPI_Session, public Events_Listener MODEL_EXPORT virtual void closeAll(); //! Starts a new operation (opens a tansaction) - MODEL_EXPORT virtual void startOperation(const std::string& theId); + MODEL_EXPORT virtual void startOperation(const std::string& theId = ""); //! Finishes the previously started operation (closes the transaction) MODEL_EXPORT virtual void finishOperation(); //! Aborts the operation diff --git a/src/ModelAPI/ModelAPI_Session.h b/src/ModelAPI/ModelAPI_Session.h index 933dfc586..613122a35 100644 --- a/src/ModelAPI/ModelAPI_Session.h +++ b/src/ModelAPI/ModelAPI_Session.h @@ -46,7 +46,7 @@ class MODELAPI_EXPORT ModelAPI_Session //! Starts a new operation (opens a tansaction) //! \param theId of operation for history (optional) - virtual void startOperation(const std::string& theId) = 0; + virtual void startOperation(const std::string& theId = "") = 0; //! Finishes the previously started operation (closes the transaction) virtual void finishOperation() = 0; //! Aborts the operation diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index bfe58446d..459af0553 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -147,6 +147,9 @@ std::shared_ptr ModuleBase_Operation::document() const void ModuleBase_Operation::start() { QString anId = getDescription()->operationId(); + if (myIsEditing) { + anId = anId.append(EditSuffix()); + } ModelAPI_Session::get()->startOperation(anId.toStdString()); if (!myIsEditing) diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 8842230b2..f43ed76e1 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -50,6 +50,9 @@ class MODULEBASE_EXPORT ModuleBase_Operation : public QObject Q_OBJECT public: + + /// Appends to operation's history id, if it is an "edit" operation (myIsEditing == true) + static QString EditSuffix() { return "_E"; } /// Constructor /// \param theId the operation identifier /// \param theParent the QObject parent diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 05409232e..a8be84bd8 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -555,6 +555,7 @@ void PartSet_Module::deleteObjects() //} } + QString aDescription = tr("Delete"); if (!aRefFeatures.empty()) { QStringList aRefNames; std::set::const_iterator anIt = aRefFeatures.begin(), @@ -567,6 +568,7 @@ void PartSet_Module::deleteObjects() } if (!aRefNames.empty()) { QString aNames = aRefNames.join(", "); + aDescription += aNames.prepend(" "); QMainWindow* aDesktop = aWorkshop->desktop(); QMessageBox::StandardButton aRes = QMessageBox::warning( @@ -580,7 +582,7 @@ void PartSet_Module::deleteObjects() } SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation("DeletePartSet"); + aMgr->startOperation(aDescription.toStdString()); std::set::const_iterator anIt = aRefFeatures.begin(), aLast = aRefFeatures.end(); for (; anIt != aLast; anIt++) { diff --git a/src/XGUI/XGUI_ActionsMgr.cpp b/src/XGUI/XGUI_ActionsMgr.cpp index c3613d22b..0798bbc48 100644 --- a/src/XGUI/XGUI_ActionsMgr.cpp +++ b/src/XGUI/XGUI_ActionsMgr.cpp @@ -228,9 +228,13 @@ QAction* XGUI_ActionsMgr::operationStateAction(OperationStateActionId theId, QOb aResult = new QAction(QIcon(":pictures/button_ok.png"), "", theParent); break; case Abort: - case AbortAll: + case AbortAll: { aResult = new QAction(QIcon(":pictures/button_cancel.png"), "", theParent); - break; + if(theId == Abort) { + aResult->setShortcut(QKeySequence(Qt::Key_Escape)); + } + } + break; case Help: aResult = new QAction(QIcon(":pictures/button_help.png"), "", theParent); break; @@ -242,6 +246,18 @@ QAction* XGUI_ActionsMgr::operationStateAction(OperationStateActionId theId, QOb return aResult; } +ActionInfo XGUI_ActionsMgr::actionInfoById(const QString& theId) +{ + ActionInfo aResult; + if(myActions.contains(theId)) { + aResult.initFrom(myActions.value(theId)); + } else { + aResult.id = theId; + aResult.text = theId; + } + return aResult; +} + void XGUI_ActionsMgr::setAllEnabled(bool isEnabled) { foreach(QString eachAction, myActions.keys()) diff --git a/src/XGUI/XGUI_ActionsMgr.h b/src/XGUI/XGUI_ActionsMgr.h index cbff72d12..00f6086ef 100644 --- a/src/XGUI/XGUI_ActionsMgr.h +++ b/src/XGUI/XGUI_ActionsMgr.h @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -77,6 +79,8 @@ class XGUI_EXPORT XGUI_ActionsMgr : public QObject, public Events_Listener //! If there is no such action, it will be created. QAction* operationStateAction(OperationStateActionId theId, QObject* theParent = 0); + ActionInfo actionInfoById(const QString& theId); + public slots: //! Update workbench actions according to OperationMgr state: //! No active operations: all actions but nested are available diff --git a/src/XGUI/XGUI_HistoryMenu.cpp b/src/XGUI/XGUI_HistoryMenu.cpp index 7ae27d0b3..95c6ae802 100644 --- a/src/XGUI/XGUI_HistoryMenu.cpp +++ b/src/XGUI/XGUI_HistoryMenu.cpp @@ -66,14 +66,16 @@ void XGUI_HistoryMenu::setHistory(const QList& theActions) } } +void XGUI_HistoryMenu::leaveEvent(QEvent* theEvent) +{ + setStackSelectedTo(NULL); + QMenu::leaveEvent(theEvent); +} void XGUI_HistoryMenu::setStackSelectedTo(QListWidgetItem * theItem) { - if (!theItem) - return; - QListWidgetItem* eachItem = NULL; - bool isSelect = true; + bool isSelect = theItem != NULL; for(int aRow = 0; aRow < myHistoryList->count(); ++aRow) { eachItem = myHistoryList->item(aRow); myHistoryList->setItemSelected(eachItem, isSelect); @@ -82,6 +84,8 @@ void XGUI_HistoryMenu::setStackSelectedTo(QListWidgetItem * theItem) isSelect = false; } } + // to avoid blinking caused by QMenu paint event (paints on top of the list) + myHistoryList->repaint(); } void XGUI_HistoryMenu::onItemPressed(QListWidgetItem * theItem) @@ -89,5 +93,4 @@ void XGUI_HistoryMenu::onItemPressed(QListWidgetItem * theItem) int selectedSize = myHistoryList->row(theItem) + 1; emit actionSelected(selectedSize); hide(); - myHistoryList->clear(); } diff --git a/src/XGUI/XGUI_HistoryMenu.h b/src/XGUI/XGUI_HistoryMenu.h index bc45f7a4d..563689e43 100644 --- a/src/XGUI/XGUI_HistoryMenu.h +++ b/src/XGUI/XGUI_HistoryMenu.h @@ -31,11 +31,15 @@ class XGUI_EXPORT XGUI_HistoryMenu : public QMenu public slots: void setHistory(const QList&); + protected: + virtual void leaveEvent(QEvent *); + protected slots: void setStackSelectedTo(QListWidgetItem *); void onItemPressed(QListWidgetItem *); void initMenu(); + private: QListWidget* myHistoryList; }; diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index 243e98eaf..348eb2a31 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -80,7 +80,7 @@ void XGUI_DataTree::commitData(QWidget* theEditor) QString aRes = aEditor->text(); ObjectPtr aFeature = mySelectedData.first(); SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation("RenameFeature"); + aMgr->startOperation("Rename"); aFeature->data()->setName(qPrintable(aRes)); aMgr->finishOperation(); } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 9d4e1ccbf..ded693fcf 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1077,11 +1077,10 @@ void XGUI_Workshop::updateCommandStatus() // Enable all commands aCmd->setEnabled(true); } + aUndoCmd->setEnabled(myModule->canUndo()); aRedoCmd->setEnabled(myModule->canRedo()); - updateHistory(); - } else { foreach(QAction* aCmd, aCommands) { QString aId = aCmd->data().toString(); @@ -1100,28 +1099,12 @@ void XGUI_Workshop::updateCommandStatus() void XGUI_Workshop::updateHistory() { std::list aUndoList = ModelAPI_Session::get()->undoList(); - std::list::iterator it = aUndoList.begin(); - QList aUndoRes; - for ( ; it != aUndoList.end(); it++) { - QString anId = QString::fromStdString(*it); - QIcon aIcon; - if (myIcons.contains(anId)) - aIcon = QIcon(myIcons[anId]); - aUndoRes << ActionInfo(aIcon, anId); - } + QList aUndoRes = processHistoryList(aUndoList); emit updateUndoHistory(aUndoRes); std::list aRedoList = ModelAPI_Session::get()->redoList(); - it = aRedoList.begin(); - QList aRedoRes; - for ( ; it != aRedoList.end(); it++) { - QString anId = QString::fromStdString(*it); - QIcon aIcon; - if (myIcons.contains(anId)) - aIcon = QIcon(myIcons[anId]); - aRedoRes << ActionInfo(aIcon, anId); - } - emit updateRedoHistory(aUndoRes); + QList aRedoRes = processHistoryList(aRedoList); + emit updateRedoHistory(aRedoRes); } //****************************************************** @@ -1345,7 +1328,15 @@ These features will be deleted also. Would you like to continue?")).arg(aNames), } SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation("DeleteObjects"); + QString aDescription = tr("Delete %1"); + QStringList aObjectNames; + foreach (ObjectPtr aObj, theList) { + if (!aObj->data().get()) + continue; + aObjectNames << QString::fromStdString(aObj->data()->name()); + } + aDescription = aDescription.arg(aObjectNames.join(", ")); + aMgr->startOperation(aDescription.toStdString()); std::set::const_iterator anIt = aRefFeatures.begin(), aLast = aRefFeatures.end(); for (; anIt != aLast; anIt++) { @@ -1373,6 +1364,7 @@ These features will be deleted also. Would you like to continue?")).arg(aNames), myDisplayer->updateViewer(); aMgr->finishOperation(); + updateCommandStatus(); } //************************************************************** @@ -1487,5 +1479,23 @@ void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, co } connect(this, theSignal, aMenu, SLOT(setHistory(const QList&))); connect(aMenu, SIGNAL(actionSelected(int)), this, theSlot); +} +QList XGUI_Workshop::processHistoryList(const std::list& theList) const +{ + QList aResult; + std::list::const_iterator it = theList.cbegin(); + for (; it != theList.cend(); it++) { + QString anId = QString::fromStdString(*it); + bool isEditing = anId.endsWith(ModuleBase_Operation::EditSuffix()); + if (isEditing) { + anId.chop(ModuleBase_Operation::EditSuffix().size()); + } + ActionInfo anInfo = myActionsMgr->actionInfoById(anId); + if (isEditing) { + anInfo.text = anInfo.text.prepend("Modify "); + } + aResult << anInfo; + } + return aResult; } diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index b492fa113..6ef022dfb 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -389,6 +389,9 @@ signals: //! \param theSlot - onUndo(int) or onRedo(int) SLOT void addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot); + //! Creates list of actions (commands) by given history list from session + QList processHistoryList(const std::list&) const; + private: AppElements_MainWindow* myMainWindow; ModuleBase_IModule* myModule; -- 2.39.2