X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Workshop.cpp;h=cdf0c42a5cf06512e9937562b8755867ebcaa84d;hb=ac8b1dc043f53cbf4f9c2a368e0c214669c21176;hp=a417021195f3fe1cb73f514dc413c536ecef6d42;hpb=0fb55fb5092b38612b54c34339d17e945480d2db;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index a41702119..cdf0c42a5 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -20,6 +20,7 @@ #include "XGUI_ViewerProxy.h" #include "XGUI_PropertyPanel.h" #include "XGUI_ContextMenuMgr.h" +#include "XGUI_ModuleConnector.h" #include #include @@ -28,6 +29,8 @@ #include #include +#include + #include #include #include @@ -45,6 +48,7 @@ #include #include #include +#include #ifdef _DEBUG #include @@ -69,7 +73,7 @@ QString XGUI_Workshop::featureIcon(const std::string& theId) XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) : QObject(), - myCurrentFile(QString()), + myCurrentDir(QString()), myPartSetModule(NULL), mySalomeConnector(theConnector), myPropertyPanel(0), @@ -90,11 +94,15 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) this, SLOT(onContextMenuCommand(const QString&, bool))); myViewerProxy = new XGUI_ViewerProxy(this); - - connect(myOperationMgr, SIGNAL(operationStarted()), this, SLOT(onOperationStarted())); - connect(myOperationMgr, SIGNAL(operationResumed()), this, SLOT(onOperationStarted())); - connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), - this, SLOT(onOperationStopped(ModuleBase_Operation*))); + + myModuleConnector = new XGUI_ModuleConnector(this); + + connect(myOperationMgr, SIGNAL(operationStarted()), SLOT(onOperationStarted())); + connect(myOperationMgr, SIGNAL(operationResumed()), SLOT(onOperationStarted())); + connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), SLOT(onOperationStopped(ModuleBase_Operation*))); + connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit())); + connect(myOperationMgr, SIGNAL(operationStarted()), myActionsMgr, SLOT(update())); + connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), myActionsMgr, SLOT(update())); connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&))); } @@ -117,6 +125,8 @@ void XGUI_Workshop::startApplication() aLoop->registerListener(this, aPartSetId); Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED); aLoop->registerListener(this, aFeatureUpdatedId); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED)); + activateModule(); if (myMainWindow) { myMainWindow->show(); @@ -184,6 +194,12 @@ void XGUI_Workshop::initMenu() aCommand = aGroup->addFeature("EXIT_CMD", tr("Exit"), tr("Exit application"), QIcon(":pictures/close.png"), QKeySequence::Close); aCommand->connectTo(this, SLOT(onExit())); + //FIXME: SBH's test action. Can be used for some GUI tests. + //#ifdef _DEBUG + // aCommand = aGroup->addFeature("TEST_CMD", "Test!", "Private debug button", + // QIcon(":pictures/close.png")); + // aCommand->connectTo(myActionsMgr, SLOT(update())); + //#endif } //****************************************************** @@ -200,9 +216,32 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage) static Events_ID aFeatureLoadedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_LOADED); if (theMessage->eventID() == aFeatureLoadedId) { const Config_FeatureMessage* aFeatureMsg = dynamic_cast(theMessage); - addFeature(aFeatureMsg); + if(!aFeatureMsg->isInternal()) { + addFeature(aFeatureMsg); + } return; } + // Process creation of Part + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) { + const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast(theMessage); + std::set aFeatures = aUpdMsg->features(); + + std::set::const_iterator aIt; + bool aHasPart = false; + for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) { + FeaturePtr aFeature = (*aIt); + if (aFeature->getKind() == PARTSET_PART_KIND) { + aHasPart = true; + break; + } + } + if (aHasPart) { + //The created part will be created in Object Browser later and we have to activate it + // only when it is created everywere + QTimer::singleShot(50, this, SLOT(activateLastPart())); + } + } + //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. static Events_ID aFeatureUpdatedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED); @@ -210,15 +249,23 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage) { const Model_FeatureUpdatedMessage* anUpdateMsg = dynamic_cast(theMessage); - FeaturePtr aNewFeature = anUpdateMsg->feature(); + std::set aFeatures = anUpdateMsg->features(); + FeaturePtr aCurrentFeature = myOperationMgr->currentOperation()->feature(); - if(aNewFeature == aCurrentFeature) { - myPropertyPanel->updateContentWidget(aCurrentFeature); + std::set::const_iterator aIt; + for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) { + FeaturePtr aNewFeature = (*aIt); + if(aNewFeature == aCurrentFeature) { + myPropertyPanel->updateContentWidget(aCurrentFeature); + break; + } } } //An operation passed by message. Start it, process and commit. const Config_PointerMessage* aPartSetMsg = dynamic_cast(theMessage); if (aPartSetMsg) { + // Clear previous content + myPropertyPanel->cleanContent(); ModuleBase_Operation* anOperation = (ModuleBase_Operation*)(aPartSetMsg->pointer()); @@ -235,9 +282,6 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage) const Events_Error* anAppError = dynamic_cast(theMessage); if (anAppError) { emit errorOccurred(QString::fromLatin1(anAppError->description())); - myErrorDlg->show(); - myErrorDlg->raise(); - myErrorDlg->activateWindow(); } } @@ -252,30 +296,22 @@ void XGUI_Workshop::onOperationStarted() showPropertyPanel(); - ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aOperation); + ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aOperation, myModuleConnector); QWidget* aContent = myPropertyPanel->contentWidget(); qDeleteAll(aContent->children()); aFactory.createWidget(aContent); myPropertyPanel->setModelWidgets(aFactory.getModelWidgets()); myPropertyPanel->setWindowTitle(aOperation->getDescription()->description()); } + updateCommandStatus(); } //****************************************************** void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) { - ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - //!< No need for property panel updateCommandStatus(); hidePropertyPanel(); - if(myOperationMgr->operationsCount() > 1) { - myActionsMgr->updateAction(theOperation->getDescription()->operationId()); - return; - } - if(!aOperation->getDescription()->xmlRepresentation().isEmpty()) { - myActionsMgr->restoreCommandState(); - } } /* @@ -296,16 +332,16 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) QString aWchName = QString::fromStdString(theMessage->workbenchId()); QString aNestedFeatures = QString::fromStdString(theMessage->nestedFeatures()); bool isUsePropPanel = theMessage->isUseInput(); + QString aId = QString::fromStdString(theMessage->id()); if (isSalomeMode()) { - QString aId = QString::fromStdString(theMessage->id()); QAction* aAction = salomeConnector()->addFeature(aWchName, aId, QString::fromStdString(theMessage->text()), QString::fromStdString(theMessage->tooltip()), QIcon(theMessage->icon().c_str()), QKeySequence(), isUsePropPanel); - myActionsMgr->addCommand(aAction); salomeConnector()->setNestedActions(aId, aNestedFeatures.split(" ")); + myActionsMgr->addCommand(aAction); myPartSetModule->featureCreated(aAction); } else { @@ -321,12 +357,12 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) aGroup = aPage->addGroup(aGroupName); } //Create feature... - XGUI_Command* aCommand = aGroup->addFeature(QString::fromStdString(theMessage->id()), + XGUI_Command* aCommand = aGroup->addFeature(aId, QString::fromStdString(theMessage->text()), QString::fromStdString(theMessage->tooltip()), QIcon(theMessage->icon().c_str()), QKeySequence(), isUsePropPanel); - aCommand->setUnblockableCommands(aNestedFeatures.split(" ")); + aCommand->setNestedCommands(aNestedFeatures.split(" ", QString::SkipEmptyParts)); myActionsMgr->addCommand(aCommand); myPartSetModule->featureCreated(aCommand); } @@ -373,7 +409,10 @@ void XGUI_Workshop::onExit() tr("The document is modified, save before exit?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel); if(anAnswer == QMessageBox::Save) { - onSave(); + bool saved = onSave(); + if(!saved) { + return; + } } else if (anAnswer == QMessageBox::Cancel) { return; } @@ -418,51 +457,63 @@ void XGUI_Workshop::onOpen() return; } aDoc->close(); - myCurrentFile = ""; + myCurrentDir = ""; } //show file dialog, check if readable and open - myCurrentFile = QFileDialog::getExistingDirectory(mainWindow()); - if(myCurrentFile.isEmpty()) + myCurrentDir = QFileDialog::getExistingDirectory(mainWindow()); + if(myCurrentDir.isEmpty()) return; - QFileInfo aFileInfo(myCurrentFile); + QFileInfo aFileInfo(myCurrentDir); if(!aFileInfo.exists() || !aFileInfo.isReadable()) { QMessageBox::critical(myMainWindow, tr("Warning"), tr("Unable to open the file.")); - myCurrentFile = ""; + myCurrentDir = ""; return; } QApplication::setOverrideCursor(Qt::WaitCursor); - aDoc->load(myCurrentFile.toLatin1().constData()); + aDoc->load(myCurrentDir.toLatin1().constData()); QApplication::restoreOverrideCursor(); updateCommandStatus(); } //****************************************************** -void XGUI_Workshop::onSave() +bool XGUI_Workshop::onSave() { - if(myCurrentFile.isEmpty()) { - onSaveAs(); - return; + if(myCurrentDir.isEmpty()) { + return onSaveAs(); } - saveDocument(myCurrentFile); + saveDocument(myCurrentDir); updateCommandStatus(); + return true; } //****************************************************** -void XGUI_Workshop::onSaveAs() +bool XGUI_Workshop::onSaveAs() { - QString aTemp = myCurrentFile; - myCurrentFile = QFileDialog::getSaveFileName(mainWindow()); - if(myCurrentFile.isEmpty()) { - myCurrentFile = aTemp; - return; + QFileDialog dialog(mainWindow()); + dialog.setWindowTitle(tr("Select directory to save files...")); + dialog.setFileMode(QFileDialog::Directory); + dialog.setFilter(tr("Folders (*)")); + dialog.setOptions(QFileDialog::HideNameFilterDetails | QFileDialog::ShowDirsOnly); + dialog.setViewMode(QFileDialog::Detail); + + if(!dialog.exec()) { + return false; } - QFileInfo aFileInfo(myCurrentFile); - if(aFileInfo.exists() && !aFileInfo.isWritable()) { - QMessageBox::critical(myMainWindow, tr("Warning"), tr("Unable to save the file.")); - return; + QString aTempDir = dialog.selectedFiles().first(); + QDir aDir(aTempDir); + if(aDir.exists() && !aDir.entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).isEmpty()) { + int answer = QMessageBox::question(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?"), + QMessageBox::Save|QMessageBox::Cancel); + if(answer == QMessageBox::Cancel) { + return false; + } } - onSave(); + myCurrentDir = aTempDir; + return onSave(); } //****************************************************** @@ -483,6 +534,8 @@ void XGUI_Workshop::onRedo() objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); DocumentPtr aDoc = aMgr->rootDocument(); + if (aDoc->isOperation()) + operationMgr()->abortOperation(); aDoc->redo(); updateCommandStatus(); } @@ -557,6 +610,7 @@ bool XGUI_Workshop::activateModule() if (!myPartSetModule) return false; myPartSetModule->createFeatures(); + myActionsMgr->update(); return true; } @@ -598,6 +652,7 @@ void XGUI_Workshop::updateCommandStatus() aCmd->setEnabled(false); } } + myActionsMgr->update(); } //****************************************************** @@ -606,6 +661,7 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) QDockWidget* aObjDock = new QDockWidget(theParent); aObjDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); aObjDock->setWindowTitle(tr("Object browser")); + aObjDock->setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }"); myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock); connect(myObjectBrowser, SIGNAL(activePartChanged(FeaturePtr)), this, SLOT(changeCurrentDocument(FeaturePtr))); aObjDock->setWidget(myObjectBrowser); @@ -635,6 +691,9 @@ void XGUI_Workshop::createDockWidgets() connect(aOkBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onCommitOperation())); QPushButton* aCancelBtn = myPropertyPanel->findChild(XGUI::PROP_PANEL_CANCEL); connect(aCancelBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onAbortOperation())); + + connect(myPropertyPanel, SIGNAL(keyReleased(const std::string&, QKeyEvent*)), + myOperationMgr, SLOT(onKeyReleased(const std::string&, QKeyEvent*))); } //****************************************************** @@ -684,9 +743,15 @@ void XGUI_Workshop::changeCurrentDocument(FeaturePtr thePart) { PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); if (thePart) { - boost::shared_ptr aDocRef = thePart->data()->docRef("PartDocument"); - if (aDocRef) - aMgr->setCurrentDocument(aDocRef->value()); + DocumentPtr aFeaDoc; + if (!XGUI_Tools::isModelObject(thePart)) { + aFeaDoc = thePart->data()->docRef("PartDocument")->value(); + } else { + ObjectPtr aObject = boost::dynamic_pointer_cast(thePart); + aFeaDoc = aObject->featureRef()->data()->docRef("PartDocument")->value(); + } + if (aFeaDoc) + aMgr->setCurrentDocument(aFeaDoc); } else { aMgr->setCurrentDocument(aMgr->rootDocument()); } @@ -708,25 +773,73 @@ XGUI_SalomeViewer* XGUI_Workshop::salomeViewer() const //************************************************************** void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) { - if (theId == "ACTIVATE_PART_CMD") - activatePart(true); + QFeatureList aFeatures = mySelector->selectedFeatures(); + if ((theId == "ACTIVATE_PART_CMD") && (aFeatures.size() > 0)) + activatePart(aFeatures.first()); else if (theId == "DEACTIVATE_PART_CMD") - activatePart(false); + activatePart(FeaturePtr()); + else if (theId == "DELETE_CMD") + deleteFeatures(aFeatures); + else if (theId == "SHOW_CMD") + showFeatures(aFeatures, true); + else if (theId == "HIDE_CMD") + showFeatures(aFeatures, false); +} +//************************************************************** +void XGUI_Workshop::activatePart(FeaturePtr theFeature) +{ + changeCurrentDocument(theFeature); + myObjectBrowser->activatePart(theFeature); } //************************************************************** -void XGUI_Workshop::activatePart(bool toActivate) +void XGUI_Workshop::activateLastPart() { - if (toActivate) { - QFeatureList aFeatures = mySelector->selectedFeatures(); - if (aFeatures.size() > 0) { - changeCurrentDocument(aFeatures.first()); - myObjectBrowser->activateCurrentPart(true); + PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); + DocumentPtr aDoc = aMgr->rootDocument(); + FeaturePtr aLastPart = aDoc->feature(PARTS_GROUP, aDoc->size(PARTS_GROUP) - 1, true); + activatePart(aLastPart); +} + +//************************************************************** +void XGUI_Workshop::deleteFeatures(QFeatureList theList) +{ + QMainWindow* aDesktop = isSalomeMode()? salomeConnector()->desktop() : myMainWindow; + QMessageBox::StandardButton aRes = QMessageBox::warning(aDesktop, tr("Delete features"), + tr("Seleted features will be deleted. Continue?"), + QMessageBox::No | QMessageBox::Yes, QMessageBox::No); + if (aRes == QMessageBox::Yes) { + PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); + aMgr->rootDocument()->startOperation(); + foreach (FeaturePtr aFeature, theList) { + if (aFeature->getKind() == PARTSET_PART_KIND) { + DocumentPtr aDoc; + if (!XGUI_Tools::isModelObject(aFeature)) { + aDoc = aFeature->data()->docRef("PartDocument")->value(); + } else { + ObjectPtr aObject = boost::dynamic_pointer_cast(aFeature); + aDoc = aObject->featureRef()->data()->docRef("PartDocument")->value(); + aFeature = aObject->featureRef(); + } + if (aDoc == aMgr->currentDocument()) { + aDoc->close(); + } + } else { + if (XGUI_Tools::isModelObject(aFeature)) { + ObjectPtr aObject = boost::dynamic_pointer_cast(aFeature); + aFeature = aObject->featureRef(); + } + } + aFeature->document()->removeFeature(aFeature); } - } else { - changeCurrentDocument(FeaturePtr()); - myObjectBrowser->activateCurrentPart(false); + aMgr->rootDocument()->finishOperation(); } } +//************************************************************** +void XGUI_Workshop::showFeatures(QFeatureList theList, bool isVisible) +{ +// foreach (FeaturePtr aFeature, theList) { +// } +}