changeset 1606:874e178f34e9

- ViewportController now has weak ptr to Viewport - Measuring tools + related commands and all trackers now store only a weak_ptr to the Viewport and lock() on demand for usage - LayerHolder and FixedPoint aligner store only a weak_ptr to the Viewport, too - Fixed float/double warning in GrayscaleWindowingSceneTracker
author Benjamin Golinvaux <bgo@osimis.io>
date Wed, 28 Oct 2020 20:14:34 +0100
parents b3c439d96d3e
children 2df998314507
files OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.cpp OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.h OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.cpp OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.h OrthancStone/Sources/Scene2D/PanSceneTracker.cpp OrthancStone/Sources/Scene2D/PanSceneTracker.h OrthancStone/Sources/Scene2D/RotateSceneTracker.cpp OrthancStone/Sources/Scene2D/RotateSceneTracker.h OrthancStone/Sources/Scene2D/ZoomSceneTracker.cpp OrthancStone/Sources/Scene2D/ZoomSceneTracker.h OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.cpp OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.h OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.cpp OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.h OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.cpp OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.h OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.cpp OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.h OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.h OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.cpp OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.h OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.cpp OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.h OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.cpp OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.h OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.cpp OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.h OrthancStone/Sources/Scene2DViewport/LayerHolder.cpp OrthancStone/Sources/Scene2DViewport/LayerHolder.h OrthancStone/Sources/Scene2DViewport/LineMeasureTool.cpp OrthancStone/Sources/Scene2DViewport/LineMeasureTool.h OrthancStone/Sources/Scene2DViewport/MeasureCommands.cpp OrthancStone/Sources/Scene2DViewport/MeasureCommands.h OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp OrthancStone/Sources/Scene2DViewport/MeasureTool.h OrthancStone/Sources/Scene2DViewport/MeasureTrackers.cpp OrthancStone/Sources/Scene2DViewport/MeasureTrackers.h OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.cpp OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.h OrthancStone/Sources/Scene2DViewport/ViewportController.cpp OrthancStone/Sources/Scene2DViewport/ViewportController.h OrthancStone/Sources/Viewport/DefaultViewportInteractor.cpp OrthancStone/Sources/Viewport/DefaultViewportInteractor.h OrthancStone/Sources/Viewport/IViewportInteractor.h OrthancStone/Sources/Volumes/VolumeSceneLayerSource.cpp OrthancStone/Sources/Volumes/VolumeSceneLayerSource.h
diffstat 47 files changed, 273 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -38,10 +38,11 @@
       FloatTextureSceneLayer*             layer_;
 
     public:
-      GrayscaleLayerAccessor(boost::shared_ptr<IViewport> viewport,
+      GrayscaleLayerAccessor(boost::weak_ptr<IViewport> viewportWeak,
                              int layerIndex) :
         layer_(NULL)
       {
+        boost::shared_ptr<IViewport> viewport = viewportWeak.lock();
         if (viewport != NULL)
         {
           lock_.reset(viewport->Lock());
@@ -89,7 +90,8 @@
   {
     if (active_)
     {
-      GrayscaleLayerAccessor accessor(viewport_, layerIndex_);
+      boost::shared_ptr<IViewport> viewport = viewport_.lock();
+      GrayscaleLayerAccessor accessor(viewport, layerIndex_);
       
       if (accessor.IsValid())
       {
@@ -100,7 +102,7 @@
   }
     
 
-  GrayscaleWindowingSceneTracker::GrayscaleWindowingSceneTracker(boost::shared_ptr<IViewport> viewport,
+  GrayscaleWindowingSceneTracker::GrayscaleWindowingSceneTracker(boost::weak_ptr<IViewport> viewport,
                                                                  int layerIndex,
                                                                  const PointerEvent& event,
                                                                  unsigned int canvasWidth,
@@ -115,7 +117,8 @@
     if (canvasWidth > 3 &&
         canvasHeight > 3)
     {
-      GrayscaleLayerAccessor accessor(viewport_, layerIndex_);
+      boost::weak_ptr<IViewport> viewport = viewport_.lock();
+      GrayscaleLayerAccessor accessor(viewport, layerIndex_);
       
       if (accessor.IsValid())
       {
@@ -143,8 +146,8 @@
       const double x = event.GetMainPosition().GetX();
       const double y = event.GetMainPosition().GetY();
 
-      float center = originalCenter_ + (x - clickX_) * normalization_;
-      float width = originalWidth_ + (y - clickY_) * normalization_;
+      float center = originalCenter_ + static_cast<float>((x - clickX_) * normalization_);
+      float width = originalWidth_ + static_cast<float>((y - clickY_) * normalization_);
 
       if (width <= 1)
       {
--- a/OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/GrayscaleWindowingSceneTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -46,7 +46,7 @@
                       float width);
     
   public:
-    GrayscaleWindowingSceneTracker(boost::shared_ptr<IViewport> viewport,
+    GrayscaleWindowingSceneTracker(boost::weak_ptr<IViewport> viewport,
                                    int layerIndex,
                                    const PointerEvent& event,
                                    unsigned int canvasWidth,
--- a/OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -26,19 +26,27 @@
 {
   namespace Internals
   {
-    FixedPointAligner::FixedPointAligner(boost::shared_ptr<IViewport> viewport,
+    FixedPointAligner::FixedPointAligner(boost::weak_ptr<IViewport> viewport,
                                          const ScenePoint2D& p) 
       : viewport_(viewport)
       , canvas_(p)
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       pivot_ = canvas_.Apply(lock->GetController().GetCanvasToSceneTransform());
     }
 
+    IViewport::ILock* FixedPointAligner::GetViewportLock()
+    {
+      boost::shared_ptr<IViewport> viewport = viewport_.lock();
+      if (viewport)
+        return viewport->Lock();
+      else
+        return nullptr;
+    }
     
     void FixedPointAligner::Apply()
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ScenePoint2D p = canvas_.Apply(
         lock->GetController().GetCanvasToSceneTransform());
 
--- a/OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/Internals/FixedPointAligner.h	Wed Oct 28 20:14:34 2020 +0100
@@ -36,12 +36,18 @@
     class FixedPointAligner : public boost::noncopyable
     {
     private:
-      boost::shared_ptr<IViewport> viewport_;
-      ScenePoint2D           pivot_;
-      ScenePoint2D           canvas_;
+      boost::weak_ptr<IViewport> viewport_;
+      ScenePoint2D               pivot_;
+      ScenePoint2D               canvas_;
+
+      /**
+      This will return a scoped lock to the viewport.
+      If the viewport does not exist anymore, then nullptr is returned.
+      */
+      IViewport::ILock* GetViewportLock();
 
     public:
-      FixedPointAligner(boost::shared_ptr<IViewport> viewport,
+      FixedPointAligner(boost::weak_ptr<IViewport> viewport,
                         const ScenePoint2D& p);
 
       void Apply();
--- a/OrthancStone/Sources/Scene2D/PanSceneTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/PanSceneTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -28,12 +28,12 @@
 
 namespace OrthancStone
 {
-  PanSceneTracker::PanSceneTracker(boost::shared_ptr<IViewport> viewport,
+  PanSceneTracker::PanSceneTracker(boost::weak_ptr<IViewport> viewport,
                                    const PointerEvent& event)
     : OneGesturePointerTracker(viewport)
   {
     
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
     originalSceneToCanvas_ = lock->GetController().GetSceneToCanvasTransform();
     originalCanvasToScene_ = lock->GetController().GetCanvasToSceneTransform();
@@ -46,7 +46,7 @@
   {
     ScenePoint2D p = event.GetMainPosition().Apply(originalCanvasToScene_);
 
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
     lock->GetController().SetSceneToCanvasTransform(
       AffineTransform2D::Combine(
@@ -58,7 +58,7 @@
 
   void PanSceneTracker::Cancel()
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     lock->GetController().SetSceneToCanvasTransform(originalSceneToCanvas_);
   }
 }
--- a/OrthancStone/Sources/Scene2D/PanSceneTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/PanSceneTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -29,7 +29,7 @@
   class PanSceneTracker : public OneGesturePointerTracker
   {
   public:
-    PanSceneTracker(boost::shared_ptr<IViewport> viewport,
+    PanSceneTracker(boost::weak_ptr<IViewport> viewport,
                     const PointerEvent& event);
 
     virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Scene2D/RotateSceneTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/RotateSceneTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -24,7 +24,7 @@
 
 namespace OrthancStone
 {
-  RotateSceneTracker::RotateSceneTracker(boost::shared_ptr<IViewport> viewport,
+  RotateSceneTracker::RotateSceneTracker(boost::weak_ptr<IViewport> viewport,
                                          const PointerEvent& event) :
     OneGesturePointerTracker(viewport),
     click_(event.GetMainPosition()),
@@ -32,7 +32,7 @@
     referenceAngle_(0),
     isFirst_(true)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     originalSceneToCanvas_ = lock->GetController().GetSceneToCanvasTransform();
   }
 
@@ -54,7 +54,7 @@
         isFirst_ = false;
       }
 
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
       lock->GetController().SetSceneToCanvasTransform(
         AffineTransform2D::Combine(
@@ -69,7 +69,7 @@
   void RotateSceneTracker::Cancel()
   {
     // See remark above
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     lock->GetController().SetSceneToCanvasTransform(originalSceneToCanvas_);
     lock->Invalidate();
   }
--- a/OrthancStone/Sources/Scene2D/RotateSceneTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/RotateSceneTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -38,7 +38,7 @@
     AffineTransform2D            originalSceneToCanvas_;
 
   public:
-    RotateSceneTracker(boost::shared_ptr<IViewport> viewport,
+    RotateSceneTracker(boost::weak_ptr<IViewport> viewport,
                        const PointerEvent& event);
 
     virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Scene2D/ZoomSceneTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/ZoomSceneTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -25,7 +25,7 @@
 
 namespace OrthancStone
 {
-  ZoomSceneTracker::ZoomSceneTracker(boost::shared_ptr<IViewport> viewport,
+  ZoomSceneTracker::ZoomSceneTracker(boost::weak_ptr<IViewport> viewport,
                                      const PointerEvent& event,
                                      unsigned int canvasHeight)
     : OneGesturePointerTracker(viewport)
@@ -33,7 +33,7 @@
     , aligner_(viewport, event.GetMainPosition())
   {
     
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     originalSceneToCanvas_ = lock->GetController().GetSceneToCanvasTransform();
 
     if (canvasHeight <= 3)
@@ -77,7 +77,7 @@
 
       double zoom = pow(2.0, z);
 
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       lock->GetController().SetSceneToCanvasTransform(
         AffineTransform2D::Combine(
           AffineTransform2D::CreateScaling(zoom, zoom),
@@ -89,7 +89,7 @@
 
   void ZoomSceneTracker::Cancel()
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     lock->GetController().SetSceneToCanvasTransform(originalSceneToCanvas_);
     lock->Invalidate();
   }
--- a/OrthancStone/Sources/Scene2D/ZoomSceneTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2D/ZoomSceneTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -34,7 +34,7 @@
   class ZoomSceneTracker : public OneGesturePointerTracker
   {
   public:
-    ZoomSceneTracker(boost::shared_ptr<IViewport> viewport,
+    ZoomSceneTracker(boost::weak_ptr<IViewport> viewport,
                      const PointerEvent& event,
                      unsigned int canvasHeight);
 
--- a/OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -43,7 +43,7 @@
   // the params in the LayerHolder ctor specify the number of polyline and text
   // layers
   AngleMeasureTool::AngleMeasureTool(
-    boost::shared_ptr<IViewport> viewport)
+    boost::weak_ptr<IViewport> viewport)
     : MeasureTool(viewport)
 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1
     , layerHolder_(boost::shared_ptr<LayerHolder>(new LayerHolder(viewport,1,5)))
@@ -54,7 +54,7 @@
   {
   }
 
-  boost::shared_ptr<AngleMeasureTool> AngleMeasureTool::Create(boost::shared_ptr<IViewport> viewport)
+  boost::shared_ptr<AngleMeasureTool> AngleMeasureTool::Create(boost::weak_ptr<IViewport> viewport)
   {
     boost::shared_ptr<AngleMeasureTool> obj(new AngleMeasureTool(viewport));
     obj->MeasureTool::PostConstructor();
@@ -142,7 +142,7 @@
 
   AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     const ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
     
@@ -202,7 +202,7 @@
 
   boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
 
@@ -216,7 +216,7 @@
       new EditLineMeasureTracker(
         boost::shared_ptr<LineMeasureTool> measureTool;
         MessageBroker & broker,
-        boost::shared_ptr<IViewport>          viewport,
+        boost::weak_ptr<IViewport>          viewport,
         const PointerEvent & e);
     */
 
@@ -235,7 +235,7 @@
   {
     if (IsSceneAlive())
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
       Scene2D& scene = controller.GetScene();
 
--- a/OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/AngleMeasureTool.h	Wed Oct 28 20:14:34 2020 +0100
@@ -41,7 +41,7 @@
   class AngleMeasureTool : public MeasureTool
   {
   public:
-    static boost::shared_ptr<AngleMeasureTool> Create(boost::shared_ptr<IViewport> viewport);
+    static boost::shared_ptr<AngleMeasureTool> Create(boost::weak_ptr<IViewport> viewport);
 
     ~AngleMeasureTool();
 
@@ -71,7 +71,7 @@
     AngleHighlightArea AngleHitTest(ScenePoint2D p) const;
 
   private:
-    explicit AngleMeasureTool(boost::shared_ptr<IViewport> viewport);
+    explicit AngleMeasureTool(boost::weak_ptr<IViewport> viewport);
 
     virtual void        RefreshScene() ORTHANC_OVERRIDE;
     void                RemoveFromScene();
--- a/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -27,13 +27,13 @@
 namespace OrthancStone
 {
   CreateAngleMeasureCommand::CreateAngleMeasureCommand(
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     ScenePoint2D           point)
     : CreateMeasureCommand(viewport)
     , measureTool_(AngleMeasureTool::Create(viewport))
   {
     
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
 
     controller.AddMeasureTool(measureTool_);
--- a/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureCommand.h	Wed Oct 28 20:14:34 2020 +0100
@@ -29,7 +29,7 @@
   public:
     /** Ctor sets end of side 1*/
     CreateAngleMeasureCommand(
-      boost::shared_ptr<IViewport> viewport,
+      boost::weak_ptr<IViewport> viewport,
       ScenePoint2D           point);
 
     /** This method sets center*/
--- a/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -26,7 +26,7 @@
 
 namespace OrthancStone
 {
-  CreateAngleMeasureTracker::CreateAngleMeasureTracker(boost::shared_ptr<IViewport> viewport,
+  CreateAngleMeasureTracker::CreateAngleMeasureTracker(boost::weak_ptr<IViewport> viewport,
                                                        const PointerEvent& e) :
     CreateMeasureTracker(viewport),
     state_(CreatingSide1)
@@ -34,7 +34,7 @@
     ScenePoint2D point;
     
     {    
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       Scene2D& scene = lock->GetController().GetScene();
       point = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform());
     }
@@ -57,7 +57,7 @@
 
     
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
 
       ScenePoint2D scenePos = event.GetMainPosition().Apply(
--- a/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateAngleMeasureTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -39,7 +39,7 @@
     must be supplied, too
     */
     CreateAngleMeasureTracker(
-      boost::shared_ptr<IViewport>          viewport,
+      boost::weak_ptr<IViewport>          viewport,
       const PointerEvent&             e);
 
     ~CreateAngleMeasureTracker();
--- a/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -27,13 +27,13 @@
 namespace OrthancStone
 {
   CreateLineMeasureCommand::CreateLineMeasureCommand(
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     ScenePoint2D           point)
     : CreateMeasureCommand(viewport)
     , measureTool_(LineMeasureTool::Create(viewport))
   {
     
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     controller.AddMeasureTool(measureTool_);
     measureTool_->Set(point, point);
--- a/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureCommand.h	Wed Oct 28 20:14:34 2020 +0100
@@ -28,7 +28,7 @@
   {
   public:
     CreateLineMeasureCommand(
-      boost::shared_ptr<IViewport> viewport,
+      boost::weak_ptr<IViewport> viewport,
       ScenePoint2D           point);
 
     // the starting position is set in the ctor
--- a/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -27,14 +27,14 @@
 namespace OrthancStone
 {
   CreateLineMeasureTracker::CreateLineMeasureTracker(
-    boost::shared_ptr<IViewport>          viewport,
+    boost::weak_ptr<IViewport>          viewport,
     const PointerEvent&             e)
     : CreateMeasureTracker(viewport)
   {
     ScenePoint2D point;
     
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
       point = e.GetMainPosition().Apply(controller.GetScene().GetCanvasToSceneTransform());
     }
@@ -56,7 +56,7 @@
         "PointerMove: active_ == false");
     }
 
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
 
     ScenePoint2D scenePos = event.GetMainPosition().Apply(
--- a/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -39,7 +39,7 @@
     must be supplied, too
     */
     CreateLineMeasureTracker(
-      boost::shared_ptr<IViewport>          viewport,
+      boost::weak_ptr<IViewport>          viewport,
       const PointerEvent&             e);
 
     ~CreateLineMeasureTracker();
--- a/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -25,7 +25,7 @@
 {
   EditAngleMeasureCommand::EditAngleMeasureCommand(
     boost::shared_ptr<MeasureTool>  measureTool,
-    boost::shared_ptr<IViewport> viewport)
+    boost::weak_ptr<IViewport> viewport)
     : EditMeasureCommand(measureTool, viewport)
     , measureTool_(measureTool)
   {
--- a/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureCommand.h	Wed Oct 28 20:14:34 2020 +0100
@@ -30,7 +30,7 @@
     /** Ctor sets end of side 1*/
     EditAngleMeasureCommand(
       boost::shared_ptr<MeasureTool>  measureTool,
-      boost::shared_ptr<IViewport> viewport);
+      boost::weak_ptr<IViewport> viewport);
 
     /** This method sets center*/
     void SetCenter(ScenePoint2D scenePos);
--- a/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -28,14 +28,14 @@
 {
   EditAngleMeasureTracker::EditAngleMeasureTracker(
     boost::shared_ptr<MeasureTool>  measureTool,
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     const PointerEvent& e)
     : EditMeasureTracker(viewport, e)
   {
     ScenePoint2D scenePos;
     
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
       scenePos = e.GetMainPosition().Apply(controller.GetScene().GetCanvasToSceneTransform());
     }
@@ -51,7 +51,7 @@
 
   void EditAngleMeasureTracker::PointerMove(const PointerEvent& e)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     
     ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
--- a/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditAngleMeasureTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -39,7 +39,7 @@
     */
     EditAngleMeasureTracker(
       boost::shared_ptr<MeasureTool>  measureTool,
-      boost::shared_ptr<IViewport> viewport,
+      boost::weak_ptr<IViewport> viewport,
       const PointerEvent& e);
 
     ~EditAngleMeasureTracker();
--- a/OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -25,7 +25,7 @@
 {
   EditLineMeasureCommand::EditLineMeasureCommand(
     boost::shared_ptr<MeasureTool>  measureTool,
-    boost::shared_ptr<IViewport> viewport)
+    boost::weak_ptr<IViewport> viewport)
     : EditMeasureCommand(measureTool, viewport)
     , measureTool_(measureTool)
   {
--- a/OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditLineMeasureCommand.h	Wed Oct 28 20:14:34 2020 +0100
@@ -29,7 +29,7 @@
   public:
     EditLineMeasureCommand(
       boost::shared_ptr<MeasureTool>  measureTool,
-      boost::shared_ptr<IViewport> viewport);
+      boost::weak_ptr<IViewport> viewport);
 
     void SetStart(ScenePoint2D scenePos);
     void SetEnd(ScenePoint2D scenePos);
--- a/OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -29,14 +29,14 @@
 {
   EditLineMeasureTracker::EditLineMeasureTracker(
     boost::shared_ptr<MeasureTool>  measureTool,
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     const PointerEvent& e)
     : EditMeasureTracker(viewport, e)
   {
     ScenePoint2D scenePos;
     
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       Scene2D& scene = lock->GetController().GetScene();
       scenePos = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform());
     }
@@ -47,7 +47,7 @@
 
   void EditLineMeasureTracker::PointerMove(const PointerEvent& e)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
 
--- a/OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/EditLineMeasureTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -44,7 +44,7 @@
     */
     EditLineMeasureTracker(
       boost::shared_ptr<MeasureTool>  measureTool,
-      boost::shared_ptr<IViewport>    viewport,
+      boost::weak_ptr<IViewport>      viewport,
       const PointerEvent&             e);
 
     virtual void PointerMove(const PointerEvent& e) ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Scene2DViewport/LayerHolder.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/LayerHolder.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -30,7 +30,7 @@
 namespace OrthancStone
 {
   LayerHolder::LayerHolder(
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     int        polylineLayerCount,
     int        textLayerCount,
     int        infoTextCount)
@@ -43,9 +43,18 @@
 
   }
 
+  IViewport::ILock* LayerHolder::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
   void LayerHolder::CreateLayers()
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     Scene2D& scene = controller.GetScene();
 
@@ -86,7 +95,7 @@
   
   void LayerHolder::DeleteLayers()
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     Scene2D& scene = lock->GetController().GetScene();
 
     for (int i = 0; i < textLayerCount_ + polylineLayerCount_; ++i)
@@ -100,7 +109,7 @@
   
   PolylineSceneLayer* LayerHolder::GetPolylineLayer(int index /*= 0*/)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     const Scene2D& scene = lock->GetController().GetScene();
 
     using namespace Orthanc;
@@ -117,7 +126,7 @@
 
   TextSceneLayer* LayerHolder::GetTextLayer(int index /*= 0*/)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     const Scene2D& scene = lock->GetController().GetScene();
 
     using namespace Orthanc;
--- a/OrthancStone/Sources/Scene2DViewport/LayerHolder.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/LayerHolder.h	Wed Oct 28 20:14:34 2020 +0100
@@ -23,6 +23,8 @@
 
 #include "PredeclaredTypes.h"
 
+#include "../Viewport/IViewport.h"
+
 #include <boost/noncopyable.hpp>
 #include <boost/weak_ptr.hpp>
 #include <boost/shared_ptr.hpp>
@@ -44,7 +46,7 @@
     performed at this time
     */
     LayerHolder(
-      boost::shared_ptr<IViewport> viewport,
+      boost::weak_ptr<IViewport> viewport,
       int polylineLayerCount, int textLayerCount, int infoTextCount = 0);
 
     /**
@@ -95,6 +97,13 @@
     //TextSceneLayer* GetTextLayer(int index = 0);
 
   private:
+
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
+
     int GetPolylineLayerIndex(int index = 0);
     int GetTextLayerIndex(int index = 0);
     int GetInfoTextLayerIndex(int index = 0);
@@ -102,7 +111,7 @@
     int textLayerCount_;
     int polylineLayerCount_;
     int infoTextCount_;
-    boost::shared_ptr<IViewport> viewport_;
+    boost::weak_ptr<IViewport> viewport_;
     int baseLayerIndex_;
   };
 }
--- a/OrthancStone/Sources/Scene2DViewport/LineMeasureTool.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/LineMeasureTool.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -32,7 +32,7 @@
 namespace OrthancStone
 {
   LineMeasureTool::LineMeasureTool(
-    boost::shared_ptr<IViewport> viewport):
+    boost::weak_ptr<IViewport> viewport):
     MeasureTool(viewport),
 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1
     layerHolder_(boost::shared_ptr<LayerHolder>(new LayerHolder(viewport,1,5))),
@@ -45,7 +45,7 @@
 
   }
 
-  boost::shared_ptr<LineMeasureTool> LineMeasureTool::Create(boost::shared_ptr<IViewport> viewport)
+  boost::shared_ptr<LineMeasureTool> LineMeasureTool::Create(boost::weak_ptr<IViewport> viewport)
   {
     boost::shared_ptr<LineMeasureTool> obj(new LineMeasureTool(viewport));
     obj->MeasureTool::PostConstructor();
@@ -117,7 +117,7 @@
 
   LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
 
@@ -153,7 +153,7 @@
 
   boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     const Scene2D& scene = controller.GetScene();
 
@@ -196,7 +196,7 @@
       if (IsEnabled())
       {
         
-        std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+        std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
         ViewportController& controller = lock->GetController();
         Scene2D& scene = controller.GetScene();
 
--- a/OrthancStone/Sources/Scene2DViewport/LineMeasureTool.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/LineMeasureTool.h	Wed Oct 28 20:14:34 2020 +0100
@@ -39,7 +39,7 @@
   class LineMeasureTool : public MeasureTool
   {
   public:
-    static boost::shared_ptr<LineMeasureTool> Create(boost::shared_ptr<IViewport> viewport);
+    static boost::shared_ptr<LineMeasureTool> Create(boost::weak_ptr<IViewport> viewport);
 
     ~LineMeasureTool();
 
@@ -68,7 +68,7 @@
     LineHighlightArea LineHitTest(ScenePoint2D p);
 
   private:
-    explicit LineMeasureTool(boost::shared_ptr<IViewport> viewport);
+    explicit LineMeasureTool(boost::weak_ptr<IViewport> viewport);
 
     virtual void        RefreshScene() ORTHANC_OVERRIDE;
     void                RemoveFromScene();
--- a/OrthancStone/Sources/Scene2DViewport/MeasureCommands.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureCommands.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -28,9 +28,19 @@
 
 namespace OrthancStone
 {
+  IViewport::ILock* MeasureCommand::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
+
   void CreateMeasureCommand::Undo()
   {
-    std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<OrthancStone::IViewport::ILock> lock(GetViewportLock());
     // simply disable the measure tool upon undo
     GetMeasureTool()->Disable();
     lock->GetController().RemoveMeasureTool(GetMeasureTool());
@@ -38,12 +48,12 @@
 
   void CreateMeasureCommand::Redo()
   {
-    std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<OrthancStone::IViewport::ILock> lock(GetViewportLock());
     GetMeasureTool()->Enable();
     lock->GetController().AddMeasureTool(GetMeasureTool());
   }
 
-  CreateMeasureCommand::CreateMeasureCommand(boost::shared_ptr<IViewport> viewport)
+  CreateMeasureCommand::CreateMeasureCommand(boost::weak_ptr<IViewport> viewport)
     : MeasureCommand(viewport)
   {
 
@@ -57,7 +67,7 @@
 
   void DeleteMeasureCommand::Redo()
   {
-    std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<OrthancStone::IViewport::ILock> lock(GetViewportLock());
     // simply disable the measure tool upon undo
     GetMeasureTool()->Disable();
     lock->GetController().RemoveMeasureTool(GetMeasureTool());
@@ -65,7 +75,7 @@
 
   void DeleteMeasureCommand::Undo()
   {
-    std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<OrthancStone::IViewport::ILock> lock(GetViewportLock());
     GetMeasureTool()->Enable();
     lock->GetController().AddMeasureTool(GetMeasureTool());
   }
@@ -77,19 +87,19 @@
   }
 
   DeleteMeasureCommand::DeleteMeasureCommand(boost::shared_ptr<MeasureTool> measureTool,
-                                             boost::shared_ptr<IViewport> viewport) :
+                                             boost::weak_ptr<IViewport> viewport) :
     MeasureCommand(viewport),
     measureTool_(measureTool),
     mementoModified_(measureTool->GetMemento()),
     mementoOriginal_(measureTool->GetMemento())
   {
-    std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<OrthancStone::IViewport::ILock> lock(GetViewportLock());
     GetMeasureTool()->Disable();
     lock->GetController().RemoveMeasureTool(GetMeasureTool());
   }
 
   EditMeasureCommand::EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool,
-                                         boost::shared_ptr<IViewport> viewport) :
+                                         boost::weak_ptr<IViewport> viewport) :
     MeasureCommand(viewport),
     mementoModified_(measureTool->GetMemento()),
     mementoOriginal_(measureTool->GetMemento())
--- a/OrthancStone/Sources/Scene2DViewport/MeasureCommands.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureCommands.h	Wed Oct 28 20:14:34 2020 +0100
@@ -29,6 +29,7 @@
 #include "AngleMeasureTool.h"
 
 #include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
 #include <boost/noncopyable.hpp>
 
 namespace OrthancStone
@@ -36,10 +37,16 @@
   class MeasureCommand : public boost::noncopyable
   {
   protected:
-    boost::shared_ptr<IViewport> viewport_;
+    boost::weak_ptr<IViewport> viewport_;
+
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
 
   public:
-    explicit MeasureCommand(boost::shared_ptr<IViewport> viewport) :
+    explicit MeasureCommand(boost::weak_ptr<IViewport> viewport) :
       viewport_(viewport)
     {
     }
@@ -61,7 +68,7 @@
     virtual boost::shared_ptr<MeasureTool> GetMeasureTool() = 0;
 
   public:
-    explicit CreateMeasureCommand(boost::shared_ptr<IViewport> viewport);
+    explicit CreateMeasureCommand(boost::weak_ptr<IViewport> viewport);
     
     virtual ~CreateMeasureCommand();
     
@@ -83,7 +90,7 @@
 
   public:
     EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool,
-                       boost::shared_ptr<IViewport> viewport);
+                       boost::weak_ptr<IViewport> viewport);
 
     virtual ~EditMeasureCommand();
 
@@ -113,7 +120,7 @@
 
   public:
     DeleteMeasureCommand(boost::shared_ptr<MeasureTool> measureTool,
-                         boost::shared_ptr<IViewport> viewport);
+                         boost::weak_ptr<IViewport> viewport);
 
     virtual ~DeleteMeasureCommand();
     
--- a/OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -25,6 +25,7 @@
 #include <Enumerations.h>
 #include <OrthancException.h>
 
+#include <boost/shared_ptr.hpp>
 #include <boost/math/constants/constants.hpp>
 
 #include "../Viewport/IViewport.h"
@@ -48,7 +49,25 @@
     return enabled_;
   }
 
-  MeasureTool::MeasureTool(boost::shared_ptr<IViewport> viewport) :
+  IViewport::ILock* MeasureTool::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if(viewport)
+        return viewport->Lock();
+    else
+        return nullptr;
+  }
+
+  IViewport::ILock* MeasureTool::GetViewportLock() const
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
+  MeasureTool::MeasureTool(boost::weak_ptr<IViewport> viewport) :
     enabled_(true),
     viewport_(viewport)
   {
@@ -56,7 +75,7 @@
 
   void MeasureTool::PostConstructor()
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
 
     Register<ViewportController::SceneTransformChanged>(
--- a/OrthancStone/Sources/Scene2DViewport/MeasureTool.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureTool.h	Wed Oct 28 20:14:34 2020 +0100
@@ -46,7 +46,7 @@
 
 
   protected:
-    explicit MeasureTool(boost::shared_ptr<IViewport> viewport);
+    explicit MeasureTool(boost::weak_ptr<IViewport> viewport);
 
     void PostConstructor();
 
@@ -74,8 +74,14 @@
        Protected to allow sub-classes to use this weak pointer in factory methods
        (pass them to created objects)
     */
-    boost::shared_ptr<IViewport> viewport_;
+    boost::weak_ptr<IViewport> viewport_;
 
+    /**
+    This will return a scoped lock to the viewport. 
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
+    IViewport::ILock* GetViewportLock() const;
 
   public:
     virtual ~MeasureTool()
--- a/OrthancStone/Sources/Scene2DViewport/MeasureTrackers.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureTrackers.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -25,13 +25,22 @@
 namespace OrthancStone
 {
 
-  CreateMeasureTracker::CreateMeasureTracker(boost::shared_ptr<IViewport> viewport) :
+  CreateMeasureTracker::CreateMeasureTracker(boost::weak_ptr<IViewport> viewport) :
     commitResult_(true),
     viewport_(viewport),
     alive_(true)
   {
   }
 
+  IViewport::ILock* CreateMeasureTracker::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
   void CreateMeasureTracker::Cancel()
   {
     commitResult_ = false;
@@ -49,7 +58,7 @@
     // to the undo stack
     // otherwise, we simply undo it
 
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
     if (commitResult_)
       lock->GetController().PushCommand(command_);
@@ -59,18 +68,27 @@
     lock->Invalidate();
   }
 
-  EditMeasureTracker::EditMeasureTracker(boost::shared_ptr<IViewport> viewport,
-                                         const PointerEvent& e) :
+  EditMeasureTracker::EditMeasureTracker(boost::weak_ptr<IViewport> viewport,
+    const PointerEvent& e) :
     commitResult_(true),
     viewport_(viewport),
     alive_(true)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
     originalClickPosition_ = e.GetMainPosition().Apply(
       lock->GetController().GetScene().GetCanvasToSceneTransform());
   }
 
+  IViewport::ILock* EditMeasureTracker::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
   void EditMeasureTracker::Cancel()
   {
     commitResult_ = false;
@@ -88,7 +106,7 @@
     // to the undo stack
     // otherwise, we simply undo it
 
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
 
     if (commitResult_)
       lock->GetController().PushCommand(command_);
--- a/OrthancStone/Sources/Scene2DViewport/MeasureTrackers.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/MeasureTrackers.h	Wed Oct 28 20:14:34 2020 +0100
@@ -42,10 +42,16 @@
     
   protected:
     boost::shared_ptr<CreateMeasureCommand>  command_;
-    boost::shared_ptr<IViewport>             viewport_;
+    boost::weak_ptr<IViewport>               viewport_;
     bool                                     alive_;
 
-    explicit CreateMeasureTracker(boost::shared_ptr<IViewport> viewport);
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
+
+    explicit CreateMeasureTracker(boost::weak_ptr<IViewport> viewport);
 
     virtual ~CreateMeasureTracker();
     
@@ -64,10 +70,16 @@
 
   protected:
     boost::shared_ptr<EditMeasureCommand>  command_;
-    boost::shared_ptr<IViewport>           viewport_;
+    boost::weak_ptr<IViewport>             viewport_;
     bool                                   alive_;
     
-    EditMeasureTracker(boost::shared_ptr<IViewport> viewport,
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
+
+    EditMeasureTracker(boost::weak_ptr<IViewport> viewport,
                        const PointerEvent& e);
 
     ~EditMeasureTracker();
--- a/OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -28,13 +28,22 @@
 
 namespace OrthancStone
 {
-  OneGesturePointerTracker::OneGesturePointerTracker(boost::shared_ptr<IViewport> viewport) :
+  OneGesturePointerTracker::OneGesturePointerTracker(boost::weak_ptr<IViewport> viewport) :
     alive_(true),
     currentTouchCount_(1),
     viewport_(viewport)
   {
   }
 
+  IViewport::ILock* OneGesturePointerTracker::GetViewportLock()
+  {
+	  boost::shared_ptr<IViewport> viewport = viewport_.lock();
+	  if (viewport)
+		  return viewport->Lock();
+	  else
+		  return nullptr;
+  }
+
   void OneGesturePointerTracker::PointerUp(const PointerEvent& event)
   {
     // pointer up is only called for the LAST up event in case of a multi-touch
--- a/OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/OneGesturePointerTracker.h	Wed Oct 28 20:14:34 2020 +0100
@@ -51,10 +51,16 @@
     int   currentTouchCount_;
 
   protected:
-    boost::shared_ptr<IViewport> viewport_;
+    boost::weak_ptr<IViewport> viewport_;
+
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
 
   public:
-    explicit OneGesturePointerTracker(boost::shared_ptr<IViewport> viewport);
+    explicit OneGesturePointerTracker(boost::weak_ptr<IViewport> viewport);
     
     virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE;
     
--- a/OrthancStone/Sources/Scene2DViewport/ViewportController.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/ViewportController.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -29,7 +29,7 @@
 
 namespace OrthancStone
 {
-  ViewportController::ViewportController(boost::shared_ptr<IViewport> viewport)
+  ViewportController::ViewportController(boost::weak_ptr<IViewport> viewport)
     : viewport_(viewport)
     , scene_(new Scene2D)
     , canvasToSceneFactor_(1)
--- a/OrthancStone/Sources/Scene2DViewport/ViewportController.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Scene2DViewport/ViewportController.h	Wed Oct 28 20:14:34 2020 +0100
@@ -88,7 +88,7 @@
                                         SceneTransformChanged, \
                                         ViewportController);
 
-    explicit ViewportController(boost::shared_ptr<IViewport> viewport);
+    explicit ViewportController(boost::weak_ptr<IViewport> viewport);
 
     ~ViewportController();
 
@@ -233,7 +233,7 @@
   private:
     double GetCanvasToSceneFactor() const;
 
-    boost::shared_ptr<IViewport>                  viewport_;
+    boost::weak_ptr<IViewport>                    viewport_;
     boost::weak_ptr<UndoStack>                    undoStackW_;  // Global stack, possibly shared by all viewports
     std::vector<boost::shared_ptr<MeasureTool> >  measureTools_;
     boost::shared_ptr<IFlexiblePointerTracker>    activeTracker_;  // TODO - Couldn't this be a "std::unique_ptr"?
--- a/OrthancStone/Sources/Viewport/DefaultViewportInteractor.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Viewport/DefaultViewportInteractor.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -31,7 +31,7 @@
 namespace OrthancStone
 {
   IFlexiblePointerTracker* DefaultViewportInteractor::CreateTrackerInternal(
-    boost::shared_ptr<IViewport> viewport,
+    boost::weak_ptr<IViewport> viewport,
     MouseAction action,
     const PointerEvent& event,
     unsigned int viewportWidth,
@@ -62,10 +62,10 @@
 
 
   IFlexiblePointerTracker* DefaultViewportInteractor::CreateTracker(
-    boost::shared_ptr<IViewport>  viewport,
-    const PointerEvent&           event,
-    unsigned int                  viewportWidth,
-    unsigned int                  viewportHeight)
+    boost::weak_ptr<IViewport>  viewport,
+    const PointerEvent&         event,
+    unsigned int                viewportWidth,
+    unsigned int                viewportHeight)
   {
     MouseAction action;
     
--- a/OrthancStone/Sources/Viewport/DefaultViewportInteractor.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Viewport/DefaultViewportInteractor.h	Wed Oct 28 20:14:34 2020 +0100
@@ -36,7 +36,7 @@
     MouseAction  middleButtonAction_;
     MouseAction  rightButtonAction_;
 
-    IFlexiblePointerTracker* CreateTrackerInternal(boost::shared_ptr<IViewport> viewport,
+    IFlexiblePointerTracker* CreateTrackerInternal(boost::weak_ptr<IViewport> viewport,
                                                    MouseAction action,
                                                    const PointerEvent& event,
                                                    unsigned int viewportWidth,
@@ -91,7 +91,7 @@
       rightButtonAction_ = action;
     }
     
-    virtual IFlexiblePointerTracker* CreateTracker(boost::shared_ptr<IViewport> viewport,
+    virtual IFlexiblePointerTracker* CreateTracker(boost::weak_ptr<IViewport> viewport,
                                                    const PointerEvent& event,
                                                    unsigned int viewportWidth,
                                                    unsigned int viewportHeight) ORTHANC_OVERRIDE;
--- a/OrthancStone/Sources/Viewport/IViewportInteractor.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Viewport/IViewportInteractor.h	Wed Oct 28 20:14:34 2020 +0100
@@ -33,7 +33,7 @@
     {
     }
 
-    virtual IFlexiblePointerTracker* CreateTracker(boost::shared_ptr<IViewport> viewport,
+    virtual IFlexiblePointerTracker* CreateTracker(boost::weak_ptr<IViewport> viewport,
                                                    const PointerEvent& event,
                                                    unsigned int viewportWidth,
                                                    unsigned int viewportHeight) = 0;
--- a/OrthancStone/Sources/Volumes/VolumeSceneLayerSource.cpp	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Volumes/VolumeSceneLayerSource.cpp	Wed Oct 28 20:14:34 2020 +0100
@@ -40,11 +40,10 @@
             LinearAlgebra::IsCloseToZero(distance));
   }
 
-
   void VolumeSceneLayerSource::ClearLayer()
   {
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
       Scene2D& scene = controller.GetScene();
       scene.DeleteLayer(layerDepth_);
@@ -52,8 +51,27 @@
     lastPlane_.reset(NULL);
   }
 
+  IViewport::ILock* VolumeSceneLayerSource::GetViewportLock()
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
+  IViewport::ILock* VolumeSceneLayerSource::GetViewportLock() const
+  {
+    boost::shared_ptr<IViewport> viewport = viewport_.lock();
+    if (viewport)
+      return viewport->Lock();
+    else
+      return nullptr;
+  }
+
+
   VolumeSceneLayerSource::VolumeSceneLayerSource(
-    boost::shared_ptr<OrthancStone::IViewport>  viewport,
+    boost::weak_ptr<OrthancStone::IViewport>  viewport,
     int layerDepth,
     const boost::shared_ptr<IVolumeSlicer>& slicer) :
     viewport_(viewport),
@@ -68,7 +86,7 @@
     }
 
     {
-      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
       ViewportController& controller = lock->GetController();
       Scene2D& scene = controller.GetScene();
       ORTHANC_ASSERT(!scene.HasLayer(layerDepth_));
@@ -119,7 +137,7 @@
 
   void VolumeSceneLayerSource::Update(const CoordinateSystem3D& plane)
   {
-    std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+    std::unique_ptr<IViewport::ILock> lock(GetViewportLock());
     ViewportController& controller = lock->GetController();
     Scene2D& scene = controller.GetScene();
 
--- a/OrthancStone/Sources/Volumes/VolumeSceneLayerSource.h	Wed Oct 28 20:06:55 2020 +0100
+++ b/OrthancStone/Sources/Volumes/VolumeSceneLayerSource.h	Wed Oct 28 20:14:34 2020 +0100
@@ -23,6 +23,7 @@
 #pragma once
 
 #include "../Scene2D/Scene2D.h"
+#include "../Viewport/IViewport.h"
 #include "IVolumeSlicer.h"
 
 #include <boost/shared_ptr.hpp>
@@ -40,7 +41,7 @@
   class VolumeSceneLayerSource : public boost::noncopyable
   {
   private:
-    boost::shared_ptr<OrthancStone::IViewport>  viewport_;
+    boost::weak_ptr<OrthancStone::IViewport>  viewport_;
     int                                       layerDepth_;
     boost::shared_ptr<IVolumeSlicer>          slicer_;
     std::unique_ptr<ILayerStyleConfigurator>  configurator_;
@@ -50,8 +51,15 @@
 
     void ClearLayer();
 
+    /**
+    This will return a scoped lock to the viewport.
+    If the viewport does not exist anymore, then nullptr is returned.
+    */
+    IViewport::ILock* GetViewportLock();
+    IViewport::ILock* GetViewportLock() const;
+
   public:
-    VolumeSceneLayerSource(boost::shared_ptr<OrthancStone::IViewport>  viewport,
+    VolumeSceneLayerSource(boost::weak_ptr<OrthancStone::IViewport>  viewport,
                            int layerDepth,
                            const boost::shared_ptr<IVolumeSlicer>& slicer);