diff --git a/plugins/python/example_scripts/resize_to_all_layers.py b/plugins/python/example_scripts/resize_to_all_layers.py index e854763086..d6314a7609 100644 --- a/plugins/python/example_scripts/resize_to_all_layers.py +++ b/plugins/python/example_scripts/resize_to_all_layers.py @@ -1,34 +1,40 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode + +""" +This script will iterate over all toplevel nodes, create +keeping track of the layer boundaries and then resize +the image to the unity of all boundaries. +""" + +from krita import Krita +from PyQt5.QtCore import QRect -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' -# -# This script will iterate over all toplevel nodes, create -# keeping track of the layer boundaries and then resize -# the image to the unity of all boundaries. -# -from krita import * d = Krita.instance().activeDocument() w = d.width() h = d.height() x = d.xOffset() y = d.yOffset() print(x, y, w, h) r = QRect(x, y, w, h) print(r) for n in d.topLevelNodes(): - print (n, n.bounds()) + print(n, n.bounds()) b = n.bounds() r = r.united(b) - -print (r) + +print(r) d.resizeImage(r.x(), r.y(), r.width(), r.height()) diff --git a/plugins/python/exportlayers/__init__.py b/plugins/python/exportlayers/__init__.py index b0a4cf13f3..b2074e48a0 100644 --- a/plugins/python/exportlayers/__init__.py +++ b/plugins/python/exportlayers/__init__.py @@ -1,2 +1,5 @@ -# let's make a module -from .exportlayers import * +import krita +from .exportlayers import ExportLayersExtension + + +Scripter.addExtension(ExportLayersExtension(krita.Krita.instance())) diff --git a/plugins/python/exportlayers/exportlayers.py b/plugins/python/exportlayers/exportlayers.py index 17cb698d71..23d5f63fdd 100644 --- a/plugins/python/exportlayers/exportlayers.py +++ b/plugins/python/exportlayers/exportlayers.py @@ -1,34 +1,34 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' import krita from . import uiexportlayers class ExportLayersExtension(krita.Extension): def __init__(self, parent): super(ExportLayersExtension, self).__init__(parent) def setup(self): pass def createActions(self, window): action = window.createAction("export_layers", i18n("Export Layers")) action.setToolTip(i18n("Plugin to export layers from a document.")) action.triggered.connect(self.initialize) def initialize(self): self.uiexportlayers = uiexportlayers.UIExportLayers() self.uiexportlayers.initialize() - - -Scripter.addExtension(ExportLayersExtension(krita.Krita.instance())) diff --git a/plugins/python/exportlayers/exportlayersdialog.py b/plugins/python/exportlayers/exportlayersdialog.py index 4d16217464..ec939eb89a 100644 --- a/plugins/python/exportlayers/exportlayersdialog.py +++ b/plugins/python/exportlayers/exportlayersdialog.py @@ -1,21 +1,24 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' from PyQt5.QtWidgets import QDialog class ExportLayersDialog(QDialog): def __init__(self, parent=None): super(ExportLayersDialog, self).__init__(parent) def closeEvent(self, event): event.accept() diff --git a/plugins/python/exportlayers/uiexportlayers.py b/plugins/python/exportlayers/uiexportlayers.py index 6650f4135a..0555bb3dab 100644 --- a/plugins/python/exportlayers/uiexportlayers.py +++ b/plugins/python/exportlayers/uiexportlayers.py @@ -1,185 +1,211 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' from . import exportlayersdialog from PyQt5.QtCore import Qt from PyQt5.QtWidgets import (QFormLayout, QListWidget, QHBoxLayout, QDialogButtonBox, QVBoxLayout, QFrame, QPushButton, QAbstractScrollArea, QLineEdit, QMessageBox, QFileDialog, QCheckBox, QSpinBox, QComboBox) import os -import errno import krita class UIExportLayers(object): def __init__(self): self.mainDialog = exportlayersdialog.ExportLayersDialog() self.mainLayout = QVBoxLayout(self.mainDialog) self.formLayout = QFormLayout() self.documentLayout = QVBoxLayout() self.directorySelectorLayout = QHBoxLayout() self.optionsLayout = QVBoxLayout() self.resolutionLayout = QHBoxLayout() self.refreshButton = QPushButton(i18n("Refresh")) self.widgetDocuments = QListWidget() self.directoryTextField = QLineEdit() self.directoryDialogButton = QPushButton(i18n("...")) - self.exportFilterLayersCheckBox = QCheckBox(i18n("Export filter layers")) + self.exportFilterLayersCheckBox = QCheckBox( + i18n("Export filter layers")) self.batchmodeCheckBox = QCheckBox(i18n("Export in batchmode")) - self.ignoreInvisibleLayersCheckBox = QCheckBox(i18n("Ignore invisible layers")) + self.ignoreInvisibleLayersCheckBox = QCheckBox( + i18n("Ignore invisible layers")) self.xResSpinBox = QSpinBox() self.yResSpinBox = QSpinBox() self.formatsComboBox = QComboBox() - self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + self.buttonBox = QDialogButtonBox( + QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.kritaInstance = krita.Krita.instance() self.documentsList = [] self.directoryTextField.setReadOnly(True) self.batchmodeCheckBox.setChecked(True) self.directoryDialogButton.clicked.connect(self._selectDir) self.widgetDocuments.currentRowChanged.connect(self._setResolution) self.refreshButton.clicked.connect(self.refreshButtonClicked) self.buttonBox.accepted.connect(self.confirmButton) self.buttonBox.rejected.connect(self.mainDialog.close) self.mainDialog.setWindowModality(Qt.NonModal) - self.widgetDocuments.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents) + self.widgetDocuments.setSizeAdjustPolicy( + QAbstractScrollArea.AdjustToContents) def initialize(self): self.loadDocuments() self.xResSpinBox.setRange(1, 10000) self.yResSpinBox.setRange(1, 10000) self.formatsComboBox.addItem(i18n("JPEG")) self.formatsComboBox.addItem(i18n("PNG")) self.documentLayout.addWidget(self.widgetDocuments) self.documentLayout.addWidget(self.refreshButton) self.directorySelectorLayout.addWidget(self.directoryTextField) self.directorySelectorLayout.addWidget(self.directoryDialogButton) self.optionsLayout.addWidget(self.exportFilterLayersCheckBox) self.optionsLayout.addWidget(self.batchmodeCheckBox) self.optionsLayout.addWidget(self.ignoreInvisibleLayersCheckBox) self.resolutionLayout.addWidget(self.xResSpinBox) self.resolutionLayout.addWidget(self.yResSpinBox) self.formLayout.addRow(i18n("Documents:"), self.documentLayout) - self.formLayout.addRow(i18n("Initial directory:"), self.directorySelectorLayout) + self.formLayout.addRow( + i18n("Initial directory:"), self.directorySelectorLayout) self.formLayout.addRow(i18n("Export options:"), self.optionsLayout) self.formLayout.addRow(i18n("Resolution:"), self.resolutionLayout) - self.formLayout.addRow(i18n("Images extensions:"), self.formatsComboBox) + self.formLayout.addRow( + i18n("Images extensions:"), self.formatsComboBox) self.line = QFrame() self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.mainLayout.addLayout(self.formLayout) self.mainLayout.addWidget(self.line) self.mainLayout.addWidget(self.buttonBox) self.mainDialog.resize(500, 300) self.mainDialog.setWindowTitle(i18n("Export Layers")) self.mainDialog.setSizeGripEnabled(True) self.mainDialog.show() self.mainDialog.activateWindow() def loadDocuments(self): self.widgetDocuments.clear() - self.documentsList = [document for document in self.kritaInstance.documents() if document.fileName()] + self.documentsList = [ + document for document in self.kritaInstance.documents() + if document.fileName() + ] for document in self.documentsList: self.widgetDocuments.addItem(document.fileName()) def refreshButtonClicked(self): self.loadDocuments() def confirmButton(self): - selectedPaths = [item.text() for item in self.widgetDocuments.selectedItems()] - selectedDocuments = [document for document in self.documentsList for path in selectedPaths if path == document.fileName()] + selectedPaths = [ + item.text() for item in self.widgetDocuments.selectedItems()] + selectedDocuments = [ + document for document in self.documentsList + for path in selectedPaths if path == document.fileName() + ] self.msgBox = QMessageBox(self.mainDialog) if not selectedDocuments: self.msgBox.setText(i18n("Select one document.")) elif not self.directoryTextField.text(): self.msgBox.setText(i18n("Select the initial directory.")) else: self.export(selectedDocuments[0]) self.msgBox.setText(i18n("All layers has been exported.")) self.msgBox.exec_() def mkdir(self, directory): target_directory = self.directoryTextField.text() + directory - if os.path.exists(target_directory) and os.path.isdir(target_directory): + if (os.path.exists(target_directory) + and os.path.isdir(target_directory)): return try: os.makedirs(target_directory) except OSError as e: raise e def export(self, document): Application.setBatchmode(self.batchmodeCheckBox.isChecked()) - documentName = document.fileName() if document.fileName() else 'Untitled' + documentName = document.fileName() if document.fileName() else 'Untitled' # noqa: E501 fileName, extension = os.path.splitext(os.path.basename(documentName)) self.mkdir('/' + fileName) - self._exportLayers(document.rootNode(), self.formatsComboBox.currentText(), '/' + fileName) + self._exportLayers( + document.rootNode(), + self.formatsComboBox.currentText(), + '/' + fileName) Application.setBatchmode(True) def _exportLayers(self, parentNode, fileFormat, parentDir): """ This method get all sub-nodes from the current node and export then in the defined format.""" for node in parentNode.childNodes(): newDir = '' if node.type() == 'grouplayer': newDir = os.path.join(parentDir, node.name()) self.mkdir(newDir) - elif not self.exportFilterLayersCheckBox.isChecked() and 'filter' in node.type(): + elif (not self.exportFilterLayersCheckBox.isChecked() + and 'filter' in node.type()): continue - elif self.ignoreInvisibleLayersCheckBox.isChecked() and not node.visible(): + elif (self.ignoreInvisibleLayersCheckBox.isChecked() + and not node.visible()): continue else: nodeName = node.name() _fileFormat = self.formatsComboBox.currentText() if '[jpeg]' in nodeName: _fileFormat = 'jpeg' elif '[png]' in nodeName: _fileFormat = 'png' - layerFileName = '{0}{1}/{2}.{3}'.format(self.directoryTextField.text(), - parentDir, node.name(), _fileFormat) + layerFileName = '{0}{1}/{2}.{3}'.format( + self.directoryTextField.text(), + parentDir, node.name(), _fileFormat) node.save(layerFileName, self.xResSpinBox.value(), self.yResSpinBox.value(), krita.InfoObject()) if node.childNodes(): self._exportLayers(node, fileFormat, newDir) def _selectDir(self): - directory = QFileDialog.getExistingDirectory(self.mainDialog, i18n("Select a Folder"), os.path.expanduser("~"), QFileDialog.ShowDirsOnly) + directory = QFileDialog.getExistingDirectory( + self.mainDialog, + i18n("Select a Folder"), + os.path.expanduser("~"), + QFileDialog.ShowDirsOnly) self.directoryTextField.setText(directory) def _setResolution(self, index): document = self.documentsList[index] self.xResSpinBox.setValue(document.width()) self.yResSpinBox.setValue(document.height()) diff --git a/plugins/python/filtermanager/__init__.py b/plugins/python/filtermanager/__init__.py index 3dcf5557d9..ca1fbb26e7 100644 --- a/plugins/python/filtermanager/__init__.py +++ b/plugins/python/filtermanager/__init__.py @@ -1,2 +1,5 @@ -# let's make a module -from .filtermanager import * +import krita +from .filtermanager import FilterManagerExtension + + +Scripter.addExtension(FilterManagerExtension(krita.Krita.instance())) diff --git a/plugins/python/filtermanager/components/filtercombobox.py b/plugins/python/filtermanager/components/filtercombobox.py index 53641126a5..dcecb3e3c2 100644 --- a/plugins/python/filtermanager/components/filtercombobox.py +++ b/plugins/python/filtermanager/components/filtercombobox.py @@ -1,23 +1,25 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' 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/python/filtermanager/components/filtermanagertreeitem.py b/plugins/python/filtermanager/components/filtermanagertreeitem.py index ec73a6a2ba..dd5c37261a 100644 --- a/plugins/python/filtermanager/components/filtermanagertreeitem.py +++ b/plugins/python/filtermanager/components/filtermanagertreeitem.py @@ -1,46 +1,50 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. + +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' 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/python/filtermanager/components/filtermanagertreemodel.py b/plugins/python/filtermanager/components/filtermanagertreemodel.py index b2bb646938..c0055ae85d 100644 --- a/plugins/python/filtermanager/components/filtermanagertreemodel.py +++ b/plugins/python/filtermanager/components/filtermanagertreemodel.py @@ -1,134 +1,139 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' -from PyQt5.QtCore import QAbstractItemModel, QFile, QIODevice, QModelIndex, Qt -from PyQt5.QtWidgets import QApplication, QTreeView -from . import filtermanagertreeitem +# https://creativecommons.org/publicdomain/zero/1.0/legalcode + +from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt from PyQt5.QtGui import QPixmap +from . import filtermanagertreeitem class FilterManagerTreeModel(QAbstractItemModel): TYPE_COLUMN = 1 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.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.UserRole + 3: return item.data(self.TYPE_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) + 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) + item = filtermanagertreeitem.FilterManagerTreeItem( + columnData, parent) parent.appendChild(item) childNodes = node.childNodes() if len(childNodes): self._addSubNodes(childNodes[::-1], item, documentIndex) diff --git a/plugins/python/filtermanager/filtermanager.py b/plugins/python/filtermanager/filtermanager.py index 806ce710c9..1a073e6428 100644 --- a/plugins/python/filtermanager/filtermanager.py +++ b/plugins/python/filtermanager/filtermanager.py @@ -1,34 +1,34 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' import krita from . import uifiltermanager class FilterManagerExtension(krita.Extension): def __init__(self, parent): super(FilterManagerExtension, self).__init__(parent) def setup(self): pass def createActions(self, window): action = window.createAction("filter_manager", i18n("Filter Manager")) action.setToolTip(i18n("Plugin to filters management.")) action.triggered.connect(self.initialize) def initialize(self): self.uifiltermanager = uifiltermanager.UIFilterManager() self.uifiltermanager.initialize() - - -Scripter.addExtension(FilterManagerExtension(krita.Krita.instance())) diff --git a/plugins/python/filtermanager/filtermanagerdialog.py b/plugins/python/filtermanager/filtermanagerdialog.py index 64feab062d..e436e61c5a 100644 --- a/plugins/python/filtermanager/filtermanagerdialog.py +++ b/plugins/python/filtermanager/filtermanagerdialog.py @@ -1,21 +1,24 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' from PyQt5.QtWidgets import QDialog class FilterManagerDialog(QDialog): def __init__(self, parent=None): super(FilterManagerDialog, self).__init__(parent) def closeEvent(self, event): event.accept() diff --git a/plugins/python/filtermanager/uifiltermanager.py b/plugins/python/filtermanager/uifiltermanager.py index a270bbdf85..5541bd3dd7 100644 --- a/plugins/python/filtermanager/uifiltermanager.py +++ b/plugins/python/filtermanager/uifiltermanager.py @@ -1,107 +1,112 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' from . import filtermanagerdialog from .components import (filtercombobox, filtermanagertreemodel) from PyQt5.QtCore import Qt from PyQt5.QtWidgets import (QFormLayout, QAbstractItemView, QDialogButtonBox, - QVBoxLayout, QFrame, QAbstractScrollArea, QWidget, - QTreeView) + QVBoxLayout, QFrame, QTreeView) import krita class UIFilterManager(object): def __init__(self): self.mainDialog = filtermanagerdialog.FilterManagerDialog() self.mainLayout = QVBoxLayout(self.mainDialog) self.formLayout = QFormLayout() - self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + 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.SingleSelection) + self.documentsTreeView.setSelectionMode( + QAbstractItemView.SingleSelection) self.mainDialog.setWindowModality(Qt.NonModal) def initialize(self): self.documentsTreeView.setModel(self.treeModel) self.documentsTreeView.setWindowTitle(i18n("Document Tree Model")) self.documentsTreeView.resizeColumnToContents(0) self.documentsTreeView.resizeColumnToContents(1) self.documentsTreeView.resizeColumnToContents(2) self.formLayout.addRow(i18n("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) self.mainDialog.resize(500, 300) self.mainDialog.setWindowTitle(i18n("Filter Manager")) self.mainDialog.setSizeGripEnabled(True) self.mainDialog.show() self.mainDialog.activateWindow() def confirmButton(self): documentsIndexes = [] 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) _type = self.treeModel.data(index, Qt.UserRole + 3) if _type == 'Document': self.applyFilterOverDocument(self.documents[documentIndex]) else: self.applyFilterOverNode(node, self.documents[documentIndex]) documentsIndexes.append(documentIndex) self.refreshDocumentsProjections(set(documentsIndexes)) def refreshDocumentsProjections(self, indexes): for index in indexes: document = self.documents[index] document.refreshProjection() def applyFilterOverNode(self, node, document): _filter = self.kritaInstance.filter(self.filterComboBox.currentText()) _filter.apply(node, 0, 0, document.width(), document.height()) def applyFilterOverDocument(self, document): - """ This method applies the selected filter just to topLevelNodes, then - if topLevelNodes are GroupLayers, that filter will not be applied. """ + """This method applies the selected filter just to topLevelNodes, + then if topLevelNodes are GroupLayers, that filter will not be + applied.""" for node in document.topLevelNodes(): self.applyFilterOverNode(node, document) @property def filters(self): return self._filters @property def documents(self): return self._documents diff --git a/plugins/python/hello/__init__.py b/plugins/python/hello/__init__.py index de744cb395..70c5b36650 100644 --- a/plugins/python/hello/__init__.py +++ b/plugins/python/hello/__init__.py @@ -1,2 +1,11 @@ -# let's make a module -from .hello import * +from krita import Krita, DockWidgetFactory, DockWidgetFactoryBase +from .hello import HelloExtension, HelloDocker + + +# Initialize and add the extension +Scripter.addExtension(HelloExtension(Krita.instance())) + + +# Register the docker so Krita can use it! +Application.addDockWidgetFactory( + DockWidgetFactory("hello", DockWidgetFactoryBase.DockRight, HelloDocker)) diff --git a/plugins/python/hello/hello.py b/plugins/python/hello/hello.py index cf2c6b3c8a..faba69991f 100644 --- a/plugins/python/hello/hello.py +++ b/plugins/python/hello/hello.py @@ -1,88 +1,87 @@ -''' -This script is licensed CC 0 1.0, so that you can learn from it. +# This script is licensed CC 0 1.0, so that you can learn from it. ------- CC 0 1.0 --------------- +# ------ CC 0 1.0 --------------- -The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. +# The person who associated a work with this deed has dedicated the +# work to the public domain by waiving all of his or her rights to the +# work worldwide under copyright law, including all related and +# neighboring rights, to the extent allowed by law. -You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. +# You can copy, modify, distribute and perform the work, even for +# commercial purposes, all without asking permission. + +# https://creativecommons.org/publicdomain/zero/1.0/legalcode + +""" +This is a simple example of a Python script for Krita. +It demonstrates how to set up a custom extension and a custom docker! +""" -https://creativecommons.org/publicdomain/zero/1.0/legalcode -''' -# -# This is a simple example of a Python script for Krita. -# It demonstrates how to set up a custom extension and a custom docker! -# from PyQt5.QtWidgets import QWidget, QLabel, QMessageBox -from krita import (Krita, Extension, DockWidget, - DockWidgetFactory, DockWidgetFactoryBase) +from krita import Extension, DockWidget def hello(): """ Show a test message box. """ - QMessageBox.information(QWidget(), i18n("Test"), i18n("Hello! This is Krita version %s") % Application.version()) + QMessageBox.information( + QWidget(), + i18n("Test"), + i18n("Hello! This is Krita version %s") % Application.version()) class HelloExtension(Extension): """ - HelloExtension is a small example extension demonstrating basic Python scripting support in Krita! + HelloExtension is a small example extension demonstrating basic + Python scripting support in Krita! """ def __init__(self, parent): """ Standard Krita Python extension constructor. Most of the initialization happens in :func:`setup` :param parent: Parent widget :type parent: :class:`QWidget` or None """ super(HelloExtension, self).__init__(parent) def setup(self): pass def createActions(self, window): """ This is where most of the setup takes place! """ action = window.createAction("hello_python", i18n("Hello")) action.triggered.connect(hello) -# Initialize and add the extension -Scripter.addExtension(HelloExtension(Krita.instance())) - - class HelloDocker(DockWidget): """ The HelloDocker is an example of a simple Python-based docker. """ def __init__(self): """ Constructs an instance of HelloDocker and the widget it contains """ super(HelloDocker, self).__init__() # The window title is also used in the Docker menu, # so it should be set to something sensible! self.setWindowTitle("HelloDocker") label = QLabel("Hello", self) self.setWidget(label) self._label = label def canvasChanged(self, canvas): """ Override canvasChanged from :class:`DockWidget`. This gets called when the canvas changes. You can also access the active canvas via :func:`DockWidget.canvas` Parameter `canvas` can be null if the last document is closed """ self._label.setText("HelloDocker: canvas changed") - - -# Register the docker so Krita can use it! -Application.addDockWidgetFactory(DockWidgetFactory("hello", DockWidgetFactoryBase.DockRight, HelloDocker))