File indexing completed on 2024-06-16 04:17:41
0001 """ 0002 SPDX-FileCopyrightText: 2017 Eliakin Costa <eliakim170@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 """ 0006 from PyQt5.QtCore import Qt, QObject, QFileInfo, QRect 0007 from PyQt5.QtGui import QTextCursor, QPalette 0008 from PyQt5.QtWidgets import (QToolBar, QMenuBar, QTabWidget, 0009 QLabel, QVBoxLayout, QMessageBox, 0010 QSplitter, QSizePolicy) 0011 from .ui_scripter.syntax import syntax, syntaxstyles 0012 from .ui_scripter.editor import pythoneditor 0013 from . import scripterdialog, utils 0014 import importlib 0015 import krita 0016 0017 KEY_GEOMETRY = "geometry" 0018 DEFAULT_GEOMETRY = QRect(600, 200, 400, 500) 0019 # essentially randomly placed 0020 0021 0022 class Elided_Text_Label(QLabel): 0023 mainText = str() 0024 0025 def __init__(self, parent=None): 0026 super(QLabel, self).__init__(parent) 0027 self.setMinimumWidth(self.fontMetrics().width("...")) 0028 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) 0029 0030 def setMainText(self, text=str()): 0031 self.mainText = text 0032 self.elideText() 0033 0034 def elideText(self): 0035 self.setText(self.fontMetrics().elidedText(self.mainText, Qt.ElideRight, self.width())) 0036 0037 def resizeEvent(self, event): 0038 self.elideText() 0039 0040 0041 class UIController(object): 0042 documentModifiedText = "" 0043 documentStatusBarText = "untitled" 0044 0045 def __init__(self): 0046 self.mainWidget = scripterdialog.ScripterDialog(self) 0047 self.actionToolbar = QToolBar('toolBar', self.mainWidget) 0048 self.menu_bar = QMenuBar(self.mainWidget) 0049 0050 self.actionToolbar.setObjectName('toolBar') 0051 self.menu_bar.setObjectName('menuBar') 0052 0053 self.actions = [] 0054 0055 self.mainWidget.setWindowModality(Qt.NonModal) 0056 0057 def initialize(self, scripter): 0058 self.editor = pythoneditor.CodeEditor(scripter) 0059 self.tabWidget = QTabWidget() 0060 self.statusBar = Elided_Text_Label() 0061 self.statusBar.setMainText('untitled') 0062 self.splitter = QSplitter() 0063 self.splitter.setOrientation(Qt.Vertical) 0064 self.highlight = syntax.PythonHighlighter(self.editor.document(), syntaxstyles.DefaultSyntaxStyle()) 0065 p = self.editor.palette() 0066 p.setColor(QPalette.Base, syntaxstyles.DefaultSyntaxStyle()['background'].foreground().color()) 0067 p.setColor(QPalette.Text, syntaxstyles.DefaultSyntaxStyle()['foreground'].foreground().color()) 0068 self.editor.setPalette(p) 0069 0070 utils.setNeedDarkIcon(self.mainWidget.palette().window().color()) 0071 self.scripter = scripter 0072 0073 self.loadMenus() 0074 self.loadWidgets() 0075 self.loadActions() 0076 self._readSettings() # sets window size 0077 0078 vbox = QVBoxLayout(self.mainWidget) 0079 vbox.addWidget(self.menu_bar) 0080 vbox.addWidget(self.actionToolbar) 0081 self.splitter.addWidget(self.editor) 0082 self.splitter.addWidget(self.tabWidget) 0083 vbox.addWidget(self.splitter) 0084 vbox.addWidget(self.statusBar) 0085 0086 self.mainWidget.setWindowTitle(i18n("Scripter")) 0087 self.mainWidget.setSizeGripEnabled(True) 0088 self.mainWidget.show() 0089 self.mainWidget.activateWindow() 0090 0091 self.editor.undoAvailable.connect(self.setStatusModified) 0092 0093 def loadMenus(self): 0094 self.addMenu(i18n('File'), i18n('File')) 0095 0096 def addMenu(self, menuName, parentName): 0097 parent = self.menu_bar.findChild(QObject, parentName) 0098 self.newMenu = None 0099 0100 if parent: 0101 self.newMenu = parent.addMenu(menuName) 0102 else: 0103 self.newMenu = self.menu_bar.addMenu(menuName) 0104 0105 self.newMenu.setObjectName(menuName) 0106 0107 return self.newMenu 0108 0109 def loadActions(self): 0110 module_path = 'scripter.ui_scripter.actions' 0111 actions_module = importlib.import_module(module_path) 0112 modules = [] 0113 0114 for class_path in actions_module.action_classes: 0115 _module = class_path[:class_path.rfind(".")] 0116 _klass = class_path[class_path.rfind(".") + 1:] 0117 modules.append(dict(module='{0}.{1}'.format(module_path, _module), 0118 klass=_klass)) 0119 0120 for module in modules: 0121 m = importlib.import_module(module['module']) 0122 action_class = getattr(m, module['klass']) 0123 obj = action_class(self.scripter) 0124 obj_parent = obj.parent 0125 for name in obj_parent: 0126 parent = self.mainWidget.findChild(QObject, i18n(name)) 0127 self.actions.append(dict(action=obj, parent=parent)) 0128 0129 for action in self.actions: 0130 action['parent'].addAction(action['action']) 0131 0132 def loadWidgets(self): 0133 modulePath = 'scripter.ui_scripter.tabwidgets' 0134 widgetsModule = importlib.import_module(modulePath) 0135 modules = [] 0136 0137 for class_path in widgetsModule.widgetClasses: 0138 _module = class_path[:class_path.rfind(".")] 0139 _klass = class_path[class_path.rfind(".") + 1:] 0140 modules.append(dict(module='{0}.{1}'.format(modulePath, _module), 0141 klass=_klass)) 0142 0143 for module in modules: 0144 m = importlib.import_module(module['module']) 0145 widgetClass = getattr(m, module['klass']) 0146 obj = widgetClass(self.scripter) 0147 self.tabWidget.addTab(obj, obj.objectName()) 0148 0149 def invokeAction(self, actionName): 0150 for action in self.actions: 0151 if action['action'].objectName() == actionName: 0152 method = getattr(action['action'], actionName) 0153 if method: 0154 return method() 0155 0156 def findTabWidget(self, widgetName, childName=''): 0157 for index in range(self.tabWidget.count()): 0158 widget = self.tabWidget.widget(index) 0159 if widget.objectName() == widgetName: 0160 if childName: 0161 widget = widget.findChild(QObject, childName) 0162 return widget 0163 0164 def showException(self, exception): 0165 QMessageBox.critical(self.editor, i18n("Error Running Script"), str(exception)) 0166 0167 def setDocumentEditor(self, document): 0168 self.editor.clear() 0169 self.editor.moveCursor(QTextCursor.Start) 0170 self.editor._documentModified = False 0171 self.editor.setPlainText(document.data) 0172 self.editor.moveCursor(QTextCursor.End) 0173 0174 def setStatusBar(self, value='untitled'): 0175 self.documentStatusBarText = value 0176 self.statusBar.setMainText(self.documentStatusBarText + self.documentModifiedText) 0177 0178 def setStatusModified(self): 0179 self.documentModifiedText = "" 0180 if (self.editor._documentModified is True): 0181 self.documentModifiedText = " [Modified]" 0182 self.statusBar.setMainText(self.documentStatusBarText + self.documentModifiedText) 0183 0184 def setActiveWidget(self, widgetName): 0185 widget = self.findTabWidget(widgetName) 0186 0187 if widget: 0188 self.tabWidget.setCurrentWidget(widget) 0189 0190 def setStepped(self, status): 0191 self.editor.setStepped(status) 0192 0193 def clearEditor(self): 0194 self.editor.clear() 0195 0196 def repaintDebugArea(self): 0197 self.editor.repaintDebugArea() 0198 0199 def closeScripter(self): 0200 self.mainWidget.close() 0201 0202 def _writeSettings(self): 0203 """ _writeSettings is a method invoked when the scripter starts, making 0204 control inversion. Actions can implement a writeSettings method to 0205 save your own settings without this method to know about it. """ 0206 0207 self.scripter.settings.beginGroup('scripter') 0208 0209 document = self.scripter.documentcontroller.activeDocument 0210 if document: 0211 self.scripter.settings.setValue('activeDocumentPath', document.filePath) 0212 else: 0213 self.scripter.settings.setValue('activeDocumentPath', '') 0214 0215 self.scripter.settings.setValue('editorFontSize', self.editor.fontInfo().pointSize()) 0216 0217 for action in self.actions: 0218 writeSettings = getattr(action['action'], "writeSettings", None) 0219 if callable(writeSettings): 0220 writeSettings() 0221 0222 # Window Geometry 0223 rect = self.mainWidget.geometry() 0224 self.scripter.settings.setValue(KEY_GEOMETRY, rect) 0225 0226 self.scripter.settings.endGroup() 0227 0228 def _readSettings(self): 0229 """ It's similar to _writeSettings, but reading the settings when the ScripterDialog is closed. """ 0230 0231 self.scripter.settings.beginGroup('scripter') 0232 0233 activeDocumentPath = self.scripter.settings.value('activeDocumentPath', '') 0234 0235 if activeDocumentPath: 0236 if QFileInfo(activeDocumentPath).exists(): 0237 document = self.scripter.documentcontroller.openDocument(activeDocumentPath) 0238 self.setStatusBar(document.filePath) 0239 self.setDocumentEditor(document) 0240 0241 for action in self.actions: 0242 readSettings = getattr(action['action'], "readSettings", None) 0243 if callable(readSettings): 0244 readSettings() 0245 0246 pointSize = self.scripter.settings.value('editorFontSize', str(self.editor.fontInfo().pointSize())) 0247 self.editor.setFontSize(int(pointSize)) 0248 0249 # Window Geometry 0250 rect = self.scripter.settings.value(KEY_GEOMETRY, DEFAULT_GEOMETRY) 0251 self.mainWidget.setGeometry(rect) 0252 0253 self.scripter.settings.endGroup() 0254 0255 def _saveSettings(self): 0256 self.scripter.settings.sync()