Merge pull request #2008 from davidlatwe/feature/project-archive-state

Settings: Flag project as deactivated and hide from tools' view
This commit is contained in:
Milan Kolar 2021-09-23 09:21:51 +01:00 committed by GitHub
commit bf021183dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 182 additions and 85 deletions

View file

@ -812,17 +812,22 @@ class SyncServerModule(OpenPypeModule, ITrayModule):
def _prepare_sync_project_settings(self, exclude_locals):
sync_project_settings = {}
system_sites = self.get_all_site_configs()
for collection in self.connection.database.collection_names(False):
project_docs = self.connection.projects(
projection={"name": 1},
only_active=True
)
for project_doc in project_docs:
project_name = project_doc["name"]
sites = copy.deepcopy(system_sites) # get all configured sites
proj_settings = self._parse_sync_settings_from_settings(
get_project_settings(collection,
get_project_settings(project_name,
exclude_locals=exclude_locals))
sites.update(self._get_default_site_configs(
proj_settings["enabled"], collection))
proj_settings["enabled"], project_name))
sites.update(proj_settings['sites'])
proj_settings["sites"] = sites
sync_project_settings[collection] = proj_settings
sync_project_settings[project_name] = proj_settings
if not sync_project_settings:
log.info("No enabled and configured projects for sync.")
return sync_project_settings

View file

@ -77,8 +77,8 @@ class SyncServerWindow(QtWidgets.QDialog):
self.setWindowTitle("Sync Queue")
self.projects.project_changed.connect(
lambda: repres.table_view.model().set_project(
self.projects.current_project))
self._on_project_change
)
self.pause_btn.clicked.connect(self._pause)
self.pause_btn.setAutoDefault(False)
@ -87,6 +87,13 @@ class SyncServerWindow(QtWidgets.QDialog):
self.representationWidget = repres
def _on_project_change(self):
if self.projects.current_project is None:
return
self.representationWidget.table_view.model().set_project(
self.projects.current_project
)
def showEvent(self, event):
self.representationWidget.model.set_project(
self.projects.current_project)

View file

@ -17,25 +17,6 @@ from . import lib
log = PypeLogger().get_logger("SyncServer")
class ProjectModel(QtCore.QAbstractListModel):
def __init__(self, *args, projects=None, **kwargs):
super(ProjectModel, self).__init__(*args, **kwargs)
self.projects = projects or []
def data(self, index, role):
if role == Qt.DisplayRole:
# See below for the data structure.
status, text = self.projects[index.row()]
# Return the todo text only.
return text
def rowCount(self, _index):
return len(self.todos)
def columnCount(self, _index):
return len(self._header)
class _SyncRepresentationModel(QtCore.QAbstractTableModel):
COLUMN_LABELS = []

View file

@ -6,10 +6,7 @@ from functools import partial
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCore import Qt
from openpype.tools.settings import (
ProjectListWidget,
style
)
from openpype.tools.settings import style
from openpype.api import get_local_site_id
from openpype.lib import PypeLogger
@ -28,28 +25,56 @@ from . import delegates
log = PypeLogger().get_logger("SyncServer")
class SyncProjectListWidget(ProjectListWidget):
class SyncProjectListWidget(QtWidgets.QWidget):
"""
Lists all projects that are synchronized to choose from
"""
project_changed = QtCore.Signal()
def __init__(self, sync_server, parent):
super(SyncProjectListWidget, self).__init__(parent)
self.setObjectName("ProjectListWidget")
self._parent = parent
label_widget = QtWidgets.QLabel("Projects", self)
project_list = QtWidgets.QListView(self)
project_model = QtGui.QStandardItemModel()
project_list.setModel(project_model)
project_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
# Do not allow editing
project_list.setEditTriggers(
QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers
)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(3)
layout.addWidget(label_widget, 0)
layout.addWidget(project_list, 1)
project_list.customContextMenuRequested.connect(self._on_context_menu)
project_list.selectionModel().currentChanged.connect(
self._on_index_change
)
self.project_model = project_model
self.project_list = project_list
self.sync_server = sync_server
self.project_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.project_list.customContextMenuRequested.connect(
self._on_context_menu)
self.current_project = None
self.project_name = None
self.local_site = None
self.icons = {}
self.layout().setContentsMargins(0, 0, 0, 0)
def _on_index_change(self, new_idx, _old_idx):
project_name = new_idx.data(QtCore.Qt.DisplayRole)
def validate_context_change(self):
return True
self.current_project = project_name
self.project_changed.emit()
def refresh(self):
model = self.project_list.model()
model = self.project_model
model.clear()
project_name = None
@ -70,8 +95,7 @@ class SyncProjectListWidget(ProjectListWidget):
QtCore.Qt.DisplayRole
)
if not self.current_project:
self.current_project = self.project_list.model().item(0). \
data(QtCore.Qt.DisplayRole)
self.current_project = model.item(0).data(QtCore.Qt.DisplayRole)
if project_name:
self.local_site = self.sync_server.get_active_site(project_name)

View file

@ -22,5 +22,6 @@
"aftereffects/2021",
"unreal/4-26"
],
"tools_env": []
"tools_env": [],
"active": true
}

View file

@ -69,6 +69,11 @@
"type": "tools-enum",
"key": "tools_env",
"label": "Tools"
},
{
"type": "boolean",
"key": "active",
"label": "Active Project"
}
]
}

View file

@ -326,8 +326,6 @@ class ProjectModel(QtGui.QStandardItemModel):
super(ProjectModel, self).__init__(parent=parent)
self.dbcon = dbcon
self.hide_invisible = False
self.project_icon = qtawesome.icon("fa.map", color="white")
self._project_names = set()
@ -380,16 +378,5 @@ class ProjectModel(QtGui.QStandardItemModel):
self.invisibleRootItem().insertRows(row, items)
def get_projects(self):
project_docs = []
for project_doc in sorted(
self.dbcon.projects(), key=lambda x: x["name"]
):
if (
self.hide_invisible
and not project_doc["data"].get("visible", True)
):
continue
project_docs.append(project_doc)
return project_docs
return sorted(self.dbcon.projects(only_active=True),
key=lambda x: x["name"])

View file

@ -271,7 +271,6 @@ class LauncherWindow(QtWidgets.QDialog):
)
project_model = ProjectModel(self.dbcon)
project_model.hide_invisible = True
project_handler = ProjectHandler(self.dbcon, project_model)
project_panel = ProjectsPanel(project_handler)

View file

@ -43,18 +43,14 @@ class ProjectModel(QtGui.QStandardItemModel):
none_project.setData(None)
project_items.append(none_project)
database = self.dbcon.database
project_names = set()
for project_name in database.collection_names():
# Each collection will have exactly one project document
project_doc = database[project_name].find_one(
{"type": "project"},
{"name": 1}
)
if not project_doc:
continue
project_name = project_doc.get("name")
for doc in sorted(
self.dbcon.projects(projection={"name": 1}, only_active=True),
key=lambda x: x["name"]
):
project_name = doc.get("name")
if project_name:
project_names.add(project_name)
project_items.append(QtGui.QStandardItem(project_name))

View file

@ -809,7 +809,7 @@ class ProjectSettingsWidget(QtWidgets.QWidget):
self.modules_manager = modules_manager
projects_widget = _ProjectListWidget(self)
projects_widget = _ProjectListWidget(self, only_active=True)
roos_site_widget = RootSiteWidget(
modules_manager, project_settings, self
)

View file

@ -602,6 +602,12 @@ class NiceCheckbox(QtWidgets.QFrame):
return super(NiceCheckbox, self).mouseReleaseEvent(event)
class ProjectListModel(QtGui.QStandardItemModel):
sort_role = QtCore.Qt.UserRole + 10
filter_role = QtCore.Qt.UserRole + 11
selected_role = QtCore.Qt.UserRole + 12
class ProjectListView(QtWidgets.QListView):
left_mouse_released_at = QtCore.Signal(QtCore.QModelIndex)
@ -612,11 +618,35 @@ class ProjectListView(QtWidgets.QListView):
super(ProjectListView, self).mouseReleaseEvent(event)
class ProjectListSortFilterProxy(QtCore.QSortFilterProxyModel):
def __init__(self, *args, **kwargs):
super(ProjectListSortFilterProxy, self).__init__(*args, **kwargs)
self._enable_filter = True
def filterAcceptsRow(self, source_row, source_parent):
if not self._enable_filter:
return True
index = self.sourceModel().index(source_row, 0, source_parent)
is_active = bool(index.data(self.filterRole()))
is_selected = bool(index.data(ProjectListModel.selected_role))
return is_active or is_selected
def is_filter_enabled(self):
return self._enable_filter
def set_filter_enabled(self, value):
self._enable_filter = value
self.invalidateFilter()
class ProjectListWidget(QtWidgets.QWidget):
default = "< Default >"
project_changed = QtCore.Signal()
def __init__(self, parent):
def __init__(self, parent, only_active=False):
self._parent = parent
self.current_project = None
@ -625,8 +655,17 @@ class ProjectListWidget(QtWidgets.QWidget):
self.setObjectName("ProjectListWidget")
label_widget = QtWidgets.QLabel("Projects")
project_list = ProjectListView(self)
project_list.setModel(QtGui.QStandardItemModel())
project_model = ProjectListModel()
project_proxy = ProjectListSortFilterProxy()
project_proxy.setFilterRole(ProjectListModel.filter_role)
project_proxy.setSortRole(ProjectListModel.sort_role)
project_proxy.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive)
project_proxy.setSourceModel(project_model)
project_list.setModel(project_proxy)
# Do not allow editing
project_list.setEditTriggers(
@ -640,11 +679,27 @@ class ProjectListWidget(QtWidgets.QWidget):
layout.addWidget(label_widget, 0)
layout.addWidget(project_list, 1)
if only_active:
inactive_chk = None
else:
inactive_chk = QtWidgets.QCheckBox(" Show Inactive Projects ")
inactive_chk.setChecked(not project_proxy.is_filter_enabled())
layout.addSpacing(5)
layout.addWidget(inactive_chk, 0)
layout.addSpacing(5)
inactive_chk.stateChanged.connect(self.on_inactive_vis_changed)
project_list.left_mouse_released_at.connect(self.on_item_clicked)
self.project_list = project_list
self.project_proxy = project_proxy
self.project_model = project_model
self.inactive_chk = inactive_chk
self.dbcon = None
self._only_active = only_active
def on_item_clicked(self, new_index):
new_project_name = new_index.data(QtCore.Qt.DisplayRole)
@ -679,6 +734,14 @@ class ProjectListWidget(QtWidgets.QWidget):
else:
self.select_project(self.current_project)
def on_inactive_vis_changed(self):
if self.inactive_chk is None:
# should not happen.
return
enable_filter = not self.inactive_chk.isChecked()
self.project_proxy.set_filter_enabled(enable_filter)
def validate_context_change(self):
return not self._parent.entity.has_unsaved_changes
@ -691,12 +754,18 @@ class ProjectListWidget(QtWidgets.QWidget):
self.select_project(self.default)
def select_project(self, project_name):
model = self.project_list.model()
model = self.project_model
proxy = self.project_proxy
found_items = model.findItems(project_name)
if not found_items:
found_items = model.findItems(self.default)
index = model.indexFromItem(found_items[0])
model.setData(index, True, ProjectListModel.selected_role)
index = proxy.mapFromSource(index)
self.project_list.selectionModel().clear()
self.project_list.selectionModel().setCurrentIndex(
index, QtCore.QItemSelectionModel.SelectionFlag.SelectCurrent
@ -708,11 +777,9 @@ class ProjectListWidget(QtWidgets.QWidget):
selected_project = index.data(QtCore.Qt.DisplayRole)
break
model = self.project_list.model()
model = self.project_model
model.clear()
items = [self.default]
mongo_url = os.environ["OPENPYPE_MONGO"]
# Force uninstall of whole avalon connection if url does not match
@ -730,17 +797,37 @@ class ProjectListWidget(QtWidgets.QWidget):
self.dbcon = None
self.current_project = None
items = [(self.default, True)]
if self.dbcon:
database = self.dbcon.database
for project_name in database.collection_names():
project_doc = database[project_name].find_one(
{"type": "project"},
{"name": 1}
for doc in self.dbcon.projects(
projection={"name": 1, "data.active": 1},
only_active=self._only_active
):
items.append(
(doc["name"], doc.get("data", {}).get("active", True))
)
if project_doc:
items.append(project_doc["name"])
for item in items:
model.appendRow(QtGui.QStandardItem(item))
for project_name, is_active in items:
row = QtGui.QStandardItem(project_name)
row.setData(is_active, ProjectListModel.filter_role)
row.setData(False, ProjectListModel.selected_role)
if is_active:
row.setData(project_name, ProjectListModel.sort_role)
else:
row.setData("~" + project_name, ProjectListModel.sort_role)
font = row.font()
font.setItalic(True)
row.setFont(font)
model.appendRow(row)
self.project_proxy.sort(0)
self.select_project(selected_project)

View file

@ -273,8 +273,11 @@ class AssetWidget(QtWidgets.QWidget):
def _set_projects(self):
project_names = list()
for project in self.dbcon.projects():
project_name = project.get("name")
for doc in self.dbcon.projects(projection={"name": 1},
only_active=True):
project_name = doc.get("name")
if project_name:
project_names.append(project_name)
@ -299,7 +302,9 @@ class AssetWidget(QtWidgets.QWidget):
def on_project_change(self):
projects = list()
for project in self.dbcon.projects():
for project in self.dbcon.projects(projection={"name": 1},
only_active=True):
projects.append(project['name'])
project_name = self.combo_projects.currentText()
if project_name in projects: