X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_Workshop.cpp;h=6ae78b95d4bd588ba7199f934272c0fb3a1c06b0;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=678e112fbd68ab17679b2140b19052405dcc509d;hpb=d588149317acbc2bd8e6ceb00f8e82e806571775;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 678e112fb..6ae78b95d 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -51,7 +51,10 @@ #include #include -#ifndef HAVE_SALOME +#ifdef HAVE_SALOME +#include +#include +#else #include #include #include @@ -66,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -79,14 +83,22 @@ #include #include #include +#include //#include #include #include #include +#include + +#include +#include +#include +#include #include +#include #include #include @@ -98,7 +110,6 @@ #include #include #include -#include #include #include #include @@ -140,17 +151,20 @@ #include #include #include +#include +#include +#include +#include #include #ifdef TINSPECTOR -#include -#include +#include +#include #include #include static TInspector_Communicator* MyTCommunicator; static Handle(VInspector_CallBack) MyVCallBack; - #endif #ifdef _DEBUG @@ -160,6 +174,8 @@ static Handle(VInspector_CallBack) MyVCallBack; #ifdef WIN32 #include +#pragma warning(disable : 4456) // for nested foreach +#pragma warning(disable : 4189) // for declaration of unused variables (MAYBE_UNUSED) #else #include #endif @@ -167,6 +183,7 @@ static Handle(VInspector_CallBack) MyVCallBack; //#define DEBUG_WITH_MESSAGE_REPORT QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end"); +QString XGUI_Workshop::MOVE_TO_END_SPLIT_COMMAND = QObject::tr("Move to the end and split"); //#define DEBUG_DELETE //#define DEBUG_FEATURE_NAME @@ -182,22 +199,24 @@ static QString MyFilter2(QObject::tr("CAD Builder files (*.cadbld)")); static QString MyExtension(".cadbld"); #endif +static QString MyImportPartFilter(QObject::tr("Part files (*.shaperpart);;All files (*.*)")); + //****************************************************** XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) : QObject(), myModule(NULL), - mySalomeConnector(theConnector), + myObjectBrowser(0), myPropertyPanel(0), - myInspectionPanel(0), myFacesPanel(0), - myObjectBrowser(0), - myDisplayer(0) - //myViewerSelMode(TopAbs_FACE) + myDisplayer(0), + mySalomeConnector(theConnector), + //myViewerSelMode(TopAbs_FACE), + myInspectionPanel(0) { mySelector = new XGUI_SelectionMgr(this); myModuleConnector = new XGUI_ModuleConnector(this); - myOperationMgr = new XGUI_OperationMgr(this, 0); + myOperationMgr = new XGUI_OperationMgr(this, myModuleConnector); ModuleBase_IWorkshop* aWorkshop = moduleConnector(); // Has to be defined first in order to get errors and messages from other components myEventsListener = new XGUI_WorkshopListener(this); @@ -219,7 +238,15 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) // Load translations QStringList aLangs; aLangs << "*_en.ts"; // load by default eng translations + + /// If version of OCCT is 7.4.0 or more then it means that + /// this is version of SALOME older then 9.4.0 +#if OCC_VERSION_HEX >= 0x070400 + QString aCurrLang = aResMgr->language(); +#else QString aCurrLang = aResMgr->stringValue("language", "language", "en"); +#endif + if(aCurrLang != "en") { aLangs << "*_" + aCurrLang + ".ts"; // then replace with translated files } @@ -252,8 +279,6 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) //connect(myViewerProxy, SIGNAL(selectionChanged()), // myActionsMgr, SLOT(updateOnViewSelection())); - myOperationMgr->setWorkshop(aWorkshop); - myErrorMgr = new XGUI_ErrorMgr(this, aWorkshop); connect(myOperationMgr, SIGNAL(operationResumed(ModuleBase_Operation*)), @@ -273,6 +298,9 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) connect(myEventsListener, SIGNAL(errorOccurred(std::shared_ptr)), myErrorDlg, SLOT(addError(std::shared_ptr))); + Config_PropManager::registerProp("Visualization", "selection_color", "Selection color", + Config_Prop::Color, "255,255,255"); + if (ModuleBase_Preferences::resourceMgr()->booleanValue("Viewer", "face-selection", true)) myViewerSelMode.append(TopAbs_FACE); if (ModuleBase_Preferences::resourceMgr()->booleanValue("Viewer", "edge-selection", true)) @@ -329,6 +357,15 @@ void XGUI_Workshop::startApplication() // Calling of loadCustomProps before activating module is required // by Config_PropManger to restore user-defined path to plugins ModuleBase_Preferences::loadCustomProps(); + std::vector aColor; + try { + aColor = Config_PropManager::color("Visualization", "selection_color"); + } + catch (...) { + } + if (aColor.size() == 3) + myDisplayer->setSelectionColor(aColor); + createModule(); #ifndef HAVE_SALOME @@ -440,18 +477,49 @@ void XGUI_Workshop::initMenu() // Add commands to a file menu - aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."), + // Import sub-menu + aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Part set..."), + tr("Import native file"), + QIcon(), QKeySequence(), + false, "MEN_DESK_FILE", tr("Import"), 10, 10); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen())); + + aAction = salomeConnector()->addDesktopCommand("IMPORT_PART_CMD", tr("Part..."), + tr("Import structure of a part"), + QIcon(), QKeySequence(), + false, "MEN_DESK_FILE", tr("Import"), 10, 10); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportPart())); + + aAction = salomeConnector()->addDesktopCommand("IMPORT_SHAPE_CMD", tr("From CAD format..."), + tr("Import shape from a CAD format file"), + ModuleBase_IconFactory::loadIcon("icons/Exchange/import.png"), + QKeySequence(), false, "MEN_DESK_FILE", tr("Import"), 10, 10); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportShape())); + + aAction = salomeConnector()->addDesktopCommand("IMPORT_IMAGE_CMD", tr("Picture..."), + tr("Import a picture from an image file"), + QIcon(), + QKeySequence(), false, "MEN_DESK_FILE", tr("Import"), 10, 10); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportImage())); + + // Export sub-menu + aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Part set..."), tr("Export the current document into a native file"), QIcon(), QKeySequence(), - false, "MEN_DESK_FILE"); + false, "MEN_DESK_FILE", tr("Export"), 10, 11); connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSaveAs())); - aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Import native..."), - tr("Import native file"), - QIcon(), QKeySequence(), - false, "MEN_DESK_FILE"); - connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen())); - salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE"); + aAction = salomeConnector()->addDesktopCommand("EXPORT_PART_CMD", tr("Part..."), + tr("Export a part of the current document into a file"), + QIcon(), QKeySequence(), + false, "MEN_DESK_FILE", tr("Export"), 10, 11); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onExportPart())); + + aAction = salomeConnector()->addDesktopCommand("EXPORT_SHAPE_CMD", tr("To CAD format..."), + tr("Export shape to a CAD format file"), + ModuleBase_IconFactory::loadIcon("icons/Exchange/export.png"), + QKeySequence(), false, "MEN_DESK_FILE", tr("Export"), 10, 11); + connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onExportShape())); #else // File commands group @@ -537,13 +605,11 @@ void XGUI_Workshop::onStartWaiting() //****************************************************** void XGUI_Workshop::onAcceptActionClicked() { - QAction* anAction = dynamic_cast(sender()); XGUI_OperationMgr* anOperationMgr = operationMgr(); if (anOperationMgr) { ModuleBase_OperationFeature* aFOperation = dynamic_cast (anOperationMgr->currentOperation()); if (aFOperation) { - //if (errorMgr()->canProcessClick(anAction, aFOperation->feature())) myOperationMgr->commitOperation(); } } @@ -552,7 +618,6 @@ void XGUI_Workshop::onAcceptActionClicked() //****************************************************** void XGUI_Workshop::onAcceptPlusActionClicked() { - QAction* anAction = dynamic_cast(sender()); XGUI_OperationMgr* anOperationMgr = operationMgr(); if (anOperationMgr) { ModuleBase_OperationFeature* aFOperation = dynamic_cast @@ -581,16 +646,22 @@ void XGUI_Workshop::onPreviewActionClicked() //****************************************************** -void XGUI_Workshop::onHelpActionClicked() +void XGUI_Workshop::onHelpActionClicked() const { XGUI_OperationMgr* anOperationMgr = operationMgr(); if (anOperationMgr) { ModuleBase_Operation* aOperation = anOperationMgr->currentOperation(); if (aOperation) { - QString aHelpPage = aOperation->helpFileName(); - if (!aHelpPage.isEmpty()) { - QString aDocDir; - const QChar aSep = QDir::separator(); + showHelpPage(aOperation->helpFileName()); + } + } +} + +void XGUI_Workshop::showHelpPage(const QString& thePage) const +{ + if (!thePage.isEmpty()) { + QString aDocDir; + const QChar aSep = QDir::separator(); // QString platform; // SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr(); //#ifdef WIN32 @@ -601,21 +672,29 @@ void XGUI_Workshop::onHelpActionClicked() // QString aBrowserName = aResMgr->stringValue("ExternalBrowser", platform); #ifdef HAVE_SALOME - QString aDir(getenv("SHAPER_ROOT_DIR")); - if (!aDir.isEmpty()) { - aDocDir = aDir + aSep + "share" + aSep + "doc" + aSep + - "salome" + aSep + "gui" + aSep + "SHAPER"; - } + QString aDir(getenv("SHAPER_ROOT_DIR")); + if (!aDir.isEmpty()) { + aDocDir = aDir + aSep + "share" + aSep + "doc" + aSep + + "salome" + aSep + "gui" + aSep + "SHAPER"; + } #else - QString aDir(getenv("CADBUILDER_ROOT_DIR")); - aDocDir = aDir + aSep + "doc" + aSep + "gui"; + QString aDir(getenv("CADBUILDER_ROOT_DIR")); + aDocDir = aDir + aSep + "doc" + aSep + "gui"; #endif - QString aFileName = aDocDir + aSep + aHelpPage; - if (QFile::exists(aFileName)) { - QUrl aUrl = QUrl::fromLocalFile(aFileName); - QDesktopServices::openUrl(aUrl); - } + QString aFileName = aDocDir + aSep + thePage; + if (QFile::exists(aFileName)) { +#ifdef HAVE_SALOME + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if (app) + app->onHelpContextModule("SHAPER", aFileName); + else { + QUrl aUrl = QUrl::fromLocalFile(aFileName); + QDesktopServices::openUrl(aUrl); } +#else + QUrl aUrl = QUrl::fromLocalFile(aFileName); + QDesktopServices::openUrl(aUrl); +#endif } } } @@ -659,12 +738,11 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) if (!aFOperation) return; - showPanel(myPropertyPanel); myPropertyPanel->cleanContent(); QList aWidgets; - if (!module()->createWidgets(theOperation, aWidgets)) { - QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation(); + QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation(); + if (!module()->createWidgets(aFOperation->feature(), aXmlRepr, aWidgets)) { ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myModuleConnector); aFactory.createWidget(myPropertyPanel->contentWidget()); aWidgets = aFactory.getModelWidgets(); @@ -745,6 +823,12 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation) #endif myErrorMgr->setPropertyPanel(myPropertyPanel); + if (Config_PropManager::boolean("Windows", "use_hide_faces_panel")) { + theOperation->setHideFacesVisible(myFacesPanel->isVisible()); + if (aFeatureInfo.get() && aFeatureInfo->isHideFacesPanel() && !myFacesPanel->isVisible()) + myFacesPanel->show(); + } + showPanel(myPropertyPanel); } //****************************************************** @@ -826,6 +910,11 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation) } } activateObjectsSelection(anObjects); + + if (Config_PropManager::boolean("Windows", "use_hide_faces_panel")) { + if (!theOperation->isHideFacesVisible()) + myFacesPanel->close(); + } } //****************************************************** @@ -972,18 +1061,47 @@ void XGUI_Workshop::openFile(const QString& theDirectory) #ifdef _DEBUG bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start"); if (aNewPart) { - - DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); int aSize = aRootDoc->size(ModelAPI_ResultPart::group()); if (aSize > 0 ) { - ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), 0); - ResultPartPtr aPart = std::dynamic_pointer_cast(aObject); + ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), 0); + ResultPartPtr aPart = std::dynamic_pointer_cast(anObject); if (aPart.get()) aPart->activate(); } } #endif + int anActivationId = + ModuleBase_Preferences::resourceMgr()->integerValue("General", "part_activation_study", -1); + int aSize = aRootDoc->size(ModelAPI_ResultPart::group()); + + if (anActivationId == 0 && aSize > 0) { + ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1); + ResultPartPtr aPart = std::dynamic_pointer_cast(anObject); + if (aPart.get()) { + aPart->activate(); + ModuleBase_Tools::setDisplaying(aPart); + } + } + else if (anActivationId == 1) { + for (int anIndex = 0; anIndex < aSize; ++anIndex) { + ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), anIndex); + ResultPartPtr aPart = std::dynamic_pointer_cast(anObject); + if (aPart.get()) { + aPart->activate(); + ModuleBase_Tools::setDisplaying(aPart); + + if (anIndex < aSize - 1) { + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation("Activation"); + aMgr->setActiveDocument(aMgr->moduleDocument()); + aMgr->finishOperation(); + updateCommandStatus(); + viewer()->update(); + } + } + } + } QApplication::restoreOverrideCursor(); } @@ -1002,6 +1120,8 @@ void XGUI_Workshop::onNew() QMdiSubWindow* aWnd = myMainWindow->viewer()->createView(); aWnd->showMaximized(); updateCommandStatus(); + PyConsole_Console* aConsole = myMainWindow->pythonConsole(); + connect(aConsole, SIGNAL(scriptLoaded()), SLOT(updateCommandStatus())); #endif myContextMenuMgr->connectViewer(); QApplication::restoreOverrideCursor(); @@ -1035,15 +1155,29 @@ void XGUI_Workshop::onPreferences() ModuleBase_Preferences::editPreferences(aModif); if (aModif.size() > 0) { QString aSection; - foreach (ModuleBase_Pref aPref, aModif) - { + foreach (ModuleBase_Pref aPref, aModif) { aSection = aPref.first; if (aSection == ModuleBase_Preferences::VIEWER_SECTION) { myMainWindow->viewer()->updateFromResources(); } else if (aSection == ModuleBase_Preferences::MENU_SECTION) { myMainWindow->menuObject()->updateFromResources(); } + else if (aSection == ModuleBase_Preferences::GENERAL_SECTION && aPref.second == "create_init_part") { + bool aCreate = ModuleBase_Preferences::resourceMgr()->booleanValue( + ModuleBase_Preferences::GENERAL_SECTION, "create_init_part", true); + Events_MessageBool aCreateMsg(Events_Loop::eventByName(EVENT_CREATE_PART_ON_START), aCreate); + aCreateMsg.send(); + } + } + std::vector aColor; + try { + aColor = Config_PropManager::color("Visualization", "selection_color"); } + catch (...) { + } + if (aColor.size() == 3) + displayer()->setSelectionColor(aColor); + displayer()->redisplayObjects(); } } @@ -1137,20 +1271,32 @@ void XGUI_Workshop::processUndoRedo(const ModuleBase_ActionType theActionType, i if (anActiveWidget->processAction(theActionType, aParam)) return; } + else + { + XGUI_FacesPanel * anFacePannel = facesPanel(); + if(ActionUndo == theActionType && anFacePannel->isActivePanel()) + { + anFacePannel->processUndo(); + return; + } + } // 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); + int aTimes = theTimes; SessionPtr aMgr = ModelAPI_Session::get(); if (aMgr->isOperation()) { XGUI_OperationMgr* aOpMgr = operationMgr(); /// this is important for nested operations /// when sketch operation is active, this condition is false and /// the sketch operation is not aborted - if (aOpMgr->canStopOperation(aOpMgr->currentOperation())) + if (aOpMgr->canStopOperation(aOpMgr->currentOperation())) { aOpMgr->abortOperation(aOpMgr->currentOperation()); + aTimes--; + } else { myDisplayer->enableUpdateViewer(isUpdateEnabled); @@ -1161,19 +1307,25 @@ void XGUI_Workshop::processUndoRedo(const ModuleBase_ActionType theActionType, i std::list anActionList = theActionType == ActionUndo ? aMgr->undoList() : aMgr->redoList(); std::list::const_iterator aIt = anActionList.cbegin(); - for (int i = 0; (i < theTimes) && (aIt != anActionList.cend()); ++i, ++aIt) { + for (int i = 0; (i < aTimes) && (aIt != anActionList.cend()); ++i, ++aIt) { if (theActionType == ActionUndo) aMgr->undo(); else aMgr->redo(); - if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND) + if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND || + QString((*aIt).c_str()) == MOVE_TO_END_SPLIT_COMMAND) myObjectBrowser->rebuildDataTree(); } operationMgr()->updateApplyOfOperations(); facesPanel()->reset(true); updateCommandStatus(); + QObjectPtrList aList = myDisplayer->displayedObjects(); + foreach(ObjectPtr aObj, aList) { + module()->customizePresentation(aObj, myDisplayer->getAISObject(aObj)); + } + // unblock the viewer update functionality and make update on purpose myDisplayer->enableUpdateViewer(isUpdateEnabled); myDisplayer->updateViewer(); @@ -1226,6 +1378,71 @@ void XGUI_Workshop::onWidgetObjectUpdated() myDisplayer->updateViewer(); } +//****************************************************** +void XGUI_Workshop::onImportPart() +{ + if (abortAllOperations()) { + ModuleBase_OperationFeature* anImportPartOp = dynamic_cast( + module()->createOperation(ExchangePlugin_ImportPart::ID())); + anImportPartOp->setHelpFileName(QString("ExchangePlugin") + QDir::separator() + + "importFeature.html"); + myPropertyPanel->updateApplyPlusButton(anImportPartOp->feature()); + operationMgr()->startOperation(anImportPartOp); + } +} + +//****************************************************** +void XGUI_Workshop::onImportShape() +{ + if (abortAllOperations()) { + ModuleBase_OperationFeature* anImportOp = dynamic_cast( + module()->createOperation(ExchangePlugin_Import::ID())); + anImportOp->setHelpFileName(QString("ExchangePlugin") + QDir::separator() + + "importFeature.html"); + myPropertyPanel->updateApplyPlusButton(anImportOp->feature()); + operationMgr()->startOperation(anImportOp); + } +} + +//****************************************************** +void XGUI_Workshop::onImportImage() +{ + if (abortAllOperations()) { + ModuleBase_OperationFeature* anImportOp = dynamic_cast( + module()->createOperation(ExchangePlugin_Import_Image::ID())); + anImportOp->setHelpFileName(QString("ExchangePlugin") + QDir::separator() + + "importFeature.html"); + myPropertyPanel->updateApplyPlusButton(anImportOp->feature()); + operationMgr()->startOperation(anImportOp); + } +} + +//****************************************************** +void XGUI_Workshop::onExportShape() +{ + if (abortAllOperations()) { + ModuleBase_OperationFeature* anExportOp = dynamic_cast( + module()->createOperation(ExchangePlugin_ExportFeature::ID())); + anExportOp->setHelpFileName(QString("ExchangePlugin") + QDir::separator() + + "exportFeature.html"); + myPropertyPanel->updateApplyPlusButton(anExportOp->feature()); + operationMgr()->startOperation(anExportOp); + } +} + +//****************************************************** +void XGUI_Workshop::onExportPart() +{ + if (abortAllOperations()) { + ModuleBase_OperationFeature* anExportPartOp = dynamic_cast( + module()->createOperation(ExchangePlugin_ExportPart::ID())); + anExportPartOp->setHelpFileName(QString("ExchangePlugin") + QDir::separator() + + "exportFeature.html"); + myPropertyPanel->updateApplyPlusButton(anExportPartOp->feature()); + operationMgr()->startOperation(anExportPartOp); + } +} + //****************************************************** ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule) { @@ -1399,6 +1616,7 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) myObjectBrowser->initialize(myModule->rootNode()); myModule->customizeObjectBrowser(myObjectBrowser); aObjDock->setWidget(myObjectBrowser); + aObjDock->setObjectName("Object browser"); connect(myObjectBrowser, SIGNAL(sizeChanged()), SLOT(onDockSizeChanged())); @@ -1426,14 +1644,14 @@ void XGUI_Workshop::createDockWidgets() hidePanel(myPropertyPanel); ///addSelector(new XGUI_FacesPanelSelector(myFacesPanel)); myFacesPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); connect(myFacesPanel, SIGNAL(closed()), myFacesPanel, SLOT(onClosed())); - myInspectionPanel = new XGUI_InspectionPanel(aDesktop, mySelector); + myInspectionPanel = new XGUI_InspectionPanel(aDesktop, this); myInspectionPanel->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); aDesktop->addDockWidget(Qt::RightDockWidgetArea, myInspectionPanel); @@ -1509,17 +1727,20 @@ void XGUI_Workshop::showPanel(QDockWidget* theDockWidget) // in order to operation manager could process key events of the panel. // otherwise they are ignored. It happens only if the same(activateWindow) is // not happened by property panel activation(e.g. resume operation of Sketch) - ModuleBase_Tools::setFocus(theDockWidget, "XGUI_Workshop::showPanel()"); + //ModuleBase_Tools::setFocus(theDockWidget, "XGUI_Workshop::showPanel()"); } //****************************************************** void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget) { - if (theDockWidget && theDockWidget == myPropertyPanel) { + if (!theDockWidget) return; + + if (theDockWidget == myPropertyPanel) { QAction* aViewAct = theDockWidget->toggleViewAction(); ///setEnabled(false); } + theDockWidget->hide(); // the property panel is active window of the desktop, when it is @@ -1563,37 +1784,56 @@ ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const //************************************************************** void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) { - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); if (theId == "DELETE_CMD") deleteObjects(); else if (theId == "CLEAN_HISTORY_CMD") cleanHistory(); - else if (theId == "MOVE_CMD") - moveObjects(); + else if (theId == "MOVE_CMD" || theId == "MOVE_SPLIT_CMD") + moveObjects(theId == "MOVE_SPLIT_CMD"); + else if (theId == "RECOVER_CMD") + recoverFeature(); else if (theId == "COLOR_CMD") - changeColor(aObjects); + changeColor(anObjects); + else if (theId == "AUTOCOLOR_CMD") + changeAutoColor(anObjects); + else if (theId == "ISOLINES_CMD") + changeIsoLines(anObjects); + else if (theId == "SHOW_ISOLINES_CMD") { + foreach(ObjectPtr aObj, anObjects) { + ResultPtr aResult = std::dynamic_pointer_cast(aObj); + if (aResult.get()) + ModelAPI_Tools::showIsoLines(aResult, !ModelAPI_Tools::isShownIsoLines(aResult)); + } + mySelector->clearSelection(); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } else if (theId == "DEFLECTION_CMD") - changeDeflection(aObjects); + changeDeflection(anObjects); else if (theId == "TRANSPARENCY_CMD") - changeTransparency(aObjects); + changeTransparency(anObjects); else if (theId == "SHOW_CMD") { - showObjects(aObjects, true); + showObjects(anObjects, true); mySelector->updateSelectionBy(ModuleBase_ISelection::Browser); updateCommandStatus(); } else if (theId == "HIDE_CMD") { - showObjects(aObjects, false); + showObjects(anObjects, false); updateCommandStatus(); } else if (theId == "SHOW_ONLY_CMD") { - showOnlyObjects(aObjects); + showOnlyObjects(anObjects); mySelector->updateSelectionBy(ModuleBase_ISelection::Browser); updateCommandStatus(); } else if (theId == "SHADING_CMD") - setDisplayMode(aObjects, XGUI_Displayer::Shading); + setDisplayMode(anObjects, XGUI_Displayer::Shading); else if (theId == "WIREFRAME_CMD") - setDisplayMode(aObjects, XGUI_Displayer::Wireframe); + setDisplayMode(anObjects, XGUI_Displayer::Wireframe); + else if (theId == "SHOW_EDGES_DIRECTION_CMD") + toggleEdgesDirection(anObjects); + else if (theId == "BRING_TO_FRONT_CMD") + toggleBringToFront(anObjects); else if (theId == "HIDEALL_CMD") { QObjectPtrList aList = myDisplayer->displayedObjects(); foreach (ObjectPtr aObj, aList) { @@ -1630,9 +1870,9 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) setViewerSelectionMode(ModuleBase_ResultPrs::Sel_Result); setViewerSelectionMode(TopAbs_COMPSOLID); } else if (theId == "SHOW_RESULTS_CMD") { - highlightResults(aObjects); + highlightResults(anObjects); } else if (theId == "SHOW_FEATURE_CMD") { - highlightFeature(aObjects); + highlightFeature(anObjects); } else if (theId == "SET_VIEW_NORMAL_CMD") { setNormalView(); } else if (theId == "SET_VIEW_INVERTEDNORMAL_CMD") { @@ -1640,7 +1880,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) } #ifdef TINSPECTOR else if (theId == "TINSPECTOR_VIEW") { - Handle(CDF_Application) anApplication = CDF_Session::CurrentSession()->CurrentApplication(); + std::shared_ptr aSession = + std::dynamic_pointer_cast(ModelAPI_Session::get()); + + Handle(TDocStd_Application) anApplication = aSession->application(); if (!anApplication.IsNull()) { if (!MyTCommunicator) @@ -1756,7 +1999,7 @@ bool XGUI_Workshop::prepareForDisplay(const std::set& theObjects) con if (!facesPanel()->isObjectHiddenByPanel(*anObjectsIt)) continue; aHiddenObjects.insert(*anObjectsIt); - aHiddenObjectNames.append((*anObjectsIt)->data()->name().c_str()); + aHiddenObjectNames.append(QString::fromStdWString((*anObjectsIt)->data()->name())); } if (aHiddenObjects.empty()) // in parameter objects there are no hidden objects in hide face return true; @@ -1781,10 +2024,14 @@ void XGUI_Workshop::deleteObjects() // allow the module to delete objects, do nothing if it has succeed if (aModule->deleteObjects()) { updateCommandStatus(); + myDisplayer->updateViewer(); return; } QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + if (anObjects.isEmpty()) + return; + if (!abortAllOperations()) return; @@ -1794,8 +2041,9 @@ void XGUI_Workshop::deleteObjects() bool hasCompositeOwner = false; bool hasResultInHistory = false; bool hasFolder = false; + bool hasGroupsOnly = false; ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasCompositeOwner, - hasResultInHistory, hasFolder); + hasResultInHistory, hasFolder, hasGroupsOnly); if (!(hasResult || hasFeature || hasParameter || hasFolder)) return; @@ -1807,7 +2055,7 @@ void XGUI_Workshop::deleteObjects() ResultConstructionPtr aConstr = std::dynamic_pointer_cast(aObj); FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); if (aFeature) { - notDelete = (!aFeature->isInHistory()) && aConstr->isInfinite(); + notDelete = (!aFeature->isInHistory()) && (aConstr && aConstr->isInfinite()); if (notDelete) { anObjects.removeAll(aObj); aIt--; @@ -1826,7 +2074,7 @@ void XGUI_Workshop::deleteObjects() bool aDone = false; QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1"; aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", ")); - ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module()); + ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription, module()); operationMgr()->startOperation(anOpAction); @@ -1958,7 +2206,7 @@ void XGUI_Workshop::cleanHistory() if (!anUnusedObjects.empty()) { QStringList aNames; foreach (const FeaturePtr& aFeature, anUnusedObjects) { - aNames.append(aFeature->name().c_str()); + aNames.append(QString::fromStdWString(aFeature->name())); } aNames.sort(); QString anUnusedNames = aNames.join(", "); @@ -1983,7 +2231,7 @@ void XGUI_Workshop::cleanHistory() // 1. start operation aDescription += "by deleting of " + aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", ")); - ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module()); + ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription, module()); operationMgr()->startOperation(anOpAction); // WORKAROUND, should be done before each object remove, if it presents in XGUI_DataModel tree @@ -2026,7 +2274,7 @@ bool compareFeature(const FeaturePtr& theF1, const FeaturePtr& theF2) { DocumentPtr aDoc = theF1->document(); return aDoc->index(theF1) < aDoc->index(theF2); } -void XGUI_Workshop::moveObjects() +void XGUI_Workshop::moveObjects(const bool theSplit) { if (!abortAllOperations()) return; @@ -2043,7 +2291,7 @@ void XGUI_Workshop::moveObjects() if (!XGUI_Tools::canRemoveOrRename(desktop(), aFeatures)) return; - QString anActionId = "MOVE_CMD"; + QString anActionId = theSplit ? "MOVE_CMD" : "MOVE_SPLIT_CMD"; QString aDescription = contextMenuMgr()->action(anActionId)->text(); aMgr->startOperation(aDescription.toStdString()); @@ -2059,11 +2307,21 @@ void XGUI_Workshop::moveObjects() if (!aFeature.get() || !myModule->canApplyAction(aFeature, anActionId)) continue; - anActiveDocument->moveFeature(aFeature, aCurrentFeature); + anActiveDocument->moveFeature(aFeature, aCurrentFeature, theSplit); aCurrentFeature = anActiveDocument->currentFeature(true); } aMgr->finishOperation(); updateCommandStatus(); + myViewerProxy->update(); +} + +void XGUI_Workshop::recoverFeature() +{ + if (!abortAllOperations()) + return; + + static const QString RECOVER_OP_NAME = "Recover"; + module()->launchOperation(RECOVER_OP_NAME, false); } //************************************************************** @@ -2110,8 +2368,8 @@ std::list allFeatures(const DocumentPtr& theDocument) std::dynamic_pointer_cast(aResult); if (aResultPart.get() && aResultPart->partDoc().get()) { // Recursion - std::list anAllFeatures = allFeatures(aResultPart->partDoc()); - aResultList.insert(aResultList.end(), anAllFeatures.begin(), anAllFeatures.end()); + std::list aPartFeatures = allFeatures(aResultPart->partDoc()); + aResultList.insert(aResultList.end(), aPartFeatures.begin(), aPartFeatures.end()); } } @@ -2129,9 +2387,9 @@ std::list toCurrentFeatures(const ObjectPtr& theObject) DocumentPtr aDocument = theObject->document(); std::list anAllFeatures = allFeatures(aDocument); // find the object iterator - std::list::iterator aObjectIt = + std::list::iterator anObjectIt = std::find(anAllFeatures.begin(), anAllFeatures.end(), theObject); - if (aObjectIt == anAllFeatures.end()) + if (anObjectIt == anAllFeatures.end()) return aResult; // find the current feature iterator std::list::iterator aCurrentIt = @@ -2139,14 +2397,14 @@ std::list toCurrentFeatures(const ObjectPtr& theObject) if (aCurrentIt == anAllFeatures.end()) return aResult; // check the right order - if (std::distance(aObjectIt, anAllFeatures.end()) <= + if (std::distance(anObjectIt, anAllFeatures.end()) <= std::distance(aCurrentIt, anAllFeatures.end())) return aResult; // exclude the object - std::advance(aObjectIt, 1); + std::advance(anObjectIt, 1); // include the current feature std::advance(aCurrentIt, 1); - return std::list(aObjectIt, aCurrentIt); + return std::list(anObjectIt, aCurrentIt); } //****************************************************** @@ -2154,55 +2412,80 @@ bool XGUI_Workshop::canMoveFeature() { QString anActionId = "MOVE_CMD"; - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); QObjectPtrList aValidatedObjects; - foreach (ObjectPtr aObject, aObjects) { - if (!myModule->canApplyAction(aObject, anActionId)) + std::set aSelectedFeatures; + foreach (ObjectPtr anObject, anObjects) { + if (!myModule->canApplyAction(anObject, anActionId)) continue; // To be moved feature should be in active document - if (aObject->document() != ModelAPI_Session::get()->activeDocument()) + if (anObject->document() != ModelAPI_Session::get()->activeDocument()) continue; - aValidatedObjects.append(aObject); + aValidatedObjects.append(anObject); + FeaturePtr aFeat = std::dynamic_pointer_cast(anObject); + aSelectedFeatures.insert(aFeat); } - if (aValidatedObjects.size() != aObjects.size()) - aObjects = aValidatedObjects; + if (aValidatedObjects.size() != anObjects.size()) + anObjects = aValidatedObjects; - bool aCanMove = !aObjects.empty(); + bool aCanMove = !anObjects.empty(); - QObjectPtrList::const_iterator anIt = aObjects.begin(), aLast = aObjects.end(); + QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); for (; anIt != aLast && aCanMove; anIt++) { - ObjectPtr aObject = *anIt; - if (!aObject.get() || !aObject->data().get() || !aObject->data()->isValid()) { + ObjectPtr anObject = *anIt; + if (!anObject.get() || !anObject->data().get() || !anObject->data()->isValid()) { aCanMove = false; break; } - FeaturePtr aFeat = std::dynamic_pointer_cast(aObject); - // only groups can be moved to the end for now (#2451) - if (aFeat.get() && aFeat->getKind() != "Group") { - aCanMove = false; - break; + FeaturePtr aFeat = std::dynamic_pointer_cast(anObject); + // only groups can be moved to the end for now (#2451 old_id, #23105 tuleap id) + // and groups created by other groups (#34401) + if (aFeat.get()) { + std::string aKindOfFeature = aFeat->getKind(); + if (aKindOfFeature != "Group" && + aKindOfFeature != "GroupSubstraction" && + aKindOfFeature != "GroupAddition" && + aKindOfFeature != "GroupIntersection") { + aCanMove = false; + break; + } } + // Check that the feature can be moved due to its dependencies + // i.e. Check that there are no features between the moved one and its destination + // with references to it + // Details on #21340 (old_id #660) + // NOTE: we can ignore dependend features, if they are also moved! + // 1. Get features placed between selected and current in the document - std::list aFeaturesBetween = toCurrentFeatures(aObject); - // if aFeaturesBetween is empty it means wrong order or aObject is the current feature + std::list aFeaturesBetween = toCurrentFeatures(anObject); + // if aFeaturesBetween is empty it means wrong order or anObject is the current feature if (aFeaturesBetween.empty()) aCanMove = false; else { std::set aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end()); // 2. Get all reference features to the selected object in the document std::set aRefFeatures; - ModuleBase_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures); + ModuleBase_Tools::refsToFeatureInFeatureDocument(anObject, aRefFeatures); if (aRefFeatures.empty()) continue; else { - // 3. Find any placed features in all reference features + // 3.1. Check, if any reference feature is going to be moved, too. + // If it is, we can ignore its dependency in our subsequent check (3.2) + std::set aNoMoveRefFeatures; + std::set_difference(aRefFeatures.begin(), aRefFeatures.end(), + aSelectedFeatures.begin(), aSelectedFeatures.end(), + std::inserter(aNoMoveRefFeatures, aNoMoveRefFeatures.begin())); + if (aNoMoveRefFeatures.empty()) + continue; + + // 3.2. Find any placed features in all remaining (non-moved) reference features std::set aIntersectionFeatures; - std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(), + std::set_intersection(aNoMoveRefFeatures.begin(), aNoMoveRefFeatures.end(), aPlacedFeatures.begin(), aPlacedFeatures.end(), std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin())); - // 4. Return false if any reference feature is placed before current feature + // 4. Return false if any (non-moved) reference feature is placed before current feature if (!aIntersectionFeatures.empty()) aCanMove = false; } @@ -2235,7 +2518,7 @@ bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const if (theActionName == "COLOR_CMD" || theActionName == "DEFLECTION_CMD" || theActionName == "TRANSPARENCY_CMD") { - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); std::set aTypes; aTypes.insert(ModelAPI_ResultGroup::group()); @@ -2243,29 +2526,41 @@ bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const aTypes.insert(ModelAPI_ResultBody::group()); aTypes.insert(ModelAPI_ResultPart::group()); - return hasResults(aObjects, aTypes); + return hasResults(anObjects, aTypes); + } + if (theActionName == "AUTOCOLOR_CMD") { + + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + + std::set aTypes; + aTypes.insert(ModelAPI_ResultGroup::group()); + + return hasResults(anObjects, aTypes); } return false; } -//****************************************************** -void setColor(ResultPtr theResult, const std::vector& theColor) -{ - if (!theResult.get()) - return; - AttributeIntArrayPtr aColorAttr = theResult->data()->intArray(ModelAPI_Result::COLOR_ID()); - if (aColorAttr.get() != NULL) { - if (!aColorAttr->size()) { - aColorAttr->setSize(3); +//************************************************************** +void getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid, + std::vector& theColor) +{ + theColor.clear(); + // get default color from the preferences manager for the given result + if (theColor.empty()) { + std::string aSection, aName, aDefault; + theObject->colorConfigInfo(aSection, aName, aDefault); + if (!aSection.empty() && !aName.empty()) { + theColor = Config_PropManager::color(aSection, aName); } - aColorAttr->setValue(0, theColor[0]); - aColorAttr->setValue(1, theColor[1]); - aColorAttr->setValue(2, theColor[2]); } - static const Events_ID kRedisplayEvent = - Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(theResult, kRedisplayEvent); + if (!isEmptyColorValid && theColor.empty()) { + // all AIS objects, where the color is not set, are in black. + // The color should be defined in XML or set in the attribute + theColor = Config_PropManager::color("Visualization", "object_default_color"); + Events_InfoMessage("XGUI_CustomPrs", + "A default color is not defined in the preferences for this kind of result").send(); + } } //************************************************************** @@ -2280,20 +2575,17 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get()) { ModelAPI_Tools::getColor(aResult, aColor); - } - else { - // TODO: remove the obtaining a color from the AIS object - // this does not happen never because: - // 1. The color can be changed only on results - // 2. The result can be not visualized in the viewer(e.g. Origin Construction) - AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); - if (anAISObj.get()) { - aColor.resize(3); - anAISObj->getColor(aColor[0], aColor[1], aColor[2]); + if (aColor.empty()) { + AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); + if (anAISObj.get()) { + aColor.resize(3); + anAISObj->getColor(aColor[0], aColor[1], aColor[2]); + } + } + if (aColor.empty()) { + getDefaultColor(aResult, false, aColor); } } - if (!aColor.empty()) - break; } if (aColor.size() != 3) return; @@ -2313,6 +2605,7 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) // 3. abort the previous operation and start a new one SessionPtr aMgr = ModelAPI_Session::get(); QString aDescription = contextMenuMgr()->action("COLOR_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); // 4. set the value to all results @@ -2325,42 +2618,66 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) std::list allRes; ModelAPI_Tools::allSubs(aBodyResult, allRes); for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { - setColor(*aRes, !isRandomColor ? aColorResult : aDlg->getRandomColor()); + ModelAPI_Tools::setColor(*aRes, !isRandomColor ? aColorResult : aDlg->getRandomColor()); } } - setColor(aResult, !isRandomColor ? aColorResult : aDlg->getRandomColor()); + ModelAPI_Tools::setColor(aResult, !isRandomColor ? aColorResult : aDlg->getRandomColor()); } } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); aMgr->finishOperation(); updateCommandStatus(); + myViewerProxy->update(); } //************************************************************** -void setDeflection(ResultPtr theResult, const double theDeflection) +void XGUI_Workshop::changeAutoColor(const QObjectPtrList& theObjects) { - if (!theResult.get()) - return; + if (!abortAllOperations()) + return; - AttributeDoublePtr aDeflectionAttr = theResult->data()->real(ModelAPI_Result::DEFLECTION_ID()); - if (aDeflectionAttr.get() != NULL) - aDeflectionAttr->setValue(theDeflection); - static const Events_ID kRedisplayEvent = - Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(theResult, kRedisplayEvent); -} + std::vector aColor; -//************************************************************** -void setTransparency(ResultPtr theResult, double theTransparency) -{ - if (!theResult.get()) - return; + // abort the previous operation and start a new one + SessionPtr aMgr = ModelAPI_Session::get(); + QString aDescription = contextMenuMgr()->action("AUTOCOLOR_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); - AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); - if (anAttribute.get() != NULL) - anAttribute->setValue(theTransparency); - static const Events_ID kRedisplayEvent = - Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - ModelAPI_EventCreator::get()->sendUpdated(theResult, kRedisplayEvent); + if (Config_PropManager::getAutoColorStatus()) { + contextMenuMgr()->action("AUTOCOLOR_CMD")->setText(tr("Auto color")); + Config_PropManager::setAutoColorStatus(false); + ModelAPI_Tools::findRandomColor(aColor, true); + } else { + // set the value to all results + foreach (ObjectPtr anObj, theObjects) { + DocumentPtr aDocument = anObj->document(); + std::list anAllFeatures = allFeatures(aDocument); + // find the object iterator + std::list::iterator anObjectIt = anAllFeatures.begin(); + for (; anObjectIt != anAllFeatures.end(); ++ anObjectIt) { + FeaturePtr aFeature = *anObjectIt; + if (aFeature.get()) { + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + std::list >::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) { + ResultPtr aGroupResult = *aIt; + if (aGroupResult.get() && + aGroupResult->groupName() == ModelAPI_ResultGroup::group()) { + ModelAPI_Tools::findRandomColor(aColor); + ModelAPI_Tools::setColor(aGroupResult, aColor); + } + } + } + } + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aMgr->finishOperation(); + updateCommandStatus(); + myViewerProxy->update(); + contextMenuMgr()->action("AUTOCOLOR_CMD")->setText(tr("Disable auto color")); + Config_PropManager::setAutoColorStatus(true); + } } //************************************************************** @@ -2373,13 +2690,42 @@ void setTransparency(double theTransparency, const QObjectPtrList& theObjects) if (aBodyResult.get() != NULL) { // change property for all sub-solids std::list allRes; ModelAPI_Tools::allSubs(aBodyResult, allRes); - for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { - setTransparency(*aRes, theTransparency); + std::list::iterator aRes; + for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + ModelAPI_Tools::setTransparency(*aRes, theTransparency); } } - setTransparency(aResult, theTransparency); + ModelAPI_Tools::setTransparency(aResult, theTransparency); + } + } +} + +//************************************************************** +double getDefaultDeflection(const ObjectPtr& theObject) +{ + double aDeflection = -1; + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + bool isConstruction = false; + + std::string aResultGroup = aResult->groupName(); + if (aResultGroup == ModelAPI_ResultConstruction::group()) + isConstruction = true; + else if (aResultGroup == ModelAPI_ResultBody::group()) { + GeomShapePtr aGeomShape = aResult->shape(); + if (aGeomShape.get()) { + // if the shape could not be exploded on faces, it contains only wires, edges, and vertices + // correction of deviation for them should not influence to the application performance + GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE); + isConstruction = !anExp.more(); + } } + if (isConstruction) + aDeflection = Config_PropManager::real("Visualization", "construction_deflection"); + else + aDeflection = Config_PropManager::real("Visualization", "body_deflection"); } + return aDeflection; } //************************************************************** @@ -2393,6 +2739,8 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get()) { aDeflection = ModelAPI_Tools::getDeflection(aResult); + if (aDeflection < 0) + aDeflection = getDefaultDeflection(aResult); } else { // TODO: remove the obtaining a property from the AIS object @@ -2435,16 +2783,23 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) std::list allRes; ModelAPI_Tools::allSubs(aBodyResult, allRes); for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { - setDeflection(*aRes, aDeflection); + ModelAPI_Tools::setDeflection(*aRes, aDeflection); } } - setDeflection(aResult, aDeflection); + ModelAPI_Tools::setDeflection(aResult, aDeflection); } } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); aMgr->finishOperation(); updateCommandStatus(); } +//************************************************************** +double getDefaultTransparency(const ResultPtr& theResult) +{ + return Config_PropManager::integer("Visualization", "shaper_default_transparency") / 100.; +} + //************************************************************** void XGUI_Workshop::changeTransparency(const QObjectPtrList& theObjects) { @@ -2456,6 +2811,8 @@ void XGUI_Workshop::changeTransparency(const QObjectPtrList& theObjects) ResultPtr aResult = std::dynamic_pointer_cast(anObject); if (aResult.get()) { aCurrentValue = ModelAPI_Tools::getTransparency(aResult); + if (aCurrentValue < 0) + aCurrentValue = getDefaultTransparency(aResult); } if (aCurrentValue > 0) break; @@ -2502,7 +2859,11 @@ void XGUI_Workshop::onTransparencyValueChanged() QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); setTransparency(aTransparencyWidget->getValue(), anObjects); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + static const Events_ID kRedisplayEvent = + Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + Events_Loop::loop()->flush(kRedisplayEvent); + + myViewerProxy->update(); } @@ -2573,11 +2934,11 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) //************************************************************** void XGUI_Workshop::updateColorScaleVisibility() { - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); - viewer()->setColorScaleShown(false); - if (aObjects.size() == 1) { + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + myViewerProxy->setColorScaleShown(false); + if (anObjects.size() == 1) { FieldStepPtr aStep = - std::dynamic_pointer_cast(aObjects.first()); + std::dynamic_pointer_cast(anObjects.first()); if (aStep.get() && myDisplayer->isVisible(aStep)) { AISObjectPtr aAisPtr = myDisplayer->getAISObject(aStep); Handle(AIS_InteractiveObject) aIO = aAisPtr->impl(); @@ -2597,7 +2958,7 @@ void XGUI_Workshop::updateColorScaleVisibility() aPrs->dataRange(aMin, aMax); myViewerProxy->setColorScaleRange(aMin, aMax); } - myViewerProxy->setColorScaleTitle(aStep->name().c_str()); + myViewerProxy->setColorScaleTitle(QString::fromStdWString(aStep->name())); myViewerProxy->setColorScaleShown(true); } } @@ -2605,6 +2966,55 @@ void XGUI_Workshop::updateColorScaleVisibility() } } +//************************************************************** +void XGUI_Workshop::updateGroupsText() +{ + ModuleBase_IViewer::TextColor aText; + + int aSize = 10; + SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr(); + if (aResMgr->booleanValue("Viewer", "group_names_display")) { + // the first item in the TextColor list is font name -> text color + QColor aTextColor = aResMgr->colorValue("Viewer", "group_names_color"); + std::vector aTextCV; + aTextCV.push_back(aTextColor.red()); + aTextCV.push_back(aTextColor.green()); + aTextCV.push_back(aTextColor.blue()); + QString aFontName = aResMgr->stringValue("Viewer", "group_names_font"); + aText.push_back(std::pair >(aFontName.toStdWString(), aTextCV)); + aSize = aResMgr->integerValue("Viewer", "group_names_size"); + + DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument(); + int aNbGroups = aDoc->size(ModelAPI_ResultGroup::group()); + for (int aGIndex = 0; aGIndex < aNbGroups; aGIndex++) + { + ResultGroupPtr aGroup = std::dynamic_pointer_cast( + aDoc->object(ModelAPI_ResultGroup::group(), aGIndex)); + if (aGroup.get() && !aGroup->isDisabled() && aGroup->isDisplayed()) + { + std::vector aColor; + ModelAPI_Tools::getColor(aGroup, aColor); + if (aColor.empty()) + { // default groups colors + std::string aSection, aName, aDefault; + aGroup->colorConfigInfo(aSection, aName, aDefault); + if (!aSection.empty() && !aName.empty()) { + aColor = Config_PropManager::color(aSection, aName); + } + } + if (aColor.empty()) + { + aColor.push_back(150.); + aColor.push_back(150.); + aColor.push_back(150.); + } + aText.push_back(std::pair >(aGroup->data()->name(), aColor)); + } + } + } + myViewerProxy->setText(aText, aSize); +} + //************************************************************** void XGUI_Workshop::setNormalView(bool toInvert) @@ -2614,7 +3024,7 @@ void XGUI_Workshop::setNormalView(bool toInvert) GeomShapePtr aPlanarFace; foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) { GeomShapePtr aShape = aPrs->shape(); - if (aShape.get() && aShape->isPlanar()) { + if (aShape.get() && aShape->isFace() && aShape->isPlanar()) { aPlanarFace = aShape; break; } @@ -2631,7 +3041,6 @@ void XGUI_Workshop::setNormalView(bool toInvert) aFace->computeSize(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); Handle(V3d_View) aView = myViewerProxy->activeView(); - double aScale = aView->Scale(); aView->SetAt(aPos->x(), aPos->y(), aPos->z()); aView->SetProj(aNormal->x(), aNormal->y(), aNormal->z()); Bnd_Box aBox; @@ -2644,7 +3053,7 @@ void XGUI_Workshop::setNormalView(bool toInvert) void XGUI_Workshop::registerValidators() const { SessionPtr aMgr = ModelAPI_Session::get(); - ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + MAYBE_UNUSED ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); } //************************************************************** @@ -2684,6 +3093,49 @@ void XGUI_Workshop::setDisplayMode(const QObjectPtrList& theList, int theMode) myDisplayer->updateViewer(); } +//************************************************************** +void XGUI_Workshop::toggleEdgesDirection(const QObjectPtrList& theList) +{ + foreach(ObjectPtr anObj, theList) { + ResultPtr aResult = std::dynamic_pointer_cast(anObj); + if (aResult.get() != NULL) + { + bool aToShow = !ModelAPI_Tools::isShowEdgesDirection(aResult); + ResultBodyPtr aBodyResult = std::dynamic_pointer_cast(aResult); + if (aBodyResult.get() != NULL) { // change property for all sub-solids + std::list allRes; + ModelAPI_Tools::allSubs(aBodyResult, allRes); + std::list::iterator aRes; + for (aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + ModelAPI_Tools::showEdgesDirection(*aRes, aToShow); + myDisplayer->redisplay(*aRes, false); + } + } + ModelAPI_Tools::showEdgesDirection(aResult, aToShow); + myDisplayer->redisplay(anObj, false); + } + } + if (theList.size() > 0) + myDisplayer->updateViewer(); +} + +//************************************************************** +void XGUI_Workshop::toggleBringToFront(const QObjectPtrList& theList) +{ + // Toggle the "BringToFront" state of all objects in the list + foreach(ObjectPtr anObj, theList) { + ResultPtr aResult = std::dynamic_pointer_cast(anObj); + if (aResult.get() != NULL) + { + bool aBringToFront = !ModelAPI_Tools::isBringToFront(aResult); + ModelAPI_Tools::bringToFront(aResult, aBringToFront); + myDisplayer->redisplay(anObj, false); + } + } + if (theList.size() > 0) + myDisplayer->updateViewer(); +} + //************************************************************** void XGUI_Workshop::closeDocument() { @@ -2787,6 +3239,8 @@ void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc, int aSize = theDoc->numInternalFeatures(); for (int i = 0; i < aSize; i++) { aFeature = theDoc->internalFeature(i); + if (!aFeature.get()) + continue; const std::list& aResults = aFeature->results(); std::list::const_iterator aIt; aFeature->setDisplayed(false); @@ -2890,10 +3344,10 @@ void XGUI_Workshop::highlightFeature(const QObjectPtrList& theObjects) void XGUI_Workshop::insertFeatureFolder() { - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); - if (aObjects.isEmpty()) + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + if (anObjects.isEmpty()) return; - ObjectPtr aObj = aObjects.first(); + ObjectPtr aObj = anObjects.first(); FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); if (aFeature.get() == NULL) return; @@ -2966,12 +3420,12 @@ void XGUI_Workshop::onAutoApply() SessionPtr aMgr = ModelAPI_Session::get(); bool isBlocked = aMgr->isAutoUpdateBlocked(); aMgr->blockAutoUpdate(!isBlocked); + myDisplayer->updateViewer(); } void XGUI_Workshop::updateAutoComputeState() { SessionPtr aMgr = ModelAPI_Session::get(); - bool isComputeBlocked = aMgr->isAutoUpdateBlocked(); #ifdef HAVE_SALOME // QAction* aUpdateCmd; // QList aCommands = mySalomeConnector->commandList(); @@ -2984,6 +3438,7 @@ void XGUI_Workshop::updateAutoComputeState() // aUpdateCmd->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") : // QIcon(":pictures/autoapply_start.png")); #else + bool isComputeBlocked = aMgr->isAutoUpdateBlocked(); AppElements_MainMenu* aMenuBar = myMainWindow->menuObject(); AppElements_Command* aUpdateCmd = aMenuBar->feature("AUTOCOMPUTE_CMD"); aUpdateCmd->button()->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") : @@ -3023,3 +3478,66 @@ void XGUI_Workshop::deactivateCurrentSelector() { myActiveControlMgr->deactivateSelector(myActiveControlMgr->activeSelector()); } + +void XGUI_Workshop::changeIsoLines(const QObjectPtrList& theObjects) +{ + if (theObjects.isEmpty()) + return; + + QList aResultList; + ResultPtr aRes; + foreach(ObjectPtr aObj, theObjects) { + aRes = std::dynamic_pointer_cast(aObj); + if (aRes.get()) + aResultList.append(aRes); + } + + std::vector aValues; + bool isVisible; + if (aResultList.size() == 1) { + ResultPtr aResult = aResultList.first(); + if (aResult.get()) + ModelAPI_Tools::getIsoLines(aResult, isVisible, aValues); + else + return; + } + if (aValues.size() == 0) { + aValues.push_back(1); + aValues.push_back(1); + } + + if (!abortAllOperations()) + return; + + XGUI_PropertyDialog aDlg(desktop()); + aDlg.setWindowTitle(tr("Number of Iso-lines")); + + QWidget* aIsosWgt = new QWidget(&aDlg); + QFormLayout* aLayout = new QFormLayout(aIsosWgt); + ModuleBase_Tools::adjustMargins(aLayout); + aDlg.setContent(aIsosWgt); + + QSpinBox* aUNb = new QSpinBox(&aDlg); + aUNb->setValue(aValues[0]); + aLayout->addRow("U:", aUNb); + + QSpinBox* aVNb = new QSpinBox(&aDlg); + aVNb->setValue(aValues[1]); + aLayout->addRow("V:", aVNb); + + if (aDlg.exec() == QDialog::Accepted) { + SessionPtr aMgr = ModelAPI_Session::get(); + QString aDescription = contextMenuMgr()->action("ISOLINES_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); + + aValues[0] = aUNb->value(); + aValues[1] = aVNb->value(); + foreach(ResultPtr aResult, aResultList) { + ModelAPI_Tools::setIsoLines(aResult, aValues); + } + mySelector->clearSelection(); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aMgr->finishOperation(); + updateCommandStatus(); + } +}