Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Autoupdate launcher #1725

Merged
merged 6 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions openpype/tools/launcher/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,19 +325,59 @@ def __init__(self, dbcon, parent=None):

self.hide_invisible = False
self.project_icon = qtawesome.icon("fa.map", color="white")
self._project_names = set()

def refresh(self):
self.clear()
self.beginResetModel()

project_names = set()
for project_doc in self.get_projects():
item = QtGui.QStandardItem(self.project_icon, project_doc["name"])
self.appendRow(item)
project_names.add(project_doc["name"])

origin_project_names = set(self._project_names)
self._project_names = project_names

project_names_to_remove = origin_project_names - project_names
if project_names_to_remove:
row_counts = {}
continuous = None
for row in range(self.rowCount()):
index = self.index(row, 0)
index_name = index.data(QtCore.Qt.DisplayRole)
if index_name in project_names_to_remove:
if continuous is None:
continuous = row
row_counts[continuous] = 0
row_counts[continuous] += 1
else:
continuous = None

for row in reversed(sorted(row_counts.keys())):
count = row_counts[row]
self.removeRows(row, count)

continuous = None
row_counts = {}
for idx, project_name in enumerate(sorted(project_names)):
if project_name in origin_project_names:
continuous = None
continue

self.endResetModel()
if continuous is None:
continuous = idx
row_counts[continuous] = []

row_counts[continuous].append(project_name)

for row in reversed(sorted(row_counts.keys())):
items = []
for project_name in row_counts[row]:
item = QtGui.QStandardItem(self.project_icon, project_name)
items.append(item)

self.invisibleRootItem().insertRows(row, items)

def get_projects(self):
project_docs = []

for project_doc in sorted(
self.dbcon.projects(), key=lambda x: x["name"]
):
Expand Down
40 changes: 23 additions & 17 deletions openpype/tools/launcher/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
class ProjectBar(QtWidgets.QWidget):
project_changed = QtCore.Signal(int)

# Project list will be refreshed each 10000 msecs
refresh_interval = 10000

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

Expand All @@ -47,49 +50,52 @@ def __init__(self, dbcon, parent=None):
QtWidgets.QSizePolicy.Maximum
)

refresh_timer = QtCore.QTimer()
refresh_timer.setInterval(self.refresh_interval)

self.model = model
self.project_delegate = project_delegate
self.project_combobox = project_combobox

# Initialize
self.refresh()
self.refresh_timer = refresh_timer

# Signals
refresh_timer.timeout.connect(self._on_refresh_timeout)
self.project_combobox.currentIndexChanged.connect(self.project_changed)

# Set current project by default if it's set.
project_name = self.dbcon.Session.get("AVALON_PROJECT")
if project_name:
self.set_project(project_name)

def showEvent(self, event):
if not self.refresh_timer.isActive():
self.refresh_timer.start()
super(ProjectBar, self).showEvent(event)

def _on_refresh_timeout(self):
if not self.isVisible():
# Stop timer if widget is not visible
self.refresh_timer.stop()

elif self.isActiveWindow():
# Refresh projects if window is active
self.model.refresh()

def get_current_project(self):
return self.project_combobox.currentText()

def set_project(self, project_name):
index = self.project_combobox.findText(project_name)
if index < 0:
# Try refresh combobox model
self.project_combobox.blockSignals(True)
self.model.refresh()
self.project_combobox.blockSignals(False)

self.refresh()
index = self.project_combobox.findText(project_name)

if index >= 0:
self.project_combobox.setCurrentIndex(index)

def refresh(self):
prev_project_name = self.get_current_project()

# Refresh without signals
self.project_combobox.blockSignals(True)

self.model.refresh()
self.set_project(prev_project_name)

self.project_combobox.blockSignals(False)

self.project_changed.emit(self.project_combobox.currentIndex())


class ActionBar(QtWidgets.QWidget):
Expand Down
48 changes: 43 additions & 5 deletions openpype/tools/launcher/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class ProjectsPanel(QtWidgets.QWidget):
"""Projects Page"""

project_clicked = QtCore.Signal(str)
# Refresh projects each 10000 msecs
refresh_interval = 10000

def __init__(self, dbcon, parent=None):
super(ProjectsPanel, self).__init__(parent=parent)
Expand All @@ -106,21 +108,40 @@ def __init__(self, dbcon, parent=None):
flick.activateOn(view)
model = ProjectModel(self.dbcon)
model.hide_invisible = True
model.refresh()
view.setModel(model)

layout.addWidget(view)

refresh_timer = QtCore.QTimer()
refresh_timer.setInterval(self.refresh_interval)

refresh_timer.timeout.connect(self._on_refresh_timeout)
view.clicked.connect(self.on_clicked)

self.model = model
self.view = view
self.refresh_timer = refresh_timer

def on_clicked(self, index):
if index.isValid():
project_name = index.data(QtCore.Qt.DisplayRole)
self.project_clicked.emit(project_name)

def showEvent(self, event):
self.model.refresh()
if not self.refresh_timer.isActive():
self.refresh_timer.start()
super(ProjectsPanel, self).showEvent(event)

def _on_refresh_timeout(self):
if not self.isVisible():
# Stop timer if widget is not visible
self.refresh_timer.stop()

elif self.isActiveWindow():
# Refresh projects if window is active
self.model.refresh()


class AssetsPanel(QtWidgets.QWidget):
"""Assets page"""
Expand Down Expand Up @@ -276,6 +297,8 @@ def on_task_change(self):

class LauncherWindow(QtWidgets.QDialog):
"""Launcher interface"""
# Refresh actions each 10000msecs
actions_refresh_timeout = 10000

def __init__(self, parent=None):
super(LauncherWindow, self).__init__(parent)
Expand Down Expand Up @@ -344,6 +367,10 @@ def __init__(self, parent=None):
layout.setSpacing(0)
layout.setContentsMargins(0, 0, 0, 0)

actions_refresh_timer = QtCore.QTimer()
actions_refresh_timer.setInterval(self.actions_refresh_timeout)

self.actions_refresh_timer = actions_refresh_timer
self.message_label = message_label
self.project_panel = project_panel
self.asset_panel = asset_panel
Expand All @@ -353,6 +380,7 @@ def __init__(self, parent=None):
self._page = 0

# signals
actions_refresh_timer.timeout.connect(self._on_action_timer)
actions_bar.action_clicked.connect(self.on_action_clicked)
action_history.trigger_history.connect(self.on_history_action)
project_panel.project_clicked.connect(self.on_project_clicked)
Expand All @@ -367,9 +395,11 @@ def __init__(self, parent=None):
self.resize(520, 740)

def showEvent(self, event):
super().showEvent(event)
# TODO implement refresh/reset which will trigger updating
self.discover_actions()
if not self.actions_refresh_timer.isActive():
self.actions_refresh_timer.start()
self.discover_actions()

super(LauncherWindow, self).showEvent(event)

def set_page(self, page):
current = self.page_slider.currentIndex()
Expand Down Expand Up @@ -402,6 +432,15 @@ def discover_actions(self):
def filter_actions(self):
self.actions_bar.filter_actions()

def _on_action_timer(self):
if not self.isVisible():
# Stop timer if widget is not visible
self.actions_refresh_timer.stop()

elif self.isActiveWindow():
# Refresh projects if window is active
self.discover_actions()

def on_project_clicked(self, project_name):
self.dbcon.Session["AVALON_PROJECT"] = project_name
# Refresh projects
Expand All @@ -412,7 +451,6 @@ def on_project_clicked(self, project_name):
def on_back_clicked(self):
self.dbcon.Session["AVALON_PROJECT"] = None
self.set_page(0)
self.project_panel.model.refresh() # Refresh projects
self.discover_actions()

def on_action_clicked(self, action):
Expand Down