def add_item(self, item: QtGui.QTreeWidgetItem) -> None: if self.max_number is not None and self.topLevelItemCount() >= self.max_number: warning(_('Unable to add item'), _('Unable to add more than %(s)d items.') % {'s': self.max_number}, only_ok=True) return index = self.indexOfTopLevelItem(item) self.insert_item(values={}, index=index)
def remove_item(self, item: QtGui.QTreeWidgetItem) -> None: if self.min_number is not None and self.topLevelItemCount() <= self.min_number: warning(_('Unable to remove item'), _('At least %(s)d items are required.') % {'s': self.min_number}, only_ok=True) return index = self.indexOfTopLevelItem(item) self.takeTopLevelItem(index)
def check_base_type(self, value): if not isinstance(value, dict): raise InvalidValueException(_('Value must be a dict of standard JSON types')) try: json.dumps(value) except TypeError: raise InvalidValueException(_('Value must be a dict of standard JSON types'))
def check_base_type(self, value): if not isinstance(value, list) and not isinstance(value, tuple): raise InvalidValueException(_('Value must be a list or tuple of base JSON types')) if self.base_type in (str, int, float, bool): pass try: json.dumps(value) except TypeError: raise InvalidValueException(_('Value must be a list of base JSON types'))
def base_open_recent(self): actions = [] seen_basefilenames = set() for filename in application.GlobalInfos.last_documents: if not os.path.isfile(filename): continue basename = os.path.basename(filename) if basename in seen_basefilenames: basename = filename seen_basefilenames.add(basename) actions.append(MenuAction(functools.partial(self.base_open_document, filename), _('Open %(name)s') % {'name': basename}, _('File'))) return actions
def __init__(self, verbose_name='', help_text=None, default=None, disabled=False, validators=None, choices=None, on_change=None): super().__init__(verbose_name=verbose_name, help_text=help_text, disabled=disabled, validators=validators, default=default, on_change=on_change) if choices is None: raise InvalidValueException(_('You must provide a list of tuples for ‘choices’ argument.')) self.choices = choices
def __init__(self, *args, **kwargs): QtGui.QLineEdit.__init__(self, *args, **kwargs) self.setPlaceholderText(_("Search…")) self.setStyleSheet( "QLineEdit { padding: 2px; border-radius: 9px; border-color: #8e8e8e; };" "QLineEdit:focus { padding: 2px; border-radius: 9px; };" )
def __init__(self, args: list): super().__init__() self.load() # load preferences # initialize QtApplication self.application = QtGui.QApplication(args) self.parent = QtGui.QWidget() global_dict[application_key] = self # initialize thread pool executor self.executor = QtCore.QThreadPool() self.executor.setMaxThreadCount(self.GlobalInfos.pool_thread_size) # set some global stuff if self.description_icon: self.application.setWindowIcon(get_icon(self.description_icon)) if self.verbose_name: self.application.setApplicationName(str(self.verbose_name)) if self.application_version: self.application.setApplicationVersion(self.application_version) if self.systemtray_icon: self._parent_obj = QtGui.QWidget() self.systray = QtGui.QSystemTrayIcon(get_icon(self.systemtray_icon), self._parent_obj) self.systray.setVisible(True) self.systray.show() # retrieve menu and associated actions for the whole class hierarchy created_action_keys = set() menu = None for qualname in self.__class__.__mro__: cls_name = qualname.__name__.rpartition('.')[2] if cls_name not in registered_menus: continue for menu_action in registered_menu_actions[cls_name]: if menu is None: menu = QtGui.QMenu(self.verbose_name, self._parent_obj) if menu_action.uid in created_action_keys: # skip overriden actions (there are already created) continue created_action_keys.add(menu_action.uid) menu_action.create(self, menu) if menu is not None: self.systray.setContextMenu(menu) # noinspection PyUnresolvedReferences self.systray.activated.connect(self.systray_activated) # noinspection PyUnresolvedReferences self.systray.messageClicked.connect(self.systray_message_clicked) if self.splashscreen_icon: self.splashscreen = QtGui.QSplashScreen(self.parent, get_pixmap(self.splashscreen_icon), QtCore.Qt.WindowStaysOnTopHint) self.splashscreen.showMessage(_('Loading data…')) self.splashscreen.show() # noinspection PyUnresolvedReferences self.application.lastWindowClosed.connect(self.save) self.load_data() if self.splashscreen is not None: self.splashscreen.hide()
def __init__(self, filename: str = None, selection_filter: str = None, parent: QtGui.QWidget = None): self.selection_filter = selection_filter self.filename = None super().__init__(parent) self.select_button = create_button( _("Choose a file…"), min_size=True, connect=self.select_file, icon="edit-find" ) self.line_editor = QtGui.QLineEdit(p(self)) self.set_value(filename) layout = h_layout(self, self.select_button, self.line_editor) self.setLayout(layout) self.adjustSize()
def __init__(self, message, parent=None): super().__init__(p(parent)) widgets = [] if application.splashscreen_icon: pixmap = get_pixmap(application.splashscreen_icon) label = QtGui.QLabel(p(self)) label.setPixmap(pixmap) widgets.append(label) edit = QtGui.QTextEdit(message, self) edit.setReadOnly(True) widgets.append(edit) widgets.append(create_button(_('Close'), min_size=True, parent=self, connect=self.close)) self.setLayout(v_layout(self, *widgets))
def select_file(self): try: from qthelpers.application import application dirname = application.GlobalInfos.last_open_folder except AttributeError: dirname = os.path.expanduser("~") # noinspection PyTypeChecker filename, selected_filter = QtGui.QFileDialog.getOpenFileName( p(self), _("Select a file"), dirname, self.selection_filter, "", 0 ) if filename: self.set_value(filename)
def base_open_document(self, filename=None): if self._base_check_is_modified(): return False if not filename: # noinspection PyCallByClass (filename, selected_filter) = QtGui.QFileDialog.getOpenFileName(p(self), _('Please select a file'), application.GlobalInfos.last_open_folder, self.document_known_extensions) if not filename: return False application.GlobalInfos.last_open_folder = os.path.dirname(filename) if not self.is_valid_document(filename): warning(_('Invalid document'), _('Unable to open document %(filename)s.') % {'filename': os.path.basename(filename)}, only_ok=True) return False self.unload_document() self.current_document_filename = filename self.current_document_is_modified = False self.base_window_title() self.base_add_recent_filename() self.load_document() return True
def __init__(self, color: str = None, parent: QtGui.QWidget = None): self.color = None super().__init__(parent) self.select_button = create_button( _("Choose a color…"), min_size=True, connect=self.select_color, icon="preferences-color" ) self.line_editor = QtGui.QLineEdit(p(self)) self.line_editor.setValidator(self.validator) if not color or not COLOR_RE.match(color): color = None self.set_value(color) layout = h_layout(self, self.select_button, self.line_editor) self.setLayout(layout) self.adjustSize()
def base_save_document_as(self): # noinspection PyCallByClass (filename, selected_filter) = QtGui.QFileDialog.getSaveFileName(p(self), _('Please choose a name'), application.GlobalInfos.last_save_folder, filter=self.document_known_extensions) if not filename: return False application.GlobalInfos.last_save_folder = os.path.dirname(filename) self.current_document_filename = filename if self.save_document(): self.current_document_is_modified = False self.base_window_title() self.base_add_recent_filename() return True return False
def check_base_type(self, value): if value is None or isinstance(value, float): return raise InvalidValueException(_('value must be a float'))
def _base_check_is_modified(self): return self.current_document_is_modified and not warning(_('The document has been modified'), _('The current document has been modified. ' 'Any change will be lost if you close it. ' 'Do you really want to continue?'))
def check_base_type(self, value): try: json.dumps(value) except TypeError: raise InvalidValueException(_('Value must be a list of base JSON types'))
def valid_max(value): if value is not None and len(value) > max_length: raise InvalidValueException(_('list must count at most %(m)d values') % {'m': min_length})
def check_required(value): if value is None: raise InvalidValueException(_('no value provided'))
def valid_max(value): if value is not None and len(value) > max_length: raise InvalidValueException(_('value must be at most %(m)d character long') % {'m': min_length})
def valid_max(value): if value is not None and value > max_value: raise InvalidValueException(_('value must be smaller than %(m)d') % {'m': max_value})
def valid_min(value): if value is not None and value < min_value: raise InvalidValueException(_('value must be greater than %(m)d') % {'m': min_value})
def check_base_type(self, value): if isinstance(value, str): return raise InvalidValueException(_('value must be a string'))
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, p(parent)) ThreadedCalls.__init__(self) self._window_id = next(BaseMainWindow._window_counter) self._docks = {} application.windows[self._window_id] = self # retrieve menus and associated actions from the whole class hierarchy menubar = self.menuBar() defined_qmenus = {} created_action_keys = set() supernames = [x.__name__.rpartition('.')[2] for x in self.__class__.__mro__] supernames.reverse() for menu_name in self.menus: defined_qmenus[menu_name] = menubar.addMenu(menu_name) for cls_name in supernames: for menu_name in registered_menus.get(cls_name, []): # create all top-level menus if menu_name not in defined_qmenus: defined_qmenus[menu_name] = menubar.addMenu(menu_name) supernames.reverse() for cls_name in supernames: for menu_action in registered_menu_actions.get(cls_name, []): if menu_action.uid in created_action_keys: # skip overriden actions (there are already created) continue created_action_keys.add(menu_action.uid) menu_action.create(self, defined_qmenus[menu_action.menu]) # retrieve toolbar actions from the whole class hierarchy self.setUnifiedTitleAndToolBarOnMac(True) defined_qtoolbars = {} created_action_keys = set() for superclass in self.__class__.__mro__: cls_name = superclass.__name__.rpartition('.')[2] if cls_name not in registered_toolbars: continue for toolbar_name in registered_toolbars[cls_name]: # create all top-level menus if toolbar_name not in defined_qtoolbars: if toolbar_name is not None: defined_qtoolbars[toolbar_name] = BaseToolBar(toolbar_name, p(self)) else: defined_qtoolbars[toolbar_name] = BaseToolBar(_('Toolbar'), p(self)) self.addToolBar(defined_qtoolbars[toolbar_name]) for toolbar_action in registered_toolbar_actions[cls_name]: if toolbar_action.uid in created_action_keys: # skip overriden actions (there are already created) continue created_action_keys.add(toolbar_action.uid) toolbar_action.create(self, defined_qtoolbars[toolbar_action.toolbar]) # create all dock widgets for dock_cls in self.docks: """:type dock_cls: type""" if not isinstance(dock_cls, type) or not issubclass(dock_cls, BaseDock): continue dock = dock_cls(parent=self) """:type dock: BaseDock""" self._docks[dock_cls] = dock self.addDockWidget(dock.default_position, dock) menu_name = dock.menu if menu_name is not None: if menu_name not in defined_qmenus: defined_qmenus[menu_name] = menubar.addMenu(menu_name) connect = functools.partial(self._base_swap_dock_display, dock_cls) action = MenuAction(connect, verbose_name=dock.verbose_name, menu=menu_name, shortcut=dock.shortcut) action.create(self, defined_qmenus[menu_name]) # some extra stuff self.setWindowTitle(self.verbose_name) if self.description_icon: self.setWindowIcon(get_icon(self.description_icon)) self.setCentralWidget(self.central_widget()) # restore state and geometry # noinspection PyBroadException self.adjustSize() try: cls_name = self.__class__.__name__ if cls_name in application['GlobalInfos/main_window_geometries']: geometry_str = application['GlobalInfos/main_window_geometries'][cls_name].encode('utf-8') geometry = base64.b64decode(geometry_str) self.restoreGeometry(geometry) if cls_name in application['GlobalInfos/main_window_states']: state_str = application['GlobalInfos/main_window_states'][cls_name].encode('utf-8') state = base64.b64decode(state_str) self.restoreState(state) except ValueError: pass self.raise_()
def check_base_type(self, value): if not isinstance(value, bool): raise InvalidValueException(_('Value must be a boolean'))