From cbfda384f47ad85ce8725a4e7f77e0135ecc3f3e Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauld.mccarthy@gmail.com>
Date: Mon, 20 Jul 2015 22:11:31 +0100
Subject: [PATCH] Bugfix to DisplayContext overlayOrder update - should have
 noticed this a long time ago. Overlay order was not being preserved when
 overlays were removed from the list.

---
 fsl/fslview/displaycontext/displaycontext.py | 51 +++++++++++++++++---
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/fsl/fslview/displaycontext/displaycontext.py b/fsl/fslview/displaycontext/displaycontext.py
index 623c0286e..1804040ea 100644
--- a/fsl/fslview/displaycontext/displaycontext.py
+++ b/fsl/fslview/displaycontext/displaycontext.py
@@ -290,21 +290,56 @@ class DisplayContext(props.SyncableHasProperties):
 
         # Ensure that the overlayOrder
         # property is valid ...
+        #
+        # NOTE: The following logic assumes that operations
+        #       which modify the overlay list will only do
+        #       one of the following:
+        #
+        #        - Adding one or more overlays to the list
+        #        - Removing one or more overlays from the list
         # 
+        # More complex overlay list modifications
+        # will cause this code to break.
+
+        oldList  = self.__overlayList.getLastValue('overlays')[:]
+        oldOrder = self.overlayOrder[:]
+        
         # If overlays have been added to
         # the overlay list, add indices
         # for them to the overlayOrder list
         if len(self.overlayOrder) < len(self.__overlayList):
-            self.overlayOrder.extend(range(len(self.overlayOrder),
-                                           len(self.__overlayList)))
 
-        # Otherwise, if overlays have been removed
-        # from the overlay list, remove the corresponding
-        # indices from the overlayOrder list
+            newOrder      = []
+            newOverlayIdx = len(oldList)
+
+            # The order of existing overlays is preserved,
+            # and all new overlays added to the end of the
+            # overlay order. 
+            for overlay in self.__overlayList:
+
+                if overlay in oldList:
+                    newOrder.append(oldOrder[oldList.index(overlay)])
+                else:
+                    newOrder.append(newOverlayIdx)
+                    newOverlayIdx += 1
+
+            self.overlayOrder[:] = newOrder
+
+        # Otherwise, if overlays have been 
+        # removed from the overlay list ...
         elif len(self.overlayOrder) > len(self.__overlayList):
-            for idx in range(len(self.__overlayList),
-                             len(self.overlayOrder)):
-                self.overlayOrder.remove(idx)
+
+            # Remove the corresponding indices
+            # from the overlayOrder list
+            for overlay, orderIdx in zip(oldList, self.overlayOrder):
+                if overlay not in self.__overlayList:
+                    oldOrder.remove(orderIdx)
+
+            # Re-generate new indices,
+            # preserving the order of
+            # the remaining overlays
+            newOrder = [sorted(oldOrder).index(idx) for idx in oldOrder]
+            self.overlayOrder[:] = newOrder
 
         # Ensure that the bounds property is accurate
         self.__updateBounds()
-- 
GitLab