File indexing completed on 2024-12-22 04:16:28
0001 # SPDX-FileCopyrightText: 2019 Rebecca Breu <rebecca@rbreu.de> 0002 0003 # This file is part of Krita. 0004 0005 # SPDX-License-Identifier: GPL-3.0-or-later 0006 0007 import html 0008 import os 0009 import tempfile 0010 0011 import krita 0012 0013 from PyQt5.QtCore import QStandardPaths 0014 from PyQt5.QtWidgets import QFileDialog, QMessageBox, QInputDialog 0015 0016 from .plugin_importer import PluginImporter, PluginImportError 0017 from .plugin_downloader import download_plugin, PluginDownloadError 0018 0019 0020 class PluginImporterExtension(krita.Extension): 0021 0022 def __init__(self, parent): 0023 super().__init__(parent) 0024 self.parent = parent 0025 0026 def setup(self): 0027 pass 0028 0029 def createActions(self, window): 0030 action = window.createAction( 0031 'plugin_importer_file', 0032 i18n('Import Python Plugin from File...'), 0033 'tools/scripts') 0034 action.triggered.connect(self.import_plugin_from_file) 0035 action = window.createAction( 0036 'plugin_importer_web', 0037 i18n('Import Python Plugin from Web...'), 0038 'tools/scripts') 0039 action.triggered.connect(self.import_plugin_from_web) 0040 0041 def confirm_overwrite(self, plugin): 0042 reply = QMessageBox.question( 0043 self.parent.activeWindow().qwindow(), 0044 i18n('Overwrite Plugin'), 0045 i18n('The plugin "%s" already exists. Overwrite it?') % ( 0046 plugin['ui_name']), 0047 QMessageBox.Yes | QMessageBox.No) 0048 return reply == QMessageBox.Yes 0049 0050 def confirm_activate(self, plugins): 0051 txt = [ 0052 '<p>', 0053 i18n('The following plugins were imported:'), 0054 '</p>', 0055 '<ul>' 0056 ] 0057 for plugin in plugins: 0058 txt.append('<li>%s</li>' % plugin['ui_name']) 0059 0060 txt.append('</ul>') 0061 txt.append('<p><strong>') 0062 txt.append(i18n( 0063 'Enable plugins now? (Requires restart)')) 0064 txt.append('</strong></p>') 0065 0066 reply = QMessageBox.question( 0067 self.parent.activeWindow().qwindow(), 0068 i18n('Activate Plugins?'), 0069 ('\n').join(txt), 0070 QMessageBox.Yes | QMessageBox.No) 0071 return reply == QMessageBox.Yes 0072 0073 def display_errors(self, error): 0074 msg = '<p>%s</p><pre>%s</pre>' % ( 0075 i18n('Error during import:'), 0076 html.escape(str(error))) 0077 QMessageBox.warning( 0078 self.parent.activeWindow().qwindow(), 0079 i18n('Error'), 0080 msg) 0081 0082 def activate_plugins(self, plugins): 0083 for plugin in plugins: 0084 Application.writeSetting( 0085 'python', 0086 'enable_%s' % plugin['name'], 0087 'true') 0088 0089 def get_resources_dir(self): 0090 return Krita.instance().getAppDataLocation() 0091 0092 def import_plugin_from_web(self): 0093 infotext = i18n( 0094 '<p><strong>Enter download URL</strong></p>' 0095 '<p>For example:' 0096 '<ul>' 0097 '<li>Zip download link (http://example.com/plugin.zip)</li>' 0098 '<li>Github repository (https://github.com/test/plugin)</li>' 0099 ) 0100 url = QInputDialog.getText( 0101 self.parent.activeWindow().qwindow(), 0102 i18n('Import Plugin'), 0103 infotext)[0] 0104 if url: 0105 with tempfile.TemporaryDirectory() as tmpdir: 0106 try: 0107 zipfile = download_plugin(url=url, dest_dir=tmpdir) 0108 except PluginDownloadError as e: 0109 self.display_errors(e) 0110 return 0111 self.do_import(zipfile) 0112 0113 def import_plugin_from_file(self): 0114 zipfile = QFileDialog.getOpenFileName( 0115 self.parent.activeWindow().qwindow(), 0116 i18n('Import Plugin'), 0117 os.path.expanduser('~'), 0118 '%s (*.zip)' % i18n('Zip Archives'), 0119 )[0] 0120 0121 if not zipfile: 0122 return 0123 0124 self.do_import(zipfile) 0125 0126 def do_import(self, zipfile): 0127 try: 0128 imported = PluginImporter( 0129 zipfile, 0130 self.get_resources_dir(), 0131 self.confirm_overwrite 0132 ).import_all() 0133 except PluginImportError as e: 0134 self.display_errors(e) 0135 return 0136 0137 if imported: 0138 activate = self.confirm_activate(imported) 0139 if activate: 0140 self.activate_plugins(imported)