From e81177a174bb7824dcc860064b08fb57a1221a85 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Aug 2016 22:06:19 +0200 Subject: [PATCH 1/9] Starting work on Section implementation (experimental) --- pyblish_lite/app.css | 5 + pyblish_lite/tree.py | 278 +++++++++++++++++++++++++++++++++++++++++ pyblish_lite/window.py | 19 ++- 3 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 pyblish_lite/tree.py diff --git a/pyblish_lite/app.css b/pyblish_lite/app.css index 253badf..4427d64 100644 --- a/pyblish_lite/app.css +++ b/pyblish_lite/app.css @@ -37,6 +37,11 @@ QListView { background: "transparent" } +QTreeView { + border: 0px; + background: "transparent" +} + QPushButton { width: 27px; height: 27px; diff --git a/pyblish_lite/tree.py b/pyblish_lite/tree.py new file mode 100644 index 0000000..afab446 --- /dev/null +++ b/pyblish_lite/tree.py @@ -0,0 +1,278 @@ + +from .vendor import Qt +from Qt import QtWidgets, QtCore +from itertools import groupby + + +class Item(object): + """Base class for an Item in the Group By Proxy""" + def __init__(self): + self._parent = None + self._children = list() + + def parent(self): + return self._parent + + def addChild(self, node): + node._parent = self + self._children.append(node) + + def rowCount(self): + return len(self._children) + + def row(self): + + parent = self.parent() + if not parent: + return 0 + else: + return self.parent().children().index(self) + + def columnCount(self): + return 1 + + def child(self, row): + return self._children[row] + + def children(self): + return self._children + + def data(self, role=QtCore.Qt.DisplayRole): + return None + + +class ProxyItem(Item): + def __init__(self, source_index): + super(ProxyItem, self).__init__() + self.source_index = source_index + + def data(self, role=QtCore.Qt.DisplayRole): + return self.source_index.data(role) + + +class ProxySectionItem(Item): + def __init__(self, label): + super(ProxySectionItem, self).__init__() + self.label = "{0}".format(label) + + def data(self, role=QtCore.Qt.DisplayRole): + + if role == QtCore.Qt.DisplayRole: + return self.label + + elif role == QtCore.Qt.FontRole: + font = QtWidgets.QFont() + font.setPointSize(10) + font.setWeight(900) + return font + + elif role == QtCore.Qt.TextColorRole: + return QtWidgets.QColor(50, 20, 20) + + elif role == QtCore.Qt.BackgroundColorRole: + return QtWidgets.QColor(220, 220, 220) + + +class Proxy(QtWidgets.QAbstractProxyModel): + """Proxy that groups by based on a specific role + + This assumes the source data is a flat list and not a tree. + + """ + + def __init__(self): + super(Proxy, self).__init__() + self.root = Item() + self.group_role = QtCore.Qt.DisplayRole + + def set_group_role(self, role): + self.group_role = role + + def rebuild(self): + """Update proxy sections and items + + This should be called after changes in the source model that require + changes in this list (for example new indices, less indices or update + sections) + + """ + + # Start with new root node + self.root = Item() + + # Get indices from source model + source = self.sourceModel() + source_rows = source.rowCount() + source_indices = [source.index(i, 0) for i in range(source_rows)] + + def key_getter(source_index): + """Return group role data for source index""" + return source.data(source_index, self.group_role) + + for section, group in groupby(source_indices, key=key_getter): + + # section + section_item = ProxySectionItem(section) + self.root.addChild(section_item) + + # items in section + for i, index in enumerate(group): + proxy_item = ProxyItem(index) + section_item.addChild(proxy_item) + + def data(self, index, role=QtCore.Qt.DisplayRole): + + if not index.isValid(): + return + + node = index.internalPointer() + + if not node: + return + + return node.data(role) + + def is_header(self, index): + """Return whether index is a header""" + if index in self.to_source: + return False + else: + return True + + def mapFromSource(self, index): + + for section_item in self.root.children(): + for item in section_item.children(): + if item.source_index == index: + return self.createIndex(item.row(), + index.column(), + item) + + return QtCore.QModelIndex() + + def mapToSource(self, index): + + if not index.isValid(): + return QtCore.QModelIndex() + + node = index.internalPointer() + if not node: + return QtCore.QModelIndex() + + if not hasattr(node, "source_index"): + return QtCore.QModelIndex() + + return node.source_index + + def columnCount(self, parent=QtCore.QModelIndex()): + return 1 + + def rowCount(self, parent): + + if not parent.isValid(): + node = self.root + else: + node = parent.internalPointer() + + if not node: + return 0 + + return node.rowCount() + + def index(self, row, column, parent): + + if parent and parent.isValid(): + parent_node = parent.internalPointer() + else: + parent_node = self.root + + item = parent_node.child(row) + if item: + return self.createIndex(row, column, item) + else: + return QtCore.QModelIndex() + + def parent(self, index): + + if not index.isValid(): + return QtCore.QModelIndex() + + node = index.internalPointer() + if not node: + return QtCore.QModelIndex() + else: + parent = node.parent() + if not parent: + return QtCore.QModelIndex() + + row = parent.row() + return self.createIndex(row, 0, parent) + + +class View(QtWidgets.QTreeView): + # An item is requesting to be toggled, with optional forced-state + toggled = QtCore.Signal("QModelIndex", object) + + # An item is requesting details + inspected = QtCore.Signal("QModelIndex") + + def __init__(self, parent=None): + super(View, self).__init__(parent) + + self.horizontalScrollBar().hide() + self.viewport().setAttribute(QtCore.Qt.WA_Hover, True) + self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + #self.setResizeMode(QtWidgets.QTreeView.Adjust) + self.setVerticalScrollMode(QtWidgets.QTreeView.ScrollPerPixel) + self.setHeaderHidden(True) + self.setRootIsDecorated(False) + self.setIndentation(10) + #self.setItemsExpandable(False) + + def event(self, event): + if not event.type() == QtCore.QEvent.KeyPress: + return super(View, self).event(event) + + elif event.key() == QtCore.Qt.Key_Space: + for index in self.selectionModel().selectedIndexes(): + self.toggled.emit(index, None) + + return True + + elif event.key() == QtCore.Qt.Key_Backspace: + for index in self.selectionModel().selectedIndexes(): + self.toggled.emit(index, False) + + return True + + elif event.key() == QtCore.Qt.Key_Return: + for index in self.selectionModel().selectedIndexes(): + self.toggled.emit(index, True) + + return True + + return super(View, self).event(event) + + def focusOutEvent(self, event): + self.selectionModel().clear() + + def leaveEvent(self, event): + self._inspecting = False + super(View, self).leaveEvent(event) + + def mousePressEvent(self, event): + if event.button() == QtCore.Qt.MidButton: + index = self.indexAt(event.pos()) + self.inspected.emit(index) if index.isValid() else None + + return super(View, self).mousePressEvent(event) + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + indexes = self.selectionModel().selectedIndexes() + if len(indexes) <= 1 and event.pos().x() < 20: + for index in indexes: + self.toggled.emit(index, None) + + return super(View, self).mouseReleaseEvent(event) diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index fc0bf1b..0a1a41b 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -42,7 +42,7 @@ from Qt import QtCore, QtWidgets, QtGui -from . import model, view, util, delegate +from . import model, view, util, delegate, tree from .awesome import tags as awesome @@ -133,8 +133,8 @@ def __init__(self, controller, parent=None): overview_page = QtWidgets.QWidget() - left_view = view.Item() - right_view = view.Item() + left_view = tree.View() + right_view = tree.View() item_delegate = delegate.Item() left_view.setItemDelegate(item_delegate) @@ -357,7 +357,12 @@ def __init__(self, controller, parent=None): terminal_model = model.Terminal() artist_view.setModel(instance_model) - left_view.setModel(instance_model) + + left_proxy = tree.Proxy() + left_proxy.setSourceModel(instance_model) + left_proxy.set_group_role(model.Families) + left_view.setModel(left_proxy) + right_view.setModel(plugin_model) terminal_view.setModel(terminal_model) @@ -490,6 +495,12 @@ def __init__(self, controller, parent=None): controller.was_acted.connect(self.on_was_acted) controller.finished.connect(self.on_finished) + controller.was_reset.connect(left_proxy.rebuild) + controller.was_validated.connect(left_proxy.rebuild) + controller.was_published.connect(left_proxy.rebuild) + controller.was_acted.connect(left_proxy.rebuild) + controller.finished.connect(left_proxy.rebuild) + # Discovery happens synchronously during reset, that's # why it's important that this connection is triggered # right away. From e613c836e7a0848e66db7137ed02617a7674006b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Aug 2016 22:17:09 +0200 Subject: [PATCH 2/9] Group right hand side by order into sections (experimental) --- pyblish_lite/model.py | 2 ++ pyblish_lite/window.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pyblish_lite/model.py b/pyblish_lite/model.py index bd74e09..3bda46d 100644 --- a/pyblish_lite/model.py +++ b/pyblish_lite/model.py @@ -46,6 +46,7 @@ Label = QtCore.Qt.DisplayRole + 0 Families = QtCore.Qt.DisplayRole + 1 Icon = QtCore.Qt.DisplayRole + 13 +Order = QtCore.Qt.UserRole + 62 # The item has not been used IsIdle = QtCore.Qt.UserRole + 2 @@ -129,6 +130,7 @@ def __init__(self, parent=None): Actions: "actions", IsOptional: "optional", Icon: "icon", + Order: "order", # GUI-only data Type: "_type", diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index 0a1a41b..40037bb 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -363,7 +363,10 @@ def __init__(self, controller, parent=None): left_proxy.set_group_role(model.Families) left_view.setModel(left_proxy) - right_view.setModel(plugin_model) + right_proxy = tree.Proxy() + right_proxy.setSourceModel(plugin_model) + right_proxy.set_group_role(model.Order) + right_view.setModel(right_proxy) terminal_view.setModel(terminal_model) instance_combo.setModel(instance_model) @@ -501,6 +504,12 @@ def __init__(self, controller, parent=None): controller.was_acted.connect(left_proxy.rebuild) controller.finished.connect(left_proxy.rebuild) + controller.was_reset.connect(right_proxy.rebuild) + controller.was_validated.connect(right_proxy.rebuild) + controller.was_published.connect(right_proxy.rebuild) + controller.was_acted.connect(right_proxy.rebuild) + controller.finished.connect(right_proxy.rebuild) + # Discovery happens synchronously during reset, that's # why it's important that this connection is triggered # right away. From c478ed3afe0fc31ed8b68ca1c74ff7afdfe1db34 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Aug 2016 22:47:29 +0200 Subject: [PATCH 3/9] Group right hand side by order range (e.g. Collector) instead or order float numbers. (experimental) --- pyblish_lite/tree.py | 68 ++++++++++++++++++++++++++++++++++++------ pyblish_lite/window.py | 2 +- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/pyblish_lite/tree.py b/pyblish_lite/tree.py index afab446..d95c0de 100644 --- a/pyblish_lite/tree.py +++ b/pyblish_lite/tree.py @@ -1,4 +1,6 @@ +import pyblish + from .vendor import Qt from Qt import QtWidgets, QtCore from itertools import groupby @@ -88,6 +90,35 @@ def __init__(self): def set_group_role(self, role): self.group_role = role + def groupby_key(self, source_index): + """Returns the data to group by. + + Override this in subclasses to group by customized data instead of + by simply the currently set group role. + + Args: + source_index (QtCore.QModelIndex): index from source to retrieve + data from to group by. + + Returns: + object: Collected data to group by for index. + + """ + return source_index.data(self.group_role) + + def groupby_label(self, section): + """Returns the label for a section based on the collected group key. + + Override this in subclasses to format the name for a specific key. + + Args: + section: key value for this group section + + Returns: + str: Label of the section header based on group key + """ + return section + def rebuild(self): """Update proxy sections and items @@ -105,14 +136,12 @@ def rebuild(self): source_rows = source.rowCount() source_indices = [source.index(i, 0) for i in range(source_rows)] - def key_getter(source_index): - """Return group role data for source index""" - return source.data(source_index, self.group_role) - - for section, group in groupby(source_indices, key=key_getter): + for section, group in groupby(source_indices, + key=self.groupby_key): # section - section_item = ProxySectionItem(section) + label = self.groupby_label(section) + section_item = ProxySectionItem(label) self.root.addChild(section_item) # items in section @@ -209,6 +238,29 @@ def parent(self, index): return self.createIndex(row, 0, parent) +class PluginOrderGroupProxy(Proxy): + """Proxy grouping by order by full range known. + + Before Collectors and after Integrators will be grouped as "Other". + + """ + + def groupby_key(self, source_index): + plugin_order = super(PluginOrderGroupProxy, + self).groupby_key(source_index) + label = "Other" + + mapping = {pyblish.plugin.CollectorOrder: "Collector", + pyblish.plugin.ValidatorOrder: "Validator", + pyblish.plugin.ExtractorOrder: "Extractor", + pyblish.plugin.IntegratorOrder: "Integrator"} + for order, _type in mapping.items(): + if pyblish.lib.inrange(plugin_order, base=order): + label = _type + + return label + + class View(QtWidgets.QTreeView): # An item is requesting to be toggled, with optional forced-state toggled = QtCore.Signal("QModelIndex", object) @@ -223,12 +275,10 @@ def __init__(self, parent=None): self.viewport().setAttribute(QtCore.Qt.WA_Hover, True) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) - #self.setResizeMode(QtWidgets.QTreeView.Adjust) self.setVerticalScrollMode(QtWidgets.QTreeView.ScrollPerPixel) self.setHeaderHidden(True) self.setRootIsDecorated(False) - self.setIndentation(10) - #self.setItemsExpandable(False) + self.setIndentation(40) # TODO: Set to 0 when styling is better def event(self, event): if not event.type() == QtCore.QEvent.KeyPress: diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index 40037bb..f8091a9 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -363,7 +363,7 @@ def __init__(self, controller, parent=None): left_proxy.set_group_role(model.Families) left_view.setModel(left_proxy) - right_proxy = tree.Proxy() + right_proxy = tree.PluginOrderGroupProxy() right_proxy.setSourceModel(plugin_model) right_proxy.set_group_role(model.Order) right_view.setModel(right_proxy) From 66b07aa8d60c00b0ca2eacd83a9d31d4f17470ad Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 23 Aug 2016 05:52:14 +0200 Subject: [PATCH 4/9] Add .idea/ (pycharm) to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1b296a9..44702c2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ __pycache__ dist cover .coverage -build \ No newline at end of file +build +.idea/ From c451c3d8acaf3f1d0facdb4e5b508df344d7c583 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 23 Aug 2016 05:55:08 +0200 Subject: [PATCH 5/9] Fix header section styling (changed Delegates) Add FamilyGroupProxy to list only first family for instances Fix checkbox updating by implementing setData on proxy Always expandAll (for now) Fix Proxy.is_header method --- pyblish_lite/delegate.py | 60 ++++++++++++++++++++++++++++++++++++++++ pyblish_lite/tree.py | 41 +++++++++++++++++++++++---- pyblish_lite/window.py | 16 +++++++++-- 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/pyblish_lite/delegate.py b/pyblish_lite/delegate.py index 2dfc6d6..d213977 100644 --- a/pyblish_lite/delegate.py +++ b/pyblish_lite/delegate.py @@ -119,6 +119,66 @@ def sizeHint(self, option, index): return QtCore.QSize(option.rect.width(), 20) +class Section(QtWidgets.QStyledItemDelegate): + """Generic delegate for section header""" + + def paint(self, painter, option, index): + """Paint text + _ + My label + + """ + + body_rect = QtCore.QRectF(option.rect) + + metrics = painter.fontMetrics() + + label_rect = QtCore.QRectF(option.rect.adjusted(0, 2, 0, -2)) + + assert label_rect.width() > 0 + + label = index.data(model.Label) + label = metrics.elidedText(label, + QtCore.Qt.ElideRight, + label_rect.width()) + + font_color = colors["idle"] + if not index.data(model.IsChecked): + font_color = colors["inactive"] + + # Maintain reference to state, so we can restore it once we're done + painter.save() + + # Draw label + painter.setFont(fonts["h4"]) + painter.setPen(QtGui.QPen(font_color)) + painter.drawText(label_rect, label) + + if option.state & QtWidgets.QStyle.State_MouseOver: + painter.fillRect(body_rect, colors["hover"]) + + if option.state & QtWidgets.QStyle.State_Selected: + painter.fillRect(body_rect, colors["selected"]) + + # Ok, we're done, tidy up. + painter.restore() + + def sizeHint(self, option, index): + return QtCore.QSize(option.rect.width(), 20) + + +class ItemAndSection(Item): + """Generic delegate for model items in proxy tree view""" + def paint(self, painter, option, index): + + model = index.model() + if model.is_header(index): + Section().paint(painter, option, index) + return + + super(ItemAndSection, self).paint(painter, option, index) + + class Artist(QtWidgets.QStyledItemDelegate): """Delegate used on Artist page""" diff --git a/pyblish_lite/tree.py b/pyblish_lite/tree.py index d95c0de..945c74f 100644 --- a/pyblish_lite/tree.py +++ b/pyblish_lite/tree.py @@ -2,7 +2,7 @@ import pyblish from .vendor import Qt -from Qt import QtWidgets, QtCore +from Qt import QtWidgets, QtCore, __binding__ from itertools import groupby @@ -128,6 +128,8 @@ def rebuild(self): """ + self.reset() + # Start with new root node self.root = Item() @@ -161,12 +163,27 @@ def data(self, index, role=QtCore.Qt.DisplayRole): return node.data(role) + def setData(self, index, data, role): + + source_idx = self.mapToSource(index) + if not source_idx.isValid(): + return + + model = source_idx.model() + model.setData(index, data, role) + + if __binding__ in ("PyQt4", "PySide"): + self.dataChanged.emit(index, index) + else: + self.dataChanged.emit(index, index, [role]) + def is_header(self, index): """Return whether index is a header""" - if index in self.to_source: - return False - else: + + if index.isValid() and not self.mapToSource(index).isValid(): return True + else: + return False def mapFromSource(self, index): @@ -261,6 +278,20 @@ def groupby_key(self, source_index): return label +class FamilyGroupProxy(Proxy): + """Proxy grouping by order by full range known. + + Before Collectors and after Integrators will be grouped as "Other". + + """ + + def groupby_key(self, source_index): + families = super(FamilyGroupProxy, + self).groupby_key(source_index) + family = families[0] + return family + + class View(QtWidgets.QTreeView): # An item is requesting to be toggled, with optional forced-state toggled = QtCore.Signal("QModelIndex", object) @@ -278,7 +309,7 @@ def __init__(self, parent=None): self.setVerticalScrollMode(QtWidgets.QTreeView.ScrollPerPixel) self.setHeaderHidden(True) self.setRootIsDecorated(False) - self.setIndentation(40) # TODO: Set to 0 when styling is better + self.setIndentation(0) def event(self, event): if not event.type() == QtCore.QEvent.KeyPress: diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index f8091a9..f1ef027 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -136,7 +136,7 @@ def __init__(self, controller, parent=None): left_view = tree.View() right_view = tree.View() - item_delegate = delegate.Item() + item_delegate = delegate.ItemAndSection() left_view.setItemDelegate(item_delegate) right_view.setItemDelegate(item_delegate) @@ -358,7 +358,7 @@ def __init__(self, controller, parent=None): artist_view.setModel(instance_model) - left_proxy = tree.Proxy() + left_proxy = tree.FamilyGroupProxy() left_proxy.setSourceModel(instance_model) left_proxy.set_group_role(model.Families) left_view.setModel(left_proxy) @@ -504,12 +504,24 @@ def __init__(self, controller, parent=None): controller.was_acted.connect(left_proxy.rebuild) controller.finished.connect(left_proxy.rebuild) + controller.was_reset.connect(left_view.expandAll) + controller.was_validated.connect(left_view.expandAll) + controller.was_published.connect(left_view.expandAll) + controller.was_acted.connect(left_view.expandAll) + controller.finished.connect(left_view.expandAll) + controller.was_reset.connect(right_proxy.rebuild) controller.was_validated.connect(right_proxy.rebuild) controller.was_published.connect(right_proxy.rebuild) controller.was_acted.connect(right_proxy.rebuild) controller.finished.connect(right_proxy.rebuild) + controller.was_reset.connect(right_view.expandAll) + controller.was_validated.connect(right_view.expandAll) + controller.was_published.connect(right_view.expandAll) + controller.was_acted.connect(right_view.expandAll) + controller.finished.connect(right_view.expandAll) + # Discovery happens synchronously during reset, that's # why it's important that this connection is triggered # right away. From bdf18f8a49f51d467d335ffb3823c8c252d23079 Mon Sep 17 00:00:00 2001 From: David Lai Date: Mon, 12 Nov 2018 18:25:04 +0800 Subject: [PATCH 6/9] Update Qy.py --- pyblish_lite/vendor/Qt.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyblish_lite/vendor/Qt.py b/pyblish_lite/vendor/Qt.py index 841c823..3155c57 100644 --- a/pyblish_lite/vendor/Qt.py +++ b/pyblish_lite/vendor/Qt.py @@ -790,7 +790,7 @@ def _translate(context, sourceText, *args): encoding = None else: raise TypeError( - "Expected 4 or 5 arguments, got {0}.".format(len(args)+2)) + "Expected 4 or 5 arguments, got {0}.".format(len(args) + 2)) if hasattr(Qt.QtCore, "QCoreApplication"): app = getattr(Qt.QtCore, "QCoreApplication") @@ -1222,7 +1222,7 @@ def _reassign_misplaced_members(binding): # exist, there is no need to continue. This can happen if a # request was made to rename a member that didn't exist, for # example if QtWidgets isn't available on the target platform. - _log("Misplaced member has no source: {}".format(src)) + _log("Misplaced member has no source: {0}".format(src)) continue try: @@ -1345,6 +1345,7 @@ def _pyside2(): if hasattr(Qt, "_shiboken2"): Qt.QtCompat.wrapInstance = _wrapinstance Qt.QtCompat.getCppPointer = _getcpppointer + Qt.QtCompat.delete = shiboken2.delete if hasattr(Qt, "_QtUiTools"): Qt.QtCompat.loadUi = _loadUi @@ -1382,6 +1383,7 @@ def _pyside(): if hasattr(Qt, "_shiboken"): Qt.QtCompat.wrapInstance = _wrapinstance Qt.QtCompat.getCppPointer = _getcpppointer + Qt.QtCompat.delete = shiboken.delete if hasattr(Qt, "_QtUiTools"): Qt.QtCompat.loadUi = _loadUi @@ -1417,6 +1419,7 @@ def _pyqt5(): if hasattr(Qt, "_sip"): Qt.QtCompat.wrapInstance = _wrapinstance Qt.QtCompat.getCppPointer = _getcpppointer + Qt.QtCompat.delete = sip.delete if hasattr(Qt, "_uic"): Qt.QtCompat.loadUi = _loadUi @@ -1482,6 +1485,7 @@ def _pyqt4(): if hasattr(Qt, "_sip"): Qt.QtCompat.wrapInstance = _wrapinstance Qt.QtCompat.getCppPointer = _getcpppointer + Qt.QtCompat.delete = sip.delete if hasattr(Qt, "_uic"): Qt.QtCompat.loadUi = _loadUi @@ -1824,4 +1828,4 @@ def _install(): # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From b043b24ee727c19dd2870ed6d6416159e5ff50d2 Mon Sep 17 00:00:00 2001 From: David Lai Date: Mon, 12 Nov 2018 18:28:57 +0800 Subject: [PATCH 7/9] Fix Qt module and method name --- pyblish_lite/tree.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pyblish_lite/tree.py b/pyblish_lite/tree.py index 945c74f..e9cf654 100644 --- a/pyblish_lite/tree.py +++ b/pyblish_lite/tree.py @@ -1,8 +1,7 @@ import pyblish -from .vendor import Qt -from Qt import QtWidgets, QtCore, __binding__ +from .vendor.Qt import QtWidgets, QtCore, __binding__ from itertools import groupby @@ -75,7 +74,7 @@ def data(self, role=QtCore.Qt.DisplayRole): return QtWidgets.QColor(220, 220, 220) -class Proxy(QtWidgets.QAbstractProxyModel): +class Proxy(QtCore.QAbstractProxyModel): """Proxy that groups by based on a specific role This assumes the source data is a flat list and not a tree. @@ -128,7 +127,7 @@ def rebuild(self): """ - self.reset() + self.beginResetModel() # Start with new root node self.root = Item() @@ -151,6 +150,8 @@ def rebuild(self): proxy_item = ProxyItem(index) section_item.addChild(proxy_item) + self.endResetModel() + def data(self, index, role=QtCore.Qt.DisplayRole): if not index.isValid(): From 6cd07003af99ce8ffd3f9065c18e68543cb08790 Mon Sep 17 00:00:00 2001 From: David Lai Date: Mon, 12 Nov 2018 18:29:47 +0800 Subject: [PATCH 8/9] Update `finished` signal name --- pyblish_lite/window.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index 07389cd..0bf677d 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -508,25 +508,25 @@ def __init__(self, controller, parent=None): controller.was_validated.connect(left_proxy.rebuild) controller.was_published.connect(left_proxy.rebuild) controller.was_acted.connect(left_proxy.rebuild) - controller.finished.connect(left_proxy.rebuild) + controller.was_finished.connect(left_proxy.rebuild) controller.was_reset.connect(left_view.expandAll) controller.was_validated.connect(left_view.expandAll) controller.was_published.connect(left_view.expandAll) controller.was_acted.connect(left_view.expandAll) - controller.finished.connect(left_view.expandAll) + controller.was_finished.connect(left_view.expandAll) controller.was_reset.connect(right_proxy.rebuild) controller.was_validated.connect(right_proxy.rebuild) controller.was_published.connect(right_proxy.rebuild) controller.was_acted.connect(right_proxy.rebuild) - controller.finished.connect(right_proxy.rebuild) + controller.was_finished.connect(right_proxy.rebuild) controller.was_reset.connect(right_view.expandAll) controller.was_validated.connect(right_view.expandAll) controller.was_published.connect(right_view.expandAll) controller.was_acted.connect(right_view.expandAll) - controller.finished.connect(right_view.expandAll) + controller.was_finished.connect(right_view.expandAll) # Discovery happens synchronously during reset, that's # why it's important that this connection is triggered From ae27facd28b0820d0ba269c0ec7e6f8c168a8a41 Mon Sep 17 00:00:00 2001 From: David Lai Date: Mon, 12 Nov 2018 19:21:24 +0800 Subject: [PATCH 9/9] Change to `plugin_model` --- pyblish_lite/window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index 0bf677d..a43f8b3 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -368,7 +368,7 @@ def __init__(self, controller, parent=None): left_view.setModel(left_proxy) right_proxy = tree.PluginOrderGroupProxy() - right_proxy.setSourceModel(filter_model) + right_proxy.setSourceModel(plugin_model) right_proxy.set_group_role(model.Order) right_view.setModel(right_proxy)