#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_ResultParameter.h>
//#include <PartSetPlugin_Part.h>
#include <ModuleBase_WidgetFactory.h>
#include <ModuleBase_Tools.h>
#include <ModuleBase_IViewer.h>
-#include<ModuleBase_FilterFactory.h>
+#include <ModuleBase_FilterFactory.h>
#include <ModuleBase_PageBase.h>
+#include <ModuleBase_Tools.h>
#include <Config_Common.h>
#include <Config_FeatureMessage.h>
//#define DEBUG_FEATURE_CREATED
//#define DEBUG_FEATURE_REDISPLAY
-QString objectInfo(ObjectPtr theObj)
-{
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(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<QString, QString> XGUI_Workshop::myIcons;
myObjectBrowser(0),
myDisplayer(0),
myUpdatePrefs(false),
- myPartActivating(false)
+ myPartActivating(false),
+ myIsLoadingData(false)
{
myMainWindow = mySalomeConnector ? 0 : new AppElements_MainWindow();
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
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<Events_Error> anAppError = std::dynamic_pointer_cast<Events_Error>(theMessage);
#ifdef DEBUG_FEATURE_REDISPLAY
QStringList anInfo;
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
- anInfo.append(objectInfo((*aIt)));
+ anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
}
QString anInfoStr = anInfo.join(", ");
qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
// Redisplay the visible object or the object of the current operation
bool isVisibleObject = myDisplayer->isVisible(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() &&
ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
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))
#ifdef DEBUG_FEATURE_CREATED
QStringList anInfo;
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
- anInfo.append(objectInfo((*aIt)));
+ anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
}
QString anInfoStr = anInfo.join(", ");
qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
//bool aHasPart = false;
bool isDisplayed = false;
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
-
+ ObjectPtr anObject = *aIt;
+ // the validity of the data should be checked here in order to avoid display of the objects,
+ // which were created, then deleted, but flush for the creation event happens after that
+ if (!anObject->data() || !anObject->data()->isValid())
+ continue;
//ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aIt);
//if (aPart) {
//aHasPart = true;
// 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);
+ }
}
QStringList aNestedFeatures =
QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
QString aDocKind = QString::fromStdString(theMessage->documentKind());
+ QList<QAction*> 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);
// Enrich created button with accept/abort buttons if necessary
AppElements_Button* aButton = aCommand->button();
if (aButton->isColumnButton()) {
- QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
- QList<QAction*> 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);
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
+ myIsLoadingData = true;
aSession->load(myCurrentDir.toLatin1().constData());
myObjectBrowser->rebuildDataTree();
displayAllResults();
updateCommandStatus();
+ myIsLoadingData = false;
QApplication::restoreOverrideCursor();
}
//******************************************************
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())
aMgr->redo();
}
updateCommandStatus();
+
+ // unblock the viewer update functionality and make update on purpose
+ myDisplayer->enableUpdateViewer(isUpdateEnabled);
+ myDisplayer->updateViewer();
}
//******************************************************
} 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")
myDisplayer->eraseAll();
else if (theId == "EDIT_CMD") {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObjects.first());
- if (aFeature)
+ if (aFeature == NULL) {
+ ResultParameterPtr aParam =
+ std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aObjects.first());
+ if (aParam.get() != NULL) {
+ aFeature = ModelAPI_Feature::feature(aParam);
+ }
+ }
+ if (aFeature.get() != NULL)
myModule->editFeature(aFeature);
}
}
//}
//**************************************************************
-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<FeaturePtr> 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<ModelAPI_ResultPart>(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<ModelAPI_Feature>(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<FeaturePtr> 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<FeaturePtr> theIgnoredFeatures,
+ QWidget* theParent,
+ const bool theAskAboutDeleteReferences)
+{
+ // 1. find all referenced features
+ std::set<FeaturePtr> 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<FeaturePtr>::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<FeaturePtr>::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<ModelAPI_ResultPart>(aObj);
- if (aPart) {
- if (aDoc == aMgr->activeDocument()) {
- aDoc->close();
- }
- } else {
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(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<std::string>& theTypes)
myDisplayer->display(theObj, false);
if (aNb == 0)
viewer()->fitAll();
- } else
+ } else if (!(myIsLoadingData || myPartActivating))
myDisplayer->display(theObj, false);
return true;
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 ");
}