FreeCAD

Форк
0
/
composite_view.py 
170 строк · 7.7 Кб
1
# SPDX-License-Identifier: LGPL-2.1-or-later
2
# ***************************************************************************
3
# *                                                                         *
4
# *   Copyright (c) 2022-2024 The FreeCAD Project Association AISBL         *
5
# *                                                                         *
6
# *   This file is part of FreeCAD.                                         *
7
# *                                                                         *
8
# *   FreeCAD is free software: you can redistribute it and/or modify it    *
9
# *   under the terms of the GNU Lesser General Public License as           *
10
# *   published by the Free Software Foundation, either version 2.1 of the  *
11
# *   License, or (at your option) any later version.                       *
12
# *                                                                         *
13
# *   FreeCAD is distributed in the hope that it will be useful, but        *
14
# *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
15
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
16
# *   Lesser General Public License for more details.                       *
17
# *                                                                         *
18
# *   You should have received a copy of the GNU Lesser General Public      *
19
# *   License along with FreeCAD. If not, see                               *
20
# *   <https://www.gnu.org/licenses/>.                                      *
21
# *                                                                         *
22
# ***************************************************************************
23

24
""" Provides a class for showing the list view and detail view at the same time. """
25

26
import base64
27

28
from addonmanager_freecad_interface import Preferences
29

30
from Addon import Addon
31
from Widgets.addonmanager_widget_package_details_view import PackageDetailsView
32
from Widgets.addonmanager_widget_view_selector import AddonManagerDisplayStyle
33
from addonmanager_package_details_controller import PackageDetailsController
34
from package_list import PackageList
35

36
# Get whatever version of PySide we can
37
try:
38
    import PySide  # Use the FreeCAD wrapper
39
except ImportError:
40
    try:
41
        import PySide6 as PySide  # Outside FreeCAD, try Qt6 first
42
    except ImportError:
43
        # Fall back to Qt5 (if this fails, Python will kill this module's import)
44
        import PySide2 as PySide
45

46
from PySide import QtCore, QtWidgets
47

48

49
class CompositeView(QtWidgets.QWidget):
50
    """A widget that displays the Addon Manager's top bar, the list of Addons, and the detail
51
    view. Depending on the view mode selected, these may all be displayed at once, or selecting
52
    an addon in the list may case the list to hide and the detail view to show."""
53

54
    install = QtCore.Signal(Addon)
55
    uninstall = QtCore.Signal(Addon)
56
    update = QtCore.Signal(Addon)
57
    execute = QtCore.Signal(Addon)
58
    update_status = QtCore.Signal(Addon)
59
    check_for_update = QtCore.Signal(Addon)
60

61
    def __init__(self, parent=None):
62
        super().__init__(parent)
63
        self.package_details = PackageDetailsView(self)
64
        self.package_details_controller = PackageDetailsController(self.package_details)
65
        self.package_list = PackageList(self)
66
        prefs = Preferences()
67
        self.display_style = prefs.get("ViewStyle")
68
        self.main_layout = QtWidgets.QHBoxLayout(self)
69
        self.splitter = QtWidgets.QSplitter(self)
70
        self.splitter.addWidget(self.package_list)
71
        self.splitter.addWidget(self.package_details)
72
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
73
        self.splitter.setContentsMargins(0, 0, 0, 0)
74
        self.splitter.setSizePolicy(
75
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding
76
        )
77
        self.main_layout.addWidget(self.splitter)
78
        self.layout().setContentsMargins(0, 0, 0, 0)
79
        self._setup_ui()
80
        self._setup_connections()
81
        self._restore_splitter_state()
82
        self.scroll_position = 0
83

84
    def _save_splitter_state(self):
85
        """Write the splitter state into an Addon manager preference, CompositeSplitterState"""
86
        prefs = Preferences()
87
        state = self.splitter.saveState()
88
        encoded = base64.b64encode(state).decode("ASCII")
89
        prefs.set("CompositeSplitterState", encoded)
90

91
    def _restore_splitter_state(self):
92
        """Restore the splitter state from CompositeSplitterState"""
93
        prefs = Preferences()
94
        encoded = prefs.get("CompositeSplitterState")
95
        if encoded:
96
            state = base64.b64decode(encoded)
97
            self.splitter.restoreState(state)
98

99
    def setModel(self, model):
100
        self.package_list.setModel(model)
101

102
    def set_display_style(self, style: AddonManagerDisplayStyle):
103
        self.display_style = style
104
        self._setup_ui()
105

106
    def _setup_ui(self):
107
        if self.display_style == AddonManagerDisplayStyle.EXPANDED:
108
            self._setup_expanded_ui()
109
        elif self.display_style == AddonManagerDisplayStyle.COMPACT:
110
            self._setup_compact_ui()
111
        elif self.display_style == AddonManagerDisplayStyle.COMPOSITE:
112
            self._setup_composite_ui()
113
        else:
114
            raise RuntimeError("Invalid display style")
115
        self.package_list.set_view_style(self.display_style)
116

117
    def _setup_expanded_ui(self):
118
        self.package_list.show()
119
        self.package_details.hide()
120
        self.package_details.button_bar.set_show_back_button(True)
121

122
    def _setup_compact_ui(self):
123
        self.package_list.show()
124
        self.package_details.hide()
125
        self.package_details.button_bar.set_show_back_button(True)
126

127
    def _setup_composite_ui(self):
128
        self.package_list.show()
129
        self.package_details.show()
130
        self.package_details.button_bar.set_show_back_button(False)
131

132
    def _setup_connections(self):
133
        self.package_list.itemSelected.connect(self.addon_selected)
134
        self.package_details_controller.back.connect(self._back_button_clicked)
135
        self.package_details_controller.install.connect(self.install)
136
        self.package_details_controller.uninstall.connect(self.uninstall)
137
        self.package_details_controller.update.connect(self.update)
138
        self.package_details_controller.execute.connect(self.execute)
139
        self.package_details_controller.update_status.connect(self.update_status)
140
        self.package_list.ui.view_bar.view_changed.connect(self.set_display_style)
141
        self.splitter.splitterMoved.connect(self._splitter_moved)
142

143
    def addon_selected(self, addon):
144
        """Depending on the display_style, show addon details (possibly hiding the package_list
145
        widget in the process."""
146
        self.package_details_controller.show_repo(addon)
147
        if self.display_style != AddonManagerDisplayStyle.COMPOSITE:
148
            self.scroll_position = (
149
                self.package_list.ui.listPackages.verticalScrollBar().sliderPosition()
150
            )
151
            print(f"Saved slider position at {self.scroll_position}")
152
            self.package_list.hide()
153
            self.package_details.show()
154
            self.package_details.button_bar.set_show_back_button(True)
155

156
    def _back_button_clicked(self):
157
        if self.display_style != AddonManagerDisplayStyle.COMPOSITE:
158
            print(f"Set slider position to {self.scroll_position}")
159
            self.package_list.show()
160
            self.package_details.hide()
161
            # The following must be done *after* a cycle through the event loop
162
            QtCore.QTimer.singleShot(
163
                0,
164
                lambda: self.package_list.ui.listPackages.verticalScrollBar().setSliderPosition(
165
                    self.scroll_position
166
                ),
167
            )
168

169
    def _splitter_moved(self, _1: int, _2: int) -> None:
170
        self._save_splitter_state()
171

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.