X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Workshop.cpp;h=1d72cff78d8cb26ae25ff9cebddb7fbbb925eb40;hb=4c7569f230373cbe5db483d5885b0a7932bb8dc6;hp=24fea8453e98aab44e834f9efca2895d1c39142e;hpb=a8d0fddcc65db1fe234df36354b6735918075a70;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 24fea8453..1d72cff78 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1,4 +1,4 @@ -#include "XGUI_Module.h" +#include "ModuleBase_IModule.h" #include "XGUI_Constants.h" #include "XGUI_Command.h" #include "XGUI_MainMenu.h" @@ -8,34 +8,45 @@ #include "XGUI_Workbench.h" #include "XGUI_Workshop.h" #include "XGUI_Viewer.h" -#include "ModuleBase_WidgetFactory.h" #include "XGUI_SelectionMgr.h" +#include "XGUI_Selection.h" #include "XGUI_ObjectsBrowser.h" #include "XGUI_Displayer.h" #include "XGUI_OperationMgr.h" #include "XGUI_SalomeConnector.h" -#include "XGUI_SalomeViewer.h" #include "XGUI_ActionsMgr.h" #include "XGUI_ErrorDialog.h" #include "XGUI_ViewerProxy.h" #include "XGUI_PropertyPanel.h" #include "XGUI_ContextMenuMgr.h" #include "XGUI_ModuleConnector.h" +#include "XGUI_Preferences.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 @@ -48,10 +59,12 @@ #include #include #include -#include +#include +#include #ifdef _DEBUG #include +#include #endif #ifdef WIN32 @@ -60,7 +73,6 @@ #include #endif - QMap XGUI_Workshop::myIcons; QString XGUI_Workshop::featureIcon(const std::string& theId) @@ -72,43 +84,51 @@ QString XGUI_Workshop::featureIcon(const std::string& theId) } XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) - : QObject(), - myCurrentDir(QString()), - myPartSetModule(NULL), - mySalomeConnector(theConnector), - myPropertyPanel(0), - myObjectBrowser(0), - myDisplayer(0) + : QObject(), + myCurrentDir(QString()), + myModule(NULL), + mySalomeConnector(theConnector), + myPropertyPanel(0), + myObjectBrowser(0), + myDisplayer(0), + myUpdatePrefs(false), + myPartActivating(false) { - myMainWindow = mySalomeConnector? 0 : new XGUI_MainWindow(); + myMainWindow = mySalomeConnector ? 0 : new XGUI_MainWindow(); myDisplayer = new XGUI_Displayer(this); mySelector = new XGUI_SelectionMgr(this); + //connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateModuleCommands())); myOperationMgr = new XGUI_OperationMgr(this); myActionsMgr = new XGUI_ActionsMgr(this); myErrorDlg = new XGUI_ErrorDialog(myMainWindow); myContextMenuMgr = new XGUI_ContextMenuMgr(this); - connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), - this, SLOT(onContextMenuCommand(const QString&, bool))); + connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this, + SLOT(onContextMenuCommand(const QString&, bool))); myViewerProxy = new XGUI_ViewerProxy(this); - + connect(myViewerProxy, SIGNAL(selectionChanged()), this, SLOT(updateCommandsOnViewSelection())); + myModuleConnector = new XGUI_ModuleConnector(this); - connect(myOperationMgr, SIGNAL(operationStarted()), SLOT(onOperationStarted())); + connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), + SLOT(onOperationStarted())); connect(myOperationMgr, SIGNAL(operationResumed()), SLOT(onOperationStarted())); - connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), SLOT(onOperationStopped(ModuleBase_Operation*))); + 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(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), myActionsMgr, + SLOT(update())); connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&))); } //****************************************************** XGUI_Workshop::~XGUI_Workshop(void) { + delete myDisplayer; } //****************************************************** @@ -117,21 +137,28 @@ void XGUI_Workshop::startApplication() initMenu(); //Initialize event listening Events_Loop* aLoop = Events_Loop::loop(); - aLoop->registerListener(this, Events_Error::errorID()); //!< Listening application errors. + aLoop->registerListener(this, Events_Error::errorID()); //!< Listening application errors. //TODO(sbh): Implement static method to extract event id [SEID] - Events_ID aFeatureId = aLoop->eventByName(EVENT_FEATURE_LOADED); - aLoop->registerListener(this, aFeatureId); - Events_ID aPartSetId = aLoop->eventByName("PartSetModuleEvent"); - 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)); - + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_LOADED)); + // TODO Is it good to use non standard event within workshop? + 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_Loop::eventByName("LongOperation")); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_PLUGIN_LOADED)); + aLoop->registerListener(this, Events_Loop::eventByName("CurrentDocumentChanged")); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOSHOW)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); + + registerValidators(); activateModule(); if (myMainWindow) { myMainWindow->show(); updateCommandStatus(); } + XGUI_Preferences::loadCustomProps(); onNew(); } @@ -142,23 +169,25 @@ void XGUI_Workshop::initMenu() if (isSalomeMode()) { // Create only Undo, Redo commands - QAction* aAction = salomeConnector()->addEditCommand("UNDO_CMD", - tr("Undo"), tr("Undo last command"), - QIcon(":pictures/undo.png"), - QKeySequence::Undo, false); + QAction* aAction = salomeConnector()->addEditCommand("UNDO_CMD", tr("Undo"), + tr("Undo last command"), + QIcon(":pictures/undo.png"), + QKeySequence::Undo, false); connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo())); - aAction = salomeConnector()->addEditCommand("REDO_CMD", - tr("Redo"), tr("Redo last command"), - QIcon(":pictures/redo.png"), - QKeySequence::Redo, false); + aAction = salomeConnector()->addEditCommand("REDO_CMD", tr("Redo"), tr("Redo last command"), + QIcon(":pictures/redo.png"), QKeySequence::Redo, + false); connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRedo())); salomeConnector()->addEditMenuSeparator(); + aAction = salomeConnector()->addEditCommand("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"), + QIcon(":pictures/rebuild.png"), QKeySequence(), + false); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild())); + salomeConnector()->addEditMenuSeparator(); return; } - XGUI_Workbench* aPage = myMainWindow->menuObject()->generalPage(); - // File commands group - XGUI_MenuGroupPanel* aGroup = aPage->addGroup("Default"); + XGUI_MenuGroupPanel* aGroup = myMainWindow->menuObject()->generalPage(); XGUI_Command* aCommand; @@ -176,10 +205,11 @@ void XGUI_Workshop::initMenu() aCommand->connectTo(this, SLOT(onRedo())); aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"), - QIcon(":pictures/rebuild.png")); + QIcon(":pictures/rebuild.png"), QKeySequence()); + aCommand->connectTo(this, SLOT(onRebuild())); aCommand = aGroup->addFeature("SAVEAS_CMD", tr("Save as..."), tr("Save the document into a file"), - QIcon(":pictures/save.png")); + QIcon(":pictures/save.png"), QKeySequence()); aCommand->connectTo(this, SLOT(onSaveAs())); //aCommand->disable(); @@ -191,15 +221,19 @@ void XGUI_Workshop::initMenu() // QIcon(":pictures/new.png"), QKeySequence::New); //aCommand->connectTo(this, SLOT(onNew())); + aCommand = aGroup->addFeature("PREF_CMD", tr("Preferences"), tr("Edit preferences"), + QIcon(":pictures/preferences.png"), QKeySequence::Preferences); + aCommand->connectTo(this, SLOT(onPreferences())); + 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 +// #ifdef _DEBUG +// aCommand = aGroup->addFeature("TEST_CMD", "Test!", "Private debug button", +// QIcon(":pictures/close.png"), QKeySequence(), true); +// aCommand->connectTo(myMainWindow, SLOT(dockPythonConsole())); +// #endif } //****************************************************** @@ -210,125 +244,294 @@ XGUI_Workbench* XGUI_Workshop::addWorkbench(const QString& theName) } //****************************************************** -void XGUI_Workshop::processEvent(const Events_Message* theMessage) +void XGUI_Workshop::processEvent(const boost::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. - static Events_ID aFeatureLoadedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_LOADED); - if (theMessage->eventID() == aFeatureLoadedId) { - const Config_FeatureMessage* aFeatureMsg = dynamic_cast(theMessage); - if(!aFeatureMsg->isInternal()) { + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_LOADED)) { + boost::shared_ptr aFeatureMsg = + boost::dynamic_pointer_cast(theMessage); + 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; - } else { - myDisplayer->display(aFeature, false); - } - } - myDisplayer->updateViewer(); - 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())); + // Process creation of Part + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) { + boost::shared_ptr aUpdMsg = + boost::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)) { + boost::shared_ptr aUpdMsg = + boost::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. - static Events_ID aFeatureUpdatedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED); - if (theMessage->eventID() == aFeatureUpdatedId) { - const Model_FeatureUpdatedMessage* anUpdateMsg = - dynamic_cast(theMessage); + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) { + boost::shared_ptr anUpdateMsg = + boost::dynamic_pointer_cast(theMessage); + onFeatureUpdatedMsg(anUpdateMsg); + } - std::set aFeatures = anUpdateMsg->features(); - if (myOperationMgr->hasOperation()) - { - FeaturePtr aCurrentFeature = myOperationMgr->currentOperation()->feature(); - std::set::const_iterator aIt; - for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) { - FeaturePtr aNewFeature = (*aIt); - if(aNewFeature == aCurrentFeature) { - myPropertyPanel->updateContentWidget(aCurrentFeature); - break; - } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { + boost::shared_ptr aDelMsg = + boost::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)) { + boost::shared_ptr anUpdateMsg = + boost::dynamic_pointer_cast(theMessage); + const std::set& aObjList = anUpdateMsg->objects(); + QList 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)) { + boost::shared_ptr anUpdateMsg = + boost::dynamic_pointer_cast(theMessage); + const std::set& aObjList = anUpdateMsg->objects(); + QList 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)) { + boost::shared_ptr aPartSetMsg = + boost::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(); } } - // Redisplay feature if it is modified - std::set::const_iterator aIt; + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName("CurrentDocumentChanged")) { + 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 = boost::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 { + //Show error dialog if error message received. + boost::shared_ptr anAppError = boost::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()); + } +} + + +//****************************************************** +void XGUI_Workshop::onStartWaiting() +{ + if (Events_LongOp::isPerformed()) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + } +} + +//****************************************************** +void XGUI_Workshop::onFeatureUpdatedMsg(const boost::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) { - FeaturePtr aFeature = (*aIt); - if (aFeature->getKind() != PARTSET_PART_KIND) { - if (myDisplayer->isVisible(aFeature)) - myDisplayer->redisplay(aFeature, false); - else - myDisplayer->display(aFeature, false); + ObjectPtr aNewFeature = (*aIt); + if (aNewFeature == aCurrentFeature) { + myPropertyPanel->updateContentWidget(aCurrentFeature); + break; } } - myDisplayer->updateViewer(); } - //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()); + myOperationMgr->onValidateOperation(); + if (myObjectBrowser) + myObjectBrowser->processEvent(theMsg); +} - if (myOperationMgr->startOperation(anOperation)) { - myPropertyPanel->updateContentWidget(anOperation->feature()); - if (anOperation->getDescription()->xmlRepresentation().isEmpty()) { - anOperation->commit(); - updateCommandStatus(); +//****************************************************** +void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptr& theMsg) +{ + std::set aObjects = theMsg->objects(); + std::set::const_iterator aIt; + QIntList aModes; + 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 = boost::dynamic_pointer_cast(aObj); + aHide = aRes && aRes->isConcealed(); + } + if (aHide) + myDisplayer->erase(aObj, false); + else { + if (myDisplayer->isVisible(aObj)) { + myDisplayer->display(aObj, false); // In order to update presentation + if (myOperationMgr->hasOperation()) { + ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); + if (!aOperation->hasObject(aObj)) + if (!myDisplayer->isActive(aObj)) + myDisplayer->activate(aObj, aModes); + } + } else { + if (myOperationMgr->hasOperation()) { + ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); + // Display only current operation results if operation has preview + if (aOperation->hasObject(aObj) && aOperation->hasPreview()) { + myDisplayer->display(aObj, false); + // Deactivate object of current operation from selection + if (myDisplayer->isActive(aObj)) + myDisplayer->deactivate(aObj); + } + } } } - return; } - //Show error dialog if error message received. - const Events_Error* anAppError = dynamic_cast(theMessage); - if (anAppError) { - emit errorOccurred(QString::fromLatin1(anAppError->description())); + myDisplayer->updateViewer(); +} + +//****************************************************** +void XGUI_Workshop::onFeatureCreatedMsg(const boost::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 = boost::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 (myOperationMgr->hasOperation()) { + ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); + if (aOperation->hasObject(*aIt)) { // Display only current operation results + myDisplayer->display(*aIt, false); + 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 boost::shared_ptr& theMsg) +{ + if (myObjectBrowser) + myObjectBrowser->processEvent(theMsg); + //std::set aFeatures = theMsg->objects(); } //****************************************************** void XGUI_Workshop::onOperationStarted() { ModuleBase_Operation* aOperation = myOperationMgr->currentOperation(); - - if(!aOperation->getDescription()->xmlRepresentation().isEmpty()) { //!< No need for property panel + if (this->isSalomeMode()) + aOperation->setNestedFeatures(mySalomeConnector->nestedActions(aOperation->id())); + else + aOperation->setNestedFeatures(myActionsMgr->nestedCommands(aOperation->id())); + + if (aOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel connectWithOperation(aOperation); showPropertyPanel(); + QString aXmlRepr = aOperation->getDescription()->xmlRepresentation(); + ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aXmlRepr.toStdString(), + myModuleConnector); - ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aOperation, myModuleConnector); - QWidget* aContent = myPropertyPanel->contentWidget(); - qDeleteAll(aContent->children()); - aFactory.createWidget(aContent); - - // Init default values - if (!aOperation->isEditOperation()) { - QList aWidgets = aFactory.getModelWidgets(); - QList::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end(); - for (; anIt != aLast; anIt++) { - (*anIt)->storeValue(aOperation->feature()); + myPropertyPanel->cleanContent(); + aFactory.createWidget(myPropertyPanel->contentWidget()); + ModuleBase_Tools::zeroMargins(myPropertyPanel->contentWidget()); + + QList aWidgets = aFactory.getModelWidgets(); + foreach (ModuleBase_ModelWidget* aWidget, aWidgets) { + aWidget->setFeature(aOperation->feature()); + aWidget->enableFocusProcessing(); + QObject::connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged())); + // Init default values + if (!aOperation->isEditOperation() && !aWidget->isComputedDefault()) { + aWidget->storeValue(); } } - myPropertyPanel->setModelWidgets(aFactory.getModelWidgets()); - myPropertyPanel->setWindowTitle(aOperation->getDescription()->description()); + aOperation->setPropertyPanel(myPropertyPanel); + myPropertyPanel->setModelWidgets(aWidgets); + if (!aOperation->activateByPreselection()) + myPropertyPanel->activateNextWidget(NULL); + // Widget activation (from the previous method) may commit the current operation + // if pre-selection is enougth for it. So we shouldn't update prop panel's title + if(myOperationMgr->isCurrentOperation(aOperation)) { + myPropertyPanel->setWindowTitle(aOperation->getDescription()->description()); + } } updateCommandStatus(); } @@ -339,12 +542,24 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) //!< No need for property panel updateCommandStatus(); hidePropertyPanel(); + myPropertyPanel->cleanContent(); +} + +bool XGUI_Workshop::event(QEvent * theEvent) +{ + PostponeMessageQtEvent* aPostponedEv = dynamic_cast(theEvent); + if (aPostponedEv) { + boost::shared_ptr aEventPtr = aPostponedEv->postponedMessage(); + processEvent(aEventPtr); + return true; + } + return false; } /* * */ -void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) +void XGUI_Workshop::addFeature(const boost::shared_ptr& theMessage) { if (!theMessage) { #ifdef _DEBUG @@ -359,17 +574,19 @@ 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()); + QString aFeatureId = QString::fromStdString(theMessage->id()); if (isSalomeMode()) { - QAction* aAction = salomeConnector()->addFeature(aWchName, - aId, - QString::fromStdString(theMessage->text()), - QString::fromStdString(theMessage->tooltip()), - QIcon(theMessage->icon().c_str()), - QKeySequence(), isUsePropPanel); - salomeConnector()->setNestedActions(aId, aNestedFeatures.split(" ")); + QAction* aAction = salomeConnector()->addFeature(aWchName, aFeatureId, + QString::fromStdString(theMessage->text()), + QString::fromStdString(theMessage->tooltip()), + QIcon(theMessage->icon().c_str()), + QKeySequence(), + isUsePropPanel); + salomeConnector()->setNestedActions(aFeatureId, aNestedFeatures.split(" ", QString::SkipEmptyParts)); + salomeConnector()->setDocumentKind(aFeatureId, QString::fromStdString(theMessage->documentKind())); + myActionsMgr->addCommand(aAction); - myPartSetModule->featureCreated(aAction); + myModule->featureCreated(aAction); } else { XGUI_MainMenu* aMenuBar = myMainWindow->menuObject(); @@ -383,15 +600,21 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) if (!aGroup) { aGroup = aPage->addGroup(aGroupName); } - //Create feature... - XGUI_Command* aCommand = aGroup->addFeature(aId, + QString aDocKind = QString::fromStdString(theMessage->documentKind()); + // Check if hotkey sequence is already defined: + QKeySequence aHotKey = myActionsMgr->registerShortcut( + QString::fromStdString(theMessage->keysequence())); + // Create feature... + XGUI_Command* aCommand = aGroup->addFeature(aFeatureId, QString::fromStdString(theMessage->text()), QString::fromStdString(theMessage->tooltip()), QIcon(theMessage->icon().c_str()), - QKeySequence(), isUsePropPanel); + aDocKind, + aHotKey, + isUsePropPanel); aCommand->setNestedCommands(aNestedFeatures.split(" ", QString::SkipEmptyParts)); myActionsMgr->addCommand(aCommand); - myPartSetModule->featureCreated(aCommand); + myModule->featureCreated(aCommand); } } @@ -407,37 +630,43 @@ void XGUI_Workshop::connectWithOperation(ModuleBase_Operation* theOperation) aCommand = salomeConnector()->command(theOperation->getDescription()->operationId()); } else { XGUI_MainMenu* aMenu = myMainWindow->menuObject(); - aCommand = aMenu->feature(theOperation->getDescription()->operationId()); + FeaturePtr aFeature = theOperation->feature(); + if(aFeature) + aCommand = aMenu->feature(QString::fromStdString(aFeature->getKind())); } //Abort operation on uncheck the command - connect(aCommand, SIGNAL(triggered(bool)), theOperation, SLOT(setRunning(bool))); + if (aCommand) { + connect(aCommand, SIGNAL(triggered(bool)), theOperation, SLOT(setRunning(bool))); + } } /* * Saves document with given name. */ -void XGUI_Workshop::saveDocument(QString theName) +void XGUI_Workshop::saveDocument(const QString& theName, std::list& theFileNames) { QApplication::restoreOverrideCursor(); - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - aDoc->save(theName.toLatin1().constData()); + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->save(theName.toLatin1().constData(), theFileNames); QApplication::restoreOverrideCursor(); } +bool XGUI_Workshop::isActiveOperationAborted() +{ + return myOperationMgr->abortAllOperations(); +} + //****************************************************** void XGUI_Workshop::onExit() { - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - if(aDoc->isModified()) { + SessionPtr aMgr = ModelAPI_Session::get(); + if (aMgr->isModified()) { int anAnswer = QMessageBox::question( - myMainWindow, tr("Save current file"), - tr("The document is modified, save before exit?"), + myMainWindow, tr("Save current file"), tr("The document is modified, save before exit?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel); - if(anAnswer == QMessageBox::Save) { + if (anAnswer == QMessageBox::Save) { bool saved = onSave(); - if(!saved) { + if (!saved) { return; } } else if (anAnswer == QMessageBox::Cancel) { @@ -470,55 +699,63 @@ void XGUI_Workshop::onNew() //****************************************************** void XGUI_Workshop::onOpen() { + if(!isActiveOperationAborted()) + return; //save current file before close if modified - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - if(aDoc->isModified()) { + SessionPtr aSession = ModelAPI_Session::get(); + if (aSession->isModified()) { //TODO(sbh): re-launch the app? int anAnswer = QMessageBox::question( myMainWindow, tr("Save current file"), tr("The document is modified, save before opening another?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel); - if(anAnswer == QMessageBox::Save) { + if (anAnswer == QMessageBox::Save) { onSave(); } else if (anAnswer == QMessageBox::Cancel) { return; } - aDoc->close(); + aSession->moduleDocument()->close(); myCurrentDir = ""; } //show file dialog, check if readable and open myCurrentDir = QFileDialog::getExistingDirectory(mainWindow()); - if(myCurrentDir.isEmpty()) + if (myCurrentDir.isEmpty()) return; QFileInfo aFileInfo(myCurrentDir); - if(!aFileInfo.exists() || !aFileInfo.isReadable()) { + if (!aFileInfo.exists() || !aFileInfo.isReadable()) { QMessageBox::critical(myMainWindow, tr("Warning"), tr("Unable to open the file.")); myCurrentDir = ""; return; } QApplication::setOverrideCursor(Qt::WaitCursor); - aDoc->load(myCurrentDir.toLatin1().constData()); - updateCommandStatus(); + aSession->load(myCurrentDir.toLatin1().constData()); myObjectBrowser->rebuildDataTree(); + displayAllResults(); + updateCommandStatus(); QApplication::restoreOverrideCursor(); } //****************************************************** bool XGUI_Workshop::onSave() { - if(myCurrentDir.isEmpty()) { + if(!isActiveOperationAborted()) + return false; + if (myCurrentDir.isEmpty()) { return onSaveAs(); } - saveDocument(myCurrentDir); + std::list aFiles; + saveDocument(myCurrentDir, aFiles); updateCommandStatus(); + myMainWindow->setModifiedState(false); return true; } //****************************************************** bool XGUI_Workshop::onSaveAs() { + if(!isActiveOperationAborted()) + return false; QFileDialog dialog(mainWindow()); dialog.setWindowTitle(tr("Select directory to save files...")); dialog.setFileMode(QFileDialog::Directory); @@ -526,22 +763,27 @@ bool XGUI_Workshop::onSaveAs() dialog.setOptions(QFileDialog::HideNameFilterDetails | QFileDialog::ShowDirsOnly); dialog.setViewMode(QFileDialog::Detail); - if(!dialog.exec()) { + if (!dialog.exec()) { return false; } 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) { + 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; } } myCurrentDir = aTempDir; + if (!isSalomeMode()) { + myMainWindow->setCurrentDir(myCurrentDir, false); + myMainWindow->setModifiedState(false); + } return onSave(); } @@ -549,11 +791,10 @@ bool XGUI_Workshop::onSaveAs() void XGUI_Workshop::onUndo() { objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - if (aDoc->isOperation()) - operationMgr()->abortOperation(); - aDoc->undo(); + SessionPtr aMgr = ModelAPI_Session::get(); + if (aMgr->isOperation()) + operationMgr()->onAbortOperation(); + aMgr->undo(); updateCommandStatus(); } @@ -561,22 +802,56 @@ void XGUI_Workshop::onUndo() void XGUI_Workshop::onRedo() { objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - if (aDoc->isOperation()) - operationMgr()->abortOperation(); - aDoc->redo(); + SessionPtr aMgr = ModelAPI_Session::get(); + if (aMgr->isOperation()) + operationMgr()->onAbortOperation(); + aMgr->redo(); updateCommandStatus(); } //****************************************************** -XGUI_Module* XGUI_Workshop::loadModule(const QString& theModule) +void XGUI_Workshop::onRebuild() { - QString libName = - QString::fromStdString(library(theModule.toStdString())); + SessionPtr aMgr = ModelAPI_Session::get(); + bool aWasOperation = aMgr->isOperation(); // keep this value + if (!aWasOperation) { + aMgr->startOperation(); + } + static const Events_ID aRebuildEvent = Events_Loop::loop()->eventByName("Rebuild"); + Events_Loop::loop()->send(boost::shared_ptr( + new Events_Message(aRebuildEvent, this))); + if (!aWasOperation) { + aMgr->finishOperation(); + } +} + +//****************************************************** +void XGUI_Workshop::onPreferences() +{ + XGUI_Prefs aModif; + XGUI_Preferences::editPreferences(aModif); + if (aModif.size() > 0) { + QString aSection; + foreach (XGUI_Pref aPref, aModif) + { + aSection = aPref.first; + if (aSection == XGUI_Preferences::VIEWER_SECTION) { + if (!isSalomeMode()) + myMainWindow->viewer()->updateFromResources(); + } else if (aSection == XGUI_Preferences::MENU_SECTION) { + if (!isSalomeMode()) + myMainWindow->menuObject()->updateFromResources(); + } + } + } +} + +//****************************************************** +ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule) +{ + QString libName = QString::fromStdString(library(theModule.toStdString())); if (libName.isEmpty()) { - qWarning( - qPrintable( tr( "Information about module \"%1\" doesn't exist." ).arg( theModule ) )); + qWarning(qPrintable(tr("Information about module \"%1\" doesn't exist.").arg(theModule))); return 0; } @@ -618,13 +893,13 @@ XGUI_Module* XGUI_Workshop::loadModule(const QString& theModule) } #endif - XGUI_Module* aModule = crtInst ? crtInst(this) : 0; + ModuleBase_IModule* aModule = crtInst ? crtInst(myModuleConnector) : 0; if (!err.isEmpty()) { if (mainWindow()) { - QMessageBox::warning(mainWindow(), tr("Error"), err); + Events_Error::send(err.toStdString()); } else { - qWarning( qPrintable( err )); + qWarning(qPrintable(err)); } } return aModule; @@ -635,10 +910,10 @@ bool XGUI_Workshop::activateModule() { Config_ModuleReader aModuleReader; QString moduleName = QString::fromStdString(aModuleReader.getModuleName()); - myPartSetModule = loadModule(moduleName); - if (!myPartSetModule) + myModule = loadModule(moduleName); + if (!myModule) return false; - myPartSetModule->createFeatures(); + myModule->createFeatures(); myActionsMgr->update(); return true; } @@ -647,15 +922,15 @@ bool XGUI_Workshop::activateModule() void XGUI_Workshop::updateCommandStatus() { QList aCommands; - if (isSalomeMode()) { // update commands in SALOME mode + if (isSalomeMode()) { // update commands in SALOME mode aCommands = salomeConnector()->commandList(); } else { XGUI_MainMenu* aMenuBar = myMainWindow->menuObject(); foreach (XGUI_Command* aCmd, aMenuBar->features()) aCommands.append(aCmd); } - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - if (aMgr->hasRootDocument()) { + SessionPtr aMgr = ModelAPI_Session::get(); + if (aMgr->hasModuleDocument()) { QAction* aUndoCmd; QAction* aRedoCmd; foreach(QAction* aCmd, aCommands) { @@ -664,12 +939,12 @@ void XGUI_Workshop::updateCommandStatus() aUndoCmd = aCmd; else if (aId == "REDO_CMD") aRedoCmd = aCmd; - else // Enable all commands + else + // Enable all commands aCmd->setEnabled(true); } - DocumentPtr aDoc = aMgr->rootDocument(); - aUndoCmd->setEnabled(aDoc->canUndo()); - aRedoCmd->setEnabled(aDoc->canRedo()); + aUndoCmd->setEnabled(aMgr->canUndo()); + aRedoCmd->setEnabled(aMgr->canRedo()); } else { foreach(QAction* aCmd, aCommands) { QString aId = aCmd->data().toString(); @@ -677,22 +952,40 @@ void XGUI_Workshop::updateCommandStatus() aCmd->setEnabled(true); else if (aId == "EXIT_CMD") aCmd->setEnabled(true); - else + else aCmd->setEnabled(false); } } myActionsMgr->update(); } +//****************************************************** +QList XGUI_Workshop::getModuleCommands() const +{ + QList aCommands; + if (isSalomeMode()) { // update commands in SALOME mode + aCommands = salomeConnector()->commandList(); + } else { + XGUI_MainMenu* aMenuBar = myMainWindow->menuObject(); + foreach(XGUI_Command* aCmd, aMenuBar->features()) + { + aCommands.append(aCmd); + } + } + return aCommands; +} + //****************************************************** QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) { QDockWidget* aObjDock = new QDockWidget(theParent); - aObjDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + aObjDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); aObjDock->setWindowTitle(tr("Object browser")); - aObjDock->setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }"); + 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))); + connect(myObjectBrowser, SIGNAL(activePartChanged(ObjectPtr)), this, + SLOT(changeCurrentDocument(ObjectPtr))); aObjDock->setWidget(myObjectBrowser); myContextMenuMgr->connectObjectBrowser(); @@ -706,23 +999,26 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) */ void XGUI_Workshop::createDockWidgets() { - QMainWindow* aDesktop = isSalomeMode()? salomeConnector()->desktop() : - myMainWindow; + QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow; QDockWidget* aObjDock = createObjectBrowser(aDesktop); aDesktop->addDockWidget(Qt::LeftDockWidgetArea, aObjDock); myPropertyPanel = new XGUI_PropertyPanel(aDesktop); + myPropertyPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); aDesktop->addDockWidget(Qt::LeftDockWidgetArea, myPropertyPanel); - hidePropertyPanel(); //tabifyDockWidget(aObjDock, myPropertyPanel); + myPropertyPanel->installEventFilter(myOperationMgr); QPushButton* aOkBtn = myPropertyPanel->findChild(XGUI::PROP_PANEL_OK); 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(QKeyEvent*)), myOperationMgr, + SLOT(onKeyReleased(QKeyEvent*))); + connect(myOperationMgr, SIGNAL(operationValidated(bool)), myPropertyPanel, + SLOT(setAcceptEnabled(bool))); - connect(myPropertyPanel, SIGNAL(keyReleased(const std::string&, QKeyEvent*)), - myOperationMgr, SLOT(onKeyReleased(const std::string&, QKeyEvent*))); } //****************************************************** @@ -763,27 +1059,25 @@ void XGUI_Workshop::onFeatureTriggered() if (aCmd) { QString aId = salomeConnector()->commandId(aCmd); if (!aId.isNull()) - myPartSetModule->launchOperation(aId); + myModule->launchOperation(aId); } } //****************************************************** -void XGUI_Workshop::changeCurrentDocument(FeaturePtr thePart) +void XGUI_Workshop::changeCurrentDocument(ObjectPtr theObj) { - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - if (thePart) { - 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(); + SessionPtr aMgr = ModelAPI_Session::get(); + if (theObj) { + ResultPartPtr aPart = boost::dynamic_pointer_cast(theObj); + if (aPart) { + DocumentPtr aPartDoc = aPart->partDoc(); + if (aPartDoc) { + aMgr->setActiveDocument(aPartDoc); + return; + } } - if (aFeaDoc) - aMgr->setCurrentDocument(aFeaDoc); - } else { - aMgr->setCurrentDocument(aMgr->rootDocument()); } + aMgr->setActiveDocument(aMgr->moduleDocument()); } //****************************************************** @@ -792,94 +1086,235 @@ void XGUI_Workshop::salomeViewerSelectionChanged() emit salomeViewerSelection(); } - //************************************************************** -XGUI_SalomeViewer* XGUI_Workshop::salomeViewer() const -{ - return mySalomeConnector->viewer(); +ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const +{ + return mySalomeConnector->viewer(); } //************************************************************** void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) { - QFeatureList aFeatures = mySelector->selectedFeatures(); - if ((theId == "ACTIVATE_PART_CMD") && (aFeatures.size() > 0)) - activatePart(aFeatures.first()); - else if (theId == "DEACTIVATE_PART_CMD") - activatePart(FeaturePtr()); + QList aObjects = mySelector->selection()->selectedObjects(); + if ((theId == "ACTIVATE_PART_CMD") && (aObjects.size() > 0)) { + ResultPartPtr aPart = boost::dynamic_pointer_cast(aObjects.first()); + activatePart(aPart); + } else if (theId == "DEACTIVATE_PART_CMD") + activatePart(ResultPartPtr()); else if (theId == "DELETE_CMD") - deleteFeatures(aFeatures); + deleteObjects(aObjects); else if (theId == "SHOW_CMD") - showFeatures(aFeatures, true); + showObjects(aObjects, true); else if (theId == "HIDE_CMD") - showFeatures(aFeatures, false); + showObjects(aObjects, false); + else if (theId == "SHOW_ONLY_CMD") + showOnlyObjects(aObjects); + else if (theId == "SHADING_CMD") + setDisplayMode(aObjects, XGUI_Displayer::Shading); + else if (theId == "WIREFRAME_CMD") + setDisplayMode(aObjects, XGUI_Displayer::Wireframe); + else if (theId == "HIDEALL_CMD") + myDisplayer->eraseAll(); +} + +//************************************************************** +void XGUI_Workshop::onWidgetValuesChanged() +{ + ModuleBase_Operation* anOperation = myOperationMgr->currentOperation(); + FeaturePtr aFeature = anOperation->feature(); + + ModuleBase_ModelWidget* aSenderWidget = dynamic_cast(sender()); + //if (aCustom) + // aCustom->storeValue(aFeature); + + 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->isInitialized(aFeature) ||*/aCustom == aSenderWidget)) { + //aCustom->storeValue(aFeature); + aCustom->storeValue(); + } + } } //************************************************************** -void XGUI_Workshop::activatePart(FeaturePtr theFeature) +void XGUI_Workshop::activatePart(ResultPartPtr theFeature) { - changeCurrentDocument(theFeature); - myObjectBrowser->activatePart(theFeature); + if (!myPartActivating) { + myPartActivating = true; + if (theFeature) + theFeature->activate(); + changeCurrentDocument(theFeature); + myObjectBrowser->activatePart(theFeature); + myPartActivating = false; + } } //************************************************************** void XGUI_Workshop::activateLastPart() { - PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); - DocumentPtr aDoc = aMgr->rootDocument(); - FeaturePtr aLastPart = aDoc->feature(PARTS_GROUP, aDoc->size(PARTS_GROUP) - 1, true); - activatePart(aLastPart); + 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 = boost::dynamic_pointer_cast(aLastPart); + if (aPart) { + activatePart(aPart); + } } //************************************************************** -void XGUI_Workshop::deleteFeatures(QFeatureList theList) +void XGUI_Workshop::deleteObjects(const QList& 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); + 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); + // ToDo: definbe deleting method 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()) { + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation(); + foreach (ObjectPtr aObj, theList) + { + ResultPartPtr aPart = boost::dynamic_pointer_cast(aObj); + if (aPart) { + DocumentPtr aDoc = aPart->document(); + if (aDoc == aMgr->activeDocument()) { aDoc->close(); } + //aMgr->moduleDocument()->removeFeature(aPart->owner()); } else { - if (XGUI_Tools::isModelObject(aFeature)) { - ObjectPtr aObject = boost::dynamic_pointer_cast(aFeature); - aFeature = aObject->featureRef(); - } + FeaturePtr aFeature = boost::dynamic_pointer_cast(aObj); + if (aFeature) + aObj->document()->removeFeature(aFeature); } - if (myDisplayer->isVisible(aFeature)) - myDisplayer->erase(aFeature, false); - aFeature->document()->removeFeature(aFeature); } myDisplayer->updateViewer(); - aMgr->rootDocument()->finishOperation(); + aMgr->finishOperation(); } } //************************************************************** -void XGUI_Workshop::showFeatures(QFeatureList theList, bool isVisible) +void XGUI_Workshop::showObjects(const QList& theList, bool isVisible) { - if (isVisible) { - foreach (FeaturePtr aFeature, theList) { - myDisplayer->display(aFeature, false); + foreach (ObjectPtr aObj, theList) + { + ResultPtr aRes = boost::dynamic_pointer_cast(aObj); + if (aRes) { + if (isVisible) { + myDisplayer->display(aRes, false); + } else { + myDisplayer->erase(aRes, false); + } } - } else { - foreach (FeaturePtr aFeature, theList) { - myDisplayer->erase(aFeature, false); + } + myDisplayer->updateViewer(); +} + +//************************************************************** +void XGUI_Workshop::showOnlyObjects(const QList& theList) +{ + myDisplayer->eraseAll(false); + showObjects(theList, true); +} + + +//************************************************************** +void XGUI_Workshop::updateCommandsOnViewSelection() +{ + XGUI_Selection* aSelection = mySelector->selection(); + if (aSelection->getSelected().size() == 0) + return; + + // Restrict validators to manage only nested (child) features + // of the current feature i.e. if current feature is Sketch - + // Sketch Features & Constraints can be validated. + QStringList aNestedIds; + if(myOperationMgr->hasOperation()) { + FeaturePtr aFeature = myOperationMgr->currentOperation()->feature(); + if(aFeature) { + aNestedIds << myActionsMgr->nestedCommands(QString::fromStdString(aFeature->getKind())); + } + } + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + QList aActions = getModuleCommands(); + foreach(QAction* aAction, aActions) { + QString aId = aAction->data().toString(); + if(!aNestedIds.contains(aId)) + continue; + std::list aValidators; + std::list > anArguments; + aFactory->validators(aId.toStdString(), aValidators, anArguments); + std::list::iterator aValidator = aValidators.begin(); + for (; aValidator != aValidators.end(); aValidator++) { + if (*aValidator) { + const ModuleBase_SelectionValidator* aSelValidator = + dynamic_cast(*aValidator); + if (aSelValidator) { + aAction->setEnabled(aSelValidator->isValid(aSelection)); + } + } } } +} + +//************************************************************** +void XGUI_Workshop::registerValidators() const +{ + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); +} + +//************************************************************** +void XGUI_Workshop::displayAllResults() +{ + SessionPtr aMgr = ModelAPI_Session::get(); + DocumentPtr aRootDoc = aMgr->moduleDocument(); + displayDocumentResults(aRootDoc); + for (int i = 0; i < aRootDoc->size(ModelAPI_ResultPart::group()); i++) { + ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), i); + ResultPartPtr aPart = boost::dynamic_pointer_cast(aObject); + displayDocumentResults(aPart->partDoc()); + } myDisplayer->updateViewer(); } + +//************************************************************** +void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc) +{ + if (!theDoc) + return; + displayGroupResults(theDoc, ModelAPI_ResultConstruction::group()); + displayGroupResults(theDoc, ModelAPI_ResultBody::group()); +} + +//************************************************************** +void XGUI_Workshop::displayGroupResults(DocumentPtr theDoc, std::string theGroup) +{ + for (int i = 0; i < theDoc->size(theGroup); i++) + myDisplayer->display(theDoc->object(theGroup, i), false); +} + +//************************************************************** +void XGUI_Workshop::setDisplayMode(const QList& theList, int theMode) +{ + foreach(ObjectPtr aObj, theList) { + myDisplayer->setDisplayMode(aObj, (XGUI_Displayer::DisplayMode)theMode, false); + } + if (theList.size() > 0) + myDisplayer->updateViewer(); +} + +//************************************************************** +void XGUI_Workshop::closeDocument() +{ + myDisplayer->closeLocalContexts(); + myDisplayer->eraseAll(); + objectBrowser()->clearContent(); + + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->moduleDocument()->close(); + objectBrowser()->clearContent(); +}