File: notebook.py

package info (click to toggle)
grass 8.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 277,040 kB
  • sloc: ansic: 460,798; python: 227,732; cpp: 42,026; sh: 11,262; makefile: 7,007; xml: 3,637; sql: 968; lex: 520; javascript: 484; yacc: 450; asm: 387; perl: 157; sed: 25; objc: 6; ruby: 4
file content (190 lines) | stat: -rw-r--r-- 6,061 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
"""
@package main_window.notebook

@brief Custom AuiNotebook class and class for undocked AuiNotebook frame

Classes:
 - notebook::MainPageFrame
 - notebook::MainNotebook

(C) 2022 by the GRASS Development Team

This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.

@author Linda Kladivova <lindakladivova gmail.com>
@author Anna Petrasova <kratochanna gmail.com>
"""

import os

import wx
import wx.lib.agw.aui as aui

from core import globalvar
from gui_core.wrap import SimpleTabArt
from mapdisp.frame import MapPanel


class MainPageFrame(wx.Frame):
    """Frame for independent window."""

    def __init__(self, parent, panel, size, pos, title, icon="grass", menu=None):
        wx.Frame.__init__(self, parent=parent, size=size, pos=pos, title=title)
        self.panel = panel
        self.panel.Reparent(self)

        self._layout()

        # set system icon
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ICONDIR, icon + ".ico"), wx.BITMAP_TYPE_ICO)
        )

        if menu is not None:
            self.SetMenuBar(menu)

        self.panel.onFocus.emit()
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        self._show()

    def _layout(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panel, proportion=1, flag=wx.EXPAND)
        self.SetSizer(sizer)
        self.CentreOnParent()

    def _show(self):
        """Show frame and contained panel"""
        self.panel.Show()
        self.Show()

    def SetDockingCallback(self, function):
        """Set docking callback on reparented panel"""
        self.panel.SetDockingCallback(function)

    def OnClose(self, event):
        """Close frame and associated layer notebook page."""
        if isinstance(self.panel, MapPanel):
            self.panel.OnCloseWindow(event=None, askIfSaveWorkspace=True)
        else:
            self.panel.OnCloseWindow(event=None)


class MainNotebook(aui.AuiNotebook):
    """Main notebook class. Overrides some AuiNotebook classes.
    Takes into consideration the dock/undock functionality.
    """

    def __init__(
        self,
        parent,
        agwStyle=aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER,
    ):
        self.parent = parent
        super().__init__(parent=self.parent, id=wx.ID_ANY, agwStyle=agwStyle)

        self.SetArtProvider(SimpleTabArt())

        # bindings
        self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnClose)

        # remember number of items in the menu
        self._menuCount = self.parent.menubar.GetMenuCount()

    def OnPageChanged(self, event):
        page = self.GetCurrentPage()
        page.onFocus.emit()

        # set up menu
        mbar = self.parent.menubar
        if page.HasMenu():
            # add new (or replace if exists) additional menu item related to this page
            menu, menuName = page.GetMenu()
            if mbar.GetMenuCount() == self._menuCount:
                appendMenu = mbar.Insert
            else:
                appendMenu = mbar.Replace
            appendMenu(self._menuCount - 1, menu, menuName)
        elif mbar.GetMenuCount() > self._menuCount:
            # remove additional menu item
            mbar.Remove(self._menuCount - 1)

    def UndockPage(self, page):
        """Undock active page to independent MainFrame object"""
        index = self.GetPageIndex(page)
        text = self.GetPageText(index)
        original_size = page.GetSize()
        original_pos = page.GetPosition()
        icon = "grass_map" if isinstance(page, MapPanel) else "grass"
        if page.HasMenu():
            menu, _ = page.GetMenu()
        else:
            menu = None
        self.RemovePage(index)
        frame = MainPageFrame(
            parent=self.parent,
            panel=page,
            size=original_size,
            pos=original_pos,
            title=text,
            icon=icon,
            menu=menu,
        )
        frame.SetDockingCallback(self.DockPage)

    def DockPage(self, page):
        """Dock independent MainFrame object back to Aui.Notebook"""
        frame = page.GetParent()
        page.Reparent(self)
        page.SetDockingCallback(self.UndockPage)
        self.AddPage(page, frame.GetTitle())
        if frame.GetMenuBar():
            # avoid destroying menu if defined
            frame.SetMenuBar(None)
        frame.Destroy()

    def AddPage(self, *args, **kwargs):
        """Overrides Aui.Notebook AddPage method.
        Adds page to notebook and makes it current"""
        super().AddPage(*args, **kwargs)
        self.SetSelection(self.GetPageCount() - 1)

    def SetSelectionToMainPage(self, page):
        """Decides whether to set selection to a MainNotebook page
        or an undocked independent frame"""
        self.SetSelection(self.GetPageIndex(page))

        if not page.IsDocked():
            frame = page.GetParent()
            wx.CallLater(500, lambda: frame.Raise() if frame else None)

    def DeleteMainPage(self, page):
        """Decides whether to delete a MainNotebook page
        or close an undocked independent frame"""
        if page.IsDocked():
            self.DeletePage(self.GetPageIndex(page))
        else:
            frame = page.GetParent()
            frame.Destroy()

    def SetMainPageText(self, page, text):
        """Decides whether sets title to MainNotebook page
        or an undocked independent frame"""
        if page.IsDocked():
            self.SetPageText(page_idx=self.GetPageIndex(page), text=text)
        else:
            frame = page.GetParent()
            frame.SetTitle(text)
            wx.CallLater(500, frame.Raise)

    def OnClose(self, event):
        """Page of map notebook is being closed"""
        page = self.GetCurrentPage()
        if isinstance(page, MapPanel):
            page.OnCloseWindow(event=None, askIfSaveWorkspace=True)
        else:
            page.OnCloseWindow(event=None)
        event.Veto()