[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/sofibox/winpython/master/winpython/controlpanel.py [Back]  [Original]

# -*- coding: utf-8 -*- # # Copyright 2012 Pierre Raybaut # Licensed under the terms of the MIT License # (see winpython/__init__.py for details) """ WinPython Package Manager GUI Created on Mon Aug 13 11:40:01 2012 """ from pathlib import Path import os import sys import platform import locale # winpython.qt becomes winpython._vendor.qtpy from winpython._vendor.qtpy.QtWidgets import ( QApplication, QMainWindow, QWidget, QLineEdit, QHBoxLayout, QVBoxLayout, QMessageBox, QAbstractItemView, QProgressDialog, QTableView, QPushButton, QLabel, QTabWidget, QToolTip, ) from winpython._vendor.qtpy.QtGui import ( QColor, QDesktopServices, ) from winpython._vendor.qtpy.QtCore import ( Qt, QAbstractTableModel, QModelIndex, Signal, QThread, QTimer, QUrl, ) from winpython._vendor.qtpy.compat import ( to_qvariant, getopenfilenames, getexistingdirectory, ) import winpython._vendor.qtpy from winpython.qthelpers import ( get_icon, add_actions, create_action, keybinding, get_std_icon, action2button, mimedata2url, ) # Local imports from winpython import __version__, __project_url__ from winpython import wppm, associate, utils COLUMNS = ACTION, CHECK, NAME, VERSION, DESCRIPTION = list( range(5) ) class PackagesModel(QAbstractTableModel): # Signals after PyQt4 old SIGNAL removal dataChanged = Signal(QModelIndex, QModelIndex) def __init__(self): QAbstractTableModel.__init__(self) self.packages = [] self.checked = set() self.actions = {} def sortByName(self): self.packages = sorted( self.packages, key=lambda x: x.name ) self.reset() def flags(self, index): if not index.isValid(): return Qt.ItemIsEnabled column = index.column() if column in (NAME, VERSION, ACTION, DESCRIPTION): return Qt.ItemFlags( QAbstractTableModel.flags(self, index) ) else: return Qt.ItemFlags( QAbstractTableModel.flags(self, index) | Qt.ItemIsUserCheckable | Qt.ItemIsEditable ) def data(self, index, role=Qt.DisplayRole): if not index.isValid() or not ( 0 0 ) nbp = len(self.table.get_selected_packages()) for act in ( self.remove_action, self.select_all_action, ): act.setEnabled(nbp > 0) self.show_drop_tip() def show_drop_tip(self): """Show drop tip on install table""" callback = lambda: QToolTip.showText( self.table.mapToGlobal(self.table.pos()), 'Drop files here
' 'Executable installers (distutils) or source packages', self, ) QTimer.singleShot(500, callback) def refresh_uninstall_button(self): """Refresh uninstall button enable state""" nbp = len(self.untable.get_selected_packages()) self.uninstall_action.setEnabled(nbp > 0) def toggle_repair(self, state): """Toggle repair mode""" self.table.repair = state self.refresh_install_button() def register_distribution(self): """Register distribution""" answer = QMessageBox.warning( self, "Register distribution", "(experimental)\n" "This will associate file extensions, icons and " "Windows explorer's context menu entries ('Edit with IDLE', ...) " "with selected Python distribution in Windows registry. " "\n\nShortcuts for all WinPython launchers will be installed " "in WinPython Start menu group (replacing existing " "shortcuts)." "\n\nNote: these actions are similar to those performed" "when installing old Pythons with the official installer before 'py' " "for Windows.\n\nDo you want to continue? ", QMessageBox.Yes | QMessageBox.No, ) if answer == QMessageBox.Yes: associate.register(self.distribution.target) def unregister_distribution(self): """Unregister distribution""" answer = QMessageBox.warning( self, "Unregister distribution", "(experimental)\n" "This will remove file extensions associations, icons and " "Windows explorer's context menu entries ('Edit with IDLE', ...) " "with selected Python distribution in Windows registry. " "\n\nShortcuts for all WinPython launchers will be removed " "from WinPython Start menu group." "\n\nDo you want to continue? ", QMessageBox.Yes | QMessageBox.No, ) if answer == QMessageBox.Yes: associate.unregister(self.distribution.target) @property def command_prompt_path(self): return str(Path(self.distribution.target).parent / "WinPython Command Prompt.exe") def distribution_changed(self, path): """Distribution path has just changed""" for package in self.table.model.packages: self.table.remove_package(package) # dist = wppm.Distribution(to_text_string(path)) dist = wppm.Distribution(str(path)) self.table.refresh_distribution(dist) self.untable.refresh_distribution(dist) self.distribution = dist self.selector.label.setText( f'Python {dist.version} {dist.architecture}bit:' ) def add_packages(self): """Add packages""" basedir = ( self.basedir if self.basedir is not None else '' ) fnames, _selfilter = getopenfilenames( parent=self, basedir=basedir, caption='Add packages', filters='*.exe *.zip *.tar.gz *.whl', ) if fnames: self.basedir = str(Path(fnames[0]).parent) self.table.add_packages(fnames) def get_packages_to_be_installed(self): """Return packages to be installed""" return [ pack for pack in self.table.get_selected_packages() if self.table.model.actions[pack] not in (NO_REPAIR_ACTION, NONE_ACTION) ] def remove_packages(self): """Remove selected packages""" for package in self.table.get_selected_packages(): self.table.remove_package(package) def process_packages(self, action): """Install/uninstall packages""" if action == 'install': text, table = 'Installing', self.table if not self.get_packages_to_be_installed(): return elif action == 'uninstall': text, table = 'Uninstalling', self.untable else: raise AssertionError packages = table.get_selected_packages() if not packages: return func = getattr(self.distribution, action) thread = Thread(self) for widget in self.children(): if isinstance(widget, QWidget): widget.setEnabled(False) try: status = self.statusBar() except AttributeError: status = self.parent().statusBar() progress = QProgressDialog( self, Qt.FramelessWindowHint ) progress.setMaximum( len(packages) ) # old vicious bug:len(packages)-1 for index, package in enumerate(packages): progress.setValue(index) progress.setLabelText( f"{text} {package.name} {package.version}..." ) QApplication.processEvents() if progress.wasCanceled(): break if package in table.model.actions: try: thread.callback = lambda: func(package) thread.start() while thread.isRunning(): QApplication.processEvents() if progress.wasCanceled(): status.setEnabled(True) status.showMessage( "Cancelling operation..." ) table.remove_package(package) error = thread.error except Exception as error: error = str(error) # to_text_string(error) if error is not None: pstr = ( package.name + ' ' + package.version ) QMessageBox.critical( self, "Error", f"Unable to {action} {pstr}/i>" f"

Error message:
{error}" , ) progress.setValue(progress.maximum()) status.clearMessage() for widget in self.children(): if isinstance(widget, QWidget): widget.setEnabled(True) thread = None for table in (self.table, self.untable): table.refresh_distribution(self.distribution) def report_issue(self): issue_template = f"""\ Python distribution: {python_distribution_infos()} Control panel version: {__version__} Python Version: {platform.python_version()} Qt Version: {winpython._vendor.qtpy.QtCore.__version__}, {winpython.qt.API_NAME} {winpython._vendor.qtpy.__version__} What steps will reproduce the problem? 1. 2. 3. What is the expected output? What do you see instead? Please provide any additional information below. """ url = QUrl(f"{__project_url__}/issues/entry") url.addQueryItem("comment", issue_template) QDesktopServices.openUrl(url) def about(self): """About this program""" QMessageBox.about( self, f"About {self.NAME}", f"""{self.NAME} {__version__}
Package Manager and Advanced Tasks

Copyright © 2012 Pierre Raybaut
Licensed under the terms of the MIT License

Created, developed and maintained by Pierre Raybaut

WinPython at Github.io: downloads, bug reports, discussions, etc.

This program is executed by:
{python_distribution_infos()}
Python {platform.python_version()}, Qt {winpython._vendor.qtpy.QtCore.__version__}, {winpython._vendor.qtpy.API_NAME} qtpy {winpython._vendor.qtpy.__version__}""" , ) def main(test=False): app = QApplication([]) win = PMWindow() win.show() if test: return app, win else: app.exec_() def test(): app, win = main(test=True) print(sys.modules) app.exec_() if __name__ == "__main__": main()


Web Proxy Viewer  |  New URL  |  Original Page