X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Workshop.cpp;h=2ce90358a4d39955c2befe66419f860d8324ebdc;hb=4e9ce2a95c42fc2c33c8d7de75c26f2208bf73b7;hp=3d7e3142e63577773d374a016e19acbaab6ab7e2;hpb=7b40e745dd80b0af027783d1d064ba84f44e97bb;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 3d7e3142e..2ce90358a 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -40,6 +40,7 @@ #include #include #include +#include //#include @@ -54,8 +55,9 @@ #include #include #include -#include +#include #include +#include #include #include @@ -95,22 +97,6 @@ //#define DEBUG_FEATURE_CREATED //#define DEBUG_FEATURE_REDISPLAY -QString objectInfo(ObjectPtr theObj) -{ - ResultPtr aRes = std::dynamic_pointer_cast(theObj); - FeaturePtr aFeature = std::dynamic_pointer_cast(theObj); - QString aFeatureStr = "feature"; - if(aRes.get()) { - aFeatureStr.append("(Result)"); - aFeature = ModelAPI_Feature::feature(aRes); - } - if (aFeature.get()) { - aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str()); - } - return aFeatureStr; -} - - QMap XGUI_Workshop::myIcons; @@ -159,7 +145,8 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) myObjectBrowser(0), myDisplayer(0), myUpdatePrefs(false), - myPartActivating(false) + myPartActivating(false), + myIsLoadingData(false) { myMainWindow = mySalomeConnector ? 0 : new AppElements_MainWindow(); @@ -225,6 +212,9 @@ void XGUI_Workshop::startApplication() aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SELFILTER_LOADED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)); + registerValidators(); // Calling of loadCustomProps before activating module is required @@ -472,6 +462,12 @@ void XGUI_Workshop::processEvent(const std::shared_ptr& theMessa aMsg->parameters()); } } + } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)) { + // the viewer's update context will not happens until viewer updated is emitted + myDisplayer->enableUpdateViewer(false); + } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)) { + // the viewer's update context is unblocked, the viewer's update works + myDisplayer->enableUpdateViewer(true); } else { //Show error dialog if error message received. std::shared_ptr anAppError = std::dynamic_pointer_cast(theMessage); @@ -530,7 +526,7 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptrisVisible(aObj); #ifdef DEBUG_FEATURE_REDISPLAY - QString anObjInfo = objectInfo((aObj)); - qDebug(QString("visible=%1 : display= %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str()); + //QString anObjInfo = ModuleBase_Tools::objectInfo((aObj)); + //qDebug(QString("visible=%1 : display= %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str()); #endif if (isVisibleObject) { // redisplay visible object - displayObject(aObj); // In order to update presentation + //displayObject(aObj); // In order to update presentation + // in order to avoid the check whether the object can be redisplayed, the exact method + // of redisplay is called. This modification is made in order to have the line is updated + // by creation of a horizontal constraint on the line by preselection + myDisplayer->redisplay(aObj, false); if (myOperationMgr->hasOperation()) { ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); if (!aOperation->isEditOperation() && @@ -567,6 +567,10 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptrcurrentOperation(); if (aOperation && aOperation->hasObject(aObj)) { ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); + #ifdef DEBUG_FEATURE_REDISPLAY + QString anObjInfo = ModuleBase_Tools::objectInfo((aObj)); + qDebug(QString(" display object = %1").arg(anObjInfo).toStdString().c_str()); + #endif if (displayObject(aObj)) { // Deactivate object of current operation from selection if (myDisplayer->isActive(aObj)) @@ -587,7 +591,7 @@ void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptrdata() || !anObject->data()->isValid()) + continue; //ResultPartPtr aPart = std::dynamic_pointer_cast(*aIt); //if (aPart) { //aHasPart = true; @@ -664,9 +672,17 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) // Activate objects created by current operation // in order to clean selection modes - QIntList aModes; - myDisplayer->activateObjects(aModes); + // the deactivation should be pefromed in the same place, where the mode is activated, + // e.g. activation in the current widget activation, deactivation - in the widget's deactivation + //QIntList aModes; + //myDisplayer->activateObjects(aModes); myModule->operationStopped(theOperation); + + if (myOperationMgr->operationsCount() == 0) { + // Activate selection mode for all objects + QIntList aModes; + myDisplayer->activateObjects(aModes); + } } @@ -746,8 +762,29 @@ void XGUI_Workshop::addFeature(const std::shared_ptr& the QStringList aNestedFeatures = QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts); QString aDocKind = QString::fromStdString(theMessage->documentKind()); + QList aNestedActList; + bool isColumnButton = !aNestedFeatures.isEmpty(); + if (isColumnButton) { + QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested()); + if (aNestedActions.contains("accept")) { + QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL); + connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(commitAllOperations())); + aNestedActList << anAction; + } + if (aNestedActions.contains("abort")) { + QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll, NULL); + connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(abortAllOperations())); + aNestedActList << anAction; + } + } + if (isSalomeMode()) { - QAction* aAction = salomeConnector()->addFeature(aWchName, aFeatureInfo); + QAction* aAction; + if (isColumnButton) { + aAction = salomeConnector()->addNestedFeature(aWchName, aFeatureInfo, aNestedActList); + } else { + aAction = salomeConnector()->addFeature(aWchName, aFeatureInfo); + } salomeConnector()->setNestedActions(aFeatureInfo.id, aNestedFeatures); salomeConnector()->setDocumentKind(aFeatureInfo.id, aDocKind); @@ -778,19 +815,7 @@ void XGUI_Workshop::addFeature(const std::shared_ptr& the // Enrich created button with accept/abort buttons if necessary AppElements_Button* aButton = aCommand->button(); if (aButton->isColumnButton()) { - QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested()); - QList anActList; - if (aNestedActions.contains("accept")) { - QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, aButton); - connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(commitAllOperations())); - anActList << anAction; - } - if (aNestedActions.contains("abort")) { - QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll, aButton); - connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(abortAllOperations())); - anActList << anAction; - } - aButton->setAdditionalButtons(anActList); + aButton->setAdditionalButtons(aNestedActList); } myActionsMgr->addCommand(aCommand); myModule->actionCreated(aCommand); @@ -908,10 +933,12 @@ void XGUI_Workshop::onOpen() return; } QApplication::setOverrideCursor(Qt::WaitCursor); + myIsLoadingData = true; aSession->load(myCurrentDir.toLatin1().constData()); myObjectBrowser->rebuildDataTree(); displayAllResults(); updateCommandStatus(); + myIsLoadingData = false; QApplication::restoreOverrideCursor(); } @@ -983,6 +1010,12 @@ void XGUI_Workshop::onUndo(int theTimes) //****************************************************** 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()) @@ -991,6 +1024,10 @@ void XGUI_Workshop::onRedo(int theTimes) aMgr->redo(); } updateCommandStatus(); + + // unblock the viewer update functionality and make update on purpose + myDisplayer->enableUpdateViewer(isUpdateEnabled); + myDisplayer->updateViewer(); } //****************************************************** @@ -1294,7 +1331,7 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) } else if (theId == "DEACTIVATE_PART_CMD") activatePart(ResultPartPtr()); else if (theId == "DELETE_CMD") - deleteObjects(aObjects); + deleteObjects(); else if (theId == "COLOR_CMD") changeColor(aObjects); else if (theId == "SHOW_CMD") @@ -1311,7 +1348,14 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) myDisplayer->eraseAll(); else if (theId == "EDIT_CMD") { FeaturePtr aFeature = std::dynamic_pointer_cast(aObjects.first()); - if (aFeature) + if (aFeature == NULL) { + ResultParameterPtr aParam = + std::dynamic_pointer_cast(aObjects.first()); + if (aParam.get() != NULL) { + aFeature = ModelAPI_Feature::feature(aParam); + } + } + if (aFeature.get() != NULL) myModule->editFeature(aFeature); } } @@ -1344,90 +1388,115 @@ void XGUI_Workshop::activatePart(ResultPartPtr theFeature) //} //************************************************************** -void XGUI_Workshop::deleteObjects(const QObjectPtrList& theList) +void XGUI_Workshop::deleteObjects() { ModuleBase_IModule* aModule = module(); - if (aModule->deleteObjects()) + // 1. allow the module to delete objects, do nothing if it has succeed + if (aModule->deleteObjects()) { + updateCommandStatus(); return; + } if (!isActiveOperationAborted()) return; + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + bool hasResult = false; + bool hasFeature = false; + bool hasParameter = false; + XGUI_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter); + if (!(hasFeature || hasParameter)) + return; - QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; - std::set aRefFeatures; - foreach (ObjectPtr aObj, theList) + // 1. start operation + QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text(); + aDescription += tr(" %1"); + QStringList aObjectNames; + foreach (ObjectPtr aObj, anObjects) { + if (!aObj->data().get()) + continue; + aObjectNames << QString::fromStdString(aObj->data()->name()); + } + aDescription = aDescription.arg(aObjectNames.join(", ")); + + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation(aDescription.toStdString()); + // 2. close the documents of the removed parts if the result part is in a list of selected objects + foreach (ObjectPtr aObj, anObjects) { 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); + DocumentPtr aDoc = aObj->document(); + if (aDoc == aMgr->activeDocument()) { + aDoc->close(); } } } + // 3. delete objects + QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; + std::set anIgnoredFeatures; + if (deleteFeatures(anObjects, anIgnoredFeatures, aDesktop, true)) { + myDisplayer->updateViewer(); + aMgr->finishOperation(); + updateCommandStatus(); + } + else { + aMgr->abortOperation(); + } +} - if (!aRefFeatures.empty()) { +//************************************************************** +bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList, + std::set theIgnoredFeatures, + QWidget* theParent, + const bool theAskAboutDeleteReferences) +{ + // 1. find all referenced features + std::set aRefFeatures; + foreach (ObjectPtr aObj, theList) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature.get() != NULL) { + aObj->document()->refsToFeature(aFeature, aRefFeatures, false); + } + } + // 2. warn about the references remove, break the delete operation if the user chose it + if (theAskAboutDeleteReferences && !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(", "); 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), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); if (aRes != QMessageBox::Yes) - return; + return false; } - 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(", ")); - SessionPtr aMgr = ModelAPI_Session::get(); - aMgr->startOperation(aDescription.toStdString()); + // 3. remove referenced features std::set::const_iterator anIt = aRefFeatures.begin(), aLast = aRefFeatures.end(); 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); + } - foreach (ObjectPtr aObj, theList) - { - DocumentPtr aDoc = aObj->document(); - ResultPartPtr aPart = std::dynamic_pointer_cast(aObj); - if (aPart) { - if (aDoc == aMgr->activeDocument()) { - aDoc->close(); - } - } else { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature) { + // 4. remove the parameter features + foreach (ObjectPtr aObj, theList) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature) { + DocumentPtr aDoc = aObj->document(); + if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) aDoc->removeFeature(aFeature); - } } } - - myDisplayer->updateViewer(); - aMgr->finishOperation(); - updateCommandStatus(); + return true; } bool hasResults(QObjectPtrList theObjects, const std::set& theTypes) @@ -1628,7 +1697,7 @@ bool XGUI_Workshop::displayObject(ObjectPtr theObj) myDisplayer->display(theObj, false); if (aNb == 0) viewer()->fitAll(); - } else + } else if (!(myIsLoadingData || myPartActivating)) myDisplayer->display(theObj, false); return true; @@ -1660,7 +1729,13 @@ QList XGUI_Workshop::processHistoryList(const std::list if (isEditing) { anId.chop(ModuleBase_Operation::EditSuffix().size()); } - ActionInfo anInfo = myActionsMgr->actionInfoById(anId); + 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 "); }