Skip to content

Commit

Permalink
Merge pull request #110 from davidlatwe/profiles-treeview-dock
Browse files Browse the repository at this point in the history
Replace header profile widgets with profiles dock page
  • Loading branch information
davidlatwe authored Oct 19, 2020
2 parents 4d72b3f + dee15ef commit dbfb98b
Show file tree
Hide file tree
Showing 18 changed files with 687 additions and 123 deletions.
15 changes: 9 additions & 6 deletions allzpark/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
localz = None

log = logging.getLogger(__name__)
Latest = None # Enum
NoVersion = None

Latest = model.Latest # Enum
NoVersion = model.NoVersion


class State(dict):
Expand Down Expand Up @@ -208,11 +209,11 @@ def __init__(self, storage, stdio=None, stderr=None, parent=None):
state = State(self, storage)

models = {
"profileVersions": QtCore.QStringListModel(),
"profileNames": QtCore.QStringListModel(),
"apps": model.ApplicationModel(),
"profileVersions": QtCore.QStringListModel(),

# Docks
"profiles": model.ProfileModel(),
"packages": model.PackagesModel(self),
"context": model.ContextModel(),
"environment": model.EnvironmentModel(),
Expand Down Expand Up @@ -589,8 +590,6 @@ def do():
default_profile = name

self._state["rezProfiles"].update(profiles)
self._models["profileNames"].setStringList(list(profiles))
self._models["profileNames"].layoutChanged.emit()

# On resetting after startup, there will be a
# currently selected profile that may differ from
Expand All @@ -607,6 +606,10 @@ def do():
if not current_profile:
current_profile = default_profile

self._models["profiles"].set_favorites(self)
self._models["profiles"].set_current(current_profile)
self._models["profiles"].reset(profiles)

self._state["profileName"] = current_profile
self._state["root"] = root

Expand Down
269 changes: 268 additions & 1 deletion allzpark/dock.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def setWidget(self, widget):


class App(AbstractDockWidget):
"""Aggregated information about the currently selected profile"""
"""Aggregated information about the currently selected application"""

icon = "Alert_Info_32"

Expand Down Expand Up @@ -1375,3 +1375,270 @@ def highlightBlock(self, text):
)
startIndex = self.comment_start_exp.indexIn(
text, startIndex + commentLength)


class ProfileView(QtWidgets.QTreeView):

activated = QtCore.Signal(str)

def __init__(self, parent=None):
super(ProfileView, self).__init__(parent)

self.setHeaderHidden(True)
self.setSortingEnabled(True)
self.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

self.customContextMenuRequested.connect(self.on_context_menu)

def on_context_menu(self, position):
index = self.indexAt(position)

if not index.isValid():
# Clicked outside any item
return

model_ = index.model()
menu = QtWidgets.QMenu(self)

name = str(model_.data(index, model.NameRole))

activate = QtWidgets.QAction("Activate", menu)
activate.triggered.connect(lambda: self.on_activate(name))
menu.addAction(activate)

menu.move(QtGui.QCursor.pos())
menu.show()

def on_activate(self, profile):
self.activated.emit(profile)

def selected_index(self):
return self.selectionModel().currentIndex()

def selected_profile(self):
index = self.selected_index()
if index.isValid():
return index.data(model.NameRole)


class Profiles(AbstractDockWidget):
"""Listing and changing profiles"""

icon = "Default_Profile"

profile_changed = QtCore.Signal(str)
version_changed = QtCore.Signal(str)
reset = QtCore.Signal()

def __init__(self, ctrl, parent=None):
super(Profiles, self).__init__("Profiles", parent)
self.setAttribute(QtCore.Qt.WA_StyledBackground)
self.setObjectName("Profiles")

panels = {
"central": QtWidgets.QWidget(),
"head": QtWidgets.QWidget(),
"body": QtWidgets.QWidget(),
}

widgets = {
# head: current profile
"icon": QtWidgets.QLabel(),
"name": QtWidgets.QLabel(),
"version": LineEditWithCompleter(),

# body: profiles view and toolset
"refresh": QtWidgets.QPushButton(""),
"search": QtWidgets.QLineEdit(),
"view": ProfileView(),

"tools": QtWidgets.QWidget(),
"favorite": QtWidgets.QPushButton(""),
"filtering": QtWidgets.QPushButton(""),
"expand": QtWidgets.QPushButton(""),
"collapse": QtWidgets.QPushButton(""),
"sep1": QtWidgets.QFrame(),
"versioning": QtWidgets.QPushButton(""),
}

models = {
"source": None,
"proxy": model.ProfileProxyModel(),
}

layout = QtWidgets.QGridLayout(panels["head"])
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(widgets["icon"], 0, 0, 2, 1)
layout.addWidget(widgets["name"], 0, 1)
layout.addWidget(widgets["version"], 1, 1)

layout = QtWidgets.QVBoxLayout(widgets["tools"])
layout.setContentsMargins(0, 2, 0, 0)
layout.addWidget(widgets["favorite"])
layout.addWidget(widgets["filtering"])
layout.addWidget(widgets["expand"])
layout.addWidget(widgets["collapse"])
layout.addWidget(widgets["sep1"])
layout.addWidget(widgets["versioning"])
# (epic) quick make profile
# (epic) quick edit profile
# (epic) remove or hide local profile
layout.addStretch()

layout = QtWidgets.QGridLayout(panels["body"])
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(widgets["refresh"], 0, 0)
layout.addWidget(widgets["tools"], 1, 0)
layout.addWidget(widgets["search"], 0, 1)
layout.addWidget(widgets["view"], 1, 1)

layout = QtWidgets.QVBoxLayout(panels["central"])
layout.setContentsMargins(4, 4, 4, 4)
layout.addWidget(panels["head"])
layout.addWidget(panels["body"], stretch=True)

version = widgets["version"]
search = widgets["search"]
view = widgets["view"]
proxy = models["proxy"]

view.setModel(proxy)
selection = view.selectionModel()

proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
search.setPlaceholderText("Filter profiles..")

version.setToolTip("Click to change profile version")
version.setEnabled(False)

widgets["sep1"].setFrameShape(QtWidgets.QFrame.HLine)
widgets["sep1"].setFrameShadow(QtWidgets.QFrame.Sunken)

# icons
icon_size = QtCore.QSize(14, 14)

icon = res.icon("refresh")
widgets["refresh"].setIcon(icon)
widgets["refresh"].setIconSize(icon_size)

icon = res.icon("star_bright")
icon.addPixmap(res.pixmap("star_dim"), icon.Disabled)
widgets["favorite"].setIcon(icon)
widgets["favorite"].setIconSize(icon_size)

icon = QtGui.QIcon()
icon.addPixmap(res.pixmap("filter_on"), icon.Normal, icon.On)
icon.addPixmap(res.pixmap("filter_off"), icon.Normal, icon.Off)
widgets["filtering"].setIcon(icon)
widgets["filtering"].setIconSize(icon_size)
widgets["filtering"].setCheckable(True)
widgets["filtering"].setAutoRepeat(True)

icon = QtGui.QIcon()
icon.addPixmap(res.pixmap("version_on"), icon.Normal, icon.On)
icon.addPixmap(res.pixmap("version_off"), icon.Normal, icon.Off)
widgets["versioning"].setIcon(icon)
widgets["versioning"].setIconSize(icon_size)
widgets["versioning"].setCheckable(True)
widgets["versioning"].setAutoRepeat(True)

icon = res.icon("expand")
widgets["expand"].setIcon(icon)
widgets["expand"].setIconSize(icon_size)

icon = res.icon("collapse")
widgets["collapse"].setIcon(icon)
widgets["collapse"].setIconSize(icon_size)

icon = res.icon("Default_Profile")
icon = icon.pixmap(QtCore.QSize(px(32), px(32)))
widgets["icon"].setPixmap(icon)

# signals
view.activated.connect(self.profile_changed.emit)
selection.currentChanged.connect(self.on_selected_profile_changed)
version.changed.connect(self.version_changed.emit)
search.textChanged.connect(view.expandAll)
search.textChanged.connect(proxy.setFilterFixedString)
widgets["refresh"].clicked.connect(self.reset.emit)
widgets["favorite"].clicked.connect(self.on_favorite)
widgets["filtering"].clicked.connect(self.on_filtering)
widgets["versioning"].clicked.connect(
lambda *args: version.setEnabled(not version.isEnabled()))
widgets["expand"].clicked.connect(view.expandAll)
widgets["collapse"].clicked.connect(view.collapseAll)
ctrl.resetted.connect(view.expandAll)

self._widgets = widgets
self._models = models
self._ctrl = ctrl

self.setWidget(panels["central"])

self.update_favorite_btn(None) # nothing selected on startup

def set_model(self, profile_model, version_model):
# profile
proxy = self._models["proxy"]
proxy.setSourceModel(profile_model)
self._models["source"] = profile_model
self._widgets["filtering"].setChecked(profile_model.is_filtering)
# version
self._widgets["version"].setModel(version_model)

def on_context_menu(self, window):
def _on_context_menu(*args):
name = self._models["source"].current

menu = MenuWithTooltip(window)
separator = QtWidgets.QWidgetAction(menu)
separator.setDefaultWidget(QtWidgets.QLabel(name))
menu.addAction(separator)

def on_reset():
window.reset()

reset = QtWidgets.QAction("Reset", menu)
reset.triggered.connect(on_reset)
reset.setToolTip("Re-scan repository for new Rez packages")
menu.addAction(reset)

menu.addSeparator()

menu.move(QtGui.QCursor.pos())
menu.show()

return _on_context_menu

def on_favorite(self):
model_ = self._models["source"]
proxy = self._models["proxy"]
view = self._widgets["view"]
index = proxy.mapToSource(view.selected_index())

model_.update_favorite(self._ctrl, index)
model_.update_profile_icon(index)

def on_filtering(self):
proxy = self._models["proxy"]
model_ = self._models["source"]
model_.is_filtering = not model_.is_filtering

proxy.invalidateFilter()

def on_selected_profile_changed(self):
view = self._widgets["view"]
self.update_favorite_btn(view.selected_profile())

def update_favorite_btn(self, profile):
btn = self._widgets["favorite"]
btn.setEnabled(bool(profile))

def update_current(self, profile, version, icon):
self._widgets["name"].setText(profile)
self._widgets["version"].setText(version)

icon = res.icon(icon)
icon = icon.pixmap(QtCore.QSize(px(32), px(32)))
self._widgets["icon"].setPixmap(icon)
Loading

0 comments on commit dbfb98b

Please sign in to comment.