diff --git a/src/Mod/AddonManager/addonmanager_freecad_interface.py b/src/Mod/AddonManager/addonmanager_freecad_interface.py index 1dcccd8f76..5fc4ca041a 100644 --- a/src/Mod/AddonManager/addonmanager_freecad_interface.py +++ b/src/Mod/AddonManager/addonmanager_freecad_interface.py @@ -41,6 +41,7 @@ try: Console = FreeCAD.Console ParamGet = FreeCAD.ParamGet + Version = FreeCAD.Version getUserAppDataDir = FreeCAD.getUserAppDataDir getUserMacroDir = FreeCAD.getUserMacroDir getUserCachePath = FreeCAD.getUserCachePath @@ -55,6 +56,9 @@ except ImportError: def translate(_context: str, string: str, _desc: str = "") -> str: return string + def Version(): + return 1, 0, 0 + class ConsoleReplacement: """If FreeCAD's Console is not available, create a replacement by redirecting FreeCAD log calls to Python's built-in logging facility.""" diff --git a/src/Mod/AddonManager/package_details.py b/src/Mod/AddonManager/package_details.py index 5a7498e83a..953ff90e0e 100644 --- a/src/Mod/AddonManager/package_details.py +++ b/src/Mod/AddonManager/package_details.py @@ -26,12 +26,9 @@ import os from typing import Optional -from PySide.QtCore import * -from PySide.QtGui import * -from PySide.QtWidgets import * +from PySide import QtCore, QtGui, QtWidgets -import FreeCAD -import FreeCADGui +import addonmanager_freecad_interface as fci import addonmanager_utilities as utils from addonmanager_workers_startup import GetMacroDetailsWorker, CheckSingleUpdateWorker @@ -46,39 +43,39 @@ try: if hasattr(git, "Repo"): have_git = True except ImportError: - pass + git = None -translate = FreeCAD.Qt.translate +translate = fci.translate show_javascript_console_output = False try: - from PySide.QtWebEngineWidgets import * + from PySide import QtWebEngineWidgets HAS_QTWEBENGINE = True except ImportError: - FreeCAD.Console.PrintWarning( + fci.Console.PrintWarning( translate( "AddonsInstaller", - "Addon Manager Warning: Could not import QtWebEngineWidgets. Your system's package manager may provide a package for this dependency, search the package manager for possible resolutions. Display of package README will be limited until this dependency is resolved.", + "Addon Manager Warning: Could not import QtWebEngineWidgets -- README data will display as text-only", ) + "\n" ) HAS_QTWEBENGINE = False -class PackageDetails(QWidget): +class PackageDetails(QtWidgets.QWidget): """The PackageDetails QWidget shows package README information and provides install, uninstall, and update buttons.""" - back = Signal() - install = Signal(Addon) - uninstall = Signal(Addon) - update = Signal(Addon) - execute = Signal(Addon) - update_status = Signal(Addon) - check_for_update = Signal(Addon) + back = QtCore.Signal() + install = QtCore.Signal(Addon) + uninstall = QtCore.Signal(Addon) + update = QtCore.Signal(Addon) + execute = QtCore.Signal(Addon) + update_status = QtCore.Signal(Addon) + check_for_update = QtCore.Signal(Addon) def __init__(self, parent=None): super().__init__(parent) @@ -128,7 +125,7 @@ class PackageDetails(QWidget): self.ui.webView.setHtml("Loading...") self.ui.webView.hide() self.ui.progressBar.show() - self.timeout = QTimer.singleShot( + self.timeout = QtCore.QTimer.singleShot( 6000, self.long_load_running ) # Six seconds else: @@ -153,7 +150,7 @@ class PackageDetails(QWidget): if repo.status() == Addon.Status.UNCHECKED: if not self.status_update_thread: - self.status_update_thread = QThread() + self.status_update_thread = QtCore.QThread() self.status_create_addon_list_worker = CheckSingleUpdateWorker(repo) self.status_create_addon_list_worker.moveToThread(self.status_update_thread) self.status_update_thread.finished.connect( @@ -179,9 +176,9 @@ class PackageDetails(QWidget): installed_version_string = "

" if repo.updated_timestamp: date = ( - QDateTime.fromTime_t(repo.updated_timestamp) + QtCore.QDateTime.fromTime_t(repo.updated_timestamp) .date() - .toString(Qt.SystemLocaleShortDate) + .toString(QtCore.Qt.SystemLocaleShortDate) ) if version and date: installed_version_string += ( @@ -236,7 +233,7 @@ class PackageDetails(QWidget): detached_head = False branch = repo.branch if have_git and repo.repo_type != Addon.Kind.MACRO: - basedir = FreeCAD.getUserAppDataDir() + basedir = fci.getUserAppDataDir() moddir = os.path.join(basedir, "Mod", repo.name) if os.path.exists(os.path.join(moddir, ".git")): gitrepo = git.Repo(moddir) @@ -267,7 +264,7 @@ class PackageDetails(QWidget): + "." ) elif status == Addon.Status.UNCHECKED: - pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons") + pref = fci.ParamGet("User parameter:BaseApp/Preferences/Addons") autocheck = pref.GetBool("AutoCheck", False) if autocheck: installed_version_string += ( @@ -292,9 +289,9 @@ class PackageDetails(QWidget): self.ui.labelPackageDetails.show() if repo.macro is not None: - moddir = FreeCAD.getUserMacroDir(True) + moddir = fci.getUserMacroDir(True) else: - basedir = FreeCAD.getUserAppDataDir() + basedir = fci.getUserAppDataDir() moddir = os.path.join(basedir, "Mod", repo.name) installationLocationString = ( translate("AddonsInstaller", "Installation location") @@ -404,8 +401,8 @@ class PackageDetails(QWidget): ) if first_supported_version is not None: required_version = first_supported_version.split(".") - fc_major = int(FreeCAD.Version()[0]) - fc_minor = int(FreeCAD.Version()[1]) + fc_major = int(fci.Version()[0]) + fc_minor = int(fci.Version()[1]) if int(required_version[0]) > fc_major: return first_supported_version @@ -420,7 +417,7 @@ class PackageDetails(QWidget): self.ui.buttonChangeBranch.hide() - pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Addons") + pref = fci.ParamGet("User parameter:BaseApp/Preferences/Addons") show_switcher = pref.GetBool("ShowBranchSwitcher", False) if not show_switcher: return @@ -438,7 +435,7 @@ class PackageDetails(QWidget): return # Is there a .git subdirectory? If not, return. - basedir = FreeCAD.getUserAppDataDir() + basedir = fci.getUserAppDataDir() path_to_git = os.path.join(basedir, "Mod", self.repo.name, ".git") if not os.path.isdir(path_to_git): return @@ -463,7 +460,7 @@ class PackageDetails(QWidget): """loads information of a given workbench""" url = utils.get_readme_html_url(repo) if HAS_QTWEBENGINE: - self.ui.webView.load(QUrl(url)) + self.ui.webView.load(QtCore.QUrl(url)) self.ui.urlBar.setText(url) else: readme_data = NetworkManager.AM_NETWORK_MANAGER.blocking_get(url) @@ -483,7 +480,7 @@ class PackageDetails(QWidget): if not readme_url: readme_url = utils.get_readme_html_url(repo) if HAS_QTWEBENGINE: - self.ui.webView.load(QUrl(readme_url)) + self.ui.webView.load(QtCore.QUrl(readme_url)) self.ui.urlBar.setText(readme_url) else: readme_data = NetworkManager.AM_NETWORK_MANAGER.blocking_get(readme_url) @@ -509,7 +506,7 @@ class PackageDetails(QWidget): if HAS_QTWEBENGINE: if url: - self.ui.webView.load(QUrl(url)) + self.ui.webView.load(QtCore.QUrl(url)) self.ui.urlBar.setText(url) else: self.ui.urlBar.setText( @@ -567,7 +564,7 @@ class PackageDetails(QWidget): sibling = article.previousSibling; } } - } else if (url.hostname === "wiki.freecad.org" || + } else if (url.hostname === "wiki.fci.org" || url.hostname === "wiki.freecadweb.org") { const first_heading = document.getElementById('firstHeading'); const body_content = document.getElementById('bodyContent'); @@ -629,7 +626,7 @@ class PackageDetails(QWidget): self.ui.loadingLabel.hide() self.ui.webView.show() - def show_error_for(self, url: QUrl) -> None: + def show_error_for(self, url: QtCore.QUrl) -> None: """Displays error information.""" m = translate( "AddonsInstaller", "Could not load README data from URL {}" @@ -639,7 +636,7 @@ class PackageDetails(QWidget): def change_branch_clicked(self) -> None: """Loads the branch-switching dialog""" - basedir = FreeCAD.getUserAppDataDir() + basedir = fci.getUserAppDataDir() path_to_repo = os.path.join(basedir, "Mod", self.repo.name) change_branch_dialog = ChangeBranchDialog(path_to_repo, self) change_branch_dialog.branch_changed.connect(self.branch_changed) @@ -656,7 +653,7 @@ class PackageDetails(QWidget): "

" + translate( "AddonsInstaller", - "This Addon will be enabled next time you restart FreeCAD.", + "This Addon will be enabled next time you restart fci.", ) + "

" ) @@ -673,7 +670,7 @@ class PackageDetails(QWidget): "

" + translate( "AddonsInstaller", - "This Addon will be disabled next time you restart FreeCAD.", + "This Addon will be disabled next time you restart fci.", ) + "

" ) @@ -683,7 +680,7 @@ class PackageDetails(QWidget): def branch_changed(self, name: str) -> None: """Displays a dialog confirming the branch changed, and tries to access the metadata file from that branch.""" - QMessageBox.information( + QtWidgets.QMessageBox.information( self, translate("AddonsInstaller", "Success"), translate( @@ -692,7 +689,7 @@ class PackageDetails(QWidget): ), ) # See if this branch has a package.xml file: - basedir = FreeCAD.getUserAppDataDir() + basedir = fci.getUserAppDataDir() path_to_metadata = os.path.join(basedir, "Mod", self.repo.name, "package.xml") if os.path.isfile(path_to_metadata): self.repo.load_metadata_file(path_to_metadata) @@ -701,7 +698,7 @@ class PackageDetails(QWidget): self.repo.repo_type = Addon.Kind.WORKBENCH self.repo.metadata = None self.repo.installed_version = None - self.repo.updated_timestamp = QDateTime.currentDateTime().toSecsSinceEpoch() + self.repo.updated_timestamp = QtCore.QDateTime.currentDateTime().toSecsSinceEpoch() self.repo.branch = name self.repo.set_status(Addon.Status.PENDING_RESTART) @@ -719,30 +716,30 @@ class PackageDetails(QWidget): if HAS_QTWEBENGINE: - class RestrictedWebPage(QWebEnginePage): + class RestrictedWebPage(QtWebEngineWidgets.QWebEnginePage): """A class that follows links to FreeCAD wiki pages, but opens all other clicked links in the system web browser""" def __init__(self, parent): super().__init__(parent) - self.settings().setAttribute(QWebEngineSettings.ErrorPageEnabled, False) + self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.ErrorPageEnabled, False) self.stored_url = None def acceptNavigationRequest(self, requested_url, _type, isMainFrame): """A callback for navigation requests: this widget will only display navigation requests to the FreeCAD Wiki (for translation purposes) -- anything else will open in a new window. """ - if _type == QWebEnginePage.NavigationTypeLinkClicked: + if _type == QtWebEngineWidgets.QWebEnginePage.NavigationTypeLinkClicked: # See if the link is to a FreeCAD Wiki page -- if so, follow it, otherwise ask the OS to open it if ( - requested_url.host() == "wiki.freecad.org" + requested_url.host() == "wiki.fci.org" or requested_url.host() == "wiki.freecadweb.org" ): return super().acceptNavigationRequest( requested_url, _type, isMainFrame ) - QDesktopServices.openUrl(requested_url) + QtGui.QDesktopServices.openUrl(requested_url) self.stored_url = self.url() - QTimer.singleShot(0, self._reload_stored_url) + QtCore.QTimer.singleShot(0, self._reload_stored_url) return False return super().acceptNavigationRequest(requested_url, _type, isMainFrame) @@ -753,12 +750,12 @@ if HAS_QTWEBENGINE: global show_javascript_console_output if show_javascript_console_output: tag = translate("AddonsInstaller", "Page JavaScript reported") - if level == QWebEnginePage.InfoMessageLevel: - FreeCAD.Console.PrintMessage(f"{tag} {lineNumber}: {message}\n") - elif level == QWebEnginePage.WarningMessageLevel: - FreeCAD.Console.PrintWarning(f"{tag} {lineNumber}: {message}\n") - elif level == QWebEnginePage.ErrorMessageLevel: - FreeCAD.Console.PrintError(f"{tag} {lineNumber}: {message}\n") + if level == QtWebEngineWidgets.QWebEnginePage.InfoMessageLevel: + fci.Console.PrintMessage(f"{tag} {lineNumber}: {message}\n") + elif level == QtWebEngineWidgets.QWebEnginePage.WarningMessageLevel: + fci.Console.PrintWarning(f"{tag} {lineNumber}: {message}\n") + elif level == QtWebEngineWidgets.QWebEnginePage.ErrorMessageLevel: + fci.Console.PrintError(f"{tag} {lineNumber}: {message}\n") def _reload_stored_url(self): if self.stored_url: @@ -771,123 +768,123 @@ class Ui_PackageDetails(object): def setupUi(self, PackageDetails): if not PackageDetails.objectName(): PackageDetails.setObjectName("PackageDetails") - self.verticalLayout_2 = QVBoxLayout(PackageDetails) + self.verticalLayout_2 = QtWidgets.QVBoxLayout(PackageDetails) self.verticalLayout_2.setObjectName("verticalLayout_2") - self.layoutDetailsBackButton = QHBoxLayout() + self.layoutDetailsBackButton = QtWidgets.QHBoxLayout() self.layoutDetailsBackButton.setObjectName("layoutDetailsBackButton") - self.buttonBack = QToolButton(PackageDetails) + self.buttonBack = QtWidgets.QToolButton(PackageDetails) self.buttonBack.setObjectName("buttonBack") self.buttonBack.setIcon( - QIcon.fromTheme("back", QIcon(":/icons/button_left.svg")) + QtGui.QIcon.fromTheme("back", QtGui.QIcon(":/icons/button_left.svg")) ) self.layoutDetailsBackButton.addWidget(self.buttonBack) - self.horizontalSpacer = QSpacerItem( - 40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum + self.horizontalSpacer = QtWidgets.QSpacerItem( + 40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum ) self.layoutDetailsBackButton.addItem(self.horizontalSpacer) - self.buttonInstall = QPushButton(PackageDetails) + self.buttonInstall = QtWidgets.QPushButton(PackageDetails) self.buttonInstall.setObjectName("buttonInstall") self.layoutDetailsBackButton.addWidget(self.buttonInstall) - self.buttonUninstall = QPushButton(PackageDetails) + self.buttonUninstall = QtWidgets.QPushButton(PackageDetails) self.buttonUninstall.setObjectName("buttonUninstall") self.layoutDetailsBackButton.addWidget(self.buttonUninstall) - self.buttonUpdate = QPushButton(PackageDetails) + self.buttonUpdate = QtWidgets.QPushButton(PackageDetails) self.buttonUpdate.setObjectName("buttonUpdate") self.layoutDetailsBackButton.addWidget(self.buttonUpdate) - self.buttonCheckForUpdate = QPushButton(PackageDetails) + self.buttonCheckForUpdate = QtWidgets.QPushButton(PackageDetails) self.buttonCheckForUpdate.setObjectName("buttonCheckForUpdate") self.layoutDetailsBackButton.addWidget(self.buttonCheckForUpdate) - self.buttonChangeBranch = QPushButton(PackageDetails) + self.buttonChangeBranch = QtWidgets.QPushButton(PackageDetails) self.buttonChangeBranch.setObjectName("buttonChangeBranch") self.layoutDetailsBackButton.addWidget(self.buttonChangeBranch) - self.buttonExecute = QPushButton(PackageDetails) + self.buttonExecute = QtWidgets.QPushButton(PackageDetails) self.buttonExecute.setObjectName("buttonExecute") self.layoutDetailsBackButton.addWidget(self.buttonExecute) - self.buttonDisable = QPushButton(PackageDetails) + self.buttonDisable = QtWidgets.QPushButton(PackageDetails) self.buttonDisable.setObjectName("buttonDisable") self.layoutDetailsBackButton.addWidget(self.buttonDisable) - self.buttonEnable = QPushButton(PackageDetails) + self.buttonEnable = QtWidgets.QPushButton(PackageDetails) self.buttonEnable.setObjectName("buttonEnable") self.layoutDetailsBackButton.addWidget(self.buttonEnable) self.verticalLayout_2.addLayout(self.layoutDetailsBackButton) - self.labelPackageDetails = QLabel(PackageDetails) + self.labelPackageDetails = QtWidgets.QLabel(PackageDetails) self.labelPackageDetails.hide() self.verticalLayout_2.addWidget(self.labelPackageDetails) - self.labelInstallationLocation = QLabel(PackageDetails) - self.labelInstallationLocation.setTextInteractionFlags(Qt.TextSelectableByMouse) + self.labelInstallationLocation = QtWidgets.QLabel(PackageDetails) + self.labelInstallationLocation.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) self.labelInstallationLocation.hide() self.verticalLayout_2.addWidget(self.labelInstallationLocation) - self.labelWarningInfo = QLabel(PackageDetails) + self.labelWarningInfo = QtWidgets.QLabel(PackageDetails) self.labelWarningInfo.hide() self.verticalLayout_2.addWidget(self.labelWarningInfo) - sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + sizePolicy1 = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy1.setHorizontalStretch(0) sizePolicy1.setVerticalStretch(0) if HAS_QTWEBENGINE: - self.webView = QWebEngineView(PackageDetails) + self.webView = QtWebEngineWidgets.QWebEngineView(PackageDetails) self.webView.setObjectName("webView") self.webView.setSizePolicy(sizePolicy1) self.webView.setPage(RestrictedWebPage(PackageDetails)) self.verticalLayout_2.addWidget(self.webView) - self.loadingLabel = QWebEngineView(PackageDetails) + self.loadingLabel = QtWebEngineWidgets.QWebEngineView(PackageDetails) self.loadingLabel.setObjectName("loadingLabel") self.loadingLabel.setSizePolicy(sizePolicy1) self.verticalLayout_2.addWidget(self.loadingLabel) - self.slowLoadLabel = QLabel(PackageDetails) + self.slowLoadLabel = QtWidgets.QLabel(PackageDetails) self.slowLoadLabel.setObjectName("slowLoadLabel") self.verticalLayout_2.addWidget(self.slowLoadLabel) - self.progressBar = QProgressBar(PackageDetails) + self.progressBar = QtWidgets.QProgressBar(PackageDetails) self.progressBar.setObjectName("progressBar") self.progressBar.setTextVisible(False) self.verticalLayout_2.addWidget(self.progressBar) - self.urlBar = QLineEdit(PackageDetails) + self.urlBar = QtWidgets.QLineEdit(PackageDetails) self.urlBar.setObjectName("urlBar") self.urlBar.setReadOnly(True) self.verticalLayout_2.addWidget(self.urlBar) else: - self.missingWebViewLabel = QLabel(PackageDetails) + self.missingWebViewLabel = QtWidgets.QLabel(PackageDetails) self.missingWebViewLabel.setObjectName("missingWebViewLabel") self.missingWebViewLabel.setWordWrap(True) self.verticalLayout_2.addWidget(self.missingWebViewLabel) - self.textBrowserReadMe = QTextBrowser(PackageDetails) + self.textBrowserReadMe = QtWidgets.QTextBrowser(PackageDetails) self.textBrowserReadMe.setObjectName("textBrowserReadMe") self.textBrowserReadMe.setOpenExternalLinks(True) self.textBrowserReadMe.setOpenLinks(True) @@ -896,45 +893,45 @@ class Ui_PackageDetails(object): self.retranslateUi(PackageDetails) - QMetaObject.connectSlotsByName(PackageDetails) + QtCore.QMetaObject.connectSlotsByName(PackageDetails) # setupUi def retranslateUi(self, _): self.buttonBack.setText("") self.buttonInstall.setText( - QCoreApplication.translate("AddonsInstaller", "Install", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Install", None) ) self.buttonUninstall.setText( - QCoreApplication.translate("AddonsInstaller", "Uninstall", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Uninstall", None) ) self.buttonUpdate.setText( - QCoreApplication.translate("AddonsInstaller", "Update", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Update", None) ) self.buttonCheckForUpdate.setText( - QCoreApplication.translate("AddonsInstaller", "Check for Update", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Check for Update", None) ) self.buttonExecute.setText( - QCoreApplication.translate("AddonsInstaller", "Run Macro", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Run Macro", None) ) self.buttonChangeBranch.setText( - QCoreApplication.translate("AddonsInstaller", "Change Branch", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Change Branch", None) ) self.buttonEnable.setText( - QCoreApplication.translate("AddonsInstaller", "Enable", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Enable", None) ) self.buttonDisable.setText( - QCoreApplication.translate("AddonsInstaller", "Disable", None) + QtCore.QCoreApplication.translate("AddonsInstaller", "Disable", None) ) self.buttonBack.setToolTip( - QCoreApplication.translate( + QtCore.QCoreApplication.translate( "AddonsInstaller", "Return to package list", None ) ) if not HAS_QTWEBENGINE: self.missingWebViewLabel.setText( "

" - + QCoreApplication.translate( + + QtCore.QCoreApplication.translate( "AddonsInstaller", "QtWebEngine Python bindings not installed -- using fallback README display. See Report View for details and installation instructions.", None, @@ -943,7 +940,7 @@ class Ui_PackageDetails(object): ) else: self.slowLoadLabel.setText( - QCoreApplication.translate( + QtCore.QCoreApplication.translate( "AddonsInstaller", "The page is taking a long time to load... showing the data we have so far...", )