浏览代码

wxGUI: refactoring: build GUI tools' status bars based on wx.StatusBar widget (#1689)

Builds status bars based on wx.StatusBar for SwipeMapFrame, IClassMapFrame, Image2Target Frame, Photo2Image Frame, and GCP manager MapFrame.
Some general methods related to a status bar and toolbars moved to gui_core class MapFrameBase.
Linda Kladivova 3 年之前
父节点
当前提交
5f65aaa978

+ 55 - 62
gui/wxpython/gcp/mapdisplay.py

@@ -97,11 +97,9 @@ class MapFrame(SingleMapFrame):
         self._mgr.SetDockSizeConstraint(0.5, 0.5)
 
         #
-        # Add statusbar
+        # Create statusbar
         #
-
-        # items for choice
-        self.statusbarItems = [
+        statusbarItems = [
             sb.SbCoordinates,
             sb.SbRegionExtent,
             sb.SbCompRegionExtent,
@@ -113,23 +111,7 @@ class MapFrame(SingleMapFrame):
             sbgcp.SbGoToGCP,
             sbgcp.SbRMSError,
         ]
-
-        # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number=4, style=0)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbRender(self, statusbar=statusbar, position=3)
-        )
-
+        self.statusbar = self.CreateStatusbar(statusbarItems)
         self.statusbarManager.SetMode(8)  # goto GCP
 
         #
@@ -190,44 +172,7 @@ class MapFrame(SingleMapFrame):
         # self.SrcMapWindow.SetSize((300, 300))
         # self.TgtMapWindow.SetSize((300, 300))
         self.list.SetSize((100, 150))
-        self._mgr.AddPane(
-            self.list,
-            wx.aui.AuiPaneInfo()
-            .Name("gcplist")
-            .Caption(_("GCP List"))
-            .LeftDockable(False)
-            .RightDockable(False)
-            .PinButton()
-            .FloatingSize((600, 200))
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Top()
-            .Layer(1)
-            .MinSize((200, 100)),
-        )
-        self._mgr.AddPane(
-            self.SrcMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("source")
-            .Caption(_("Source Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Centre(),
-        )
-        self._mgr.AddPane(
-            self.TgtMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("target")
-            .Caption(_("Target Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Right()
-            .Layer(0),
-        )
+        self._addPanes()
 
         srcwidth, srcheight = self.SrcMapWindow.GetSize()
         tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
@@ -297,7 +242,10 @@ class MapFrame(SingleMapFrame):
         """
         # default toolbar
         if name == "map":
-            self.toolbars["map"] = MapToolbar(self, self._toolSwitcher, self._giface)
+            if "map" not in self.toolbars:
+                self.toolbars["map"] = MapToolbar(
+                    self, self._toolSwitcher, self._giface
+                )
 
             self._mgr.AddPane(
                 self.toolbars["map"],
@@ -317,7 +265,8 @@ class MapFrame(SingleMapFrame):
 
         # GCP display
         elif name == "gcpdisp":
-            self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
+            if "gcpdisp" not in self.toolbars:
+                self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
 
             self._mgr.AddPane(
                 self.toolbars["gcpdisp"],
@@ -337,7 +286,8 @@ class MapFrame(SingleMapFrame):
             if not self.show_target:
                 self.toolbars["gcpdisp"].Enable("zoommenu", enable=False)
 
-            self.toolbars["gcpman"] = GCPManToolbar(self)
+            if "gcpman" not in self.toolbars:
+                self.toolbars["gcpman"] = GCPManToolbar(self)
 
             self._mgr.AddPane(
                 self.toolbars["gcpman"],
@@ -357,6 +307,49 @@ class MapFrame(SingleMapFrame):
 
         self._mgr.Update()
 
+    def _addPanes(self):
+        """Add mapwindows, toolbars and statusbar to aui manager"""
+        self._mgr.AddPane(
+            self.list,
+            wx.aui.AuiPaneInfo()
+            .Name("gcplist")
+            .Caption(_("GCP List"))
+            .LeftDockable(False)
+            .RightDockable(False)
+            .PinButton()
+            .FloatingSize((600, 200))
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Top()
+            .Layer(1)
+            .MinSize((200, 100)),
+        )
+        self._mgr.AddPane(
+            self.SrcMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("source")
+            .Caption(_("Source Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Centre(),
+        )
+        self._mgr.AddPane(
+            self.TgtMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("target")
+            .Caption(_("Target Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Right()
+            .Layer(0),
+        )
+        # statusbar
+        self.AddStatusbarPane()
+
     def OnUpdateProgress(self, event):
         """
         Update progress bar info

+ 95 - 1
gui/wxpython/gui_core/mapdisp.py

@@ -29,6 +29,7 @@ from core import globalvar
 from core.debug import Debug
 from gui_core.toolbars import ToolSwitcher
 from gui_core.wrap import NewId
+from mapdisp import statusbar as sb
 
 from grass.script import core as grass
 
@@ -169,7 +170,7 @@ class MapFrameBase(wx.Frame):
 
     def OnFullScreen(self, event):
         """!Switch fullscreen mode, hides also toolbars"""
-        for toolbar in self.toolbars.keys():
+        for toolbar in self.toolbars:
             self._mgr.GetPane(self.toolbars[toolbar]).Show(self.IsFullScreen())
         self._mgr.Update()
         self.ShowFullScreen(not self.IsFullScreen())
@@ -339,6 +340,58 @@ class MapFrameBase(wx.Frame):
             if self.statusbarManager.GetMode() == 0:
                 self.statusbarManager.ShowItem("coordinates")
 
+    def CreateStatusbar(self, statusbarItems):
+        """Create statusbar (default items)."""
+        # create statusbar and its manager
+        statusbar = wx.StatusBar(self, id=wx.ID_ANY)
+        statusbar.SetMinHeight(24)
+        statusbar.SetFieldsCount(4)
+        statusbar.SetStatusWidths([-5, -2, -1, -1])
+        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
+
+        # fill statusbar manager
+        self.statusbarManager.AddStatusbarItemsByClass(
+            statusbarItems, mapframe=self, statusbar=statusbar
+        )
+        self.statusbarManager.AddStatusbarItem(
+            sb.SbMask(self, statusbar=statusbar, position=2)
+        )
+        self.statusbarManager.AddStatusbarItem(
+            sb.SbRender(self, statusbar=statusbar, position=3)
+        )
+        self.statusbarManager.Update()
+        return statusbar
+
+    def AddStatusbarPane(self):
+        """Add statusbar as a pane"""
+        self._mgr.AddPane(
+            self.statusbar,
+            wx.aui.AuiPaneInfo()
+            .Bottom()
+            .MinSize(30, 30)
+            .Fixed()
+            .Name("statusbar")
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .ToolbarPane()
+            .Dockable(False)
+            .PaneBorder(False)
+            .Gripper(False),
+        )
+
+    def SetStatusText(self, *args):
+        """Overide wx.StatusBar method"""
+        self.statusbar.SetStatusText(*args)
+
+    def ShowStatusbar(self, show):
+        """Show/hide statusbar and associated pane"""
+        self._mgr.GetPane("statusbar").Show(show)
+        self._mgr.Update()
+
+    def IsStatusbarShown(self):
+        """Check if statusbar is shown"""
+        return self._mgr.GetPane("statusbar").IsShown()
+
     def StatusbarReposition(self):
         """Reposition items in statusbar"""
         if self.statusbarManager:
@@ -349,6 +402,47 @@ class MapFrameBase(wx.Frame):
         for toolbar in six.itervalues(self.toolbars):
             toolbar.EnableLongHelp(enable)
 
+    def ShowAllToolbars(self, show=True):
+        if not show:  # hide
+            action = self.RemoveToolbar
+        else:
+            action = self.AddToolbar
+        for toolbar in self.GetToolbarNames():
+            action(toolbar)
+
+    def AreAllToolbarsShown(self):
+        return self.GetMapToolbar().IsShown()
+
+    def GetToolbarNames(self):
+        """Return toolbar names"""
+        return list(self.toolbars.keys())
+
+    def AddToolbar(self):
+        """Add defined toolbar to the window"""
+        raise NotImplementedError("AddToolbar")
+
+    def RemoveToolbar(self, name, destroy=False):
+        """Removes defined toolbar from the window
+
+        :param name toolbar to remove
+        :param destroy True to destroy otherwise toolbar is only hidden
+        """
+        self._mgr.DetachPane(self.toolbars[name])
+        if destroy:
+            self._toolSwitcher.RemoveToolbarFromGroup("mouseUse", self.toolbars[name])
+            self.toolbars[name].Destroy()
+            self.toolbars.pop(name)
+        else:
+            self.toolbars[name].Hide()
+
+        self._mgr.Update()
+
+    def IsPaneShown(self, name):
+        """Check if pane (toolbar, mapWindow ...) of given name is currently shown"""
+        if self._mgr.GetPane(name).IsOk():
+            return self._mgr.GetPane(name).IsShown()
+        return False
+
     def OnRender(self, event):
         """Re-render map composition (each map layer)"""
         raise NotImplementedError("OnRender")

+ 47 - 59
gui/wxpython/iclass/frame.py

@@ -167,42 +167,6 @@ class IClassMapFrame(DoubleMapFrame):
 
         self.GetMapToolbar().GetActiveMapTool().Bind(wx.EVT_CHOICE, self.OnUpdateActive)
 
-        #
-        # Add statusbar
-        #
-
-        # items for choice
-        self.statusbarItems = [
-            sb.SbCoordinates,
-            sb.SbRegionExtent,
-            sb.SbCompRegionExtent,
-            sb.SbShowRegion,
-            sb.SbAlignExtent,
-            sb.SbResolution,
-            sb.SbDisplayGeometry,
-            sb.SbMapScale,
-            sb.SbGoTo,
-            sb.SbProjection,
-        ]
-
-        # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number=4, style=0)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbRender(self, statusbar=statusbar, position=3)
-        )
-
-        self.statusbarManager.Update()
-
         self.trainingMapManager = MapManager(
             self, mapWindow=self.GetFirstWindow(), Map=self.GetFirstMap()
         )
@@ -224,6 +188,20 @@ class IClassMapFrame(DoubleMapFrame):
         # PyPlot init
         self.plotPanel = PlotPanel(self, giface=self.giface, stats_data=self.stats_data)
 
+        # statusbar items
+        statusbarItems = [
+            sb.SbCoordinates,
+            sb.SbRegionExtent,
+            sb.SbCompRegionExtent,
+            sb.SbShowRegion,
+            sb.SbAlignExtent,
+            sb.SbResolution,
+            sb.SbDisplayGeometry,
+            sb.SbMapScale,
+            sb.SbGoTo,
+            sb.SbProjection,
+        ]
+        self.statusbar = self.CreateStatusbar(statusbarItems)
         self._addPanes()
         self._mgr.Update()
 
@@ -323,7 +301,8 @@ class IClassMapFrame(DoubleMapFrame):
          Toolbars 'iClassPreviewMapManager' are added in _addPanes().
         """
         if name == "iClassMap":
-            self.toolbars[name] = IClassMapToolbar(self, self._toolSwitcher)
+            if "iClassMap" not in self.toolbars:
+                self.toolbars[name] = IClassMapToolbar(self, self._toolSwitcher)
 
             self._mgr.AddPane(
                 self.toolbars[name],
@@ -344,7 +323,8 @@ class IClassMapFrame(DoubleMapFrame):
             )
 
         if name == "iClass":
-            self.toolbars[name] = IClassToolbar(self, stats_data=self.stats_data)
+            if "iClass" not in self.toolbars:
+                self.toolbars[name] = IClassToolbar(self, stats_data=self.stats_data)
 
             self._mgr.AddPane(
                 self.toolbars[name],
@@ -365,7 +345,8 @@ class IClassMapFrame(DoubleMapFrame):
             )
 
         if name == "iClassMisc":
-            self.toolbars[name] = IClassMiscToolbar(self)
+            if "iClassMisc" not in self.toolbars:
+                self.toolbars[name] = IClassMiscToolbar(self)
 
             self._mgr.AddPane(
                 self.toolbars[name],
@@ -386,25 +367,27 @@ class IClassMapFrame(DoubleMapFrame):
             )
 
         if name == "vdigit":
-            self.toolbars[name] = VDigitToolbar(
-                parent=self,
-                toolSwitcher=self._toolSwitcher,
-                MapWindow=self.GetFirstWindow(),
-                digitClass=IClassVDigit,
-                giface=self.giface,
-                tools=[
-                    "addArea",
-                    "moveVertex",
-                    "addVertex",
-                    "removeVertex",
-                    "editLine",
-                    "moveLine",
-                    "deleteArea",
-                    "undo",
-                    "redo",
-                    "settings",
-                ],
-            )
+            if "vdigit" not in self.toolbars:
+                self.toolbars[name] = VDigitToolbar(
+                    parent=self,
+                    toolSwitcher=self._toolSwitcher,
+                    MapWindow=self.GetFirstWindow(),
+                    digitClass=IClassVDigit,
+                    giface=self.giface,
+                    tools=[
+                        "addArea",
+                        "moveVertex",
+                        "addVertex",
+                        "removeVertex",
+                        "editLine",
+                        "moveLine",
+                        "deleteArea",
+                        "undo",
+                        "redo",
+                        "settings",
+                    ],
+                )
+
             self._mgr.AddPane(
                 self.toolbars[name],
                 wx.aui.AuiPaneInfo()
@@ -423,8 +406,10 @@ class IClassMapFrame(DoubleMapFrame):
                 .BestSize((self.toolbars[name].GetBestSize())),
             )
 
+        self._mgr.Update()
+
     def _addPanes(self):
-        """Add mapwindows and toolbars to aui manager"""
+        """Add mapwindows, toolbars and statusbar to aui manager"""
         self._addPaneMapWindow(name="training", position=0)
         self._addPaneToolbar(name="iClassTrainingMapManager", position=1)
         self._addPaneMapWindow(name="preview", position=2)
@@ -446,6 +431,9 @@ class IClassMapFrame(DoubleMapFrame):
             .BestSize((335, -1)),
         )
 
+        # statusbar
+        self.AddStatusbarPane()
+
     def _addPaneToolbar(self, name, position):
         if name == "iClassPreviewMapManager":
             parent = self.previewMapManager

+ 54 - 56
gui/wxpython/image2target/ii2t_mapdisplay.py

@@ -101,7 +101,7 @@ class MapFrame(SingleMapFrame):
         #
 
         # items for choice
-        self.statusbarItems = [
+        statusbarItems = [
             sb.SbCoordinates,
             sb.SbRegionExtent,
             sb.SbCompRegionExtent,
@@ -115,20 +115,7 @@ class MapFrame(SingleMapFrame):
         ]
 
         # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number=4, style=0)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbRender(self, statusbar=statusbar, position=3)
-        )
+        self.statusbar = self.CreateStatusbar(statusbarItems)
 
         self.statusbarManager.SetMode(8)  # goto GCP
 
@@ -190,44 +177,7 @@ class MapFrame(SingleMapFrame):
         # self.SrcMapWindow.SetSize((300, 300))
         # self.TgtMapWindow.SetSize((300, 300))
         self.list.SetSize((100, 150))
-        self._mgr.AddPane(
-            self.list,
-            wx.aui.AuiPaneInfo()
-            .Name("gcplist")
-            .Caption(_("GCP List"))
-            .LeftDockable(False)
-            .RightDockable(False)
-            .PinButton()
-            .FloatingSize((600, 200))
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Top()
-            .Layer(1)
-            .MinSize((200, 100)),
-        )
-        self._mgr.AddPane(
-            self.SrcMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("source")
-            .Caption(_("Source Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Centre(),
-        )
-        self._mgr.AddPane(
-            self.TgtMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("target")
-            .Caption(_("Target Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Right()
-            .Layer(0),
-        )
+        self._addPanes()
 
         srcwidth, srcheight = self.SrcMapWindow.GetSize()
         tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
@@ -297,7 +247,10 @@ class MapFrame(SingleMapFrame):
         """
         # default toolbar
         if name == "map":
-            self.toolbars["map"] = MapToolbar(self, self._toolSwitcher, self._giface)
+            if "map" not in self.toolbars:
+                self.toolbars["map"] = MapToolbar(
+                    self, self._toolSwitcher, self._giface
+                )
 
             self._mgr.AddPane(
                 self.toolbars["map"],
@@ -317,7 +270,8 @@ class MapFrame(SingleMapFrame):
 
         # GCP display
         elif name == "gcpdisp":
-            self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
+            if "gcpdisp" not in self.toolbars:
+                self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
 
             self._mgr.AddPane(
                 self.toolbars["gcpdisp"],
@@ -337,7 +291,8 @@ class MapFrame(SingleMapFrame):
             if not self.show_target:
                 self.toolbars["gcpdisp"].Enable("zoommenu", enable=False)
 
-            self.toolbars["gcpman"] = GCPManToolbar(self)
+            if "gcpman" not in self.toolbars:
+                self.toolbars["gcpman"] = GCPManToolbar(self)
 
             self._mgr.AddPane(
                 self.toolbars["gcpman"],
@@ -357,6 +312,49 @@ class MapFrame(SingleMapFrame):
 
         self._mgr.Update()
 
+    def _addPanes(self):
+        """Add mapwindows, toolbars and statusbar to aui manager"""
+        self._mgr.AddPane(
+            self.list,
+            wx.aui.AuiPaneInfo()
+            .Name("gcplist")
+            .Caption(_("GCP List"))
+            .LeftDockable(False)
+            .RightDockable(False)
+            .PinButton()
+            .FloatingSize((600, 200))
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Top()
+            .Layer(1)
+            .MinSize((200, 100)),
+        )
+        self._mgr.AddPane(
+            self.SrcMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("source")
+            .Caption(_("Source Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Centre(),
+        )
+        self._mgr.AddPane(
+            self.TgtMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("target")
+            .Caption(_("Target Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Right()
+            .Layer(0),
+        )
+        # statusbar
+        self.AddStatusbarPane()
+
     def OnUpdateProgress(self, event):
         """
         Update progress bar info

+ 36 - 112
gui/wxpython/mapdisp/frame.py

@@ -142,7 +142,38 @@ class MapFrame(SingleMapFrame):
         #
         self.statusbarManager = None
         if statusbar:
-            self.statusbar = self.CreateStatusbar()
+            # items for choice
+            statusbarItems = [
+                sb.SbCoordinates,
+                sb.SbRegionExtent,
+                sb.SbCompRegionExtent,
+                sb.SbShowRegion,
+                sb.SbAlignExtent,
+                sb.SbResolution,
+                sb.SbDisplayGeometry,
+                sb.SbMapScale,
+                sb.SbGoTo,
+                sb.SbProjection,
+            ]
+            self.statusbarItemsHiddenInNviz = (
+                sb.SbAlignExtent,
+                sb.SbDisplayGeometry,
+                sb.SbShowRegion,
+                sb.SbResolution,
+                sb.SbMapScale,
+            )
+            self.statusbar = self.CreateStatusbar(statusbarItems)
+
+            self.Map.GetRenderMgr().updateProgress.connect(
+                self.statusbarManager.SetProgress
+            )
+
+        self.Map.GetRenderMgr().renderingFailed.connect(
+            lambda cmd, error: self._giface.WriteError(
+                _("Failed to run command '%(command)s'. Details:\n%(error)s")
+                % dict(command=" ".join(cmd), error=error)
+            )
+        )
 
         # init decoration objects
         self.decorations = {}
@@ -208,20 +239,9 @@ class MapFrame(SingleMapFrame):
             .Layer(0),
         )
 
-        self._mgr.AddPane(
-            self.statusbar,
-            wx.aui.AuiPaneInfo()
-            .Bottom()
-            .MinSize(30, 30)
-            .Fixed()
-            .Name("statusbar")
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .ToolbarPane()
-            .Dockable(False)
-            .PaneBorder(False)
-            .Gripper(False),
-        )
+        # statusbar
+        self.AddStatusbarPane()
+
         self._mgr.Update()
 
         #
@@ -280,75 +300,6 @@ class MapFrame(SingleMapFrame):
             action=on_show_hide_statusbar,
         )
 
-    def CreateStatusbar(self):
-        if self.statusbarManager:
-            return
-
-        # items for choice
-        self.statusbarItems = [
-            sb.SbCoordinates,
-            sb.SbRegionExtent,
-            sb.SbCompRegionExtent,
-            sb.SbShowRegion,
-            sb.SbAlignExtent,
-            sb.SbResolution,
-            sb.SbDisplayGeometry,
-            sb.SbMapScale,
-            sb.SbGoTo,
-            sb.SbProjection,
-        ]
-
-        self.statusbarItemsHiddenInNviz = (
-            sb.SbAlignExtent,
-            sb.SbDisplayGeometry,
-            sb.SbShowRegion,
-            sb.SbResolution,
-            sb.SbMapScale,
-        )
-
-        statusbar = wx.StatusBar(self, id=wx.ID_ANY)
-        statusbar.SetMinHeight(24)
-        statusbar.SetFieldsCount(4)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        sbRender = sb.SbRender(self, statusbar=statusbar, position=3)
-        self.statusbarManager.AddStatusbarItem(sbRender)
-
-        self.statusbarManager.Update()
-
-        #
-        self.Map.GetRenderMgr().updateProgress.connect(
-            self.statusbarManager.SetProgress
-        )
-        self.Map.GetRenderMgr().renderingFailed.connect(
-            lambda cmd, error: self._giface.WriteError(
-                _("Failed to run command '%(command)s'. Details:\n%(error)s")
-                % dict(command=" ".join(cmd), error=error)
-            )
-        )
-        return statusbar
-
-    def ShowStatusbar(self, show):
-        """Show/hide statusbar and associated pane"""
-        self._mgr.GetPane("statusbar").Show(show)
-        self._mgr.Update()
-
-    def IsStatusbarShown(self):
-        """Check if statusbar is shown"""
-        return self._mgr.GetPane("statusbar").IsShown()
-
-    def SetStatusText(self, *args):
-        """Overide wx.StatusBar method"""
-        self.statusbar.SetStatusText(*args)
-
     def GetMapWindow(self):
         return self.MapWindow
 
@@ -699,13 +650,7 @@ class MapFrame(SingleMapFrame):
         :param name toolbar to remove
         :param destroy True to destroy otherwise toolbar is only hidden
         """
-        self._mgr.DetachPane(self.toolbars[name])
-        if destroy:
-            self._toolSwitcher.RemoveToolbarFromGroup("mouseUse", self.toolbars[name])
-            self.toolbars[name].Destroy()
-            self.toolbars.pop(name)
-        else:
-            self.toolbars[name].Hide()
+        super().RemoveToolbar(name, destroy)
 
         if name == "vdigit":
             self._mgr.GetPane("vdigit").Hide()
@@ -716,23 +661,6 @@ class MapFrame(SingleMapFrame):
 
         self._mgr.Update()
 
-    def ShowAllToolbars(self, show=True):
-        if not show:  # hide
-            action = self.RemoveToolbar
-        else:
-            action = self.AddToolbar
-        for toolbar in self.GetToolbarNames():
-            action(toolbar)
-
-    def AreAllToolbarsShown(self):
-        return self.GetMapToolbar().IsShown()
-
-    def IsPaneShown(self, name):
-        """Check if pane (toolbar, mapWindow ...) of given name is currently shown"""
-        if self._mgr.GetPane(name).IsOk():
-            return self._mgr.GetPane(name).IsShown()
-        return False
-
     def RemoveQueryLayer(self):
         """Removes temporary map layers (queries)"""
         qlayer = self.GetMap().GetListOfLayers(name=globalvar.QUERYLAYER)
@@ -1650,10 +1578,6 @@ class MapFrame(SingleMapFrame):
         """Returns toolbar with zooming tools"""
         return self.toolbars["map"] if "map" in self.toolbars else None
 
-    def GetToolbarNames(self):
-        """Return toolbar names"""
-        return self.toolbars.keys()
-
     def GetDialog(self, name):
         """Get selected dialog if exist"""
         return self.dialogs.get(name, None)

+ 88 - 95
gui/wxpython/mapswipe/frame.py

@@ -51,7 +51,10 @@ class SwipeMapFrame(DoubleMapFrame):
         #
         # Add toolbars
         #
-        self.AddToolbars()
+        for name in ("swipeMain", "swipeMap", "swipeMisc"):
+            self.AddToolbar(name)
+        self._mgr.Update()
+
         self._giface = giface
         #
         # create widgets
@@ -90,6 +93,21 @@ class SwipeMapFrame(DoubleMapFrame):
 
         self._mode = "swipe"
 
+        # statusbar items
+        statusbarItems = [
+            sb.SbCoordinates,
+            sb.SbRegionExtent,
+            sb.SbCompRegionExtent,
+            sb.SbShowRegion,
+            sb.SbAlignExtent,
+            sb.SbResolution,
+            sb.SbDisplayGeometry,
+            sb.SbMapScale,
+            sb.SbGoTo,
+            sb.SbProjection,
+        ]
+        self.statusbar = self.CreateStatusbar(statusbarItems)
+
         self._addPanes()
         self._bindWindowsActivation()
         self._setUpMapWindow(self.firstMapWindow)
@@ -99,8 +117,6 @@ class SwipeMapFrame(DoubleMapFrame):
         self._mgr.GetPane("sliderH").Show()
         self.slider = self.sliderH
 
-        self.InitStatusbar()
-
         self.Bind(wx.EVT_SIZE, self.OnSize)
         self.Bind(wx.EVT_IDLE, self.OnIdle)
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
@@ -159,40 +175,6 @@ class SwipeMapFrame(DoubleMapFrame):
         if not (self.rasters["first"] and self.rasters["second"]):
             self.OnSelectLayers(event=None)
 
-    def InitStatusbar(self):
-        """Init statusbar (default items)."""
-        # items for choice
-        self.statusbarItems = [
-            sb.SbCoordinates,
-            sb.SbRegionExtent,
-            sb.SbCompRegionExtent,
-            sb.SbShowRegion,
-            sb.SbAlignExtent,
-            sb.SbResolution,
-            sb.SbDisplayGeometry,
-            sb.SbMapScale,
-            sb.SbGoTo,
-            sb.SbProjection,
-        ]
-
-        # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number=4, style=0)
-        statusbar.SetMinHeight(24)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        sbRender = sb.SbRender(self, statusbar=statusbar, position=3)
-        self.statusbarManager.AddStatusbarItem(sbRender)
-
-        self.statusbarManager.Update()
-
     def ResetSlider(self):
         if self.splitter.GetSplitMode() == wx.SPLIT_VERTICAL:
             size = self.splitter.GetSize()[0]
@@ -267,75 +249,83 @@ class SwipeMapFrame(DoubleMapFrame):
         style ^= wx.SP_LIVE_UPDATE
         self.splitter.SetWindowStyle(style)
 
-    def AddToolbars(self):
+    def AddToolbar(self, name):
         """Add defined toolbar to the window
 
         Currently known toolbars are:
-         - 'swipeMap'          - basic map toolbar
          - 'swipeMain'         - swipe functionality
+         - 'swipeMap'          - basic map toolbar
          - 'swipeMisc'         - misc (settings, help)
         """
-        self.toolbars["swipeMap"] = SwipeMapToolbar(self, self._toolSwitcher)
-        self._mgr.AddPane(
-            self.toolbars["swipeMap"],
-            wx.aui.AuiPaneInfo()
-            .Name("swipeMap")
-            .Caption(_("Map Toolbar"))
-            .ToolbarPane()
-            .Top()
-            .LeftDockable(False)
-            .RightDockable(False)
-            .BottomDockable(False)
-            .TopDockable(True)
-            .CloseButton(False)
-            .Layer(2)
-            .Row(1)
-            .Position(1)
-            .BestSize((self.toolbars["swipeMap"].GetBestSize())),
-        )
 
-        self.toolbars["swipeMain"] = SwipeMainToolbar(self)
-
-        self._mgr.AddPane(
-            self.toolbars["swipeMain"],
-            wx.aui.AuiPaneInfo()
-            .Name("swipeMain")
-            .Caption(_("Main Toolbar"))
-            .ToolbarPane()
-            .Top()
-            .LeftDockable(False)
-            .RightDockable(False)
-            .BottomDockable(False)
-            .TopDockable(True)
-            .CloseButton(False)
-            .Layer(2)
-            .Row(1)
-            .Position(0)
-            .BestSize((self.toolbars["swipeMain"].GetBestSize())),
-        )
+        if name == "swipeMain":
+            if "swipeMain" not in self.toolbars:
+                self.toolbars["swipeMain"] = SwipeMainToolbar(self)
+
+            self._mgr.AddPane(
+                self.toolbars["swipeMain"],
+                wx.aui.AuiPaneInfo()
+                .Name("swipeMain")
+                .Caption(_("Main Toolbar"))
+                .ToolbarPane()
+                .Top()
+                .LeftDockable(False)
+                .RightDockable(False)
+                .BottomDockable(False)
+                .TopDockable(True)
+                .CloseButton(False)
+                .Layer(2)
+                .Row(1)
+                .Position(0)
+                .BestSize((self.toolbars["swipeMain"].GetBestSize())),
+            )
 
-        self.toolbars["swipeMisc"] = SwipeMiscToolbar(self)
+        if name == "swipeMap":
+            if "swipeMap" not in self.toolbars:
+                self.toolbars["swipeMap"] = SwipeMapToolbar(self, self._toolSwitcher)
+
+            self._mgr.AddPane(
+                self.toolbars["swipeMap"],
+                wx.aui.AuiPaneInfo()
+                .Name("swipeMap")
+                .Caption(_("Map Toolbar"))
+                .ToolbarPane()
+                .Top()
+                .LeftDockable(False)
+                .RightDockable(False)
+                .BottomDockable(False)
+                .TopDockable(True)
+                .CloseButton(False)
+                .Layer(2)
+                .Row(1)
+                .Position(1)
+                .BestSize((self.toolbars["swipeMap"].GetBestSize())),
+            )
 
-        self._mgr.AddPane(
-            self.toolbars["swipeMisc"],
-            wx.aui.AuiPaneInfo()
-            .Name("swipeMisc")
-            .Caption(_("Misc Toolbar"))
-            .ToolbarPane()
-            .Top()
-            .LeftDockable(False)
-            .RightDockable(False)
-            .BottomDockable(False)
-            .TopDockable(True)
-            .CloseButton(False)
-            .Layer(2)
-            .Row(1)
-            .Position(2)
-            .BestSize((self.toolbars["swipeMisc"].GetBestSize())),
-        )
+        if name == "swipeMisc":
+            if "swipeMisc" not in self.toolbars:
+                self.toolbars["swipeMisc"] = SwipeMiscToolbar(self)
+
+            self._mgr.AddPane(
+                self.toolbars["swipeMisc"],
+                wx.aui.AuiPaneInfo()
+                .Name("swipeMisc")
+                .Caption(_("Misc Toolbar"))
+                .ToolbarPane()
+                .Top()
+                .LeftDockable(False)
+                .RightDockable(False)
+                .BottomDockable(False)
+                .TopDockable(True)
+                .CloseButton(False)
+                .Layer(2)
+                .Row(1)
+                .Position(2)
+                .BestSize((self.toolbars["swipeMisc"].GetBestSize())),
+            )
 
     def _addPanes(self):
-        """Add splitter window and sliders to aui manager"""
+        """Add splitter window, sliders and statusbar to aui manager"""
         # splitter window
         self._mgr.AddPane(
             self.splitter,
@@ -388,6 +378,9 @@ class SwipeMapFrame(DoubleMapFrame):
             .BestSize((self.sliderV.GetBestSize())),
         )
 
+        # statusbar
+        self.AddStatusbarPane()
+
     def ZoomToMap(self):
         """
         Set display extents to match selected raster (including NULLs)

+ 54 - 57
gui/wxpython/photo2image/ip2i_mapdisplay.py

@@ -101,7 +101,7 @@ class MapFrame(SingleMapFrame):
         #
 
         # items for choice
-        self.statusbarItems = [
+        statusbarItems = [
             sb.SbCoordinates,
             sb.SbRegionExtent,
             sb.SbCompRegionExtent,
@@ -115,21 +115,7 @@ class MapFrame(SingleMapFrame):
         ]
 
         # create statusbar and its manager
-        statusbar = self.CreateStatusBar(number=4, style=0)
-        statusbar.SetStatusWidths([-5, -2, -1, -1])
-        self.statusbarManager = sb.SbManager(mapframe=self, statusbar=statusbar)
-
-        # fill statusbar manager
-        self.statusbarManager.AddStatusbarItemsByClass(
-            self.statusbarItems, mapframe=self, statusbar=statusbar
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbMask(self, statusbar=statusbar, position=2)
-        )
-        self.statusbarManager.AddStatusbarItem(
-            sb.SbRender(self, statusbar=statusbar, position=3)
-        )
-
+        self.statusbar = self.CreateStatusbar(statusbarItems)
         self.statusbarManager.SetMode(8)  # goto GCP
 
         #
@@ -190,44 +176,7 @@ class MapFrame(SingleMapFrame):
         # self.SrcMapWindow.SetSize((300, 300))
         # self.TgtMapWindow.SetSize((300, 300))
         self.list.SetSize((100, 150))
-        self._mgr.AddPane(
-            self.list,
-            wx.aui.AuiPaneInfo()
-            .Name("gcplist")
-            .Caption(_("GCP List"))
-            .LeftDockable(False)
-            .RightDockable(False)
-            .PinButton()
-            .FloatingSize((600, 200))
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Top()
-            .Layer(1)
-            .MinSize((200, 100)),
-        )
-        self._mgr.AddPane(
-            self.SrcMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("source")
-            .Caption(_("Source Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Centre(),
-        )
-        self._mgr.AddPane(
-            self.TgtMapWindow,
-            wx.aui.AuiPaneInfo()
-            .Name("target")
-            .Caption(_("Target Display"))
-            .Dockable(False)
-            .CloseButton(False)
-            .DestroyOnClose(True)
-            .Floatable(False)
-            .Right()
-            .Layer(0),
-        )
+        self._addPanes()
 
         srcwidth, srcheight = self.SrcMapWindow.GetSize()
         tgtwidth, tgtheight = self.TgtMapWindow.GetSize()
@@ -296,7 +245,10 @@ class MapFrame(SingleMapFrame):
         """
         # default toolbar
         if name == "map":
-            self.toolbars["map"] = MapToolbar(self, self._toolSwitcher, self._giface)
+            if "map" not in self.toolbars:
+                self.toolbars["map"] = MapToolbar(
+                    self, self._toolSwitcher, self._giface
+                )
 
             self._mgr.AddPane(
                 self.toolbars["map"],
@@ -316,7 +268,8 @@ class MapFrame(SingleMapFrame):
 
         # GCP display
         elif name == "gcpdisp":
-            self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
+            if "gcpdisp" not in self.toolbars:
+                self.toolbars["gcpdisp"] = GCPDisplayToolbar(self, self._toolSwitcher)
 
             self._mgr.AddPane(
                 self.toolbars["gcpdisp"],
@@ -336,7 +289,8 @@ class MapFrame(SingleMapFrame):
             if self.show_target is False:
                 self.toolbars["gcpdisp"].Enable("zoommenu", enable=False)
 
-            self.toolbars["gcpman"] = GCPManToolbar(self)
+            if "gcpman" not in self.toolbars:
+                self.toolbars["gcpman"] = GCPManToolbar(self)
 
             self._mgr.AddPane(
                 self.toolbars["gcpman"],
@@ -356,6 +310,49 @@ class MapFrame(SingleMapFrame):
 
         self._mgr.Update()
 
+    def _addPanes(self):
+        """Add mapwindows, toolbars and statusbar to aui manager"""
+        self._mgr.AddPane(
+            self.list,
+            wx.aui.AuiPaneInfo()
+            .Name("gcplist")
+            .Caption(_("GCP List"))
+            .LeftDockable(False)
+            .RightDockable(False)
+            .PinButton()
+            .FloatingSize((600, 200))
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Top()
+            .Layer(1)
+            .MinSize((200, 100)),
+        )
+        self._mgr.AddPane(
+            self.SrcMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("source")
+            .Caption(_("Source Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Centre(),
+        )
+        self._mgr.AddPane(
+            self.TgtMapWindow,
+            wx.aui.AuiPaneInfo()
+            .Name("target")
+            .Caption(_("Target Display"))
+            .Dockable(False)
+            .CloseButton(False)
+            .DestroyOnClose(True)
+            .Floatable(False)
+            .Right()
+            .Layer(0),
+        )
+        # statusbar
+        self.AddStatusbarPane()
+
     def OnUpdateProgress(self, event):
         """
         Update progress bar info