diff --git a/libs/libkis/Node.cpp b/libs/libkis/Node.cpp --- a/libs/libkis/Node.cpp +++ b/libs/libkis/Node.cpp @@ -321,7 +321,6 @@ QString Node::type() const { if (!d->node) return QString(); - return QString(); if (qobject_cast(d->node)) { return "paintlayer"; } @@ -358,6 +357,7 @@ if (qobject_cast(d->node)) { return "colorizemask"; } + return QString(); } bool Node::visible() const diff --git a/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/__init__.py b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/__init__.py new file mode 100644 diff --git a/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtercombobox.py b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtercombobox.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtercombobox.py @@ -0,0 +1,11 @@ +from PyQt5.QtWidgets import QComboBox +import krita + +class FilterComboBox(QComboBox): + + def __init__(self, uiFilterManager, parent=None): + super(FilterComboBox, self).__init__(parent) + + self.uiFilterManager = uiFilterManager + + self.addItems(self.uiFilterManager.filters) diff --git a/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreeitem.py b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreeitem.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreeitem.py @@ -0,0 +1,35 @@ +class FilterManagerTreeItem(object): + + def __init__(self, data, parent=None): + self.itemData = data + self.parentItem = parent + self.childItems = [] + + def appendChild(self, child): + self.childItems.append(child) + + def appenChildren(self, children): + self.childItems.extend(children) + + def child(self, row): + return self.childItems[row] + + def childCount(self): + return len(self.childItems) + + def columnCount(self): + return len(self.itemData) + + def data(self, column): + try: + return self.itemData[column] + except IndexError: + return None + + def row(self): + if self.parentItem: + return self.parentItem.childItems.index(self) + return 0 + + def parent(self): + return self.parentItem diff --git a/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreemodel.py b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreemodel.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/filtermanager/components/filtermanagertreemodel.py @@ -0,0 +1,119 @@ +from PyQt5.QtCore import QAbstractItemModel, QFile, QIODevice, QModelIndex, Qt +from PyQt5.QtWidgets import QApplication, QTreeView +from filtermanager.components import filtermanagertreeitem +from PyQt5.QtGui import QPixmap + + +class FilterManagerTreeModel(QAbstractItemModel): + + NODE_COLUMN = 3 + DOCUMENT_COLUMN = 4 + + def __init__(self, uiFilterManager, parent=None): + super(FilterManagerTreeModel, self).__init__(parent) + + self.rootItem = filtermanagertreeitem.FilterManagerTreeItem(("Name", "Type", "Thumbnail")) + self.uiFilterManager = uiFilterManager + self._loadTreeModel(self.rootItem) + + def index(self, row, column, parent): + if not self.hasIndex(row, column, parent): + return QModelIndex() + + if parent.isValid(): + parentItem = parent.internalPointer() + else: + parentItem = self.rootItem + + #It's a FilterManagerTreeItem + childItem = parentItem.child(row) + if childItem: + return self.createIndex(row, column, childItem) + else: + return QModelIndex() + + def parent(self, index): + if not index.isValid(): + return QModelIndex() + + childItem = index.internalPointer() + parentItem = childItem.parent() + + if parentItem == self.rootItem: + return QModelIndex() + + return self.createIndex(parentItem.row(), 0, parentItem) + + def rowCount(self, parent): + if parent.column() > 0: + return 0 + + if not parent.isValid(): + parentItem = self.rootItem + else: + parentItem = parent.internalPointer() + return parentItem.childCount() + + def columnCount(self, parent): + if parent.isValid(): + return parent.internalPointer().columnCount() + else: + return self.rootItem.columnCount() + + def data(self, index, role): + if not index.isValid(): + return None + + item = index.internalPointer() + + if role == Qt.UserRole + 1: + return item.data(self.NODE_COLUMN) + + if role == Qt.UserRole + 2: + return item.data(self.DOCUMENT_COLUMN) + + if role != Qt.DisplayRole and role != Qt.DecorationRole: + return None + + return item.data(index.column()) + + def flags(self, index): + if not index.isValid(): + return Qt.NoItemFlags + + return Qt.ItemIsEnabled | Qt.ItemIsSelectable + + def headerData(self, section, orientation, role): + if orientation == Qt.Horizontal and role == Qt.DisplayRole: + return self.rootItem.data(section) + + return None + + def _loadTreeModel(self, parent): + for index, document in enumerate(self.uiFilterManager.documents): + rootNode = document.rootNode() + columnData = (document.fileName(), + "Document", + QPixmap.fromImage(document.thumbnail(30, 30)), + rootNode, index) + item = filtermanagertreeitem.FilterManagerTreeItem(columnData, parent) + parent.appendChild(item) + + childNodes = rootNode.childNodes() + if len(childNodes): + self._addSubNodes(childNodes[::-1], item, index) + + def _addSubNodes(self, nodes, parent, documentIndex): + for node in nodes: + nodeName = node.name() + nodeType = node.type() + columnData = ("Unnamed" if nodeName == '' else nodeName, + "Untyped" if nodeType == '' else nodeType, + QPixmap.fromImage(node.thumbnail(30, 30)), + node, documentIndex) + item = filtermanagertreeitem.FilterManagerTreeItem(columnData, parent) + parent.appendChild(item) + + childNodes = node.childNodes() + if len(childNodes): + self._addSubNodes(childNodes[::-1], item, documentIndex) diff --git a/plugins/extensions/pykrita/plugin/plugins/filtermanager/uifiltermanager.py b/plugins/extensions/pykrita/plugin/plugins/filtermanager/uifiltermanager.py --- a/plugins/extensions/pykrita/plugin/plugins/filtermanager/uifiltermanager.py +++ b/plugins/extensions/pykrita/plugin/plugins/filtermanager/uifiltermanager.py @@ -1,7 +1,9 @@ from filtermanager import filtermanagerdialog +from filtermanager.components import (filtercombobox, filtermanagertreemodel) from PyQt5.QtCore import Qt from PyQt5.QtWidgets import (QFormLayout, QAbstractItemView, QDialogButtonBox, - QVBoxLayout, QFrame, QAbstractScrollArea) + QVBoxLayout, QFrame, QAbstractScrollArea, QWidget, + QTreeView) import krita @@ -13,16 +15,34 @@ self.formLayout = QFormLayout() self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + self.kritaInstance = krita.Krita.instance() + self._filters = sorted(self.kritaInstance.filters()) + self._documents = self.kritaInstance.documents() + self.treeModel = filtermanagertreemodel.FilterManagerTreeModel(self) + + self.documentsTreeView = QTreeView() + self.filterComboBox = filtercombobox.FilterComboBox(self) + self.buttonBox.accepted.connect(self.confirmButton) self.buttonBox.rejected.connect(self.mainDialog.close) + self.documentsTreeView.setSelectionMode(QAbstractItemView.MultiSelection) self.mainDialog.setWindowModality(Qt.NonModal) def initialize(self): + self.documentsTreeView.setModel(self.treeModel) + self.documentsTreeView.setWindowTitle("Document Tree Model") + self.documentsTreeView.resizeColumnToContents(0) + self.documentsTreeView.resizeColumnToContents(1) + self.documentsTreeView.resizeColumnToContents(2) + + self.formLayout.addRow("Filters", self.filterComboBox) + self.line = QFrame() self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) + self.mainLayout.addWidget(self.documentsTreeView) self.mainLayout.addLayout(self.formLayout) self.mainLayout.addWidget(self.line) self.mainLayout.addWidget(self.buttonBox) @@ -34,4 +54,20 @@ self.mainDialog.activateWindow() def confirmButton(self): - pass + selectionModel = self.documentsTreeView.selectionModel() + for index in selectionModel.selectedRows(): + node = self.treeModel.data(index, Qt.UserRole + 1) + documentIndex = self.treeModel.data(index, Qt.UserRole + 2) + self.applyFilterOverNode(node, self.documents[documentIndex]) + + def applyFilterOverNode(self, node, document): + _filter = self.kritaInstance.filter(self.filterComboBox.currentText()) + _filter.apply(node, 0, 0, document.width(), document.height()) + + @property + def filters(self): + return self._filters + + @property + def documents(self): + return self._documents