1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "XGUI_Workshop.h"
22 #include "XGUI_ActionsMgr.h"
23 #include "XGUI_ActiveControlMgr.h"
24 #include "XGUI_ActiveControlSelector.h"
25 #include "XGUI_MenuMgr.h"
26 #include "XGUI_ColorDialog.h"
27 #include "XGUI_DeflectionDialog.h"
28 #include "XGUI_TransparencyWidget.h"
29 #include "XGUI_ContextMenuMgr.h"
30 #include "XGUI_Displayer.h"
31 #include "XGUI_ErrorDialog.h"
32 #include "XGUI_ErrorMgr.h"
33 #include "XGUI_FacesPanel.h"
34 #include "XGUI_FacesPanelSelector.h"
35 #include "XGUI_ModuleConnector.h"
36 #include "XGUI_ObjectsBrowser.h"
37 #include "XGUI_OperationMgr.h"
38 #include "XGUI_PropertyPanel.h"
39 #include "XGUI_PropertyPanelSelector.h"
40 #include "XGUI_PropertyDialog.h"
41 #include "XGUI_SalomeConnector.h"
42 #include "XGUI_Selection.h"
43 #include "XGUI_SelectionActivate.h"
44 #include "XGUI_SelectionMgr.h"
45 #include "XGUI_Tools.h"
46 #include "XGUI_ViewerProxy.h"
47 #include "XGUI_WorkshopListener.h"
48 #include <XGUI_HistoryMenu.h>
49 #include <XGUI_QtEvents.h>
50 #include <XGUI_DataModel.h>
51 #include <XGUI_InspectionPanel.h>
52 #include <XGUI_CompressFiles.h>
55 #include <AppElements_Button.h>
56 #include <AppElements_Command.h>
57 #include <AppElements_MainMenu.h>
58 #include <AppElements_MainWindow.h>
59 #include <AppElements_MenuGroupPanel.h>
60 #include <AppElements_Viewer.h>
61 #include <AppElements_Workbench.h>
64 #include <Config_XMLReader.h>
66 #include <ModelAPI_AttributeDocRef.h>
67 #include <ModelAPI_AttributeIntArray.h>
68 #include <ModelAPI_AttributeDouble.h>
69 #include <ModelAPI_AttributeString.h>
70 #include <ModelAPI_Data.h>
71 #include <ModelAPI_Events.h>
72 #include <ModelAPI_Feature.h>
73 #include <ModelAPI_Object.h>
74 #include <ModelAPI_ResultBody.h>
75 #include <ModelAPI_ResultConstruction.h>
76 #include <ModelAPI_ResultGroup.h>
77 #include <ModelAPI_ResultParameter.h>
78 #include <ModelAPI_ResultField.h>
79 #include <ModelAPI_Session.h>
80 #include <ModelAPI_Validator.h>
81 #include <ModelAPI_Tools.h>
82 #include <ModelAPI_ResultField.h>
83 #include <ModuleBase_IconFactory.h>
85 //#include <PartSetPlugin_Part.h>
87 #include <Events_Loop.h>
88 #include <Events_InfoMessage.h>
89 #include <Events_LongOp.h>
91 #include <ExchangePlugin_ExportPart.h>
92 #include <ExchangePlugin_ImportPart.h>
93 #include <ExchangePlugin_Import.h>
95 #include <GeomAPI_Pnt.h>
96 #include <GeomAPI_ShapeExplorer.h>
98 #include <ModuleBase_IModule.h>
99 #include <ModuleBase_IViewer.h>
100 #include <ModuleBase_Operation.h>
101 #include <ModuleBase_OperationDescription.h>
102 #include <ModuleBase_PageBase.h>
103 #include <ModuleBase_Preferences.h>
104 #include <ModuleBase_SelectionValidator.h>
105 #include <ModuleBase_Tools.h>
106 #include <ModuleBase_WidgetFactory.h>
107 #include <ModuleBase_OperationFeature.h>
108 #include <ModuleBase_PagedContainer.h>
109 #include <ModuleBase_WidgetValidated.h>
110 #include <ModuleBase_ModelWidget.h>
111 #include <ModuleBase_ResultPrs.h>
112 #include <ModuleBase_ActionIntParameter.h>
113 #include <ModuleBase_IStepPrs.h>
115 #include <Config_Common.h>
116 #include <Config_FeatureMessage.h>
117 #include <Config_ModuleReader.h>
118 #include <Config_PointerMessage.h>
119 #include <Config_PropManager.h>
120 #include <Config_DataModelReader.h>
121 #include <Config_Translator.h>
122 #include <Config_WidgetAPI.h>
123 #include <Config_Keywords.h>
125 #include <SUIT_ResourceMgr.h>
127 #include <AIS_Trihedron.hxx>
128 #ifdef BEFORE_TRIHEDRON_PATCH
129 #include <AIS_Point.hxx>
130 #include <AIS_Axis.hxx>
133 #include <QApplication>
134 #include <QFileDialog>
135 #include <QMessageBox>
136 #include <QMdiSubWindow>
137 #include <QMainWindow>
138 #include <QPushButton>
139 #include <QDockWidget>
144 #include <QToolButton>
146 #include <QDesktopWidget>
148 #include <QDesktopServices>
149 #include <QFormLayout>
151 #include <QDialogButtonBox>
156 #include <CDF_Session.hxx>
157 #include <CDF_Application.hxx>
158 #include <inspector/TInspector_Communicator.hxx>
159 #include <inspector/VInspector_CallBack.hxx>
160 static TInspector_Communicator* MyTCommunicator;
161 static Handle(VInspector_CallBack) MyVCallBack;
176 //#define DEBUG_WITH_MESSAGE_REPORT
178 QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end");
179 QString XGUI_Workshop::MOVE_TO_END_SPLIT_COMMAND = QObject::tr("Move to the end and split");
181 //#define DEBUG_DELETE
182 //#define DEBUG_FEATURE_NAME
183 //#define DEBUG_CLEAN_HISTORY
186 static QString MyFilter(QObject::tr("SHAPER files (*.shaper *.cadbld)"));
187 static QString MyFilter2(QObject::tr("SHAPER files (*.shaper)"));
188 static QString MyExtension(".shaper");
190 static QString MyFilter(QObject::tr("CAD Builder files (*.cadbld);;All files (*.*)"));
191 static QString MyFilter2(QObject::tr("CAD Builder files (*.cadbld)"));
192 static QString MyExtension(".cadbld");
195 static QString MyImportPartFilter(QObject::tr("Part files (*.shaperpart);;All files (*.*)"));
198 //******************************************************
199 XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
202 mySalomeConnector(theConnector),
204 myInspectionPanel(0),
208 //myViewerSelMode(TopAbs_FACE)
210 mySelector = new XGUI_SelectionMgr(this);
211 myModuleConnector = new XGUI_ModuleConnector(this);
212 myOperationMgr = new XGUI_OperationMgr(this, 0);
213 ModuleBase_IWorkshop* aWorkshop = moduleConnector();
214 // Has to be defined first in order to get errors and messages from other components
215 myEventsListener = new XGUI_WorkshopListener(this);
216 mySelectionActivate = new XGUI_SelectionActivate(aWorkshop);
218 SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
220 myMainWindow = new AppElements_MainWindow();
222 bool aCloc = aResMgr->booleanValue("language", "locale", true);
224 QLocale::setDefault( QLocale::c() );
226 QLocale::setDefault( QLocale::system() );
228 QString aPath = Config_XMLReader::pluginConfigFile().c_str();
233 aLangs << "*_en.ts"; // load by default eng translations
235 /// If version of OCCT is 7.4.0 or more then it means that
236 /// this is version of SALOME older then 9.4.0
237 #if OCC_VERSION_HEX >= 0x070400
238 QString aCurrLang = aResMgr->language();
240 QString aCurrLang = aResMgr->stringValue("language", "language", "en");
243 if(aCurrLang != "en") {
244 aLangs << "*_" + aCurrLang + ".ts"; // then replace with translated files
247 foreach(QString aLang, aLangs) {
248 QStringList aFilters;
250 QStringList aTsFiles = aDir.entryList(aFilters, QDir::Files);
251 foreach(QString aFileName, aTsFiles) {
252 Config_Translator::load(aFileName.toStdString());
256 myDataModelXMLReader = new Config_DataModelReader();
257 //myDataModelXMLReader->readAll();
259 myDisplayer = new XGUI_Displayer(this);
261 connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateCommandStatus()));
263 myActionsMgr = new XGUI_ActionsMgr(this);
264 myActiveControlMgr = new XGUI_ActiveControlMgr(myModuleConnector);
265 myMenuMgr = new XGUI_MenuMgr(this);
266 myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop());
267 myContextMenuMgr = new XGUI_ContextMenuMgr(this);
268 connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this,
269 SLOT(onContextMenuCommand(const QString&, bool)));
271 myViewerProxy = new XGUI_ViewerProxy(this);
272 //connect(myViewerProxy, SIGNAL(selectionChanged()),
273 // myActionsMgr, SLOT(updateOnViewSelection()));
275 myOperationMgr->setWorkshop(aWorkshop);
277 myErrorMgr = new XGUI_ErrorMgr(this, aWorkshop);
279 connect(myOperationMgr, SIGNAL(operationResumed(ModuleBase_Operation*)),
280 SLOT(onOperationResumed(ModuleBase_Operation*)));
281 connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
282 SLOT(onOperationStopped(ModuleBase_Operation*)));
283 connect(myOperationMgr, SIGNAL(operationCommitted(ModuleBase_Operation*)),
284 SLOT(onOperationCommitted(ModuleBase_Operation*)));
285 connect(myOperationMgr, SIGNAL(operationAborted(ModuleBase_Operation*)),
286 SLOT(onOperationAborted(ModuleBase_Operation*)));
289 connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
290 myDisplayer->displayTrihedron(true);
293 connect(myEventsListener, SIGNAL(errorOccurred(std::shared_ptr<Events_InfoMessage>)),
294 myErrorDlg, SLOT(addError(std::shared_ptr<Events_InfoMessage>)));
296 Config_PropManager::registerProp("Visualization", "selection_color", "Selection color",
297 Config_Prop::Color, "255,255,255");
299 if (ModuleBase_Preferences::resourceMgr()->booleanValue("Viewer", "face-selection", true))
300 myViewerSelMode.append(TopAbs_FACE);
301 if (ModuleBase_Preferences::resourceMgr()->booleanValue("Viewer", "edge-selection", true))
302 myViewerSelMode.append(TopAbs_EDGE);
303 if (ModuleBase_Preferences::resourceMgr()->booleanValue("Viewer", "vertex-selection", true))
304 myViewerSelMode.append(TopAbs_VERTEX);
305 //IMP: an attempt to use result selection with other selection modes
306 myViewerSelMode.append(ModuleBase_ResultPrs::Sel_Result);//TopAbs_VERTEX);
307 myViewerSelMode.append(TopAbs_COMPSOLID);
310 //******************************************************
311 XGUI_Workshop::~XGUI_Workshop(void)
314 #ifdef MISSED_TRANSLATION
315 // Save Missed translations
316 Config_Translator::saveMissedTranslations();
321 delete myDataModelXMLReader;
322 delete mySelectionActivate;
327 //******************************************************
328 void XGUI_Workshop::startApplication()
330 //Initialize event listening
331 myEventsListener->initializeEventListening();
333 myDataModelXMLReader->readAll();
336 Config_PropManager::registerProp("Plugins", "default_path", "Default Path",
337 Config_Prop::Directory, "");
339 std::string aDir = Config_XMLReader::resourcesConfigFile();
340 Config_PropManager::registerProp("Plugins", "import_initial_path", "Import initial directory",
341 Config_Prop::Directory, aDir);
344 Config_PropManager::registerProp("Plugins", "create_part_by_start", "Create Part by Start",
345 Config_Prop::Boolean, "false");
347 Config_PropManager::registerProp("Plugins", "show_hide_faces", "Show Hide Faces (on the right)",
348 Config_Prop::Boolean, "false");
350 registerValidators();
352 // Calling of loadCustomProps before activating module is required
353 // by Config_PropManger to restore user-defined path to plugins
354 ModuleBase_Preferences::loadCustomProps();
355 std::vector<int> aColor;
357 aColor = Config_PropManager::color("Visualization", "selection_color");
361 if (aColor.size() == 3)
362 myDisplayer->setSelectionColor(aColor);
367 myMainWindow->show();
368 updateCommandStatus();
373 myViewerProxy->connectViewProxy();
374 connect(myViewerProxy, SIGNAL(trihedronVisibilityChanged(bool)),
375 SLOT(onTrihedronVisibilityChanged(bool)));
377 emit applicationStarted();
380 bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
382 module()->launchOperation("Part", false); // PartSetPlugin_Part::ID()
387 //******************************************************
388 void XGUI_Workshop::activateModule()
390 selectionActivate()->updateSelectionFilters();
392 connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
393 myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
394 connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
395 myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
397 updateCommandStatus();
399 // TODO: get default selection mode
401 // activate visualized objects in the viewer
402 activateObjectsSelection(displayer()->displayedObjects());
403 myOperationMgr->activate();
406 //******************************************************
407 void XGUI_Workshop::deactivateModule()
409 // remove internal displayer filter
410 displayer()->deactivateSelectionFilters(false);
412 disconnect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
413 myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
414 disconnect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
415 myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
417 XGUI_Displayer* aDisplayer = displayer();
418 QObjectPtrList aDisplayed = aDisplayer->displayedObjects();
419 aDisplayer->deactivateObjects(aDisplayed, true);
420 selectionActivate()->deactivateTrihedronInSelectionModes();
422 #ifdef BEFORE_TRIHEDRON_PATCH
423 //Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(aDisplayer->getTrihedron());
424 /// Trihedron problem: objects stayed in the viewer, should be removed manually
425 /// otherwise in SALOME happens crash by HideAll in the viewer
426 aContext->Remove(aTrihedron->Position(), true);
427 aContext->Remove(aTrihedron->Axis(), true);
428 aContext->Remove(aTrihedron->XAxis(), true);
429 aContext->Remove(aTrihedron->YAxis(), true);
432 myOperationMgr->deactivate();
435 //******************************************************
436 void XGUI_Workshop::initMenu()
438 myContextMenuMgr->createActions();
441 // Create only Undo, Redo commands
442 QAction* aAction = salomeConnector()->addDesktopCommand("UNDO_CMD", tr("Undo"),
443 tr("Undo last command"),
444 QIcon(":pictures/undo.png"),
445 QKeySequence::Undo, false,
447 QString aToolBarTitle = tr( "INF_DESK_TOOLBAR_STANDARD" );
448 salomeConnector()->addActionInToolbar( aAction,aToolBarTitle );
450 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo()));
451 addHistoryMenu(aAction, SIGNAL(updateUndoHistory(const QList<ActionInfo>&)), SLOT(onUndo(int)));
453 aAction = salomeConnector()->addDesktopCommand("REDO_CMD", tr("Redo"), tr("Redo last command"),
454 QIcon(":pictures/redo.png"), QKeySequence::Redo,
455 false, "MEN_DESK_EDIT");
456 salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
458 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRedo()));
459 addHistoryMenu(aAction, SIGNAL(updateRedoHistory(const QList<ActionInfo>&)), SLOT(onRedo(int)));
461 salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
463 //aAction = salomeConnector()->addDesktopCommand("AUTOCOMPUTE_CMD", tr("Auto rebuild"),
464 // tr("Blocks immediate apply of modifications"),
465 // QIcon(":pictures/autoapply.png"), QKeySequence(),
466 // false, "MEN_DESK_EDIT");
467 //salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
469 //connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onAutoApply()));
471 salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
474 // Add commands to a file menu
475 aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."),
476 tr("Export the current document into a native file"),
477 QIcon(), QKeySequence(),
478 false, "MEN_DESK_FILE");
479 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSaveAs()));
481 aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Import native..."),
482 tr("Import native file"),
483 QIcon(), QKeySequence(),
484 false, "MEN_DESK_FILE");
485 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen()));
486 salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
488 aAction = salomeConnector()->addDesktopCommand("EXPORT_PART_CMD", tr("Export part..."),
489 tr("Export a part of the current document into a file"),
490 QIcon(), QKeySequence(),
491 false, "MEN_DESK_FILE");
492 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onExportPart()));
494 aAction = salomeConnector()->addDesktopCommand("IMPORT_PART_CMD", tr("Import part..."),
495 tr("Import structure of a part"),
496 QIcon(), QKeySequence(),
497 false, "MEN_DESK_FILE");
498 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportPart()));
500 aAction = salomeConnector()->addDesktopCommand("IMPORT_SHAPE_CMD", tr("Import shape..."),
501 tr("Import shape from a file"),
502 ModuleBase_IconFactory::loadIcon("icons/Exchange/import.png"),
503 QKeySequence(), false, "MEN_DESK_FILE");
504 connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportShape()));
506 salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
509 // File commands group
510 AppElements_MenuGroupPanel* aGroup = myMainWindow->menuObject()->generalPage();
512 AppElements_Command* aCommand;
514 aCommand = aGroup->addFeature("SAVE_CMD", tr("Save"), tr("Save the document"),
515 QIcon(":pictures/save.png"), QKeySequence::Save);
516 aCommand->connectTo(this, SLOT(onSave()));
517 //aCommand->disable();
519 aCommand = aGroup->addFeature("SAVEAS_CMD", tr("Save as..."), tr("Save the document into a file"),
520 QIcon(":pictures/save.png"), QKeySequence());
521 aCommand->connectTo(this, SLOT(onSaveAs()));
523 QString aUndoId = "UNDO_CMD";
524 aCommand = aGroup->addFeature(aUndoId, tr("Undo"), tr("Undo last command"),
525 QIcon(":pictures/undo.png"), QKeySequence::Undo);
526 aCommand->connectTo(this, SLOT(onUndo()));
527 AppElements_Button* aUndoButton = qobject_cast<AppElements_Button*>(aGroup->widget(aUndoId));
528 addHistoryMenu(aUndoButton,
529 SIGNAL(updateUndoHistory(const QList<ActionInfo>&)),
532 QString aRedoId = "REDO_CMD";
533 aCommand = aGroup->addFeature(aRedoId, tr("Redo"), tr("Redo last command"),
534 QIcon(":pictures/redo.png"), QKeySequence::Redo);
535 aCommand->connectTo(this, SLOT(onRedo()));
536 AppElements_Button* aRedoButton = qobject_cast<AppElements_Button*>(aGroup->widget(aRedoId));
537 addHistoryMenu(aRedoButton,
538 SIGNAL(updateRedoHistory(const QList<ActionInfo>&)),
541 aCommand = aGroup->addFeature("OPEN_CMD", tr("Open..."), tr("Open a new document"),
542 QIcon(":pictures/open.png"), QKeySequence::Open);
543 aCommand->connectTo(this, SLOT(onOpen()));
546 aCommand = aGroup->addFeature("AUTOCOMPUTE_CMD", tr("Auto rebuild"),
547 tr("Blocks immediate apply of modifications"),
548 QIcon(":pictures/autoapply_start.png"), QKeySequence());
549 aCommand->setChecked(ModelAPI_Session::get()->isAutoUpdateBlocked());
550 aCommand->connectTo(this, SLOT(onAutoApply()));
552 aCommand = aGroup->addFeature("PREF_CMD", tr("Preferences"), tr("Edit preferences"),
553 QIcon(":pictures/preferences.png"), QKeySequence::Preferences);
554 aCommand->connectTo(this, SLOT(onPreferences()));
556 aCommand = aGroup->addFeature("EXIT_CMD", tr("Exit"), tr("Exit application"),
557 QIcon(":pictures/close.png"), QKeySequence::Close);
558 aCommand->connectTo(this, SLOT(onExit()));
563 //******************************************************
564 AppElements_Workbench* XGUI_Workshop::addWorkbench(const QString& theName)
566 AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
567 return aMenuBar->addWorkbench(theName);
571 //******************************************************
572 QMainWindow* XGUI_Workshop::desktop() const
575 return salomeConnector()->desktop();
581 //******************************************************
582 void XGUI_Workshop::onStartWaiting()
584 if (Events_LongOp::isPerformed()) {
585 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
589 //******************************************************
590 void XGUI_Workshop::onAcceptActionClicked()
592 QAction* anAction = dynamic_cast<QAction*>(sender());
593 XGUI_OperationMgr* anOperationMgr = operationMgr();
594 if (anOperationMgr) {
595 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
596 (anOperationMgr->currentOperation());
598 //if (errorMgr()->canProcessClick(anAction, aFOperation->feature()))
599 myOperationMgr->commitOperation();
604 //******************************************************
605 void XGUI_Workshop::onAcceptPlusActionClicked()
607 QAction* anAction = dynamic_cast<QAction*>(sender());
608 XGUI_OperationMgr* anOperationMgr = operationMgr();
609 if (anOperationMgr) {
610 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
611 (anOperationMgr->currentOperation());
613 if (myOperationMgr->commitOperation())
614 module()->launchOperation(aFOperation->id(), false);
619 //******************************************************
620 void XGUI_Workshop::onPreviewActionClicked()
622 ModuleBase_IPropertyPanel* aPanel = propertyPanel();
624 ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
625 if (anActiveWidget && anActiveWidget->getValueState() == ModuleBase_ModelWidget::ModifiedInPP) {
626 anActiveWidget->storeValue();
629 std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
630 new Events_Message(Events_Loop::eventByName(EVENT_PREVIEW_REQUESTED)));
631 Events_Loop::loop()->send(aMsg);
635 //******************************************************
636 void XGUI_Workshop::onHelpActionClicked()
638 XGUI_OperationMgr* anOperationMgr = operationMgr();
639 if (anOperationMgr) {
640 ModuleBase_Operation* aOperation = anOperationMgr->currentOperation();
642 QString aHelpPage = aOperation->helpFileName();
643 if (!aHelpPage.isEmpty()) {
645 const QChar aSep = QDir::separator();
647 // SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
649 // platform = "winapplication";
651 // platform = "application";
653 // QString aBrowserName = aResMgr->stringValue("ExternalBrowser", platform);
656 QString aDir(getenv("SHAPER_ROOT_DIR"));
657 if (!aDir.isEmpty()) {
658 aDocDir = aDir + aSep + "share" + aSep + "doc" + aSep +
659 "salome" + aSep + "gui" + aSep + "SHAPER";
662 QString aDir(getenv("CADBUILDER_ROOT_DIR"));
663 aDocDir = aDir + aSep + "doc" + aSep + "gui";
665 QString aFileName = aDocDir + aSep + aHelpPage;
666 if (QFile::exists(aFileName)) {
667 QUrl aUrl = QUrl::fromLocalFile(aFileName);
668 QDesktopServices::openUrl(aUrl);
676 //******************************************************
677 void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer)
679 if (!myModule->canActivateSelection(theObject)) {
680 if (selectionActivate()->isActive(theObject)) {
681 QObjectPtrList anObjects;
682 anObjects.append(theObject);
683 myDisplayer->deactivateObjects(anObjects, theUpdateViewer);
688 //******************************************************
689 bool XGUI_Workshop::isFeatureOfNested(const FeaturePtr& theFeature)
691 bool aHasNested = false;
692 std::string aFeatureKind = theFeature->getKind();
694 XGUI_SalomeConnector* aSalomeConnector = salomeConnector();
695 if (aSalomeConnector->isFeatureOfNested(actionsMgr()->action(aFeatureKind.c_str())))
698 AppElements_MainMenu* aMenuBar = mainWindow()->menuObject();
699 AppElements_Command* aCommand = aMenuBar->feature(aFeatureKind.c_str());
700 if (aCommand && aCommand->button()->additionalButtonWidget())
706 //******************************************************
707 void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation)
709 ModuleBase_OperationFeature* aFOperation =
710 dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
714 myPropertyPanel->cleanContent();
716 QList<ModuleBase_ModelWidget*> aWidgets;
717 QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
718 if (!module()->createWidgets(aFOperation->feature(), aXmlRepr, aWidgets)) {
719 ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myModuleConnector);
720 aFactory.createWidget(myPropertyPanel->contentWidget());
721 aWidgets = aFactory.getModelWidgets();
724 // check compatibility of feature and widgets
725 FeaturePtr aFeature = aFOperation->feature();
726 std::string aFeatureKind = aFeature->getKind();
727 foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
728 if (aWidget->usesAttribute()) {
729 if (!aWidget->attributeID().empty() && !aFeature->attribute(aWidget->attributeID()).get()) {
730 std::string anErrorMsg = "The feature '%1' has no attribute '%2' used by widget '%3'.";
731 Events_InfoMessage("XGUI_Workshop", anErrorMsg)
732 .arg(aFeatureKind).arg(aWidget->attributeID())
733 .arg(aWidget->metaObject()->className()).send();
734 myPropertyPanel->cleanContent();
739 // for performance purpose, flush should be done after all controls are filled
740 bool isUpdateFlushed = false;
741 foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
742 bool isStoreValue = !aFOperation->isEditOperation() &&
743 !aWidget->getDefaultValue().empty() &&
744 !aWidget->isComputedDefault();
745 aWidget->setFeature(aFeature, isStoreValue, isUpdateFlushed);
747 aWidget->restoreValue();
748 aWidget->enableFocusProcessing();
750 // update visible state of Preview button
751 std::shared_ptr<Config_FeatureMessage> aFeatureInfo;
753 aFeatureInfo = mySalomeConnector->featureInfo(aFeatureKind.c_str());
755 AppElements_MainMenu* aMenuBar = mainWindow()->menuObject();
756 AppElements_Command* aCommand = aMenuBar->feature(aFeatureKind.c_str());
758 aFeatureInfo = aCommand->featureMessage();
760 bool anIsAutoPreview = true;
761 if (aFeatureInfo.get()) {
762 anIsAutoPreview = aFeatureInfo->isAutoPreview();
763 theOperation->setHelpFileName(aFeatureInfo->helpFileName().c_str());
765 std::string aXmlCfg, aDescription;
766 module()->getXMLRepresentation(aFeatureKind, aXmlCfg, aDescription);
767 ModuleBase_WidgetFactory aFactory(aXmlCfg, moduleConnector());
768 anIsAutoPreview = aFactory.widgetAPI()->getBooleanAttribute(FEATURE_AUTO_PREVIEW, true);
771 if (!anIsAutoPreview) {
772 myPropertyPanel->findButton(PROP_PANEL_PREVIEW)->setVisible(true);
773 // send signal about preview should not be computed automatically, click on preview
774 // button should initiate it
775 std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
776 new Events_Message(Events_Loop::eventByName(EVENT_PREVIEW_BLOCKED)));
777 Events_Loop::loop()->send(aMsg);
779 // if update happens after preview is blocked, it does nothing when blocked
780 // it improves performance for valid objects on feature start
781 ModuleBase_Tools::flushUpdated(aFeature);
783 myPropertyPanel->setModelWidgets(aWidgets);
784 aFOperation->setPropertyPanel(myPropertyPanel);
786 myModule->propertyPanelDefined(theOperation);
788 #ifndef DEBUG_FEATURE_NAME
789 myPropertyPanel->setWindowTitle(ModuleBase_Tools::translate("workshop",
790 theOperation->getDescription()->description().toStdString()));
792 std::string aFeatureName = aFeature->name();
793 myPropertyPanel->setWindowTitle(QString("%1: %2")
794 .arg(translate(theOperation->getDescription()->description()))
795 .arg(translate(aFeatureName.c_str())));
798 myErrorMgr->setPropertyPanel(myPropertyPanel);
799 if (Config_PropManager::boolean("Windows", "use_hide_faces_panel")) {
800 theOperation->setHideFacesVisible(myFacesPanel->isVisible());
801 if (aFeatureInfo.get() && aFeatureInfo->isHideFacesPanel() && !myFacesPanel->isVisible())
802 myFacesPanel->show();
804 showPanel(myPropertyPanel);
807 //******************************************************
808 void XGUI_Workshop::connectToPropertyPanel(const bool isToConnect)
810 XGUI_PropertyPanel* aPropertyPanel = propertyPanel();
811 if (aPropertyPanel) {
812 const QList<ModuleBase_ModelWidget*>& aWidgets = aPropertyPanel->modelWidgets();
813 foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
814 myModule->connectToPropertyPanel(aWidget, isToConnect);
816 connect(aWidget, SIGNAL(valueStateChanged(int)), this, SLOT(onWidgetStateChanged(int)));
817 connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
818 connect(aWidget, SIGNAL(objectUpdated()), this, SLOT(onWidgetObjectUpdated()));
821 disconnect(aWidget, SIGNAL(valueStateChanged(int)), this, SLOT(onWidgetStateChanged(int)));
822 disconnect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onValuesChanged()));
823 disconnect(aWidget, SIGNAL(objectUpdated()), this, SLOT(onWidgetObjectUpdated()));
829 //******************************************************
830 void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation)
832 setGrantedFeatures(theOperation);
834 if (theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel
835 fillPropertyPanel(theOperation);
836 connectToPropertyPanel(true);
837 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
840 myPropertyPanel->updateApplyPlusButton(aFOperation->feature());
842 myPropertyPanel->updateApplyPlusButton(FeaturePtr());
844 updateCommandStatus();
846 myModule->operationResumed(theOperation);
849 //******************************************************
850 void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
852 updateCommandStatus();
854 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
859 ModuleBase_ISelection* aSel = mySelector->selection();
860 QObjectPtrList aObj = aSel->selectedPresentations();
861 //!< No need for property panel
862 hidePanel(myPropertyPanel);
863 myPropertyPanel->cleanContent();
865 connectToPropertyPanel(false);
866 myModule->operationStopped(aFOperation);
868 // the deactivated objects of the current operation should be activated back.
869 // They were deactivated on operation start or an object redisplay
870 QObjectPtrList anObjects;
871 FeaturePtr aFeature = aFOperation->feature();
872 if (aFeature.get()) { // feature may be not created (plugin load fail)
873 if (myDisplayer->isVisible(aFeature) && !selectionActivate()->isActive(aFeature))
874 anObjects.append(aFeature);
875 std::list<ResultPtr> aResults;
876 ModelAPI_Tools::allResults(aFeature, aResults);
877 std::list<ResultPtr>::const_iterator aIt;
878 for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
879 ResultPtr anObject = *aIt;
880 if (myDisplayer->isVisible(anObject) && !selectionActivate()->isActive(anObject)) {
881 anObjects.append(anObject);
885 activateObjectsSelection(anObjects);
887 if (Config_PropManager::boolean("Windows", "use_hide_faces_panel")) {
888 if (!theOperation->isHideFacesVisible())
889 myFacesPanel->close();
893 //******************************************************
894 void XGUI_Workshop::onOperationCommitted(ModuleBase_Operation* theOperation)
896 myModule->operationCommitted(theOperation);
899 //******************************************************
900 void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation)
902 myModule->operationAborted(theOperation);
905 //******************************************************
906 void XGUI_Workshop::setGrantedFeatures(ModuleBase_Operation* theOperation)
908 ModuleBase_OperationFeature* aFOperation =
909 dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
913 QStringList aGrantedIds;
914 if (isSalomeMode()) {
915 const std::shared_ptr<Config_FeatureMessage>& anInfo =
916 mySalomeConnector->featureInfo(theOperation->id());
918 aGrantedIds = QString::fromStdString(anInfo->nestedFeatures())
919 .split(" ", QString::SkipEmptyParts);
922 aGrantedIds = myActionsMgr->nestedCommands(theOperation->id());
924 ModuleBase_IModule* aModule = module();
926 aModule->grantedOperationIds(theOperation, aGrantedIds);
928 aFOperation->setGrantedOperationIds(aGrantedIds);
931 //******************************************************
932 void XGUI_Workshop::saveDocument(const QString& theName, std::list<std::string>& theFileNames)
934 QApplication::restoreOverrideCursor();
935 SessionPtr aMgr = ModelAPI_Session::get();
937 std::list<DocumentPtr> aDocList = aMgr->allOpenedDocuments();
938 std::list<DocumentPtr>::const_iterator aIt;
939 for (aIt = aDocList.cbegin(); aIt != aDocList.cend(); aIt++) {
940 std::list<bool> aState = myObjectBrowser->getStateForDoc(*aIt);
941 (*aIt)->storeNodesState(aState);
944 aMgr->save(theName.toLatin1().constData(), theFileNames);
946 QApplication::restoreOverrideCursor();
949 //******************************************************
950 bool XGUI_Workshop::abortAllOperations()
952 return myOperationMgr->abortAllOperations();
955 //******************************************************
956 void XGUI_Workshop::operationStarted(ModuleBase_Operation* theOperation)
958 setGrantedFeatures(theOperation);
959 if (!theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel
960 updateCommandStatus();
963 myModule->operationStarted(theOperation);
967 //******************************************************
968 void XGUI_Workshop::onOpen()
970 if(!abortAllOperations())
972 //save current file before close if modified
973 SessionPtr aSession = ModelAPI_Session::get();
974 if (aSession->isModified()) {
975 int anAnswer = QMessageBox::question(
976 desktop(), tr("Save current file"),
977 tr("The document is modified, save before opening another?"),
978 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel);
979 if (anAnswer == QMessageBox::Save) {
981 } else if (anAnswer == QMessageBox::Cancel) {
984 myCurrentFile = QString();
987 //show file dialog, check if readable and open
988 qreal aRatio = ModuleBase_Tools::currentPixelRatio();
989 // If the ratio is > 1 (HD screen) then QT has a bug in
990 // displaying of system open file dialog (too small)
991 QString aFile = QFileDialog::getOpenFileName(desktop(), tr("Open file"), QString(), MyFilter,
992 Q_NULLPTR, ((aRatio > 1)? QFileDialog::DontUseNativeDialog : QFileDialog::Options()));
997 //******************************************************
998 void XGUI_Workshop::openFile(const QString& theDirectory)
1000 myCurrentFile = theDirectory;
1001 if (myCurrentFile.isEmpty())
1004 QFileInfo aFileInfo(myCurrentFile);
1005 if (!aFileInfo.exists() || !aFileInfo.isReadable()) {
1006 QMessageBox::critical(desktop(), tr("Warning"), tr("Unable to open the file."));
1007 myCurrentFile = QString();
1011 QApplication::setOverrideCursor(Qt::WaitCursor);
1012 module()->closeDocument();
1013 SessionPtr aSession = ModelAPI_Session::get();
1014 aSession->closeAll();
1016 clearTemporaryDir();
1017 if (!XGUI_CompressFiles::uncompress(myCurrentFile, myTmpDir.path()))
1020 aSession->load(myTmpDir.path().toLatin1().constData());
1021 myObjectBrowser->rebuildDataTree();
1023 // Open first level of data tree
1024 DocumentPtr aRootDoc = aSession->moduleDocument();
1025 std::list<bool> aStates;
1026 aRootDoc->restoreNodesState(aStates);
1027 myObjectBrowser->setStateForDoc(aRootDoc, aStates);
1029 updateCommandStatus();
1031 myMainWindow->setCurrentDir(myCurrentFile, true);
1035 bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
1038 DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
1039 int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
1041 ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), 0);
1042 ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
1049 QApplication::restoreOverrideCursor();
1052 //******************************************************
1053 void XGUI_Workshop::onNew()
1055 QApplication::setOverrideCursor(Qt::WaitCursor);
1056 if (objectBrowser() == 0) {
1057 createDockWidgets();
1058 mySelector->connectViewers();
1060 myViewerProxy->connectToViewer();
1061 showObjectBrowser();
1063 myMainWindow->showPythonConsole();
1064 QMdiSubWindow* aWnd = myMainWindow->viewer()->createView();
1065 aWnd->showMaximized();
1066 updateCommandStatus();
1067 PyConsole_Console* aConsole = myMainWindow->pythonConsole();
1068 connect(aConsole, SIGNAL(scriptLoaded()), SLOT(updateCommandStatus()));
1070 myContextMenuMgr->connectViewer();
1071 QApplication::restoreOverrideCursor();
1075 //******************************************************
1076 void XGUI_Workshop::onExit()
1078 SessionPtr aMgr = ModelAPI_Session::get();
1079 if (aMgr->isModified()) {
1080 int anAnswer = QMessageBox::question(
1081 myMainWindow, tr("Save current file"), tr("The document is modified, save before exit?"),
1082 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel);
1083 if (anAnswer == QMessageBox::Save) {
1084 bool saved = onSave();
1088 } else if (anAnswer == QMessageBox::Cancel) {
1095 //******************************************************
1096 void XGUI_Workshop::onPreferences()
1098 ModuleBase_Prefs aModif;
1099 ModuleBase_Preferences::editPreferences(aModif);
1100 if (aModif.size() > 0) {
1102 foreach (ModuleBase_Pref aPref, aModif) {
1103 aSection = aPref.first;
1104 if (aSection == ModuleBase_Preferences::VIEWER_SECTION) {
1105 myMainWindow->viewer()->updateFromResources();
1106 } else if (aSection == ModuleBase_Preferences::MENU_SECTION) {
1107 myMainWindow->menuObject()->updateFromResources();
1110 std::vector<int> aColor;
1112 aColor = Config_PropManager::color("Visualization", "selection_color");
1116 if (aColor.size() == 3)
1117 displayer()->setSelectionColor(aColor);
1119 displayer()->redisplayObjects();
1124 //******************************************************
1125 void XGUI_Workshop::onTrihedronVisibilityChanged(bool theState)
1127 XGUI_Displayer* aDisplayer = displayer();
1129 aDisplayer->displayTrihedron(theState);
1130 aDisplayer->updateViewer();
1134 //******************************************************
1135 bool XGUI_Workshop::onSave()
1137 if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
1139 if (myCurrentFile.isEmpty()) {
1142 SessionPtr aMgr = ModelAPI_Session::get();
1143 if (aMgr->isAutoUpdateBlocked())
1144 aMgr->blockAutoUpdate(false);
1146 std::list<std::string> aFiles;
1147 // issue #2899: create a temporary directory, save and then remove it
1149 std::string aTmpDir = XGUI_Tools::getTmpDirByEnv("SALOME_TMP_DIR");
1151 std::string aTmpDir = XGUI_Tools::getTmpDirByEnv("");
1153 saveDocument(QString(aTmpDir.c_str()), aFiles);
1154 bool aResult = XGUI_CompressFiles::compress(myCurrentFile, aFiles);
1155 XGUI_Tools::removeTemporaryFiles(aTmpDir, aFiles);
1158 updateCommandStatus();
1160 myMainWindow->setModifiedState(false);
1166 //******************************************************
1167 bool XGUI_Workshop::onSaveAs()
1169 if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
1171 qreal aRatio = ModuleBase_Tools::currentPixelRatio();
1172 myCurrentFile = QFileDialog::getSaveFileName(desktop(), tr("Select name to save file..."),
1173 QString(), MyFilter2,
1174 Q_NULLPTR, ((aRatio > 1) ? QFileDialog::DontUseNativeDialog : QFileDialog::Options()));
1175 if (!myCurrentFile.isNull()) {
1176 if (!myCurrentFile.endsWith(MyExtension)) {
1177 myCurrentFile += MyExtension;
1183 myMainWindow->setCurrentDir(myCurrentFile, false);
1184 myMainWindow->setModifiedState(false);
1189 //******************************************************
1190 void XGUI_Workshop::onUndo(int theTimes)
1192 processUndoRedo(ActionUndo, theTimes);
1193 myObjectBrowser->updateAllIndexes(1);
1196 //******************************************************
1197 void XGUI_Workshop::onRedo(int theTimes)
1199 processUndoRedo(ActionRedo, theTimes);
1200 myObjectBrowser->updateAllIndexes(1);
1203 //******************************************************
1204 void XGUI_Workshop::processUndoRedo(const ModuleBase_ActionType theActionType, int theTimes)
1206 ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
1207 if (anActiveWidget) {
1208 ActionIntParamPtr aParam(new ModuleBase_ActionIntParameter(theTimes));
1209 if (anActiveWidget->processAction(theActionType, aParam))
1212 // the viewer update should be blocked in order to avoid the features blinking. For the created
1213 // feature a results are created, the flush of the created signal caused the viewer redisplay for
1214 // each created result. After a redisplay signal is flushed. So, the viewer update is blocked
1215 // until redo of all possible objects happens
1216 bool isUpdateEnabled = myDisplayer->enableUpdateViewer(false);
1218 SessionPtr aMgr = ModelAPI_Session::get();
1219 if (aMgr->isOperation()) {
1220 XGUI_OperationMgr* aOpMgr = operationMgr();
1221 /// this is important for nested operations
1222 /// when sketch operation is active, this condition is false and
1223 /// the sketch operation is not aborted
1224 if (aOpMgr->canStopOperation(aOpMgr->currentOperation()))
1225 aOpMgr->abortOperation(aOpMgr->currentOperation());
1228 myDisplayer->enableUpdateViewer(isUpdateEnabled);
1232 objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
1233 std::list<std::string> anActionList = theActionType == ActionUndo ? aMgr->undoList()
1235 std::list<std::string>::const_iterator aIt = anActionList.cbegin();
1236 for (int i = 0; (i < theTimes) && (aIt != anActionList.cend()); ++i, ++aIt) {
1237 if (theActionType == ActionUndo)
1242 if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND ||
1243 QString((*aIt).c_str()) == MOVE_TO_END_SPLIT_COMMAND)
1244 myObjectBrowser->rebuildDataTree();
1246 operationMgr()->updateApplyOfOperations();
1247 facesPanel()->reset(true);
1248 updateCommandStatus();
1250 // unblock the viewer update functionality and make update on purpose
1251 myDisplayer->enableUpdateViewer(isUpdateEnabled);
1252 myDisplayer->updateViewer();
1253 // Clear messages in status bar from previous operations if exists
1254 setStatusBarMessage("");
1257 //******************************************************
1258 void XGUI_Workshop::onWidgetStateChanged(int thePreviousState)
1260 ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
1261 //ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
1262 //if (anOperation) {
1263 // ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
1265 // anActiveWidget = aPanel->activeWidget();
1268 operationMgr()->onValidateOperation();
1270 myModule->widgetStateChanged(thePreviousState);
1273 //******************************************************
1274 void XGUI_Workshop::onValuesChanged()
1276 ModuleBase_ModelWidget* aSenderWidget = (ModuleBase_ModelWidget*)(sender());
1277 if (!aSenderWidget || aSenderWidget->canAcceptFocus())
1280 ModuleBase_ModelWidget* anActiveWidget = 0;
1281 ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
1283 ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
1285 anActiveWidget = aPanel->activeWidget();
1287 if (anActiveWidget) {
1288 ModuleBase_WidgetValidated* aWidgetValidated = dynamic_cast<ModuleBase_WidgetValidated*>
1290 if (aWidgetValidated)
1291 aWidgetValidated->clearValidatedCash();
1295 //******************************************************
1296 void XGUI_Workshop::onWidgetObjectUpdated()
1298 operationMgr()->onValidateOperation();
1299 myDisplayer->updateViewer();
1302 //******************************************************
1303 void XGUI_Workshop::onImportPart()
1305 if (abortAllOperations()) {
1306 ModuleBase_OperationFeature* anImportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
1307 module()->createOperation(ExchangePlugin_ImportPart::ID()));
1308 myPropertyPanel->updateApplyPlusButton(anImportPartOp->feature());
1309 operationMgr()->startOperation(anImportPartOp);
1313 //******************************************************
1314 void XGUI_Workshop::onImportShape()
1316 if (abortAllOperations()) {
1317 ModuleBase_OperationFeature* anImportOp = dynamic_cast<ModuleBase_OperationFeature*>(
1318 module()->createOperation(ExchangePlugin_Import::ID()));
1319 myPropertyPanel->updateApplyPlusButton(anImportOp->feature());
1320 operationMgr()->startOperation(anImportOp);
1324 //******************************************************
1325 void XGUI_Workshop::onExportPart()
1327 if (abortAllOperations()) {
1328 ModuleBase_OperationFeature* anExportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
1329 module()->createOperation(ExchangePlugin_ExportPart::ID()));
1330 myPropertyPanel->updateApplyPlusButton(anExportPartOp->feature());
1331 operationMgr()->startOperation(anExportPartOp);
1335 //******************************************************
1336 ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
1338 QString libName = QString::fromStdString(library(theModule.toStdString()));
1339 if (libName.isEmpty()) {
1340 qWarning(qPrintable(tr("Information about module \"%1\" doesn't exist.").arg(theModule)));
1345 CREATE_FUNC crtInst = 0;
1348 HINSTANCE modLib = ::LoadLibraryA(qPrintable(libName));
1352 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1353 0, ::GetLastError(), 0, (LPTSTR) & lpMsgBuf, 0, 0);
1354 QString aMsg((char*) &lpMsgBuf);
1355 err = QString("Failed to load %1. %2").arg(libName).arg(aMsg);
1356 ::LocalFree(lpMsgBuf);
1358 crtInst = (CREATE_FUNC) ::GetProcAddress(modLib, CREATE_MODULE);
1362 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
1363 | FORMAT_MESSAGE_IGNORE_INSERTS,
1364 0, ::GetLastError(), 0, (LPTSTR) & lpMsgBuf, 0, 0);
1365 QString aMsg((char*) &lpMsgBuf);
1366 err = QString("Failed to find %1 function. %2").arg( CREATE_MODULE).arg(aMsg);
1367 ::LocalFree(lpMsgBuf);
1371 void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
1373 err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
1375 crtInst = (CREATE_FUNC)dlsym( modLib, CREATE_MODULE );
1377 err = QString( "Failed to find function %1. %2" ).arg( CREATE_MODULE ).arg( dlerror() );
1382 ModuleBase_IModule* aModule = crtInst ? crtInst(myModuleConnector) : 0;
1384 if (!err.isEmpty()) {
1386 Events_InfoMessage("XGUI_Workshop", err.toStdString()).send();
1388 qWarning(qPrintable(err));
1394 //******************************************************
1395 bool XGUI_Workshop::createModule()
1397 Config_ModuleReader aModuleReader;
1398 QString moduleName = QString::fromStdString(aModuleReader.getModuleName());
1399 myModule = loadModule(moduleName);
1403 //connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
1404 // myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
1405 //connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
1406 // myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
1408 myModule->createFeatures();
1410 salomeConnector()->createFeatureActions();
1412 //myActionsMgr->update();
1416 //******************************************************
1417 void XGUI_Workshop::updateCommandStatus()
1419 QList<QAction*> aCommands;
1421 aCommands = salomeConnector()->commandList();
1423 AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
1424 foreach (AppElements_Command* aCmd, aMenuBar->features())
1425 aCommands.append(aCmd);
1427 SessionPtr aMgr = ModelAPI_Session::get();
1428 if (aMgr->hasModuleDocument()) {
1429 foreach(QAction* aCmd, aCommands) {
1430 QString aId = aCmd->data().toString();
1431 if (aId == "UNDO_CMD") {
1432 bool isActionEnabled = false;
1433 // if ultimate is true -> using result of operation only, or using OR combination
1434 ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
1435 if (anActiveWidget && anActiveWidget->canProcessAction(ActionUndo, isActionEnabled))
1436 aCmd->setEnabled(isActionEnabled);
1438 aCmd->setEnabled(myModule->canUndo());
1440 else if (aId == "REDO_CMD") {
1441 bool isActionEnabled = false;
1442 // if ultimate is true -> using result of operation only, or using OR combination
1443 ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
1444 if (anActiveWidget && anActiveWidget->canProcessAction(ActionRedo, isActionEnabled))
1445 aCmd->setEnabled(isActionEnabled);
1447 aCmd->setEnabled(myModule->canRedo());
1449 else if (aId == "AUTOCOMPUTE_CMD") {
1450 aCmd->setIcon(aMgr->isAutoUpdateBlocked() ?
1451 QIcon(":pictures/autoapply_stop.png") :
1452 QIcon(":pictures/autoapply_start.png"));
1455 // Enable all commands
1456 aCmd->setEnabled(true);
1460 foreach(QAction* aCmd, aCommands) {
1461 QString aId = aCmd->data().toString();
1462 if (aId == "NEW_CMD")
1463 aCmd->setEnabled(true);
1464 else if (aId == "EXIT_CMD")
1465 aCmd->setEnabled(true);
1467 aCmd->setEnabled(false);
1470 myActionsMgr->updateCommandsStatus();
1471 emit commandStatusUpdated();
1474 //******************************************************
1475 void XGUI_Workshop::updateHistory()
1477 bool isActionEnabled = false;
1478 ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
1479 QList<ActionInfo> aUndoRes;
1480 QList<ActionInfo> aRedoRes;
1481 if (anActiveWidget && anActiveWidget->canProcessAction(ActionUndo, isActionEnabled)) {
1482 aUndoRes = anActiveWidget->actionsList(ActionUndo);
1483 aRedoRes = anActiveWidget->actionsList(ActionRedo);
1485 std::list<std::string> aUndoList = ModelAPI_Session::get()->undoList();
1486 aUndoRes = processHistoryList(aUndoList);
1488 std::list<std::string> aRedoList = ModelAPI_Session::get()->redoList();
1489 aRedoRes = processHistoryList(aRedoList);
1491 emit updateUndoHistory(aUndoRes);
1492 emit updateRedoHistory(aRedoRes);
1495 //******************************************************
1496 QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent)
1498 QDockWidget* aObjDock = new QDockWidget(theParent);
1499 aObjDock->setAllowedAreas(Qt::LeftDockWidgetArea |
1500 Qt::RightDockWidgetArea);
1501 aObjDock->setWindowTitle(tr("Object browser"));
1502 aObjDock->setStyleSheet(
1503 "::title { position: relative; padding-left: 5px; text-align: left center }");
1504 myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock, this);
1505 myObjectBrowser->initialize(myModule->rootNode());
1506 myModule->customizeObjectBrowser(myObjectBrowser);
1507 aObjDock->setWidget(myObjectBrowser);
1508 aObjDock->setObjectName("Object browser");
1510 connect(myObjectBrowser, SIGNAL(sizeChanged()), SLOT(onDockSizeChanged()));
1512 myContextMenuMgr->connectObjectBrowser();
1516 //******************************************************
1518 * Creates dock widgets, places them in corresponding area
1519 * and tabifies if necessary.
1521 void XGUI_Workshop::createDockWidgets()
1523 QMainWindow* aDesktop = desktop();
1524 QDockWidget* aObjDock = createObjectBrowser(aDesktop);
1525 aDesktop->addDockWidget(Qt::LeftDockWidgetArea, aObjDock);
1526 myPropertyPanel = new XGUI_PropertyPanel(aDesktop, myOperationMgr);
1527 myActiveControlMgr->addSelector(new XGUI_PropertyPanelSelector(myPropertyPanel));
1529 myPropertyPanel->setupActions(myActionsMgr);
1530 myPropertyPanel->setAllowedAreas(Qt::LeftDockWidgetArea |
1531 Qt::RightDockWidgetArea);
1532 aDesktop->addDockWidget(Qt::LeftDockWidgetArea, myPropertyPanel);
1534 hidePanel(myPropertyPanel); ///<! Invisible by default
1536 myFacesPanel = new XGUI_FacesPanel(aDesktop, this);
1537 myActiveControlMgr->addSelector(new XGUI_FacesPanelSelector(myFacesPanel));
1538 myFacesPanel->setAllowedAreas(Qt::LeftDockWidgetArea |
1539 Qt::RightDockWidgetArea |
1540 Qt::BottomDockWidgetArea);
1541 connect(myFacesPanel, SIGNAL(closed()), myFacesPanel, SLOT(onClosed()));
1543 myInspectionPanel = new XGUI_InspectionPanel(aDesktop, this);
1544 myInspectionPanel->setAllowedAreas(Qt::LeftDockWidgetArea |
1545 Qt::RightDockWidgetArea);
1546 aDesktop->addDockWidget(Qt::RightDockWidgetArea, myInspectionPanel);
1548 myInspectionPanel->hide();
1550 aDesktop->addDockWidget(
1552 Qt::RightDockWidgetArea,
1554 Qt::LeftDockWidgetArea,
1557 hidePanel(myFacesPanel); ///<! Invisible by default
1560 bool aShowOnTheRight = Config_PropManager::boolean("Plugins", "show_hide_faces");
1561 if (aShowOnTheRight) {
1562 aDesktop->addDockWidget(Qt::RightDockWidgetArea, myFacesPanel);
1563 showPanel(myFacesPanel);
1566 hideObjectBrowser();
1570 if (!aShowOnTheRight)
1573 aDesktop->tabifyDockWidget(myFacesPanel, aObjDock);
1578 #endif // HAVE_SALOME
1580 aDesktop->tabifyDockWidget(aObjDock, myPropertyPanel);
1581 myPropertyPanel->installEventFilter(myOperationMgr);
1583 QAction* aOkAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
1584 connect(aOkAct, SIGNAL(triggered()), this, SLOT(onAcceptActionClicked()));
1586 QAction* aOkContAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptPlus);
1587 connect(aOkContAct, SIGNAL(triggered()), this, SLOT(onAcceptPlusActionClicked()));
1589 QAction* aCancelAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Abort);
1590 connect(aCancelAct, SIGNAL(triggered()), myOperationMgr, SLOT(onAbortOperation()));
1592 QAction* aPreviewAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Preview);
1593 connect(aPreviewAct, SIGNAL(triggered()), this, SLOT(onPreviewActionClicked()));
1595 QAction* aHelpAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Help);
1596 connect(aHelpAct, SIGNAL(triggered()), this, SLOT(onHelpActionClicked()));
1598 connect(myPropertyPanel, SIGNAL(keyReleased(QObject*, QKeyEvent*)),
1599 myOperationMgr, SLOT(onKeyReleased(QObject*, QKeyEvent*)));
1600 connect(myPropertyPanel, SIGNAL(enterClicked(QObject*)),
1601 myOperationMgr, SLOT(onProcessEnter(QObject*)));
1604 //******************************************************
1605 void XGUI_Workshop::showPanel(QDockWidget* theDockWidget)
1607 if (theDockWidget == myPropertyPanel) {
1608 QAction* aViewAct = myPropertyPanel->toggleViewAction();
1609 ///<! Restore ability to close panel from the window's menu
1610 aViewAct->setEnabled(true);
1612 theDockWidget->show();
1613 theDockWidget->raise();
1615 // The next code is necessary to made the property panel the active window
1616 // in order to operation manager could process key events of the panel.
1617 // otherwise they are ignored. It happens only if the same(activateWindow) is
1618 // not happened by property panel activation(e.g. resume operation of Sketch)
1619 //ModuleBase_Tools::setFocus(theDockWidget, "XGUI_Workshop::showPanel()");
1622 //******************************************************
1623 void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget)
1625 if (theDockWidget && theDockWidget == myPropertyPanel) {
1626 QAction* aViewAct = theDockWidget->toggleViewAction();
1627 ///<! Do not allow to show empty property panel
1628 aViewAct->setEnabled(false);
1630 theDockWidget->hide();
1632 // the property panel is active window of the desktop, when it is
1633 // hidden, it is undefined which window becomes active. By this reason
1634 // it is defined to perform the desktop as the active window.
1635 // in SALOME mode, work-stack made the PyConsole the active window,
1636 // set the focus on it. As a result, shortcuts of the application, like
1637 // are processed by this console. For example Undo actions.
1638 // It is possible that this code is to be moved to SHAPER package
1639 QMainWindow* aDesktop = desktop();
1640 ModuleBase_Tools::setFocus(aDesktop, "XGUI_Workshop::hidePanel()");
1643 //******************************************************
1644 void XGUI_Workshop::showObjectBrowser()
1646 if (!isSalomeMode()) {
1647 myObjectBrowser->parentWidget()->show();
1651 //******************************************************
1652 void XGUI_Workshop::hideObjectBrowser()
1654 if (!isSalomeMode())
1655 myObjectBrowser->parentWidget()->hide();
1658 //******************************************************
1659 void XGUI_Workshop::salomeViewerSelectionChanged()
1661 emit salomeViewerSelection();
1664 //**************************************************************
1665 ModuleBase_IViewer* XGUI_Workshop::salomeViewer() const
1667 return mySalomeConnector->viewer();
1670 //**************************************************************
1671 void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
1673 QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
1674 if (theId == "DELETE_CMD")
1676 else if (theId == "CLEAN_HISTORY_CMD")
1678 else if (theId == "MOVE_CMD" || theId == "MOVE_SPLIT_CMD")
1679 moveObjects(theId == "MOVE_SPLIT_CMD");
1680 else if (theId == "COLOR_CMD")
1681 changeColor(aObjects);
1682 else if (theId == "ISOLINES_CMD")
1683 changeIsoLines(aObjects);
1684 else if (theId == "DEFLECTION_CMD")
1685 changeDeflection(aObjects);
1686 else if (theId == "TRANSPARENCY_CMD")
1687 changeTransparency(aObjects);
1688 else if (theId == "SHOW_CMD") {
1689 showObjects(aObjects, true);
1690 mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
1691 updateCommandStatus();
1693 else if (theId == "HIDE_CMD") {
1694 showObjects(aObjects, false);
1695 updateCommandStatus();
1697 else if (theId == "SHOW_ONLY_CMD") {
1698 showOnlyObjects(aObjects);
1699 mySelector->updateSelectionBy(ModuleBase_ISelection::Browser);
1700 updateCommandStatus();
1702 else if (theId == "SHADING_CMD")
1703 setDisplayMode(aObjects, XGUI_Displayer::Shading);
1704 else if (theId == "WIREFRAME_CMD")
1705 setDisplayMode(aObjects, XGUI_Displayer::Wireframe);
1706 else if (theId == "HIDEALL_CMD") {
1707 QObjectPtrList aList = myDisplayer->displayedObjects();
1708 foreach (ObjectPtr aObj, aList) {
1709 if (module()->canEraseObject(aObj))
1710 aObj->setDisplayed(false);
1712 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
1714 //issue #2159 Hide all incomplete behavior
1715 viewer()->eraseAll();
1717 updateCommandStatus();
1718 // Necessary for update icons in ObjectBrowser on Linux
1719 myObjectBrowser->updateAllIndexes();
1720 } else if (theId == "SELECT_VERTEX_CMD") {
1721 setViewerSelectionMode(TopAbs_VERTEX);
1722 } else if (theId == "SELECT_EDGE_CMD") {
1723 setViewerSelectionMode(TopAbs_EDGE);
1724 } else if (theId == "SELECT_FACE_CMD") {
1725 setViewerSelectionMode(TopAbs_FACE);
1726 } else if (theId == "INSERT_FOLDER_CMD") {
1727 insertFeatureFolder();
1728 } else if (theId == "ADD_TO_FOLDER_BEFORE_CMD") {
1729 insertToFolder(true);
1730 } else if (theId == "ADD_TO_FOLDER_AFTER_CMD") {
1731 insertToFolder(false);
1732 } else if (theId == "ADD_OUT_FOLDER_BEFORE_CMD") {
1733 moveOutFolder(true);
1734 } else if (theId == "ADD_OUT_FOLDER_AFTER_CMD") {
1735 moveOutFolder(false);
1736 } else if (theId == "SELECT_RESULT_CMD") {
1737 //setViewerSelectionMode(-1);
1738 //IMP: an attempt to use result selection with other selection modes
1739 setViewerSelectionMode(ModuleBase_ResultPrs::Sel_Result);
1740 setViewerSelectionMode(TopAbs_COMPSOLID);
1741 } else if (theId == "SHOW_RESULTS_CMD") {
1742 highlightResults(aObjects);
1743 } else if (theId == "SHOW_FEATURE_CMD") {
1744 highlightFeature(aObjects);
1745 } else if (theId == "SET_VIEW_NORMAL_CMD") {
1747 } else if (theId == "SET_VIEW_INVERTEDNORMAL_CMD") {
1748 setNormalView(true);
1751 else if (theId == "TINSPECTOR_VIEW") {
1752 Handle(CDF_Application) anApplication = CDF_Session::CurrentSession()->CurrentApplication();
1753 if (!anApplication.IsNull())
1755 if (!MyTCommunicator)
1757 MyTCommunicator = new TInspector_Communicator();
1759 NCollection_List<Handle(Standard_Transient)> aParameters;
1760 aParameters.Append(anApplication);
1761 Handle(AIS_InteractiveContext) aContext = viewer()->AISContext();
1762 if (!aContext.IsNull())
1763 aParameters.Append(aContext);
1765 #ifdef DEBUG_WITH_MESSAGE_REPORT
1766 Handle(Message_Report) aContextReport = aContext->GetReport();
1767 aContext->SetReportActive (Standard_True);
1768 aContextReport->SetLimit (1000);
1769 if (!aContextReport.IsNull())
1770 aParameters.Append(aContextReport);
1772 MyVCallBack = new VInspector_CallBack();
1773 myDisplayer->setCallBack(MyVCallBack);
1775 AppElements_Viewer* aViewer = mainWindow()->viewer();
1777 aViewer->setCallBack(MyVCallBack);
1779 aParameters.Append(MyVCallBack);
1781 MyTCommunicator->RegisterPlugin("TKDFBrowser");
1782 MyTCommunicator->RegisterPlugin("TKShapeView");
1783 MyTCommunicator->RegisterPlugin("TKVInspector");
1784 #ifdef DEBUG_WITH_MESSAGE_REPORT
1785 MyTCommunicator->RegisterPlugin("TKMessageView");
1787 //MyTCommunicator->RegisterPlugin("SMBrowser"); // custom plugin to view ModelAPI
1788 //MyTCommunicator->RegisterPlugin("TKSMBrowser"); // custom plugin to view ModelAPI
1790 MyTCommunicator->Init(aParameters);
1791 MyTCommunicator->Activate("TKSMBrowser"); // to have button in TInspector
1792 #ifndef DEBUG_WITH_MESSAGE_REPORT
1793 MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
1795 MyTCommunicator->Activate("TKDFBrowser");
1797 #ifdef DEBUG_WITH_MESSAGE_REPORT
1798 MyTCommunicator->Activate("TKMessageView"); // temporary
1799 MyTCommunicator->Activate("TKVInspector"); // to have filled callback by model
1802 MyTCommunicator->SetVisible(true);
1808 //**************************************************************
1809 void XGUI_Workshop::setViewerSelectionMode(int theMode)
1812 myViewerSelMode.clear();
1814 if (myViewerSelMode.contains(theMode))
1815 myViewerSelMode.removeAll(theMode);
1817 myViewerSelMode.append(theMode);
1819 selectionActivate()->updateSelectionModes();
1822 //**************************************************************
1823 void XGUI_Workshop::activateObjectsSelection(const QObjectPtrList& theList)
1826 module()->activeSelectionModes(aModes);
1827 if (aModes.isEmpty() && (myViewerSelMode.length() > 0))
1828 aModes.append(myViewerSelMode);
1829 selectionActivate()->activateObjects(aModes, theList);
1832 //**************************************************************
1833 bool XGUI_Workshop::prepareForDisplay(const std::set<ObjectPtr>& theObjects) const
1835 if (facesPanel()->isEmpty())
1838 // generate container of objects taking into account sub elments of compsolid
1839 std::set<ObjectPtr> anAllProcessedObjects;
1840 for (std::set<ObjectPtr>::const_iterator anObjectsIt = theObjects.begin();
1841 anObjectsIt != theObjects.end(); anObjectsIt++) {
1842 ObjectPtr anObject = *anObjectsIt;
1843 ResultBodyPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObject);
1844 if (aCompRes.get()) {
1845 std::list<ResultPtr> allRes;
1846 ModelAPI_Tools::allSubs(aCompRes, allRes);
1847 if (allRes.empty()) {
1848 anAllProcessedObjects.insert(anObject);
1850 for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
1851 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRes);
1852 if (aBody.get() && aBody->numberOfSubs() == 0)
1853 anAllProcessedObjects.insert(aBody);
1857 anAllProcessedObjects.insert(anObject);
1860 // find hidden objects in faces panel
1861 std::set<ObjectPtr> aHiddenObjects;
1862 QStringList aHiddenObjectNames;
1863 for (std::set<ObjectPtr>::const_iterator anObjectsIt = anAllProcessedObjects.begin();
1864 anObjectsIt != anAllProcessedObjects.end(); anObjectsIt++) {
1865 if (!facesPanel()->isObjectHiddenByPanel(*anObjectsIt))
1867 aHiddenObjects.insert(*anObjectsIt);
1868 aHiddenObjectNames.append((*anObjectsIt)->data()->name().c_str());
1870 if (aHiddenObjects.empty()) // in parameter objects there are no hidden objects in hide face
1873 int anAnswer = QMessageBox::question(
1874 desktop(), tr("Show object"),
1875 tr("'%1'\n are hidden by %2:\nRemove objects from the panel to be displayed?")
1876 .arg(aHiddenObjectNames.join(", ")).arg(facesPanel()->windowTitle()),
1877 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
1879 bool aToBeDisplayed = anAnswer == QMessageBox::Yes;
1881 facesPanel()->restoreObjects(aHiddenObjects);
1883 return aToBeDisplayed;
1886 //**************************************************************
1887 void XGUI_Workshop::deleteObjects()
1889 ModuleBase_IModule* aModule = module();
1890 // allow the module to delete objects, do nothing if it has succeed
1891 if (aModule->deleteObjects()) {
1892 updateCommandStatus();
1893 myDisplayer->updateViewer();
1897 QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
1898 if (anObjects.isEmpty())
1901 if (!abortAllOperations())
1904 bool hasResult = false;
1905 bool hasFeature = false;
1906 bool hasParameter = false;
1907 bool hasCompositeOwner = false;
1908 bool hasResultInHistory = false;
1909 bool hasFolder = false;
1910 ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasCompositeOwner,
1911 hasResultInHistory, hasFolder);
1912 if (!(hasResult || hasFeature || hasParameter || hasFolder))
1915 // Remove from the list non-deletable objects: infinite constructions which are not in history
1916 bool notDelete = true;
1917 QObjectPtrList::iterator aIt;
1918 for (aIt = anObjects.begin(); aIt != anObjects.end(); aIt++) {
1919 ObjectPtr aObj = (*aIt);
1920 ResultConstructionPtr aConstr = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aObj);
1921 FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
1923 notDelete = (!aFeature->isInHistory()) && aConstr->isInfinite();
1925 anObjects.removeAll(aObj);
1931 std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
1932 std::set<FeaturePtr> aFeatures;
1933 ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
1934 ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
1936 std::set<FolderPtr> aFolders;
1937 ModuleBase_Tools::convertToFolders(anObjects, aFolders);
1940 QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text() + " %1";
1941 aDescription = aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
1942 ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription, module());
1944 operationMgr()->startOperation(anOpAction);
1946 std::set<FeaturePtr> aFeatureRefsToDelete;
1947 if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, desktop(), aFeatureRefsToDelete)) {
1948 // WORKAROUND, should be done before each object remove, if it presents in XGUI_DataModel tree
1949 // It is necessary to clear selection in order to avoid selection changed event during
1950 // deletion and negative consequences connected with processing of already deleted items
1951 mySelector->clearSelection();
1953 if (!aFeatureRefsToDelete.empty())
1954 aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
1955 aDone = ModelAPI_Tools::removeFeatures(aFeatures, false);
1957 if (aFolders.size() > 0) {
1958 std::set<FolderPtr>::const_iterator anIt = aFolders.begin(),
1959 aLast = aFolders.end();
1960 for (; anIt != aLast; anIt++) {
1961 FolderPtr aFolder = *anIt;
1962 if (aFolder.get()) {
1963 DocumentPtr aDoc = aFolder->document();
1964 aDoc->removeFolder(aFolder);
1968 // remove results selected
1969 std::list<ResultPtr> aResults;
1970 for(QObjectPtrList::const_iterator anIt = anObjects.begin(); anIt != anObjects.end(); anIt++) {
1971 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(*anIt);
1972 if (aRes.get() && aRes->data()->isValid() && !aRes->data()->isDeleted() &&
1973 aRes->groupName() != ModelAPI_ResultGroup::group() && // don't remove groups and fields
1974 aRes->groupName() != ModelAPI_ResultField::group()) // because they are badly selected
1975 aResults.push_back(aRes);
1977 if (!aResults.empty()) {
1978 ModelAPI_Tools::removeResults(aResults);
1982 operationMgr()->commitOperation();
1984 operationMgr()->abortOperation(operationMgr()->currentOperation());
1986 myDisplayer->updateViewer();
1989 //**************************************************************
1990 void addRefsToFeature(const FeaturePtr& theFeature,
1991 const std::map<FeaturePtr, std::set<FeaturePtr> >& theMainList,
1992 std::set<FeaturePtr>& theReferences)
1994 //if (theReferences.find(theFeature) != theReferences.end())
1996 if (theMainList.find(theFeature) == theMainList.end())
1997 return; // this feature is not in the selection list, so exists without references to it
1998 std::set<FeaturePtr> aMainReferences = theMainList.at(theFeature);
2000 std::set<FeaturePtr>::const_iterator anIt = aMainReferences.begin(),
2001 aLast = aMainReferences.end();
2002 for (; anIt != aLast; anIt++) {
2003 FeaturePtr aRefFeature = *anIt;
2004 if (theReferences.find(aRefFeature) == theReferences.end())
2005 theReferences.insert(aRefFeature);
2006 addRefsToFeature(aRefFeature, theMainList, theReferences);
2010 //**************************************************************
2011 void XGUI_Workshop::cleanHistory()
2013 if (!abortAllOperations())
2016 QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
2017 std::set<FeaturePtr> aFeatures;
2018 ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
2020 #ifdef DEBUG_CLEAN_HISTORY
2022 std::set<FeaturePtr>::const_iterator aFIt;
2023 for (aFIt = aFeatures.begin(); aFIt != aFeatures.end(); ++aFIt) {
2024 FeaturePtr aFeature = ModelAPI_Feature::feature(*aFIt);
2025 anInfo.append(aFeature->name().c_str());
2027 QString anInfoStr = anInfo.join(";\t");
2028 qDebug(QString("cleanHistory for: [%1] - %2").
2029 arg(aFeatures.size()).arg(anInfoStr).toStdString().c_str());
2032 std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
2033 ModelAPI_Tools::findAllReferences(aFeatures, aReferences, true, false);
2034 // find for each object whether all reference values are in the map as key, that means that there
2035 // is no other reference in the model to this object, so it might be removed by cleaning history
2036 // sk_1(ext_1, vertex_1) + (sk_3, bool_1) - can't be deleted, dependency to bool_1
2037 // ext_1(bool_1, sk_3) - can't be deleted, dependency to bool_1
2039 // sk_2(ext_2) + (bool_1) - can't be deleted, dependency to bool_1
2040 // ext_2(bool_1) - can't be deleted, dependency to bool_1
2042 // Information: bool_1 is not selected
2043 std::set<FeaturePtr> anUnusedObjects;
2044 std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aReferences.begin(),
2045 aMainLast = aReferences.end();
2046 for (; aMainIt != aMainLast; aMainIt++) {
2047 FeaturePtr aMainListFeature = aMainIt->first;
2048 std::set<FeaturePtr> aMainRefList = aMainIt->second;
2049 std::set<FeaturePtr>::const_iterator aRefIt = aMainRefList.begin(),
2050 aRefLast = aMainRefList.end();
2051 bool aFeatureOutOfTheList = false;
2052 for (; aRefIt != aRefLast && !aFeatureOutOfTheList; aRefIt++) {
2053 FeaturePtr aRefFeature = *aRefIt;
2054 aFeatureOutOfTheList = aReferences.find(aRefFeature) == aReferences.end();
2056 if (!aFeatureOutOfTheList)
2057 anUnusedObjects.insert(aMainListFeature);
2060 #ifdef DEBUG_CLEAN_HISTORY
2062 for (aFIt = anUnusedObjects.begin(); aFIt != anUnusedObjects.end(); ++aFIt) {
2063 FeaturePtr aFeature = *aFIt;
2064 anInfo.append(aFeature->name().c_str());
2066 qDebug(QString("unused objects: [%1] - %2").
2067 arg(anInfo.size()).arg(anInfo.join(";\t")).toStdString().c_str());
2070 // warn about the references remove, break the delete operation if the user chose it
2071 if (!anUnusedObjects.empty()) {
2073 foreach (const FeaturePtr& aFeature, anUnusedObjects) {
2074 aNames.append(aFeature->name().c_str());
2077 QString anUnusedNames = aNames.join(", ");
2079 QString anActionId = "CLEAN_HISTORY_CMD";
2080 QString aDescription = ModuleBase_Tools::translate("workshop",
2081 contextMenuMgr()->action(anActionId)->text().toStdString());
2083 QMessageBox aMessageBox(desktop());
2084 aMessageBox.setWindowTitle(aDescription);
2085 aMessageBox.setIcon(QMessageBox::Warning);
2086 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
2087 aMessageBox.setDefaultButton(QMessageBox::No);
2089 const char* aKeyStr = "Unused features are the following: "
2090 "%1.\nThese features will be deleted.\nWould you like to continue?";
2091 QString aText = QString(tr(aKeyStr).arg(anUnusedNames));
2092 aMessageBox.setText(aText);
2093 if (aMessageBox.exec() == QMessageBox::No)
2096 // 1. start operation
2097 aDescription += "by deleting of " +
2098 aDescription.arg(XGUI_Tools::unionOfObjectNames(anObjects, ", "));
2099 ModuleBase_Operation* anOpAction = new ModuleBase_Operation(aDescription, module());
2100 operationMgr()->startOperation(anOpAction);
2102 // WORKAROUND, should be done before each object remove, if it presents in XGUI_DataModel tree
2103 // It is necessary to clear selection in order to avoid selection changed event during
2104 // deletion and negative consequences connected with processing of already deleted items
2105 mySelector->clearSelection();
2107 std::set<FeaturePtr> anIgnoredFeatures;
2108 if (ModelAPI_Tools::removeFeatures(anUnusedObjects, true)) {
2109 operationMgr()->commitOperation();
2112 operationMgr()->abortOperation(operationMgr()->currentOperation());
2116 QString anActionId = "CLEAN_HISTORY_CMD";
2117 QString aDescription = contextMenuMgr()->action(anActionId)->text();
2119 QMessageBox aMessageBox(desktop());
2120 aMessageBox.setWindowTitle(aDescription);
2121 aMessageBox.setIcon(QMessageBox::Warning);
2122 aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
2123 aMessageBox.setDefaultButton(QMessageBox::No);
2126 aMessageBox.setStandardButtons(QMessageBox::Ok);
2127 aMessageBox.setDefaultButton(QMessageBox::Ok);
2129 aText = QString(tr("All features are relevant, there is nothing to be deleted"));
2130 aMessageBox.setText(aText);
2132 if (aMessageBox.exec() == QMessageBox::No)
2137 //**************************************************************
2138 bool compareFeature(const FeaturePtr& theF1, const FeaturePtr& theF2) {
2139 DocumentPtr aDoc = theF1->document();
2140 return aDoc->index(theF1) < aDoc->index(theF2);
2142 void XGUI_Workshop::moveObjects(const bool theSplit)
2144 if (!abortAllOperations())
2147 SessionPtr aMgr = ModelAPI_Session::get();
2149 QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
2150 // It is necessary to clear selection in order to avoid selection changed event during
2151 // moving and negative consequences connected with processing of already moved items
2152 mySelector->clearSelection();
2153 // check whether the object can be moved. There should not be parts which are not loaded
2154 std::set<FeaturePtr> aFeatures;
2155 ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
2156 if (!XGUI_Tools::canRemoveOrRename(desktop(), aFeatures))
2159 QString anActionId = theSplit ? "MOVE_CMD" : "MOVE_SPLIT_CMD";
2160 QString aDescription = contextMenuMgr()->action(anActionId)->text();
2161 aMgr->startOperation(aDescription.toStdString());
2163 // Sort features by index in document
2164 std::list<FeaturePtr> aFList(aFeatures.begin(), aFeatures.end());
2165 aFList.sort(compareFeature);
2167 DocumentPtr anActiveDocument = aMgr->activeDocument();
2168 FeaturePtr aCurrentFeature = anActiveDocument->currentFeature(true);
2169 std::list<FeaturePtr>::const_iterator anIt = aFList.begin(), aLast = aFList.end();
2170 for (; anIt != aLast; anIt++) {
2171 FeaturePtr aFeature = *anIt;
2172 if (!aFeature.get() || !myModule->canApplyAction(aFeature, anActionId))
2175 anActiveDocument->moveFeature(aFeature, aCurrentFeature, theSplit);
2176 aCurrentFeature = anActiveDocument->currentFeature(true);
2178 aMgr->finishOperation();
2179 updateCommandStatus();
2180 myViewerProxy->update();
2183 //**************************************************************
2184 bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theObjects)
2186 std::set<FeaturePtr> aFeatures;
2187 ModuleBase_Tools::convertToFeatures(theObjects, aFeatures);
2189 return ModelAPI_Tools::removeFeaturesAndReferences(aFeatures);
2192 //******************************************************
2193 bool hasResults(QObjectPtrList theObjects, const std::set<std::string>& theTypes)
2195 bool isFoundResultType = false;
2196 foreach(ObjectPtr anObj, theObjects)
2198 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
2199 if (aResult.get() == NULL)
2202 isFoundResultType = theTypes.find(aResult->groupName()) != theTypes.end();
2203 if (isFoundResultType)
2206 return isFoundResultType;
2209 //**************************************************************
2210 // Returns the list of all features for theDocument and all features of
2211 // all nested parts.
2212 std::list<FeaturePtr> allFeatures(const DocumentPtr& theDocument)
2214 std::list<FeaturePtr> aResultList;
2215 std::list<FeaturePtr> anAllFeatures = theDocument->allFeatures();
2216 foreach (const FeaturePtr& aFeature, anAllFeatures) {
2217 // The order of appending features of the part and the part itself is important
2219 // Append features from a part feature
2220 std::list<ResultPtr> aResults;
2221 ModelAPI_Tools::allResults(aFeature, aResults);
2222 foreach (const ResultPtr& aResult, aResults) {
2223 ResultPartPtr aResultPart =
2224 std::dynamic_pointer_cast<ModelAPI_ResultPart>(aResult);
2225 if (aResultPart.get() && aResultPart->partDoc().get()) {
2227 std::list<FeaturePtr> anAllFeatures = allFeatures(aResultPart->partDoc());
2228 aResultList.insert(aResultList.end(), anAllFeatures.begin(), anAllFeatures.end());
2232 aResultList.push_back(aFeature);
2237 //**************************************************************
2238 // Returns the list of features placed between theObject and the current feature
2239 // in the same document. Excludes theObject, includes the current feature.
2240 std::list<FeaturePtr> toCurrentFeatures(const ObjectPtr& theObject)
2242 std::list<FeaturePtr> aResult;
2243 DocumentPtr aDocument = theObject->document();
2244 std::list<FeaturePtr> anAllFeatures = allFeatures(aDocument);
2245 // find the object iterator
2246 std::list<FeaturePtr>::iterator aObjectIt =
2247 std::find(anAllFeatures.begin(), anAllFeatures.end(), theObject);
2248 if (aObjectIt == anAllFeatures.end())
2250 // find the current feature iterator
2251 std::list<FeaturePtr>::iterator aCurrentIt =
2252 std::find(anAllFeatures.begin(), anAllFeatures.end(), aDocument->currentFeature(true));
2253 if (aCurrentIt == anAllFeatures.end())
2255 // check the right order
2256 if (std::distance(aObjectIt, anAllFeatures.end()) <=
2257 std::distance(aCurrentIt, anAllFeatures.end()))
2259 // exclude the object
2260 std::advance(aObjectIt, 1);
2261 // include the current feature
2262 std::advance(aCurrentIt, 1);
2263 return std::list<FeaturePtr>(aObjectIt, aCurrentIt);
2266 //******************************************************
2267 bool XGUI_Workshop::canMoveFeature()
2269 QString anActionId = "MOVE_CMD";
2271 QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
2272 QObjectPtrList aValidatedObjects;
2273 foreach (ObjectPtr aObject, aObjects) {
2274 if (!myModule->canApplyAction(aObject, anActionId))
2276 // To be moved feature should be in active document
2277 if (aObject->document() != ModelAPI_Session::get()->activeDocument())
2279 aValidatedObjects.append(aObject);
2281 if (aValidatedObjects.size() != aObjects.size())
2282 aObjects = aValidatedObjects;
2284 bool aCanMove = !aObjects.empty();
2286 QObjectPtrList::const_iterator anIt = aObjects.begin(), aLast = aObjects.end();
2287 for (; anIt != aLast && aCanMove; anIt++) {
2288 ObjectPtr aObject = *anIt;
2289 if (!aObject.get() || !aObject->data().get() || !aObject->data()->isValid()) {
2293 FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
2294 // only groups can be moved to the end for now (#2451)
2295 if (aFeat.get() && aFeat->getKind() != "Group") {
2300 // 1. Get features placed between selected and current in the document
2301 std::list<FeaturePtr> aFeaturesBetween = toCurrentFeatures(aObject);
2302 // if aFeaturesBetween is empty it means wrong order or aObject is the current feature
2303 if (aFeaturesBetween.empty())
2306 std::set<FeaturePtr> aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end());
2307 // 2. Get all reference features to the selected object in the document
2308 std::set<FeaturePtr> aRefFeatures;
2309 ModuleBase_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures);
2311 if (aRefFeatures.empty())
2314 // 3. Find any placed features in all reference features
2315 std::set<FeaturePtr> aIntersectionFeatures;
2316 std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(),
2317 aPlacedFeatures.begin(), aPlacedFeatures.end(),
2318 std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin()));
2319 // 4. Return false if any reference feature is placed before current feature
2320 if (!aIntersectionFeatures.empty())
2328 //**************************************************************
2329 bool XGUI_Workshop::canBeShaded(const ObjectPtr& theObject) const
2331 bool aCanBeShaded = myDisplayer->canBeShaded(theObject);
2332 if (!aCanBeShaded) {
2333 ResultBodyPtr aCompRes = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theObject);
2334 if (aCompRes.get() != NULL) { // change colors for all sub-solids
2335 std::list<ResultPtr> allRes;
2336 ModelAPI_Tools::allSubs(aCompRes, allRes);
2337 std::list<ResultPtr>::iterator aRes = allRes.begin();
2338 for(; aRes != allRes.end() && !aCanBeShaded; aRes++) {
2339 aCanBeShaded = myDisplayer->canBeShaded(*aRes);
2343 return aCanBeShaded;
2346 //**************************************************************
2347 bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const
2349 if (theActionName == "COLOR_CMD" ||
2350 theActionName == "DEFLECTION_CMD" ||
2351 theActionName == "TRANSPARENCY_CMD") {
2352 QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
2354 std::set<std::string> aTypes;
2355 aTypes.insert(ModelAPI_ResultGroup::group());
2356 aTypes.insert(ModelAPI_ResultConstruction::group());
2357 aTypes.insert(ModelAPI_ResultBody::group());
2358 aTypes.insert(ModelAPI_ResultPart::group());
2360 return hasResults(aObjects, aTypes);
2366 //**************************************************************
2367 void getDefaultColor(ObjectPtr theObject, const bool isEmptyColorValid,
2368 std::vector<int>& theColor)
2371 // get default color from the preferences manager for the given result
2372 if (theColor.empty()) {
2373 std::string aSection, aName, aDefault;
2374 theObject->colorConfigInfo(aSection, aName, aDefault);
2375 if (!aSection.empty() && !aName.empty()) {
2376 theColor = Config_PropManager::color(aSection, aName);
2379 if (!isEmptyColorValid && theColor.empty()) {
2380 // all AIS objects, where the color is not set, are in black.
2381 // The color should be defined in XML or set in the attribute
2382 theColor = Config_PropManager::color("Visualization", "object_default_color");
2383 Events_InfoMessage("XGUI_CustomPrs",
2384 "A default color is not defined in the preferences for this kind of result").send();
2388 //**************************************************************
2389 void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
2392 AttributeIntArrayPtr aColorAttr;
2393 // 1. find the current color of the object. This is a color of AIS presentation
2394 // The objects are iterated until a first valid color is found
2395 std::vector<int> aColor;
2396 foreach(ObjectPtr anObject, theObjects) {
2397 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
2398 if (aResult.get()) {
2399 ModelAPI_Tools::getColor(aResult, aColor);
2401 getDefaultColor(aResult, false, aColor);
2404 // TODO: remove the obtaining a color from the AIS object
2405 // this does not happen never because:
2406 // 1. The color can be changed only on results
2407 // 2. The result can be not visualized in the viewer(e.g. Origin Construction)
2408 AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
2409 if (anAISObj.get()) {
2411 anAISObj->getColor(aColor[0], aColor[1], aColor[2]);
2414 if (!aColor.empty())
2417 if (aColor.size() != 3)
2420 if (!abortAllOperations())
2422 // 2. show the dialog to change the value
2423 XGUI_ColorDialog* aDlg = new XGUI_ColorDialog(desktop());
2424 aDlg->setColor(aColor);
2425 aDlg->move(QCursor::pos());
2426 bool isDone = aDlg->exec() == QDialog::Accepted;
2430 bool isRandomColor = aDlg->isRandomColor();
2432 // 3. abort the previous operation and start a new one
2433 SessionPtr aMgr = ModelAPI_Session::get();
2434 QString aDescription = contextMenuMgr()->action("COLOR_CMD")->text();
2435 aMgr->startOperation(aDescription.toStdString());
2437 // 4. set the value to all results
2438 std::vector<int> aColorResult = aDlg->getColor();
2439 foreach(ObjectPtr anObj, theObjects) {
2440 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
2441 if (aResult.get() != NULL) {
2442 ResultBodyPtr aBodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
2443 if (aBodyResult.get() != NULL) { // change colors for all sub-solids
2444 std::list<ResultPtr> allRes;
2445 ModelAPI_Tools::allSubs(aBodyResult, allRes);
2446 for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
2447 ModelAPI_Tools::setColor(*aRes, !isRandomColor ? aColorResult : aDlg->getRandomColor());
2450 ModelAPI_Tools::setColor(aResult, !isRandomColor ? aColorResult : aDlg->getRandomColor());
2453 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2454 aMgr->finishOperation();
2455 updateCommandStatus();
2456 myViewerProxy->update();
2459 //**************************************************************
2460 void setTransparency(double theTransparency, const QObjectPtrList& theObjects)
2462 foreach(ObjectPtr anObj, theObjects) {
2463 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
2464 if (aResult.get() != NULL) {
2465 ResultBodyPtr aBodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
2466 if (aBodyResult.get() != NULL) { // change property for all sub-solids
2467 std::list<ResultPtr> allRes;
2468 ModelAPI_Tools::allSubs(aBodyResult, allRes);
2469 std::list<ResultPtr>::iterator aRes;
2470 for(aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
2471 ModelAPI_Tools::setTransparency(*aRes, theTransparency);
2474 ModelAPI_Tools::setTransparency(aResult, theTransparency);
2479 //**************************************************************
2480 double getDefaultDeflection(const ObjectPtr& theObject)
2482 double aDeflection = -1;
2483 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
2484 if (aResult.get()) {
2485 bool isConstruction = false;
2487 std::string aResultGroup = aResult->groupName();
2488 if (aResultGroup == ModelAPI_ResultConstruction::group())
2489 isConstruction = true;
2490 else if (aResultGroup == ModelAPI_ResultBody::group()) {
2491 GeomShapePtr aGeomShape = aResult->shape();
2492 if (aGeomShape.get()) {
2493 // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
2494 // correction of deviation for them should not influence to the application performance
2495 GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
2496 isConstruction = !anExp.more();
2500 aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
2502 aDeflection = Config_PropManager::real("Visualization", "body_deflection");
2507 //**************************************************************
2508 void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects)
2510 AttributeDoublePtr aDoubleAttr;
2511 // 1. find the current property of the object. This is a property of AIS presentation
2512 // The objects are iterated until a first valid property is found
2513 double aDeflection = -1;
2514 foreach(ObjectPtr anObject, theObjects) {
2515 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
2516 if (aResult.get()) {
2517 aDeflection = ModelAPI_Tools::getDeflection(aResult);
2518 if (aDeflection < 0)
2519 aDeflection = getDefaultDeflection(aResult);
2522 // TODO: remove the obtaining a property from the AIS object
2523 // this does not happen never because:
2524 // 1. The property can be changed only on results
2525 // 2. The result can be not visualized in the viewer(e.g. Origin Construction)
2526 AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
2527 if (anAISObj.get()) {
2528 aDeflection = anAISObj->getDeflection();
2531 if (aDeflection > 0)
2534 if (aDeflection < 0)
2537 if (!abortAllOperations())
2539 // 2. show the dialog to change the value
2540 XGUI_DeflectionDialog* aDlg = new XGUI_DeflectionDialog(desktop());
2541 aDlg->setDeflection(aDeflection);
2542 aDlg->move(QCursor::pos());
2543 bool isDone = aDlg->exec() == QDialog::Accepted;
2547 // 3. abort the previous operation and start a new one
2548 SessionPtr aMgr = ModelAPI_Session::get();
2549 QString aDescription = contextMenuMgr()->action("DEFLECTION_CMD")->text();
2550 aMgr->startOperation(aDescription.toStdString());
2552 // 4. set the value to all results
2553 aDeflection = aDlg->getDeflection();
2554 foreach(ObjectPtr anObj, theObjects) {
2555 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
2556 if (aResult.get() != NULL) {
2557 ResultBodyPtr aBodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
2558 if (aBodyResult.get() != NULL) { // change property for all sub-solids
2559 std::list<ResultPtr> allRes;
2560 ModelAPI_Tools::allSubs(aBodyResult, allRes);
2561 for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
2562 ModelAPI_Tools::setDeflection(*aRes, aDeflection);
2565 ModelAPI_Tools::setDeflection(aResult, aDeflection);
2568 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2569 aMgr->finishOperation();
2570 updateCommandStatus();
2573 //**************************************************************
2574 double getDefaultTransparency(const ResultPtr& theResult)
2576 return Config_PropManager::integer("Visualization", "shaper_default_transparency") / 100.;
2579 //**************************************************************
2580 void XGUI_Workshop::changeTransparency(const QObjectPtrList& theObjects)
2582 AttributeDoublePtr aDoubleAttr;
2583 // 1. find the current property of the object. This is a property of AIS presentation
2584 // The objects are iterated until a first valid property is found
2585 double aCurrentValue = -1;
2586 foreach(ObjectPtr anObject, theObjects) {
2587 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
2588 if (aResult.get()) {
2589 aCurrentValue = ModelAPI_Tools::getTransparency(aResult);
2590 if (aCurrentValue < 0)
2591 aCurrentValue = getDefaultTransparency(aResult);
2593 if (aCurrentValue > 0)
2596 if (aCurrentValue < 0)
2599 if (!abortAllOperations())
2602 // 2. show the dialog to change the value
2603 XGUI_PropertyDialog* aDlg = new XGUI_PropertyDialog(desktop());
2604 aDlg->setWindowTitle(tr("Transparency"));
2605 XGUI_TransparencyWidget* aTransparencyWidget = new XGUI_TransparencyWidget(aDlg);
2606 connect(aTransparencyWidget, SIGNAL(transparencyValueChanged()),
2607 this, SLOT(onTransparencyValueChanged()));
2608 aDlg->setContent(aTransparencyWidget);
2609 aTransparencyWidget->setValue(aCurrentValue);
2611 // 3. abort the previous operation and start a new one
2612 SessionPtr aMgr = ModelAPI_Session::get();
2613 QString aDescription = contextMenuMgr()->action("TRANSPARENCY_CMD")->text();
2614 aMgr->startOperation(aDescription.toStdString());
2616 if (aDlg->exec() == QDialog::Accepted) {
2617 // 4. set the value to all results
2618 aCurrentValue = aTransparencyWidget->getValue();
2619 setTransparency(aCurrentValue, theObjects);
2620 aMgr->finishOperation();
2622 aMgr->abortOperation();
2623 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2626 updateCommandStatus();
2629 //**************************************************************
2630 void XGUI_Workshop::onTransparencyValueChanged()
2632 XGUI_TransparencyWidget* aTransparencyWidget = (XGUI_TransparencyWidget*)sender();
2633 if (!aTransparencyWidget)
2636 QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
2637 setTransparency(aTransparencyWidget->getValue(), anObjects);
2638 static const Events_ID kRedisplayEvent =
2639 Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
2640 Events_Loop::loop()->flush(kRedisplayEvent);
2642 myViewerProxy->update();
2646 //******************************************************
2647 void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
2650 std::set<ObjectPtr> anObjects;
2651 foreach (ObjectPtr aObj, theList) {
2652 anObjects.insert(aObj);
2654 if (!prepareForDisplay(anObjects))
2658 foreach (ObjectPtr aObj, theList) {
2659 aObj->setDisplayed(isVisible);
2661 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2662 myObjectBrowser->updateAllIndexes();
2664 updateColorScaleVisibility();
2665 displayer()->updateViewer();
2668 //**************************************************************
2669 void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
2671 QObjectPtrList aSrcList = theList;
2672 // Hide all displayed objects
2673 QObjectPtrList aList = myDisplayer->displayedObjects();
2674 foreach (ObjectPtr aObj, aList) {
2675 if ((!aSrcList.contains(aObj)) && (module()->canEraseObject(aObj)))
2676 aObj->setDisplayed(false);
2678 aSrcList.removeAll(aObj);
2680 //Do not use eraseAll if you didn't send Redisplay event:
2681 //all objects are erased from viewer, but considered as displayed in displayer
2682 // Problem in bug 2218
2683 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2685 //issue #2159 Hide all incomplete behavior
2686 viewer()->eraseAll();
2689 std::set<ObjectPtr> anObjects;
2690 foreach (ObjectPtr aObj, aSrcList) {
2691 anObjects.insert(aObj);
2694 if (!prepareForDisplay(anObjects))
2697 // Show only objects from the list
2698 foreach (ObjectPtr aObj, aSrcList) {
2699 aObj->setDisplayed(true);
2701 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2703 // Necessary for update icons in ObjectBrowser on Linux
2704 myObjectBrowser->updateAllIndexes();
2705 updateColorScaleVisibility();
2706 displayer()->updateViewer();
2710 //**************************************************************
2711 void XGUI_Workshop::updateColorScaleVisibility()
2713 QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
2714 viewer()->setColorScaleShown(false);
2715 if (aObjects.size() == 1) {
2716 FieldStepPtr aStep =
2717 std::dynamic_pointer_cast<ModelAPI_ResultField::ModelAPI_FieldStep>(aObjects.first());
2718 if (aStep.get() && myDisplayer->isVisible(aStep)) {
2719 AISObjectPtr aAisPtr = myDisplayer->getAISObject(aStep);
2720 Handle(AIS_InteractiveObject) aIO = aAisPtr->impl<Handle(AIS_InteractiveObject)>();
2721 ModuleBase_IStepPrs* aPrs = dynamic_cast<ModuleBase_IStepPrs*>(aIO.get());
2723 ModelAPI_AttributeTables::ValueType aType = aPrs->dataType();
2724 if ((aType == ModelAPI_AttributeTables::DOUBLE) ||
2725 (aType == ModelAPI_AttributeTables::INTEGER) ||
2726 (aType == ModelAPI_AttributeTables::BOOLEAN)) {
2727 myViewerProxy->setupColorScale();
2728 if (aType == ModelAPI_AttributeTables::BOOLEAN) {
2729 myViewerProxy->setColorScaleIntervals(2);
2730 myViewerProxy->setColorScaleRange(0., 1.);
2734 aPrs->dataRange(aMin, aMax);
2735 myViewerProxy->setColorScaleRange(aMin, aMax);
2737 myViewerProxy->setColorScaleTitle(aStep->name().c_str());
2738 myViewerProxy->setColorScaleShown(true);
2746 //**************************************************************
2747 void XGUI_Workshop::setNormalView(bool toInvert)
2749 QList<ModuleBase_ViewerPrsPtr> aPrsList =
2750 mySelector->selection()->getSelected(ModuleBase_ISelection::Viewer);
2751 GeomShapePtr aPlanarFace;
2752 foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) {
2753 GeomShapePtr aShape = aPrs->shape();
2754 if (aShape.get() && aShape->isPlanar()) {
2755 aPlanarFace = aShape;
2759 if (aPlanarFace.get()) {
2760 GeomFacePtr aFace(new GeomAPI_Face(aPlanarFace));
2761 GeomPlanePtr aPlane = aFace->getPlane();
2762 GeomDirPtr aNormal = aPlane->direction();
2765 GeomPointPtr aPos = aPlane->location();
2767 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2768 aFace->computeSize(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2770 Handle(V3d_View) aView = myViewerProxy->activeView();
2771 double aScale = aView->Scale();
2772 aView->SetAt(aPos->x(), aPos->y(), aPos->z());
2773 aView->SetProj(aNormal->x(), aNormal->y(), aNormal->z());
2775 aBox.Update(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2776 aView->FitAll(aBox);
2780 //**************************************************************
2781 void XGUI_Workshop::registerValidators() const
2783 SessionPtr aMgr = ModelAPI_Session::get();
2784 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
2787 //**************************************************************
2788 void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc)
2792 displayGroupResults(theDoc, ModelAPI_ResultConstruction::group());
2793 displayGroupResults(theDoc, ModelAPI_ResultBody::group());
2796 //**************************************************************
2797 void XGUI_Workshop::displayGroupResults(DocumentPtr theDoc, std::string theGroup)
2799 for (int i = 0; i < theDoc->size(theGroup); i++)
2800 theDoc->object(theGroup, i)->setDisplayed(true);
2801 //displayObject(theDoc->object(theGroup, i));
2802 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
2805 //**************************************************************
2806 void XGUI_Workshop::setDisplayMode(const QObjectPtrList& theList, int theMode)
2808 foreach(ObjectPtr anObj, theList) {
2809 myDisplayer->setDisplayMode(anObj, (XGUI_Displayer::DisplayMode)theMode, false);
2811 ResultBodyPtr aBodyResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObj);
2812 if (aBodyResult.get() != NULL) { // change display mode for all sub-solids
2813 std::list<ResultPtr> allRes;
2814 ModelAPI_Tools::allSubs(aBodyResult, allRes);
2815 for(std::list<ResultPtr>::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) {
2816 myDisplayer->setDisplayMode(*aRes, (XGUI_Displayer::DisplayMode)theMode, false);
2820 if (theList.size() > 0)
2821 myDisplayer->updateViewer();
2824 //**************************************************************
2825 void XGUI_Workshop::closeDocument()
2827 ModuleBase_Operation* anOperation = operationMgr()->currentOperation();
2828 while (anOperation) {
2829 anOperation->abort();
2830 anOperation = operationMgr()->currentOperation();
2832 //myDisplayer->closeLocalContexts();
2833 myDisplayer->eraseAll();
2834 objectBrowser()->clearContent();
2836 module()->closeDocument();
2837 // we need to clear viewer (with created filters) to do not have problems in 2nd SALOME study
2838 module()->clearViewer();
2841 // data model need not process the document's signals about objects modifications as
2842 // the document is closed
2843 //bool isBlocked = objectBrowser()->dataModel()->blockEventsProcessing(true);
2845 SessionPtr aMgr = ModelAPI_Session::get();
2848 //objectBrowser()->dataModel()->blockEventsProcessing(isBlocked);
2851 //******************************************************
2852 void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot)
2854 XGUI_HistoryMenu* aMenu = NULL;
2855 if (isSalomeMode()) {
2856 QAction* anAction = qobject_cast<QAction*>(theObject);
2859 aMenu = new XGUI_HistoryMenu(anAction);
2861 QToolButton* aButton = qobject_cast<QToolButton*>(theObject);
2862 aMenu = new XGUI_HistoryMenu(aButton);
2864 connect(this, theSignal, aMenu, SLOT(setHistory(const QList<ActionInfo>&)));
2865 connect(aMenu, SIGNAL(actionSelected(int)), this, theSlot);
2868 //******************************************************
2869 QList<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>& theList) const
2871 QList<ActionInfo> aResult;
2872 std::list<std::string>::const_iterator it = theList.cbegin();
2873 for (; it != theList.cend(); it++) {
2874 QString anId = QString::fromStdString(*it);
2875 bool isEditing = anId.endsWith(ModuleBase_OperationFeature::EditSuffix());
2877 anId.chop(ModuleBase_OperationFeature::EditSuffix().size());
2880 QAction* aContextMenuAct = myContextMenuMgr->actionByName(anId);
2881 if (aContextMenuAct) {
2882 anInfo.initFrom(aContextMenuAct);
2884 anInfo = myActionsMgr->actionInfoById(anId);
2887 anInfo.text = anInfo.text.prepend("Modify ");
2894 //******************************************************
2895 void XGUI_Workshop::setStatusBarMessage(const QString& theMessage)
2898 salomeConnector()->putInfo(theMessage, -1);
2900 myMainWindow->putInfo(theMessage, -1);
2905 //******************************************************
2906 void XGUI_Workshop::synchronizeViewer()
2908 SessionPtr aMgr = ModelAPI_Session::get();
2909 QList<DocumentPtr> aDocs;
2910 aDocs.append(aMgr->activeDocument());
2911 aDocs.append(aMgr->moduleDocument());
2913 foreach(DocumentPtr aDoc, aDocs) {
2914 synchronizeGroupInViewer(aDoc, false);
2918 //******************************************************
2919 void XGUI_Workshop::synchronizeGroupInViewer(const DocumentPtr& theDoc,
2920 bool theUpdateViewer)
2922 FeaturePtr aFeature;
2924 int aSize = theDoc->numInternalFeatures();
2925 for (int i = 0; i < aSize; i++) {
2926 aFeature = theDoc->internalFeature(i);
2927 if (!aFeature.get())
2929 const std::list<ResultPtr>& aResults = aFeature->results();
2930 std::list<ResultPtr>::const_iterator aIt;
2931 aFeature->setDisplayed(false);
2932 for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) {
2934 if (aRes->isDisplayed() && !aRes->isConcealed()) {
2935 // Hide the presentation with an empty shape. But isDisplayed state of the object should not
2936 // be changed to the object becomes visible when the shape becomes not empty
2937 if (!aRes->shape().get() || aRes->shape()->isNull())
2939 ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aRes);
2941 synchronizeResultTree(aResBody, false);
2943 if (aRes->isInHistory()) {
2944 if (aRes->isDisplayed())
2945 myDisplayer->display(aRes, false);
2947 myDisplayer->erase(aRes, false);
2950 aRes->setDisplayed(false);
2955 if (theUpdateViewer)
2956 myDisplayer->updateViewer();
2959 void XGUI_Workshop::synchronizeResultTree(const ResultBodyPtr& theRes, bool theUpdateViewer)
2961 if (theRes->numberOfSubs() > 0)
2962 for (int i = 0; i < theRes->numberOfSubs(); i++) {
2963 ResultBodyPtr aRes = theRes->subResult(i);
2965 synchronizeResultTree(aRes, theUpdateViewer);
2968 if (theRes->isDisplayed())
2969 myDisplayer->display(theRes, theUpdateViewer);
2971 myDisplayer->erase(theRes, theUpdateViewer);
2976 //******************************************************
2977 void XGUI_Workshop::highlightResults(const QObjectPtrList& theObjects)
2979 FeaturePtr aFeature;
2980 QObjectPtrList aSelList = theObjects;
2981 QObjectPtrList aNewSel;
2982 bool aHasHidden = false;
2983 foreach(ObjectPtr aObj, theObjects) {
2984 aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
2985 if (aFeature.get()) {
2986 std::list<ResultPtr> aResults;
2987 ModelAPI_Tools::allResults(aFeature, aResults);
2988 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aIt;
2989 for(aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) {
2990 aHasHidden |= (*aIt)->isConcealed();
2991 aSelList.append(*aIt);
2992 aNewSel.append(*aIt);
2996 if (aSelList.count() > theObjects.count()) {
2997 // if something was found
2998 objectBrowser()->setObjectsSelected(aSelList);
2999 objectBrowser()->ensureVisible(aNewSel.first());
3002 QMessageBox::information(desktop(), tr("Find results"),
3003 tr("Results not found"), QMessageBox::Ok);
3006 //******************************************************
3007 void XGUI_Workshop::highlightFeature(const QObjectPtrList& theObjects)
3010 QObjectPtrList aSelList = theObjects;
3011 QObjectPtrList aNewSel;
3012 FeaturePtr aFeature;
3013 foreach(ObjectPtr aObj, theObjects) {
3014 aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
3015 if (aResult.get()) {
3016 aFeature = ModelAPI_Feature::feature(aResult);
3017 if (aFeature.get()) {
3018 aSelList.append(aFeature);
3019 aNewSel.append(aFeature);
3023 if (aSelList.count() > theObjects.count()) {
3024 // if something was found
3025 objectBrowser()->setObjectsSelected(aSelList);
3026 objectBrowser()->ensureVisible(aNewSel.first());
3030 void XGUI_Workshop::insertFeatureFolder()
3032 QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
3033 if (aObjects.isEmpty())
3035 ObjectPtr aObj = aObjects.first();
3036 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
3037 if (aFeature.get() == NULL)
3039 SessionPtr aMgr = ModelAPI_Session::get();
3040 DocumentPtr aDoc = aMgr->activeDocument();
3042 QString aDescription = contextMenuMgr()->action("INSERT_FOLDER_CMD")->text();
3044 aMgr->startOperation(aDescription.toStdString());
3045 aDoc->addFolder(aFeature);
3046 aMgr->finishOperation();
3048 updateCommandStatus();
3052 void XGUI_Workshop::insertToFolder(bool isBefore)
3054 std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
3055 if (aFeatures.empty())
3058 SessionPtr aMgr = ModelAPI_Session::get();
3059 DocumentPtr aDoc = aMgr->activeDocument();
3061 FolderPtr aFolder = isBefore? aDoc->findFolderAbove(aFeatures):
3062 aDoc->findFolderBelow(aFeatures);
3066 QString aDescription = contextMenuMgr()->action(
3067 isBefore ? "ADD_TO_FOLDER_BEFORE_CMD" : "ADD_TO_FOLDER_AFTER_CMD")->text();
3069 QMap<ObjectPtr, bool> aStates = myObjectBrowser->getFoldersState(aDoc);
3071 aMgr->startOperation(aDescription.toStdString());
3072 aDoc->moveToFolder(aFeatures, aFolder);
3073 aMgr->finishOperation();
3075 myObjectBrowser->setFoldersState(aStates);
3077 updateCommandStatus();
3080 void XGUI_Workshop::moveOutFolder(bool isBefore)
3082 std::list<FeaturePtr> aFeatures = mySelector->getSelectedFeatures();
3083 if (aFeatures.empty())
3086 SessionPtr aMgr = ModelAPI_Session::get();
3087 DocumentPtr aDoc = aMgr->activeDocument();
3089 QString aDescription = contextMenuMgr()->action(
3090 isBefore ? "ADD_OUT_FOLDER_BEFORE_CMD" : "ADD_OUT_FOLDER_AFTER_CMD")->text();
3092 QMap<ObjectPtr, bool> aStates = myObjectBrowser->getFoldersState(aDoc);
3094 aMgr->startOperation(aDescription.toStdString());
3095 aDoc->removeFromFolder(aFeatures, isBefore);
3096 aMgr->finishOperation();
3098 myObjectBrowser->setFoldersState(aStates);
3100 updateCommandStatus();
3103 void XGUI_Workshop::onAutoApply()
3105 SessionPtr aMgr = ModelAPI_Session::get();
3106 bool isBlocked = aMgr->isAutoUpdateBlocked();
3107 aMgr->blockAutoUpdate(!isBlocked);
3110 void XGUI_Workshop::updateAutoComputeState()
3112 SessionPtr aMgr = ModelAPI_Session::get();
3113 bool isComputeBlocked = aMgr->isAutoUpdateBlocked();
3115 // QAction* aUpdateCmd;
3116 // QList<QAction*> aCommands = mySalomeConnector->commandList();
3117 // foreach(QAction* aCmd, aCommands) {
3118 // if (aCmd->data().toString() == "AUTOCOMPUTE_CMD") {
3119 // aUpdateCmd = aCmd;
3123 // aUpdateCmd->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") :
3124 // QIcon(":pictures/autoapply_start.png"));
3126 AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
3127 AppElements_Command* aUpdateCmd = aMenuBar->feature("AUTOCOMPUTE_CMD");
3128 aUpdateCmd->button()->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") :
3129 QIcon(":pictures/autoapply_start.png"));
3134 void XGUI_Workshop::clearTemporaryDir()
3136 QDir aDir(myTmpDir.path());
3137 if (!aDir.isEmpty()) {
3138 QStringList aEntries;
3139 aDir.entryList(aEntries);
3140 foreach(QString aFile, aEntries) {
3147 void XGUI_Workshop::onDockSizeChanged()
3149 QDockWidget* aDockWgt = dynamic_cast<QDockWidget*>(myObjectBrowser->parentWidget());
3150 int aObWidth = aDockWgt->size().width();
3151 if (myPropertyPanel->width() != aObWidth) {
3152 QList<QDockWidget*> aWgtList;
3153 aWgtList << myPropertyPanel << aDockWgt;
3154 QList<int> aSizeList;
3155 aSizeList << aObWidth << aObWidth;
3156 desktop()->resizeDocks(aWgtList, aSizeList, Qt::Horizontal);
3157 disconnect(myObjectBrowser, SIGNAL(sizeChanged()), this, SLOT(onDockSizeChanged()));
3161 void XGUI_Workshop::deactivateCurrentSelector()
3163 myActiveControlMgr->deactivateSelector(myActiveControlMgr->activeSelector());
3166 void XGUI_Workshop::changeIsoLines(const QObjectPtrList& theObjects)
3168 if (theObjects.isEmpty())
3171 std::vector<int> aValues;
3172 if (theObjects.size() == 1) {
3173 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObjects.first());
3175 ModelAPI_Tools::getIsoLines(aRes, aValues);
3179 if (aValues.size() == 0) {
3180 aValues.push_back(1);
3181 aValues.push_back(1);
3184 if (!abortAllOperations())
3188 aDlg.setWindowTitle(tr("Number of Iso-lines"));
3189 QFormLayout* aLayout = new QFormLayout(&aDlg);
3191 QSpinBox* aUNb = new QSpinBox(&aDlg);
3192 aUNb->setValue(aValues[0]);
3193 aLayout->addRow("U:", aUNb);
3195 QSpinBox* aVNb = new QSpinBox(&aDlg);
3196 aVNb->setValue(aValues[1]);
3197 aLayout->addRow("V:", aVNb);
3199 QDialogButtonBox* aButtons =
3200 new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &aDlg);
3201 connect(aButtons, SIGNAL(accepted()), &aDlg, SLOT(accept()));
3202 connect(aButtons, SIGNAL(rejected()), &aDlg, SLOT(reject()));
3203 aLayout->addRow(aButtons);
3205 if (aDlg.exec() == QDialog::Accepted) {
3206 SessionPtr aMgr = ModelAPI_Session::get();
3207 QString aDescription = contextMenuMgr()->action("ISOLINES_CMD")->text();
3208 aMgr->startOperation(aDescription.toStdString());
3210 aValues[0] = aUNb->value();
3211 aValues[1] = aVNb->value();
3213 foreach(ObjectPtr aObj, theObjects) {
3214 aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
3216 ModelAPI_Tools::setIsoLines(aRes, aValues);
3219 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
3220 aMgr->finishOperation();
3221 updateCommandStatus();