From 3dcf45e5e44045100e6370578ba5f39f78cd344e Mon Sep 17 00:00:00 2001 From: vsv Date: Wed, 21 Jan 2015 18:50:33 +0300 Subject: [PATCH] Issue #358: Prevent crashes on operations when viewer is absent --- src/NewGeom/NewGeom_Module.cpp | 19 +++++++++++- src/NewGeom/NewGeom_Module.h | 2 ++ src/NewGeom/NewGeom_SalomeViewer.cpp | 43 +++++++++++++++++++--------- src/PartSet/PartSet_Module.cpp | 4 ++- src/XGUI/XGUI_Displayer.cpp | 15 ++++++---- src/XGUI/XGUI_Selection.cpp | 15 ++++++---- 6 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/NewGeom/NewGeom_Module.cpp b/src/NewGeom/NewGeom_Module.cpp index 969295555..42c1a3d3b 100644 --- a/src/NewGeom/NewGeom_Module.cpp +++ b/src/NewGeom/NewGeom_Module.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -217,11 +218,27 @@ bool NewGeom_Module::deactivateModule(SUIT_Study* theStudy) //****************************************************** void NewGeom_Module::onViewManagerAdded(SUIT_ViewManager* theMgr) { - if ((!mySelector)) { + if (!mySelector) { mySelector = createSelector(theMgr); } } +//****************************************************** +void NewGeom_Module::onViewManagerRemoved(SUIT_ViewManager* theMgr) +{ + if (mySelector) { + if (theMgr->getType() == OCCViewer_Viewer::Type()) { + OCCViewer_Viewer* aViewer = static_cast(theMgr->getViewModel()); + if (mySelector->viewer() == aViewer) { + myWorkshop->displayer()->eraseAll(false); + myProxyViewer->setSelector(0); + delete mySelector; + mySelector = 0; + } + } + } +} + //****************************************************** QtxPopupMgr* NewGeom_Module::popupMgr() { diff --git a/src/NewGeom/NewGeom_Module.h b/src/NewGeom/NewGeom_Module.h index 83719845e..8bb37249b 100644 --- a/src/NewGeom/NewGeom_Module.h +++ b/src/NewGeom/NewGeom_Module.h @@ -100,6 +100,8 @@ Q_OBJECT protected slots: virtual void onViewManagerAdded(SUIT_ViewManager* theMgr); + virtual void onViewManagerRemoved(SUIT_ViewManager* theMgr); + void onDefaultPreferences(); // Obtains the current application and updates its actions void onUpdateCommandStatus(); diff --git a/src/NewGeom/NewGeom_SalomeViewer.cpp b/src/NewGeom/NewGeom_SalomeViewer.cpp index 3a1050248..288b0c02a 100644 --- a/src/NewGeom/NewGeom_SalomeViewer.cpp +++ b/src/NewGeom/NewGeom_SalomeViewer.cpp @@ -52,16 +52,21 @@ Handle(AIS_InteractiveContext) NewGeom_SalomeViewer::AISContext() const //********************************************** Handle(V3d_Viewer) NewGeom_SalomeViewer::v3dViewer() const { - return mySelector->viewer()->getViewer3d(); + if (mySelector) + return mySelector->viewer()->getViewer3d(); + return Handle(V3d_Viewer)(); } //********************************************** Handle(V3d_View) NewGeom_SalomeViewer::activeView() const { - OCCViewer_Viewer* aViewer = mySelector->viewer(); - SUIT_ViewManager* aMgr = aViewer->getViewManager(); - OCCViewer_ViewWindow* aWnd = static_cast(aMgr->getActiveView()); - return aWnd->getViewPort()->getView(); + if (mySelector) { + OCCViewer_Viewer* aViewer = mySelector->viewer(); + SUIT_ViewManager* aMgr = aViewer->getViewManager(); + OCCViewer_ViewWindow* aWnd = static_cast(aMgr->getActiveView()); + return aWnd->getViewPort()->getView(); + } + return Handle(V3d_View)(); } //********************************************** @@ -205,41 +210,51 @@ void NewGeom_SalomeViewer::enableSelection(bool isEnabled) //mySelector->viewer()->enableSelection(isEnabled); // The enableSelection() in SALOME 7.5 cause of forced Viewer update(we have blinking) // After this is corrected, the first row should be recommented, the last - removed - mySelector->viewer()->setInteractionStyle(isEnabled ? SUIT_ViewModel::STANDARD - : SUIT_ViewModel::KEY_FREE); + if (mySelector) + mySelector->viewer()->setInteractionStyle(isEnabled ? SUIT_ViewModel::STANDARD + : SUIT_ViewModel::KEY_FREE); } //********************************************** bool NewGeom_SalomeViewer::isSelectionEnabled() const { - return mySelector->viewer()->isSelectionEnabled(); + if (mySelector) + return mySelector->viewer()->isSelectionEnabled(); } //********************************************** void NewGeom_SalomeViewer::enableMultiselection(bool isEnable) { - mySelector->viewer()->enableMultiselection(isEnable); + if (mySelector) + mySelector->viewer()->enableMultiselection(isEnable); } //********************************************** bool NewGeom_SalomeViewer::isMultiSelectionEnabled() const { - return mySelector->viewer()->isMultiSelectionEnabled(); + if (mySelector) + return mySelector->viewer()->isMultiSelectionEnabled(); + return false; } //********************************************** void NewGeom_SalomeViewer::fitAll() { - SUIT_ViewManager* aMgr = mySelector->viewer()->getViewManager(); - OCCViewer_ViewFrame* aVFrame = dynamic_cast(aMgr->getActiveView()); - if (aVFrame) { - aVFrame->onFitAll(); + if (mySelector) { + SUIT_ViewManager* aMgr = mySelector->viewer()->getViewManager(); + OCCViewer_ViewFrame* aVFrame = dynamic_cast(aMgr->getActiveView()); + if (aVFrame) { + aVFrame->onFitAll(); + } } } //********************************************** void NewGeom_SalomeViewer::setViewProjection(double theX, double theY, double theZ) { + if (!mySelector) + return; + SUIT_ViewManager* aMgr = mySelector->viewer()->getViewManager(); OCCViewer_ViewFrame* aVFrame = dynamic_cast(aMgr->getActiveView()); if (aVFrame) { diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 797fcd116..66a4e52da 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -139,7 +139,9 @@ void PartSet_Module::operationCommitted(ModuleBase_Operation* theOperation) // the selection is cleared after commit the create operation // in order to do not use the same selected objects in the restarted operation // for common behaviour, the selection is cleared even if the operation is not restarted - myWorkshop->viewer()->AISContext()->ClearSelected(); + Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (!aContext.IsNull()) + aContext->ClearSelected(); /// Restart sketcher operations automatically FeaturePtr aFeature = theOperation->feature(); diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 8dd2d2e25..f544c5b43 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -310,6 +310,8 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes) } myActiveSelectionModes = aNewModes; Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; // Open local context if there is no one if (!aContext->HasOpenedContext()) return; @@ -435,19 +437,18 @@ void XGUI_Displayer::clearSelected() void XGUI_Displayer::eraseAll(const bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); - if (aContext.IsNull()) - return; - + if (!aContext.IsNull()) { foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) { // erase an object Handle(AIS_InteractiveObject) anIO = aAISObj->impl(); if (!anIO.IsNull()) aContext->Remove(anIO, false); } - myResult2AISObjectMap.clear(); if (isUpdateViewer) updateViewer(); - } + } + myResult2AISObjectMap.clear(); +} void XGUI_Displayer::openLocalContext() { @@ -601,6 +602,8 @@ Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter() void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { aContext->Display(anAISIO, isUpdate); @@ -621,6 +624,8 @@ void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate) void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate) { Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; Handle(AIS_InteractiveObject) anAISIO = theAIS->impl(); if (!anAISIO.IsNull()) { aContext->Remove(anAISIO, isUpdate); diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index 23b11c9fb..30c623181 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -33,6 +33,9 @@ QList XGUI_Selection::getSelected(int theShapeTypeToSkip) XGUI_Displayer* aDisplayer = myWorkshop->displayer(); Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); + if (aContext.IsNull()) + return aPresentations; + if (aContext->HasOpenedContext()) { for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { ModuleBase_ViewerPrs aPrs; @@ -112,11 +115,13 @@ QObjectPtrList XGUI_Selection::selectedPresentations() const QObjectPtrList aSelectedList; Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext(); - for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { - Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); - ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO); - if (aResult) - aSelectedList.append(aResult); + if (!aContext.IsNull()) { + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); + ObjectPtr aResult = myWorkshop->displayer()->getObject(anIO); + if (aResult) + aSelectedList.append(aResult); + } } return aSelectedList; } -- 2.39.2