X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Workshop.cpp;h=c8058f38d6fd5ac19d7bf62121dc95cca414dad2;hb=65a616a3bb6cbdf09c61fed7eb91d1f5d9667988;hp=0dbb7687697715258db406ca3179ae33e987596d;hpb=37bc296c8550959d2da0f6009fe1126b15009e66;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 0dbb76876..c8058f38d 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1,42 +1,50 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> //#include "XGUI_Constants.h" -#include "XGUI_Tools.h" #include "XGUI_Workshop.h" -#include "XGUI_SelectionMgr.h" -#include "XGUI_Selection.h" -#include "XGUI_ObjectsBrowser.h" + +#include "XGUI_ActionsMgr.h" +#include "XGUI_ColorDialog.h" +#include "XGUI_ContextMenuMgr.h" #include "XGUI_Displayer.h" +#include "XGUI_ErrorDialog.h" +#include "XGUI_ErrorMgr.h" +#include "XGUI_ModuleConnector.h" +#include "XGUI_ObjectsBrowser.h" #include "XGUI_OperationMgr.h" +#include "XGUI_PropertyPanel.h" #include "XGUI_SalomeConnector.h" -#include "XGUI_ActionsMgr.h" -#include "XGUI_ErrorDialog.h" +#include "XGUI_Selection.h" +#include "XGUI_SelectionMgr.h" +#include "XGUI_Tools.h" #include "XGUI_ViewerProxy.h" -#include "XGUI_PropertyPanel.h" -#include "XGUI_ContextMenuMgr.h" -#include "XGUI_ModuleConnector.h" -#include +#include "XGUI_WorkshopListener.h" +#include #include +#include -#include -#include +#include #include #include #include #include +#include +#include -#include -#include - +#include +#include +#include #include -#include #include -#include -#include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include //#include @@ -44,22 +52,28 @@ #include #include -#include +#include +#include +#include #include #include +#include +#include #include -#include #include -#include -#include +#include +#include +#include #include #include -#include #include +#include #include #include +#include + #include #include #include @@ -72,6 +86,9 @@ #include #include #include +#include + +#include #ifdef _DEBUG #include @@ -84,44 +101,7 @@ #include #endif -QMap XGUI_Workshop::myIcons; - - -QIcon XGUI_Workshop::featureIcon(const FeaturePtr& theFeature) -{ - QIcon anIcon; - - std::string aKind = theFeature->getKind(); - QString aId(aKind.c_str()); - if (!myIcons.contains(aId)) - return anIcon; - - QString anIconString = myIcons[aId]; - - ModelAPI_ExecState aState = theFeature->data()->execState(); - switch(aState) { - case ModelAPI_StateDone: - case ModelAPI_StateNothing: { - anIcon = QIcon(anIconString); - } - break; - case ModelAPI_StateMustBeUpdated: { - anIcon = ModuleBase_Tools::lighter(anIconString); - } - break; - case ModelAPI_StateExecFailed: { - anIcon = ModuleBase_Tools::composite(":pictures/exec_state_failed.png", anIconString); - } - break; - case ModelAPI_StateInvalidArgument: { - anIcon = ModuleBase_Tools::composite(":pictures/exec_state_invalid_parameters.png", - anIconString); - } - break; - default: break; - } - return anIcon; -} +//#define DEBUG_DELETE XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) : QObject(), @@ -130,20 +110,28 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) mySalomeConnector(theConnector), myPropertyPanel(0), myObjectBrowser(0), - myDisplayer(0), - myUpdatePrefs(false), - myPartActivating(false) + myDisplayer(0) { myMainWindow = mySalomeConnector ? 0 : new AppElements_MainWindow(); + if (myMainWindow) { + SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr(); + bool aCloc = aResMgr->booleanValue("language", "locale", true); + if (aCloc) + QLocale::setDefault( QLocale::c() ); + else + QLocale::setDefault( QLocale::system() ); + } + myDisplayer = new XGUI_Displayer(this); mySelector = new XGUI_SelectionMgr(this); //connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateModuleCommands())); - myOperationMgr = new XGUI_OperationMgr(this); + myOperationMgr = new XGUI_OperationMgr(this, 0); myActionsMgr = new XGUI_ActionsMgr(this); - myErrorDlg = new XGUI_ErrorDialog(myMainWindow); + myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop()); + myErrorMgr = new XGUI_ErrorMgr(this); myContextMenuMgr = new XGUI_ContextMenuMgr(this); connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this, SLOT(onContextMenuCommand(const QString&, bool))); @@ -154,6 +142,11 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) myModuleConnector = new XGUI_ModuleConnector(this); + ModuleBase_IWorkshop* aWorkshop = moduleConnector(); + myOperationMgr->setWorkshop(aWorkshop); + + myEventsListener = new XGUI_WorkshopListener(aWorkshop); + connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), SLOT(onOperationStarted(ModuleBase_Operation*))); connect(myOperationMgr, SIGNAL(operationResumed(ModuleBase_Operation*)), @@ -164,8 +157,26 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) SLOT(onOperationCommitted(ModuleBase_Operation*))); connect(myOperationMgr, SIGNAL(operationAborted(ModuleBase_Operation*)), SLOT(onOperationAborted(ModuleBase_Operation*))); - connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit())); + connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), + myErrorMgr, SLOT(onValidationStateChanged())); + + if (myMainWindow) + connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit())); connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&))); + connect(myEventsListener, SIGNAL(errorOccurred(const QString&)), + myErrorDlg, SLOT(addError(const QString&))); + + //Config_PropManager::registerProp("Visualization", "object_default_color", "Object color", + // Config_Prop::Color, "225,225,225"); + + Config_PropManager::registerProp("Visualization", "result_body_color", "Body color", + Config_Prop::Color, ModelAPI_ResultBody::DEFAULT_COLOR()); + Config_PropManager::registerProp("Visualization", "result_group_color", "Group color", + Config_Prop::Color, ModelAPI_ResultGroup::DEFAULT_COLOR()); + Config_PropManager::registerProp("Visualization", "result_construction_color", "Construction color", + Config_Prop::Color, ModelAPI_ResultConstruction::DEFAULT_COLOR()); + Config_PropManager::registerProp("Visualization", "result_part_color", "Part color", + Config_Prop::Color, ModelAPI_ResultPart::DEFAULT_COLOR()); } //****************************************************** @@ -183,27 +194,14 @@ void XGUI_Workshop::startApplication() Config_Prop::Directory, ""); //Initialize event listening - Events_Loop* aLoop = Events_Loop::loop(); - aLoop->registerListener(this, Events_Error::errorID()); //!< Listening application errors. - aLoop->registerListener(this, Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT())); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OPERATION_LAUNCHED)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED)); - aLoop->registerListener(this, Events_LongOp::eventID()); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_PLUGIN_LOADED)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOSHOW)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); - aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SELFILTER_LOADED)); + myEventsListener->initializeEventListening(); registerValidators(); // Calling of loadCustomProps before activating module is required // by Config_PropManger to restore user-defined path to plugins ModuleBase_Preferences::loadCustomProps(); - activateModule(); + createModule(); if (myMainWindow) { myMainWindow->show(); updateCommandStatus(); @@ -214,6 +212,42 @@ void XGUI_Workshop::startApplication() emit applicationStarted(); } +void XGUI_Workshop::activateModule() +{ + myModule->activateSelectionFilters(); + + connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)), + myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr))); + connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)), + myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr))); + + myActionsMgr->update(); + + // activate visualized objects in the viewer + XGUI_Displayer* aDisplayer = displayer(); + QObjectPtrList aDisplayed = aDisplayer->displayedObjects(); + QIntList aModes; + module()->activeSelectionModes(aModes); + aDisplayer->activateObjects(aModes, aDisplayed); +} + +void XGUI_Workshop::deactivateModule() +{ + myModule->deactivateSelectionFilters(); + + // remove internal displayer filter + displayer()->deactivateSelectionFilters(); + + disconnect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)), + myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr))); + disconnect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)), + myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr))); + + XGUI_Displayer* aDisplayer = displayer(); + QObjectPtrList aDisplayed = aDisplayer->displayedObjects(); + aDisplayer->deactivateObjects(aDisplayed, true); +} + //****************************************************** void XGUI_Workshop::initMenu() { @@ -225,15 +259,26 @@ void XGUI_Workshop::initMenu() tr("Undo last command"), QIcon(":pictures/undo.png"), QKeySequence::Undo, false, "MEN_DESK_EDIT"); + QString aToolBarTitle = tr( "INF_DESK_TOOLBAR_STANDARD" ); + salomeConnector()->addActionInToolbar( aAction,aToolBarTitle ); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo())); + addHistoryMenu(aAction, SIGNAL(updateUndoHistory(const QList&)), SLOT(onUndo(int))); + aAction = salomeConnector()->addDesktopCommand("REDO_CMD", tr("Redo"), tr("Redo last command"), QIcon(":pictures/redo.png"), QKeySequence::Redo, false, "MEN_DESK_EDIT"); + salomeConnector()->addActionInToolbar( aAction, aToolBarTitle ); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRedo())); + addHistoryMenu(aAction, SIGNAL(updateRedoHistory(const QList&)), SLOT(onRedo(int))); + salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT"); aAction = salomeConnector()->addDesktopCommand("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"), QIcon(":pictures/rebuild.png"), QKeySequence(), false, "MEN_DESK_EDIT"); + salomeConnector()->addActionInToolbar( aAction, aToolBarTitle ); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild())); salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT"); @@ -255,7 +300,7 @@ void XGUI_Workshop::initMenu() AppElements_Command* aCommand; - aCommand = aGroup->addFeature("SAVE_CMD", tr("Save..."), tr("Save the document"), + aCommand = aGroup->addFeature("SAVE_CMD", tr("Save"), tr("Save the document"), QIcon(":pictures/save.png"), QKeySequence::Save); aCommand->connectTo(this, SLOT(onSave())); //aCommand->disable(); @@ -264,25 +309,19 @@ void XGUI_Workshop::initMenu() aCommand = aGroup->addFeature(aUndoId, tr("Undo"), tr("Undo last command"), QIcon(":pictures/undo.png"), QKeySequence::Undo); aCommand->connectTo(this, SLOT(onUndo())); - - QToolButton* aToolBtn = qobject_cast(aGroup->widget(aUndoId)); - XGUI_HistoryMenu* aUndoMenu = new XGUI_HistoryMenu(aToolBtn); - connect(this, SIGNAL(updateUndoHistory(const QList&)), - aUndoMenu, SLOT(setHistory(const QList&))); - connect(aUndoMenu, SIGNAL(actionsSelected(int)), - this, SLOT(onUndo(int))); + AppElements_Button* aUndoButton = qobject_cast(aGroup->widget(aUndoId)); + addHistoryMenu(aUndoButton, + SIGNAL(updateUndoHistory(const QList&)), + SLOT(onUndo(int))); QString aRedoId = "REDO_CMD"; aCommand = aGroup->addFeature(aRedoId, tr("Redo"), tr("Redo last command"), QIcon(":pictures/redo.png"), QKeySequence::Redo); aCommand->connectTo(this, SLOT(onRedo())); - - aToolBtn = qobject_cast(aGroup->widget(aRedoId)); - XGUI_HistoryMenu* aRedoMenu = new XGUI_HistoryMenu(aToolBtn); - connect(this, SIGNAL(updateUndoHistory(const QList&)), - aRedoMenu, SLOT(setHistory(const QList&))); - connect(aRedoMenu, SIGNAL(actionsSelected(int)), - this, SLOT(onUndo(int))); + AppElements_Button* aRedoButton = qobject_cast(aGroup->widget(aRedoId)); + addHistoryMenu(aRedoButton, + SIGNAL(updateRedoHistory(const QList&)), + SLOT(onRedo(int))); aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"), QIcon(":pictures/rebuild.png"), QKeySequence()); @@ -323,147 +362,6 @@ AppElements_Workbench* XGUI_Workshop::addWorkbench(const QString& theName) return aMenuBar->addWorkbench(theName); } -//****************************************************** -void XGUI_Workshop::processEvent(const std::shared_ptr& theMessage) -{ - if (QApplication::instance()->thread() != QThread::currentThread()) { - #ifdef _DEBUG - std::cout << "XGUI_Workshop::processEvent: " << "Working in another thread." << std::endl; - #endif - SessionPtr aMgr = ModelAPI_Session::get(); - PostponeMessageQtEvent* aPostponeEvent = new PostponeMessageQtEvent(theMessage); - QApplication::postEvent(this, aPostponeEvent); - return; - } - - //A message to start feature creation received. - if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) { - std::shared_ptr aFeatureMsg = - std::dynamic_pointer_cast(theMessage); - if (!aFeatureMsg->isInternal()) { - addFeature(aFeatureMsg); - } - } - // Process creation of Part - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) { - std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); - onFeatureCreatedMsg(aUpdMsg); - if (myUpdatePrefs) { - if (mySalomeConnector) - mySalomeConnector->createPreferences(); - myUpdatePrefs = false; - } - } - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_PLUGIN_LOADED)) { - myUpdatePrefs = true; - } - // Redisplay feature - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) { - std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); - onFeatureRedisplayMsg(aUpdMsg); - } - //Update property panel on corresponding message. If there is no current operation (no - //property panel), or received message has different feature to the current - do nothing. - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) { - std::shared_ptr anUpdateMsg = - std::dynamic_pointer_cast(theMessage); - onFeatureUpdatedMsg(anUpdateMsg); - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { - std::shared_ptr aDelMsg = - std::dynamic_pointer_cast(theMessage); - onObjectDeletedMsg(aDelMsg); - } else if (theMessage->eventID() == Events_LongOp::eventID()) { - if (Events_LongOp::isPerformed()) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - } else { - QApplication::restoreOverrideCursor(); - } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TOSHOW)) { - std::shared_ptr anUpdateMsg = - std::dynamic_pointer_cast(theMessage); - const std::set& aObjList = anUpdateMsg->objects(); - QObjectPtrList aList; - std::set::const_iterator aIt; - for (aIt = aObjList.cbegin(); aIt != aObjList.cend(); ++aIt) - aList.append(*aIt); - showObjects(aList, true); - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TOHIDE)) { - std::shared_ptr anUpdateMsg = - std::dynamic_pointer_cast(theMessage); - const std::set& aObjList = anUpdateMsg->objects(); - QObjectPtrList aList; - std::set::const_iterator aIt; - for (aIt = aObjList.cbegin(); aIt != aObjList.cend(); ++aIt) - aList.append(*aIt); - showObjects(aList, false); - } - //An operation passed by message. Start it, process and commit. - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OPERATION_LAUNCHED)) { - std::shared_ptr aPartSetMsg = - std::dynamic_pointer_cast(theMessage); - //myPropertyPanel->cleanContent(); - ModuleBase_Operation* anOperation = (ModuleBase_Operation*) aPartSetMsg->pointer(); - - if (myOperationMgr->startOperation(anOperation)) { - myPropertyPanel->updateContentWidget(anOperation->feature()); - if (!anOperation->getDescription()->hasXmlRepresentation()) { - if (anOperation->commit()) - updateCommandStatus(); - } - } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) { - myActionsMgr->update(); - // Find and Activate active part - if (myPartActivating) - return; - SessionPtr aMgr = ModelAPI_Session::get(); - DocumentPtr aActiveDoc = aMgr->activeDocument(); - DocumentPtr aDoc = aMgr->moduleDocument(); - if (aActiveDoc == aDoc) { - activatePart(ResultPartPtr()); - return; - } - std::string aGrpName = ModelAPI_ResultPart::group(); - for (int i = 0; i < aDoc->size(aGrpName); i++) { - ResultPartPtr aPart = std::dynamic_pointer_cast(aDoc->object(aGrpName, i)); - if (aPart->partDoc() == aActiveDoc) { - activatePart(aPart); // Activate a part which corresponds to active Doc - return; - } - } - // If not found then activate global document - activatePart(ResultPartPtr()); - - } - else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SELFILTER_LOADED)) { - std::shared_ptr aMsg = - std::dynamic_pointer_cast(theMessage); - if (aMsg) { - ModuleBase_FilterFactory* aFactory = moduleConnector()->selectionFilters(); - if (!aMsg->attributeId().empty()) { - aFactory->assignFilter(aMsg->selectionFilterId(), aMsg->featureId(), aMsg->attributeId(), - aMsg->parameters()); - } - } - } - - - else { - //Show error dialog if error message received. - std::shared_ptr anAppError = std::dynamic_pointer_cast(theMessage); - if (anAppError) { - emit errorOccurred(QString::fromLatin1(anAppError->description())); - } - } - if (!isSalomeMode()) { - SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->isModified() != myMainWindow->isModifiedState()) - myMainWindow->setModifiedState(aMgr->isModified()); - } -} - //****************************************************** QMainWindow* XGUI_Workshop::desktop() const { @@ -478,290 +376,168 @@ void XGUI_Workshop::onStartWaiting() } } -//****************************************************** -void XGUI_Workshop::onFeatureUpdatedMsg(const std::shared_ptr& theMsg) -{ - std::set aFeatures = theMsg->objects(); - if (myOperationMgr->hasOperation()) { - FeaturePtr aCurrentFeature = myOperationMgr->currentOperation()->feature(); - std::set::const_iterator aIt; - for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) { - ObjectPtr aNewFeature = (*aIt); - if (aNewFeature == aCurrentFeature) { - myPropertyPanel->updateContentWidget(aCurrentFeature); - break; - } - } - } - myOperationMgr->onValidateOperation(); - if (myObjectBrowser) - myObjectBrowser->processEvent(theMsg); -} //****************************************************** -void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr& theMsg) +void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer) { - std::set aObjects = theMsg->objects(); - std::set::const_iterator aIt; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { - ObjectPtr aObj = (*aIt); - - bool aHide = !aObj->data() || !aObj->data()->isValid(); - if (!aHide) { // check that this is not hidden result - ResultPtr aRes = std::dynamic_pointer_cast(aObj); - aHide = aRes && aRes->isConcealed(); - } - if (aHide) - myDisplayer->erase(aObj, false); - else { - if (myDisplayer->isVisible(aObj)) { - displayObject(aObj); // In order to update presentation - if (myOperationMgr->hasOperation()) { - ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - if (!aOperation->isEditOperation() && - aOperation->hasObject(aObj) && myDisplayer->isActive(aObj)) - myDisplayer->deactivate(aObj); - } - } else { - if (myOperationMgr->hasOperation()) { - ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - if (myModule->canDisplayObject(aObj)) { - displayObject(aObj); - // Deactivate object of current operation from selection - if (myDisplayer->isActive(aObj)) - myDisplayer->deactivate(aObj); - } - } - } + if (!myModule->canActivateSelection(theObject)) { + if (myDisplayer->isActive(theObject)) { + QObjectPtrList anObjects; + anObjects.append(theObject); + myDisplayer->deactivateObjects(anObjects, theUpdateViewer); } } - myDisplayer->updateViewer(); -} - -//****************************************************** -void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptr& theMsg) -{ - std::set aObjects = theMsg->objects(); - - std::set::const_iterator aIt; - bool aHasPart = false; - bool isDisplayed = false; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { - - ResultPartPtr aPart = std::dynamic_pointer_cast(*aIt); - if (aPart) { - aHasPart = true; - // If a feature is created from the aplication's python console - // it doesn't stored in the operation mgr and doesn't displayed - } else if (myModule->canDisplayObject(*aIt)) { - displayObject(*aIt); - isDisplayed = true; - } - } - if (myObjectBrowser) - myObjectBrowser->processEvent(theMsg); - if (isDisplayed) - myDisplayer->updateViewer(); - //if (aHasPart) { // TODO: Avoid activate last part on loading of document - // activateLastPart(); - //} -} - -//****************************************************** -void XGUI_Workshop::onObjectDeletedMsg(const std::shared_ptr& theMsg) -{ - if (myObjectBrowser) - myObjectBrowser->processEvent(theMsg); - //std::set aFeatures = theMsg->objects(); } //****************************************************** void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation) { - setNestedFeatures(theOperation); + setGrantedFeatures(theOperation); - if (theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel - connectWithOperation(theOperation); - setPropertyPanel(theOperation); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (!aFOperation) + return; + + if (aFOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel + setPropertyPanel(aFOperation); + // filling the operation values by the current selection + // if the operation can be commited after the controls filling, the method perform should + // be stopped. Otherwise unnecessary presentations can be shown(e.g. operation prs in sketch) + if (!aFOperation->isEditOperation()) { + aFOperation->activateByPreselection(); + if (operationMgr()->currentOperation() != aFOperation) + return; + } } updateCommandStatus(); - myModule->operationStarted(theOperation); + myModule->onOperationStarted(aFOperation); + + // the objects of the current operation should be deactivated + QObjectPtrList anObjects; + FeaturePtr aFeature = aFOperation->feature(); + anObjects.append(aFeature); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + anObjects.append(*aIt); + } + QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); + for (; anIt != aLast; anIt++) + deactivateActiveObject(*anIt, false); + if (anObjects.size() > 0) + myDisplayer->updateViewer(); } //****************************************************** void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation) { - setNestedFeatures(theOperation); + setGrantedFeatures(theOperation); if (theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel - connectWithOperation(theOperation); setPropertyPanel(theOperation); } updateCommandStatus(); - myModule->operationResumed(theOperation); + myModule->onOperationResumed(theOperation); } //****************************************************** void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) { + updateCommandStatus(); + + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (!aFOperation) + return; + ModuleBase_ISelection* aSel = mySelector->selection(); QObjectPtrList aObj = aSel->selectedPresentations(); //!< No need for property panel - updateCommandStatus(); hidePropertyPanel(); myPropertyPanel->cleanContent(); - // Activate objects created by current operation - // in order to clean selection modes + myModule->onOperationStopped(aFOperation); + + // the deactivated objects of the current operation should be activated back. + // They were deactivated on operation start or an object redisplay + QObjectPtrList anObjects; + FeaturePtr aFeature = aFOperation->feature(); + if (myDisplayer->isVisible(aFeature) && !myDisplayer->isActive(aFeature)) + anObjects.append(aFeature); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + ResultPtr anObject = *aIt; + if (myDisplayer->isVisible(anObject) && !myDisplayer->isActive(anObject)) { + anObjects.append(anObject); + } + } QIntList aModes; - myDisplayer->activateObjects(aModes); - myModule->operationStopped(theOperation); + module()->activeSelectionModes(aModes); + myDisplayer->activateObjects(aModes, anObjects); } void XGUI_Workshop::onOperationCommitted(ModuleBase_Operation* theOperation) { - myModule->operationCommitted(theOperation); + myModule->onOperationCommitted(theOperation); } void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation) { - myModule->operationAborted(theOperation); + myModule->onOperationAborted(theOperation); } -void XGUI_Workshop::setNestedFeatures(ModuleBase_Operation* theOperation) +void XGUI_Workshop::setGrantedFeatures(ModuleBase_Operation* theOperation) { - if (this->isSalomeMode()) - theOperation->setNestedFeatures(mySalomeConnector->nestedActions(theOperation->id())); - else - theOperation->setNestedFeatures(myActionsMgr->nestedCommands(theOperation->id())); + ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); + if (!aFOperation) + return; + + QStringList aGrantedIds; + if (isSalomeMode()) + aGrantedIds = mySalomeConnector->nestedActions(theOperation->id()); + else + aGrantedIds = myActionsMgr->nestedCommands(theOperation->id()); + + aFOperation->setGrantedOperationIds(aGrantedIds); } void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); + if (!aFOperation) + return; + showPropertyPanel(); - QString aXmlRepr = theOperation->getDescription()->xmlRepresentation(); + QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation(); ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aXmlRepr.toStdString(), myModuleConnector); myPropertyPanel->cleanContent(); aFactory.createWidget(myPropertyPanel->contentWidget()); - ModuleBase_Tools::zeroMargins(myPropertyPanel->contentWidget()); QList aWidgets = aFactory.getModelWidgets(); foreach (ModuleBase_ModelWidget* aWidget, aWidgets) { - aWidget->setFeature(theOperation->feature()); + bool isStoreValue = !aFOperation->isEditOperation() && + !aWidget->getDefaultValue().empty() && + !aWidget->isComputedDefault(); + aWidget->setFeature(aFOperation->feature(), isStoreValue); aWidget->enableFocusProcessing(); - QObject::connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged())); - // Init default values - if (!theOperation->isEditOperation() && aWidget->isValueDefault() && !aWidget->isComputedDefault()) { - aWidget->storeValue(); - } } myPropertyPanel->setModelWidgets(aWidgets); - theOperation->setPropertyPanel(myPropertyPanel); + aFOperation->setPropertyPanel(myPropertyPanel); myModule->propertyPanelDefined(theOperation); myPropertyPanel->setWindowTitle(theOperation->getDescription()->description()); -} -bool XGUI_Workshop::event(QEvent * theEvent) -{ - PostponeMessageQtEvent* aPostponedEv = dynamic_cast(theEvent); - if (aPostponedEv) { - std::shared_ptr aEventPtr = aPostponedEv->postponedMessage(); - processEvent(aEventPtr); - return true; - } - return false; -} - -/* - * - */ -void XGUI_Workshop::addFeature(const std::shared_ptr& theMessage) -{ - if (!theMessage) { -#ifdef _DEBUG - qDebug() << "XGUI_Workshop::addFeature: NULL message."; -#endif - return; - } - // Remember features icons - myIcons[QString::fromStdString(theMessage->id())] = QString::fromStdString(theMessage->icon()); - - QString aWchName = QString::fromStdString(theMessage->workbenchId()); - QString aNestedFeatures = QString::fromStdString(theMessage->nestedFeatures()); - bool isUsePropPanel = theMessage->isUseInput(); - QString aFeatureId = QString::fromStdString(theMessage->id()); - if (isSalomeMode()) { - QAction* aAction = salomeConnector()->addFeature(aWchName, aFeatureId, - QString::fromStdString(theMessage->text()), - QString::fromStdString(theMessage->tooltip()), - QIcon(QString::fromStdString(theMessage->icon())), - QKeySequence(), - isUsePropPanel); - salomeConnector()->setNestedActions(aFeatureId, aNestedFeatures.split(" ", QString::SkipEmptyParts)); - salomeConnector()->setDocumentKind(aFeatureId, QString::fromStdString(theMessage->documentKind())); - - myActionsMgr->addCommand(aAction); - myModule->actionCreated(aAction); - } else { - //Find or create Workbench - AppElements_MainMenu* aMenuBar = myMainWindow->menuObject(); - AppElements_Workbench* aPage = aMenuBar->findWorkbench(aWchName); - if (!aPage) { - aPage = addWorkbench(aWchName); - } - //Find or create Group - QString aGroupName = QString::fromStdString(theMessage->groupId()); - AppElements_MenuGroupPanel* aGroup = aPage->findGroup(aGroupName); - if (!aGroup) { - aGroup = aPage->addGroup(aGroupName); - } - QString aDocKind = QString::fromStdString(theMessage->documentKind()); - // Check if hotkey sequence is already defined: - QKeySequence aHotKey = myActionsMgr->registerShortcut( - QString::fromStdString(theMessage->keysequence())); - // Create feature... - AppElements_Command* aCommand = aGroup->addFeature(aFeatureId, - QString::fromStdString(theMessage->text()), - QString::fromStdString(theMessage->tooltip()), - QIcon(theMessage->icon().c_str()), - aDocKind, - aHotKey, - isUsePropPanel); - aCommand->setNestedCommands(aNestedFeatures.split(" ", QString::SkipEmptyParts)); - myActionsMgr->addCommand(aCommand); - myModule->actionCreated(aCommand); - } -} - -/* - * Makes a signal/slot connections between Property Panel - * and given operation. The given operation becomes a - * current operation and previous operation if exists - */ -void XGUI_Workshop::connectWithOperation(ModuleBase_Operation* theOperation) -{ - QAction* aCommand = 0; - if (isSalomeMode()) { - aCommand = salomeConnector()->command(theOperation->getDescription()->operationId()); - } else { - AppElements_MainMenu* aMenu = myMainWindow->menuObject(); - FeaturePtr aFeature = theOperation->feature(); - if(aFeature) - aCommand = aMenu->feature(QString::fromStdString(aFeature->getKind())); - } - //Abort operation on uncheck the command - if (aCommand) { - connect(aCommand, SIGNAL(triggered(bool)), theOperation, SLOT(setRunning(bool))); - } + myErrorMgr->setPropertyPanel(myPropertyPanel); } /* @@ -775,7 +551,7 @@ void XGUI_Workshop::saveDocument(const QString& theName, std::list& QApplication::restoreOverrideCursor(); } -bool XGUI_Workshop::isActiveOperationAborted() +bool XGUI_Workshop::abortAllOperations() { return myOperationMgr->abortAllOperations(); } @@ -823,7 +599,7 @@ void XGUI_Workshop::onNew() //****************************************************** void XGUI_Workshop::onOpen() { - if(!isActiveOperationAborted()) + if(!abortAllOperations()) return; //save current file before close if modified SessionPtr aSession = ModelAPI_Session::get(); @@ -838,12 +614,11 @@ void XGUI_Workshop::onOpen() } else if (anAnswer == QMessageBox::Cancel) { return; } - aSession->closeAll(); myCurrentDir = ""; } //show file dialog, check if readable and open - myCurrentDir = QFileDialog::getExistingDirectory(mainWindow()); + myCurrentDir = QFileDialog::getExistingDirectory(mainWindow(), tr("Select directory")); if (myCurrentDir.isEmpty()) return; QFileInfo aFileInfo(myCurrentDir); @@ -853,9 +628,10 @@ void XGUI_Workshop::onOpen() return; } QApplication::setOverrideCursor(Qt::WaitCursor); + aSession->closeAll(); aSession->load(myCurrentDir.toLatin1().constData()); myObjectBrowser->rebuildDataTree(); - displayAllResults(); + //displayAllResults(); updateCommandStatus(); QApplication::restoreOverrideCursor(); } @@ -863,7 +639,7 @@ void XGUI_Workshop::onOpen() //****************************************************** bool XGUI_Workshop::onSave() { - if(!isActiveOperationAborted()) + if(!abortAllOperations()) return false; if (myCurrentDir.isEmpty()) { return onSaveAs(); @@ -879,18 +655,19 @@ bool XGUI_Workshop::onSave() //****************************************************** bool XGUI_Workshop::onSaveAs() { - if(!isActiveOperationAborted()) + if(!abortAllOperations()) return false; QFileDialog dialog(mainWindow()); dialog.setWindowTitle(tr("Select directory to save files...")); dialog.setFileMode(QFileDialog::Directory); - dialog.setFilter(tr("Folders (*)")); + dialog.setFilter(tr("Directories (*)")); dialog.setOptions(QFileDialog::HideNameFilterDetails | QFileDialog::ShowDirsOnly); dialog.setViewMode(QFileDialog::Detail); if (!dialog.exec()) { return false; } + QString aTempDir = dialog.selectedFiles().first(); QDir aDir(aTempDir); if (aDir.exists() && !aDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) { @@ -898,7 +675,7 @@ bool XGUI_Workshop::onSaveAs() myMainWindow, //: Title of the dialog which asks user if he wants to save study in existing non-empty folder tr("Save"), - tr("The folder already contains some files, save anyway?"), + tr("The directory already contains some files, save anyway?"), QMessageBox::Save | QMessageBox::Cancel); if (answer == QMessageBox::Cancel) { return false; @@ -917,25 +694,46 @@ void XGUI_Workshop::onUndo(int theTimes) { objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->isOperation()) + if (aMgr->isOperation()) { + /// this is important for nested operrations + /// when sketch opeation is active, this condition is false and + /// the sketch operation is not aborted operationMgr()->onAbortOperation(); + } for (int i = 0; i < theTimes; ++i) { aMgr->undo(); } + + operationMgr()->updateApplyOfOperations(); updateCommandStatus(); } //****************************************************** void XGUI_Workshop::onRedo(int theTimes) { + // the viewer update should be blocked in order to avoid the features blinking. For the created + // feature a results are created, the flush of the created signal caused the viewer redisplay for + // each created result. After a redisplay signal is flushed. So, the viewer update is blocked until + // redo of all possible objects happens + bool isUpdateEnabled = myDisplayer->enableUpdateViewer(false); + objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->isOperation()) + if (aMgr->isOperation()) { + /// this is important for nested operrations + /// when sketch opeation is active, this condition is false and + /// the sketch operation is not aborted operationMgr()->onAbortOperation(); + } for (int i = 0; i < theTimes; ++i) { aMgr->redo(); } + operationMgr()->updateApplyOfOperations(); updateCommandStatus(); + + // unblock the viewer update functionality and make update on purpose + myDisplayer->enableUpdateViewer(isUpdateEnabled); + myDisplayer->updateViewer(); } //****************************************************** @@ -952,6 +750,7 @@ void XGUI_Workshop::onRebuild() if (!aWasOperation) { aMgr->finishOperation(); } + updateCommandStatus(); } //****************************************************** @@ -972,6 +771,7 @@ void XGUI_Workshop::onPreferences() myMainWindow->menuObject()->updateFromResources(); } } + displayer()->redisplayObjects(); } } @@ -1035,15 +835,21 @@ ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule) } //****************************************************** -bool XGUI_Workshop::activateModule() +bool XGUI_Workshop::createModule() { Config_ModuleReader aModuleReader; QString moduleName = QString::fromStdString(aModuleReader.getModuleName()); myModule = loadModule(moduleName); if (!myModule) return false; + + //connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)), + // myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr))); + //connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)), + // myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr))); + myModule->createFeatures(); - myActionsMgr->update(); + //myActionsMgr->update(); return true; } @@ -1060,22 +866,17 @@ void XGUI_Workshop::updateCommandStatus() } SessionPtr aMgr = ModelAPI_Session::get(); if (aMgr->hasModuleDocument()) { - QAction *aUndoCmd, *aRedoCmd; foreach(QAction* aCmd, aCommands) { QString aId = aCmd->data().toString(); if (aId == "UNDO_CMD") - aUndoCmd = aCmd; + aCmd->setEnabled(myModule->canUndo()); else if (aId == "REDO_CMD") - aRedoCmd = aCmd; + aCmd->setEnabled(myModule->canRedo()); else // Enable all commands aCmd->setEnabled(true); } - aUndoCmd->setEnabled(aMgr->canUndo() && !aMgr->isOperation()); - aRedoCmd->setEnabled(aMgr->canRedo() && !aMgr->isOperation()); - updateHistory(); - } else { foreach(QAction* aCmd, aCommands) { QString aId = aCmd->data().toString(); @@ -1094,28 +895,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 << new QAction(aIcon, anId, NULL); - } + 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 << new QAction(aIcon, anId, NULL); - } - emit updateRedoHistory(aUndoRes); + QList aRedoRes = processHistoryList(aRedoList); + emit updateRedoHistory(aRedoRes); } //****************************************************** @@ -1127,8 +912,10 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) aObjDock->setStyleSheet( "::title { position: relative; padding-left: 5px; text-align: left center }"); myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock); - connect(myObjectBrowser, SIGNAL(activePartChanged(ObjectPtr)), this, - SLOT(changeCurrentDocument(ObjectPtr))); +#ifdef ModuleDataModel + myObjectBrowser->setDataModel(myModule->dataModel()); +#endif + myModule->customizeObjectBrowser(myObjectBrowser); aObjDock->setWidget(myObjectBrowser); myContextMenuMgr->connectObjectBrowser(); @@ -1146,25 +933,23 @@ void XGUI_Workshop::createDockWidgets() QDockWidget* aObjDock = createObjectBrowser(aDesktop); aDesktop->addDockWidget(Qt::LeftDockWidgetArea, aObjDock); myPropertyPanel = new XGUI_PropertyPanel(aDesktop); + myPropertyPanel->setupActions(myActionsMgr); myPropertyPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - - connect(myPropertyPanel, SIGNAL(noMoreWidgets()), myModule, SLOT(onNoMoreWidgets())); - aDesktop->addDockWidget(Qt::LeftDockWidgetArea, myPropertyPanel); hidePropertyPanel(); ///tabifyDockWidget(aObjDock, myPropertyPanel); myPropertyPanel->installEventFilter(myOperationMgr); - QPushButton* aOkBtn = myPropertyPanel->findChild(PROP_PANEL_OK); - connect(aOkBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onCommitOperation())); - QPushButton* aCancelBtn = myPropertyPanel->findChild(PROP_PANEL_CANCEL); - connect(aCancelBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onAbortOperation())); - connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)), myOperationMgr, - SLOT(onKeyReleased(QKeyEvent*))); - connect(myOperationMgr, SIGNAL(applyEnableChanged(bool)), myPropertyPanel, - SLOT(setAcceptEnabled(bool))); - + QAction* aOkAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept); + connect(aOkAct, SIGNAL(triggered()), myOperationMgr, SLOT(onCommitOperation())); + QAction* aCancelAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Abort); + connect(aCancelAct, SIGNAL(triggered()), myOperationMgr, SLOT(onAbortOperation())); + connect(myPropertyPanel, SIGNAL(noMoreWidgets()), myModule, SLOT(onNoMoreWidgets())); + connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)), + myOperationMgr, SLOT(onKeyReleased(QKeyEvent*))); + connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), + aOkAct, SLOT(setEnabled(bool))); } //****************************************************** @@ -1198,34 +983,6 @@ void XGUI_Workshop::hideObjectBrowser() myObjectBrowser->parentWidget()->hide(); } -//****************************************************** -void XGUI_Workshop::onFeatureTriggered() -{ - QAction* aCmd = dynamic_cast(sender()); - if (aCmd) { - QString aId = salomeConnector()->commandId(aCmd); - if (!aId.isNull()) - myModule->launchOperation(aId); - } -} - -//****************************************************** -void XGUI_Workshop::changeCurrentDocument(ObjectPtr theObj) -{ - SessionPtr aMgr = ModelAPI_Session::get(); - if (theObj) { - ResultPartPtr aPart = std::dynamic_pointer_cast(theObj); - if (aPart) { - DocumentPtr aPartDoc = aPart->partDoc(); - if (aPartDoc) { - aMgr->setActiveDocument(aPartDoc); - return; - } - } - } - aMgr->setActiveDocument(aMgr->moduleDocument()); -} - //****************************************************** void XGUI_Workshop::salomeViewerSelectionChanged() { @@ -1242,13 +999,12 @@ ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) { QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); - if ((theId == "ACTIVATE_PART_CMD") && (aObjects.size() > 0)) { - ResultPartPtr aPart = std::dynamic_pointer_cast(aObjects.first()); - activatePart(aPart); - } else if (theId == "DEACTIVATE_PART_CMD") - activatePart(ResultPartPtr()); - else if (theId == "DELETE_CMD") - deleteObjects(aObjects); + if (theId == "DELETE_CMD") + deleteObjects(); + else if (theId == "MOVE_CMD") + moveObjects(); + else if (theId == "COLOR_CMD") + changeColor(aObjects); else if (theId == "SHOW_CMD") showObjects(aObjects, true); else if (theId == "HIDE_CMD") @@ -1259,150 +1015,453 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) setDisplayMode(aObjects, XGUI_Displayer::Shading); else if (theId == "WIREFRAME_CMD") setDisplayMode(aObjects, XGUI_Displayer::Wireframe); - else if (theId == "HIDEALL_CMD") - myDisplayer->eraseAll(); - else if (theId == "EDIT_CMD") { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObjects.first()); - if (aFeature) - myModule->editFeature(aFeature); + else if (theId == "HIDEALL_CMD") { + QObjectPtrList aList = myDisplayer->displayedObjects(); + foreach (ObjectPtr aObj, aList) { + if (module()->canEraseObject(aObj)) + aObj->setDisplayed(false); + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } } //************************************************************** -void XGUI_Workshop::onWidgetValuesChanged() +void XGUI_Workshop::deleteObjects() { - ModuleBase_Operation* anOperation = myOperationMgr->currentOperation(); - FeaturePtr aFeature = anOperation->feature(); + ModuleBase_IModule* aModule = module(); + // 1. allow the module to delete objects, do nothing if it has succeed + if (aModule->deleteObjects()) { + updateCommandStatus(); + return; + } - ModuleBase_ModelWidget* aSenderWidget = dynamic_cast(sender()); + if (!abortAllOperations()) + return; + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + // It is necessary to clear selection in order to avoid selection changed event during + // deleteion and negative consequences connected with processing of already deleted items + mySelector->clearSelection(); + // check whether the object can be deleted. There should not be parts which are not loaded + if (!XGUI_Tools::canRemoveOrRename(myMainWindow, anObjects)) + return; - const QList& aWidgets = myPropertyPanel->modelWidgets(); - QList::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end(); - for (; anIt != aLast; anIt++) { - ModuleBase_ModelWidget* aCustom = *anIt; - if (aCustom && (aCustom == aSenderWidget)) { - aCustom->storeValue(); - } + bool hasResult = false; + bool hasFeature = false; + bool hasParameter = false; + bool hasSubFeature = false; + ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasSubFeature); + if (!(hasFeature || hasParameter)) + return; + + // 1. start operation + QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text(); + aDescription += tr(" %1"); + QStringList aObjectNames; + foreach (ObjectPtr aObj, anObjects) { + if (!aObj->data()->isValid()) + continue; + aObjectNames << QString::fromStdString(aObj->data()->name()); + } + aDescription = aDescription.arg(aObjectNames.join(", ")); + ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module()); + + operationMgr()->startOperation(anOpAction); + // 3. delete objects + QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; + std::set anIgnoredFeatures; + if (deleteFeatures(anObjects, anIgnoredFeatures, aDesktop, true)) { + operationMgr()->commitOperation(); + } + else { + operationMgr()->abortOperation(operationMgr()->currentOperation()); } } //************************************************************** -void XGUI_Workshop::activatePart(ResultPartPtr theFeature) +void XGUI_Workshop::moveObjects() { - if (!myPartActivating) { - myPartActivating = true; - if (theFeature) - theFeature->activate(); - changeCurrentDocument(theFeature); - myObjectBrowser->activatePart(theFeature); - myPartActivating = false; + if (!abortAllOperations()) + return; + + SessionPtr aMgr = ModelAPI_Session::get(); + + QString anActionId = "MOVE_CMD"; + QString aDescription = contextMenuMgr()->action(anActionId)->text(); + aMgr->startOperation(aDescription.toStdString()); + + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + DocumentPtr anActiveDocument = aMgr->activeDocument(); + + FeaturePtr aCurrentFeature = anActiveDocument->currentFeature(true); + foreach (ObjectPtr aObject, anObjects) { + if (!myModule->canApplyAction(aObject, anActionId)) + continue; + + FeaturePtr aFeature = std::dynamic_pointer_cast(aObject); + if (aFeature.get()) { + anActiveDocument->moveFeature(aFeature, aCurrentFeature); + aCurrentFeature = anActiveDocument->currentFeature(true); + } } - updateCommandStatus(); + aMgr->finishOperation(); } //************************************************************** -//void XGUI_Workshop::activateLastPart() -//{ -// SessionPtr aMgr = ModelAPI_Session::get(); -// DocumentPtr aDoc = aMgr->moduleDocument(); -// std::string aGrpName = ModelAPI_ResultPart::group(); -// ObjectPtr aLastPart = aDoc->object(aGrpName, aDoc->size(aGrpName) - 1); -// ResultPartPtr aPart = std::dynamic_pointer_cast(aLastPart); -// if (aPart) { -// activatePart(aPart); -// } -//} - -//************************************************************** -void XGUI_Workshop::deleteObjects(const QObjectPtrList& theList) +bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList, + const std::set& theIgnoredFeatures, + QWidget* theParent, + const bool theAskAboutDeleteReferences) { - QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; - - std::set aRefFeatures; - foreach (ObjectPtr aObj, theList) - { - ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - if (aPart) { - // TODO: check for what there is this condition. It is placed here historicaly because - // ther is this condition during remove features. - } else { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature.get() != NULL) { - aObj->document()->refsToFeature(aFeature, aRefFeatures, false); - } - } +#ifdef DEBUG_DELETE + QStringList aDInfo; + QObjectPtrList::const_iterator aDIt = theList.begin(), aDLast = theList.end(); + for (; aDIt != aDLast; ++aDIt) { + aDInfo.append(ModuleBase_Tools::objectInfo((*aDIt))); } + QString anInfoStr = aDInfo.join(", "); + qDebug(QString("deleteFeatures: %1, %2").arg(theList.size()).arg(anInfoStr).toStdString().c_str()); +#endif - if (!aRefFeatures.empty()) { - QStringList aRefNames; - std::set::const_iterator anIt = aRefFeatures.begin(), - aLast = aRefFeatures.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = (*anIt); - std::string aFName = aFeature->data()->name().c_str(); - std::string aName = (*anIt)->name().c_str(); - aRefNames.append((*anIt)->name().c_str()); - } - QString aNames = aRefNames.join(", "); + // 1. find all referenced features + std::set aDirectRefFeatures, aIndirectRefFeatures; + foreach (ObjectPtr aDeletedObj, theList) { + XGUI_Tools::refsToFeatureInAllDocuments(aDeletedObj, aDeletedObj, aDirectRefFeatures, aIndirectRefFeatures); + std::set aDifference; + std::set_difference(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end(), + aDirectRefFeatures.begin(), aDirectRefFeatures.end(), + std::inserter(aDifference, aDifference.begin())); + aIndirectRefFeatures = aDifference; + } + // 2. warn about the references remove, break the delete operation if the user chose it + if (theAskAboutDeleteReferences && !aDirectRefFeatures.empty()) { + QStringList aDirectRefNames; + foreach(const FeaturePtr& aFeature, aDirectRefFeatures) + aDirectRefNames.append(aFeature->name().c_str()); + QString aDirectNames = aDirectRefNames.join(", "); + + QStringList aIndirectRefNames; + foreach(const FeaturePtr& aFeature, aIndirectRefFeatures) + aIndirectRefNames.append(aFeature->name().c_str()); + QString aIndirectNames = aIndirectRefNames.join(", "); QMessageBox::StandardButton aRes = QMessageBox::warning( - aDesktop, tr("Delete features"), + theParent, tr("Delete features"), QString(tr("Selected features are used in the following features: %1.\ -These features will be deleted also. Would you like to continue?")).arg(aNames), + These features will be deleted.\n%2Would you like to continue?")).arg(aDirectNames) + .arg(aIndirectNames.isEmpty() ? QString() : QString("Also these features will be deleted: %1.\n").arg(aIndirectNames)), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); if (aRes != QMessageBox::Yes) - return; + return false; } - SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation("DeleteObjects"); - std::set::const_iterator anIt = aRefFeatures.begin(), - aLast = aRefFeatures.end(); + // 3. remove referenced features + std::set aFeaturesToDelete = aDirectRefFeatures; + aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end()); + std::set::const_iterator anIt = aFeaturesToDelete.begin(), + aLast = aFeaturesToDelete.end(); +#ifdef DEBUG_DELETE + QStringList anInfo; +#endif for (; anIt != aLast; anIt++) { - FeaturePtr aRefFeature = (*anIt); - DocumentPtr aDoc = aRefFeature->document(); - aDoc->removeFeature(aRefFeature); - } + FeaturePtr aFeature = (*anIt); + DocumentPtr aDoc = aFeature->document(); + if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) { + aDoc->removeFeature(aFeature); +#ifdef DEBUG_DELETE + anInfo.append(ModuleBase_Tools::objectInfo(aFeature).toStdString().c_str()); +#endif + } + } +#ifdef DEBUG_DELETE + qDebug(QString("remove references:%1").arg(anInfo.join("; ")).toStdString().c_str()); + anInfo.clear(); +#endif + QString anActionId = "DELETE_CMD"; + QString anId = QString::fromStdString(anActionId.toStdString().c_str()); + QStringList anObjectGroups = contextMenuMgr()->actionObjectGroups(anId); + // 4. remove the parameter features + foreach (ObjectPtr aObj, theList) { + // features and parameters can be removed here, + // the results are removed only by a corresponded feature remove + std::string aGroupName = aObj->groupName(); + if (!anObjectGroups.contains(aGroupName.c_str())) + continue; + + if (!myModule->canApplyAction(aObj, anActionId)) + continue; + + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature) { + /*// TODO: to learn the workshop to delegate the Part object deletion to the PartSet module + // part features are removed in the PartSet module. This condition should be moved there + if (aFeature->getKind() == "Part") + continue; + */ + DocumentPtr aDoc = aObj->document(); + if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) { +#ifdef DEBUG_DELETE + QString anInfoStr = ModuleBase_Tools::objectInfo(aFeature); + anInfo.append(anInfoStr); + qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str()); +#endif + aDoc->removeFeature(aFeature); + } + } + } +#ifdef DEBUG_DELETE + qDebug(QString("remove features:%1").arg(anInfo.join("; ")).toStdString().c_str()); +#endif + return true; +} - foreach (ObjectPtr aObj, theList) +bool hasResults(QObjectPtrList theObjects, const std::set& theTypes) +{ + bool isFoundResultType = false; + foreach(ObjectPtr anObj, theObjects) { - DocumentPtr aDoc = aObj->document(); - ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - if (aPart) { - if (aDoc == aMgr->activeDocument()) { - aDoc->close(); + ResultPtr aResult = std::dynamic_pointer_cast(anObj); + if (aResult.get() == NULL) + continue; + + isFoundResultType = theTypes.find(aResult->groupName()) != theTypes.end(); + if (isFoundResultType) + break; + } + return isFoundResultType; +} + +//************************************************************** +// Returns the list of features placed between theObject and the current feature +// in the same document. Excludes theObject, includes the current feature. +std::list toCurrentFeatures(const ObjectPtr& theObject) +{ + std::list aResult; + DocumentPtr aDocument = theObject->document(); + std::list anAllFeatures = aDocument->allFeatures(); + // find the object iterator + std::list::iterator aObjectIt = std::find(anAllFeatures.begin(), anAllFeatures.end(), theObject); + if (aObjectIt == anAllFeatures.end()) + return aResult; + // find the current feature iterator + std::list::iterator aCurrentIt = std::find(anAllFeatures.begin(), anAllFeatures.end(), aDocument->currentFeature(true)); + if (aCurrentIt == anAllFeatures.end()) + return aResult; + // check the right order + if (std::distance(aObjectIt, anAllFeatures.end()) <= std::distance(aCurrentIt, anAllFeatures.end())) + return aResult; + // exclude the object + std::advance(aObjectIt, 1); + // include the current feature + std::advance(aCurrentIt, 1); + return std::list(aObjectIt, aCurrentIt); +} + +bool XGUI_Workshop::canMoveFeature() +{ + QString anActionId = "MOVE_CMD"; + + QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + QObjectPtrList aValidatedObjects; + foreach (ObjectPtr aObject, aObjects) { + if (myModule->canApplyAction(aObject, anActionId)) + aValidatedObjects.append(aObject); + } + if (aValidatedObjects.size() != aObjects.size()) + aObjects = aValidatedObjects; + + bool aCanMove = !aObjects.empty(); + + QObjectPtrList::const_iterator anIt = aObjects.begin(), aLast = aObjects.end(); + for (; anIt != aLast && aCanMove; anIt++) { + ObjectPtr aObject = *anIt; + // 1. Get features placed between selected and current in the document + std::list aFeaturesBetween = toCurrentFeatures(aObject); + // if aFeaturesBetween is empty it means wrong order or aObject is the current feature + if (aFeaturesBetween.empty()) + aCanMove = false; + else { + std::set aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end()); + // 2. Get all reference features to the selected object in the document + std::set aRefFeatures; + XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures); + + if (aRefFeatures.empty()) + continue; + else { + // 3. Find any placed features in all reference features + std::set aIntersectionFeatures; + std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(), + aPlacedFeatures.begin(), aPlacedFeatures.end(), + std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin())); + // 4. Return false if any reference feature is placed before curent feature + if (!aIntersectionFeatures.empty()) + aCanMove = false; } - } else { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature) { - aDoc->removeFeature(aFeature); + } + } + return aCanMove; +} + +//************************************************************** +bool XGUI_Workshop::canBeShaded(const ObjectPtr& theObject) const +{ + bool aCanBeShaded = myDisplayer->canBeShaded(theObject); + if (!aCanBeShaded) { + ResultCompSolidPtr aCompsolidResult = + std::dynamic_pointer_cast(theObject); + if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + for(int i = 0; i < aCompsolidResult->numberOfSubs() && !aCanBeShaded; i++) + aCanBeShaded = myDisplayer->canBeShaded(aCompsolidResult->subResult(i)); + } + } + return aCanBeShaded; +} + +//************************************************************** +bool XGUI_Workshop::canChangeColor() const +{ + QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + + std::set aTypes; + aTypes.insert(ModelAPI_ResultGroup::group()); + aTypes.insert(ModelAPI_ResultConstruction::group()); + aTypes.insert(ModelAPI_ResultBody::group()); + aTypes.insert(ModelAPI_ResultPart::group()); + + return hasResults(aObjects, aTypes); +} + +void setColor(ResultPtr theResult, std::vector& theColor) +{ + if (!theResult.get()) + return; + + AttributeIntArrayPtr aColorAttr = theResult->data()->intArray(ModelAPI_Result::COLOR_ID()); + if (aColorAttr.get() != NULL) { + if (!aColorAttr->size()) { + aColorAttr->setSize(3); + } + aColorAttr->setValue(0, theColor[0]); + aColorAttr->setValue(1, theColor[1]); + aColorAttr->setValue(2, theColor[2]); + } +} + +//************************************************************** +void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) +{ + AttributeIntArrayPtr aColorAttr; + // 1. find the current color of the object. This is a color of AIS presentation + // The objects are iterated until a first valid color is found + std::vector aColor; + foreach(ObjectPtr anObject, theObjects) { + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) { + XGUI_CustomPrs::getResultColor(aResult, aColor); + } + else { + // TODO: remove the obtaining a color from the AIS object + // this does not happen never because: + // 1. The color can be changed only on results + // 2. The result can be not visualized in the viewer(e.g. Origin Construction) + AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); + if (anAISObj.get()) { + aColor.resize(3); + anAISObj->getColor(aColor[0], aColor[1], aColor[2]); } } + if (!aColor.empty()) + break; } + if (aColor.size() != 3) + return; - myDisplayer->updateViewer(); - aMgr->finishOperation(); + // 2. show the dialog to change the value + XGUI_ColorDialog* aDlg = new XGUI_ColorDialog(mainWindow()); + aDlg->setColor(aColor); + aDlg->move(QCursor::pos()); + bool isDone = aDlg->exec() == QDialog::Accepted; + if (!isDone) + return; + + bool isRandomColor = aDlg->isRandomColor(); + + // 3. abort the previous operation and start a new one + SessionPtr aMgr = ModelAPI_Session::get(); + bool aWasOperation = aMgr->isOperation(); // keep this value + if (!aWasOperation) { + QString aDescription = contextMenuMgr()->action("COLOR_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); + } + + // 4. set the value to all results + std::vector aColorResult = aDlg->getColor(); + foreach(ObjectPtr anObj, theObjects) { + ResultPtr aResult = std::dynamic_pointer_cast(anObj); + if (aResult.get() != NULL) { + ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(aResult); + if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) + setColor(aCompsolidResult->subResult(i), aColorResult); + } + setColor(aResult, aColorResult); + } + } + if (!aWasOperation) + aMgr->finishOperation(); + updateCommandStatus(); } //************************************************************** +#define SET_DISPLAY_GROUP(aGroupName, aDisplay) \ +for (int i = 0; i < aDoc->size(aGroupName); i++) { \ + aDoc->object(aGroupName, i)->setDisplayed(aDisplay); \ +} void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible) { - foreach (ObjectPtr aObj, theList) - { - if (isVisible) { - displayObject(aObj); + foreach (ObjectPtr aObj, theList) { + /* + ResultPartPtr aPartRes = std::dynamic_pointer_cast(aObj); + if (aPartRes) { + DocumentPtr aDoc = aPartRes->partDoc(); + SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), isVisible) + SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), isVisible) + SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), isVisible) } else { - myDisplayer->erase(aObj, false); - } + */ + aObj->setDisplayed(isVisible); + //} } - myDisplayer->updateViewer(); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } //************************************************************** void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) { - myDisplayer->showOnly(theList); + // Hide all displayed objects + QObjectPtrList aList = myDisplayer->displayedObjects(); + foreach (ObjectPtr aObj, aList) { + if (module()->canEraseObject(aObj)) + aObj->setDisplayed(false); + } + + // Show only objects from the list + foreach (ObjectPtr aObj, theList) { + /* + ResultPartPtr aPartRes = std::dynamic_pointer_cast(aObj); + if (aPartRes) { + DocumentPtr aDoc = aPartRes->partDoc(); + SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), true) + SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), true) + SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), true) + } else { + */ + aObj->setDisplayed(true); + //} + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } @@ -1414,7 +1473,7 @@ void XGUI_Workshop::registerValidators() const } //************************************************************** -void XGUI_Workshop::displayAllResults() +/*void XGUI_Workshop::displayAllResults() { SessionPtr aMgr = ModelAPI_Session::get(); DocumentPtr aRootDoc = aMgr->moduleDocument(); @@ -1425,7 +1484,7 @@ void XGUI_Workshop::displayAllResults() displayDocumentResults(aPart->partDoc()); } myDisplayer->updateViewer(); -} +}*/ //************************************************************** void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc) @@ -1439,8 +1498,10 @@ void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc) //************************************************************** void XGUI_Workshop::displayGroupResults(DocumentPtr theDoc, std::string theGroup) { - for (int i = 0; i < theDoc->size(theGroup); i++) - displayObject(theDoc->object(theGroup, i)); + for (int i = 0; i < theDoc->size(theGroup); i++) + theDoc->object(theGroup, i)->setDisplayed(true); + //displayObject(theDoc->object(theGroup, i)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } //************************************************************** @@ -1448,6 +1509,14 @@ void XGUI_Workshop::setDisplayMode(const QObjectPtrList& theList, int theMode) { foreach(ObjectPtr aObj, theList) { myDisplayer->setDisplayMode(aObj, (XGUI_Displayer::DisplayMode)theMode, false); + + ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(aObj); + if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { + myDisplayer->setDisplayMode(aCompsolidResult->subResult(i), + (XGUI_Displayer::DisplayMode)theMode, false); + } + } } if (theList.size() > 0) myDisplayer->updateViewer(); @@ -1465,20 +1534,49 @@ void XGUI_Workshop::closeDocument() myDisplayer->eraseAll(); objectBrowser()->clearContent(); + module()->closeDocument(); + SessionPtr aMgr = ModelAPI_Session::get(); aMgr->closeAll(); - objectBrowser()->clearContent(); } -//************************************************************** -void XGUI_Workshop::displayObject(ObjectPtr theObj) +void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot) { - ResultBodyPtr aBody = std::dynamic_pointer_cast(theObj); - if (aBody.get() != NULL) { - int aNb = myDisplayer->objectsCount(); - myDisplayer->display(theObj, false); - if (aNb == 0) - viewer()->fitAll(); - } else - myDisplayer->display(theObj, false); + XGUI_HistoryMenu* aMenu = NULL; + if (isSalomeMode()) { + QAction* anAction = qobject_cast(theObject); + if (!anAction) + return; + aMenu = new XGUI_HistoryMenu(anAction); + } else { + QToolButton* aButton = qobject_cast(theObject); + aMenu = new XGUI_HistoryMenu(aButton); + } + 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_OperationFeature::EditSuffix()); + if (isEditing) { + anId.chop(ModuleBase_OperationFeature::EditSuffix().size()); + } + ActionInfo anInfo; + QAction* aContextMenuAct = myContextMenuMgr->actionByName(anId); + if (aContextMenuAct) { + anInfo.initFrom(aContextMenuAct); + } else { + anInfo = myActionsMgr->actionInfoById(anId); + } + if (isEditing) { + anInfo.text = anInfo.text.prepend("Modify "); + } + aResult << anInfo; + } + return aResult; }