def __init__(self, context_model=None, parent=None, family_only=False, read_only=False): super(PackageLineEdit, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.read_only = read_only self.family_only = family_only self.default_style = None pal = self.palette() self.normal_font = self.font() self.placeholder_font = self.font() self.placeholder_font.setItalic(True) self.normal_text_color = pal.color(QtGui.QPalette.Text) self.placeholder_text_color = pal.color(QtGui.QPalette.Disabled, QtGui.QPalette.Text) if not self.read_only: self.setPlaceholderText("enter package") self._update_font() self.completer = QtGui.QCompleter(self) self.completer.setCompletionMode(QtGui.QCompleter.PopupCompletion) self.completions = QtGui.QStringListModel(self.completer) self.completer.setModel(self.completions) self.setCompleter(self.completer) self.textEdited.connect(self._textEdited) self.textChanged.connect(self._textChanged)
def __init__(self, process, command_string, parent=None): config_key = "layout/window/process" super(ProcessDialog, self).__init__(parent) StoreSizeMixin.__init__(self, app.config, config_key) self.setWindowTitle("Running: %s" % command_string) self.proc = process self.ended = False self.output_ended = False self.capture_output = True self.buffer = [] self.bar = QtGui.QProgressBar() self.bar.setRange(0, 0) self.edit = StreamableTextEdit() close_btn = QtGui.QPushButton("Close") btn_pane = create_pane([None, close_btn], True) create_pane([self.bar, self.edit, btn_pane], False, parent_widget=self) self.lock = Lock() self.stdout_thread = Thread(target=self._read_output, args=(self.proc.stdout, )) self.stderr_thread = Thread(target=self._read_output, args=(self.proc.stderr, )) self.timer = QtCore.QTimer() self.timer.setInterval(100) self.timer.timeout.connect(self._update) self.timer.start() self.stdout_thread.start() self.stderr_thread.start() close_btn.clicked.connect(self.close)
def refresh(self): self.clear() self.tool_widgets = {} context = self.context() if not context: return variants = (x for x in context.resolved_packages if x.tools) for variant in sorted(variants, key=lambda x: x.name): if not variant.tools: continue item = QtGui.QTreeWidgetItem(self) item.setIcon(0, self.package_icon) widget = _TreeNode(item, variant.qualified_package_name) widget.clicked.connect(self._clear_selection) self.setItemWidget(item, 1, widget) for tool in sorted(variant.tools): item_ = QtGui.QTreeWidgetItem(item) widget = ToolWidget(context, tool, app.process_tracker) widget.clicked.connect(self._clear_selection) self.setItemWidget(item_, 1, widget) self.tool_widgets[tool] = widget self.resizeColumnToContents(0) self.toolsChanged.emit()
def set_context(self, context): self.clear() self.context = context if self.context is None: return environ = self.context.get_environ() self.setRowCount(len(environ)) for i, (name, value) in enumerate(sorted(environ.items())): item = QtGui.QTableWidgetItem(name) self.setItem(i, 0, item) if self.split_char == ' ': value = '\n'.join(value.strip().split()) elif self.split_char is not None: value = value.strip(self.split_char).replace( self.split_char, '\n') item = QtGui.QTableWidgetItem(value) self.setItem(i, 1, item) self.setHorizontalHeaderLabels(["variable", "value"]) self.resizeRowsToContents() self.resizeColumnsToContents() hh = self.horizontalHeader() hh.setStretchLastSection(True) hh.setVisible(True) self.setEnabled(True)
def __init__(self, pivot_widget, width=240, height=160, parent=None): super(TimeSelecterPopup, self).__init__(parent) self.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised) self.setWindowFlags(QtCore.Qt.Popup) self.seconds = None self.label = QtGui.QLabel("") canvas_frame = QtGui.QFrame() canvas_frame.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken) canvas = Canvas(width, height) layout = QtGui.QVBoxLayout() layout.setSpacing(2) layout.setContentsMargins(2, 2, 2, 2) layout.addWidget(canvas) canvas_frame.setLayout(layout) create_pane([self.label, canvas_frame], False, compact=True, parent_widget=self) self.adjustSize() pt = pivot_widget.rect().topLeft() global_pt = pivot_widget.mapToGlobal(pt) self.move(global_pt - QtCore.QPoint(0, self.height())) canvas.secondsHover.connect(self._secondsHover) canvas.secondsClicked.connect(self._secondsClicked)
def __init__(self, context, tool_name, process_tracker=None, parent=None): super(ToolWidget, self).__init__(parent) self.context = context self.tool_name = tool_name self.process_tracker = process_tracker tool_icon = get_icon_widget("spanner") self.label = QtGui.QLabel(tool_name) self.instances_label = QtGui.QLabel("") self.instances_label.setEnabled(False) update_font(self.instances_label, italic=True) if self.context: self.setCursor(QtCore.Qt.PointingHandCursor) if self.process_tracker: entries = self.get_processes() self.set_instance_count(len(entries)) layout = QtGui.QHBoxLayout() layout.setSpacing(2) layout.setContentsMargins(2, 2, 2, 2) layout.addWidget(tool_icon) layout.addWidget(self.label, 1) layout.addWidget(self.instances_label) self.setLayout(layout)
def __init__(self, context_model=None, reference_variant=None, in_window=False, parent=None): """ Args: reference_variant (`Variant`): Used to show the difference between two variants. in_window (bool): If True, the 'view changelogs' option turns into a checkbox, dropping the 'View in window' option. """ super(VariantVersionsWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.in_window = in_window self.variant = None self.reference_variant = reference_variant self.pending_changelog_packages = None self.label = QtGui.QLabel() self.changelog_edit = ChangelogEdit() self.table = VariantVersionsTable(self.context_model, reference_variant=reference_variant) self.tab = QtGui.QTabWidget() self.tab.addTab(self.table, "list view") self.tab.addTab(self.changelog_edit, "changelogs") self.tab.currentChanged.connect(self._tabIndexChanged) buttons = [None] if self.in_window: close_btn = QtGui.QPushButton("Close") buttons.append(close_btn) close_btn.clicked.connect(self._close_window) else: browse_versions_btn = QtGui.QPushButton("Browse Versions...") browse_versions_btn.clicked.connect(self._browseVersions) buttons.append(browse_versions_btn) window_btn = QtGui.QPushButton("View In Window...") window_btn.clicked.connect(self._view_changelogs_window) buttons.append(window_btn) btn_pane = create_pane(buttons, True, compact=not self.in_window) pane = create_pane([self.label, self.tab, btn_pane], False, compact=True) self.set_main_widget(pane) self.set_loader_swap_delay(300) self.clear()
def __init__(self, context_model=None, parent=None, lock_package=False, package_selectable_callback=None): super(BrowsePackageWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.edit = PackageLineEdit(context_model, family_only=True) if lock_package: self.edit.hide() self.versions_table = PackageVersionsTable(context_model, callback=package_selectable_callback) self.package_tab = PackageTabWidget(versions_tab=False) splitter = ConfiguredSplitter(app.config, "layout/splitter/browse_package") splitter.setOrientation(QtCore.Qt.Vertical) splitter.addWidget(self.versions_table) splitter.addWidget(self.package_tab) if not splitter.apply_saved_layout(): splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 1) layout = QtGui.QVBoxLayout() layout.addWidget(self.edit) layout.addWidget(splitter) self.setLayout(layout) self.edit.focusOutViaKeyPress.connect(self._set_package_name) self.versions_table.itemSelectionChanged.connect(self._set_package)
def get_icon(name, as_qicon=False): """Returns a `QPixmap` containing the given image, or a QIcon if `as_qicon` is True""" filename = name + ".png" icon = icons.get(filename) if not icon: path = os.path.dirname(__file__) path = os.path.join(path, "icons") filepath = os.path.join(path, filename) if not os.path.exists(filepath): filepath = os.path.join(path, "pink.png") icon = QtGui.QPixmap(filepath) icons[filename] = icon return QtGui.QIcon(icon) if as_qicon else icon
def get_icon_widget(filename, tooltip=None): icon = get_icon(filename) icon_label = QtGui.QLabel() icon_label.setPixmap(icon) if tooltip: icon_label.setToolTip(tooltip) return icon_label
def __init__(self, image_file, parent=None): config_key = "layout/window/resolve_graph" super(ImageViewerDialog, self).__init__(parent) StoreSizeMixin.__init__(self, app.config, config_key) self.setWindowTitle("Resolve Graph") self.image_viewer = ImageViewerWidget(image_file) close_btn = QtGui.QPushButton("Close") fit_checkbox = QtGui.QCheckBox("Fit to window") btn_pane = create_pane([None, fit_checkbox, 10, close_btn], True) create_pane([(self.image_viewer, 1), btn_pane], False, parent_widget=self) close_btn.clicked.connect(self.close) fit_checkbox.stateChanged.connect(self.image_viewer.fit_to_window) app.config.attach(fit_checkbox, "resolve/fit_graph")
def __init__(self, context_model, variant, reference_variant=None, hide_locks=False, read_only=False, parent=None): super(VariantCellWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.variant = variant self.reference_variant = reference_variant self.stale = False self.lock_status = None self.lock_icon = None self.hide_locks = hide_locks self.read_only = read_only self.icons = [] # 3-tuples: widget, name, tooltip qname = self.variant.qualified_package_name self.label = QtGui.QLabel(qname) desc = "%s@%s" % (qname, self.variant.wrapped.location) self.label.setToolTip(desc) self.depends_icon = get_icon_widget("depends", "dependent package") self.depends_icon.hide() create_pane([self.label, self.depends_icon, None], True, compact=True, parent_widget=self) self.refresh()
def contextMenuEvent(self, event): if self.read_only or self.hide_locks: return current_lock = self.context_model.get_patch_lock(self.variant.name) menu = QtGui.QMenu(self) consumed_reqs = set() for lock_type in PatchLock: if lock_type == PatchLock.no_lock: desc = lock_type.description else: req = self._get_lock_requirement(lock_type) if lock_type == PatchLock.lock: desc = "Exact version (%s)" % str(req) elif req and req not in consumed_reqs: unit = lock_type.description.split()[0] desc = ("%s version updates only (%s.*)" % (unit.capitalize(), str(req))) consumed_reqs.add(req) else: continue fn = partial(self._set_lock_type, lock_type) action = add_menu_action(menu, desc, fn, lock_type.name) if lock_type == current_lock: action.setEnabled(False) menu.addSeparator() action = add_menu_action(menu, "Remove Lock", self._remove_lock) action.setEnabled(current_lock is not None) menu.exec_(self.mapToGlobal(event.pos())) menu.setParent(None)
def _log(self, msg, color=None): if color: old_color = self.edit.textColor() self.edit.setTextColor(QtGui.QColor(color)) self.edit.append(msg) self.edit.moveCursor(QtGui.QTextCursor.End) if color: self.edit.setTextColor(old_color)
def _set_cell_text(self, row, column, txt): if row >= self.rowCount(): self.setRowCount(row + 1) if self.cellWidget(row, column): self.removeCellWidget(row, column) item = QtGui.QTableWidgetItem(txt) self.setItem(row, column, item)
def _contextChanged(self, flags=0): update_request_columns = {} # apply request and variant widgets to columns if flags & ContextModel.CONTEXT_CHANGED: self.clear() if self.diff_mode: hh = self.horizontalHeader() hh.setResizeMode(2, QtGui.QHeaderView.Fixed) self.setColumnWidth(2, 50) if self.context(): if self.diff_mode: self._apply_request(self.diff_context_model, 4) self._apply_resolve(self.diff_context_model, 3, 4, hide_locks=True, read_only=True) self._apply_request(self.context_model, 0) self._apply_resolve(self.context_model, 1, 3, reference_column_is_variants=True) self._update_comparison_column(2) update_request_columns[4] = self.diff_context_model else: self._apply_request(self.context_model, 0) self._apply_resolve(self.context_model, 1, 0) else: self._set_package_cell(0, 0) update_request_columns[0] = self.context_model if flags & ContextModel.LOCKS_CHANGED and self._show_effective_request: update_request_columns[0] = self.context_model for column, context_model in update_request_columns.iteritems(): self._update_request_column(column, context_model) # set column headers if self.diff_mode: headers = [["current request", False], ["current resolve", False], [self.double_arrow, False], ["reference resolve", True], ["reference request", True]] else: headers = [["request", False], ["resolve", False]] if self.context_model.is_stale(): headers[0][0] += '*' headers[1][0] += " (stale)" headers[1][1] = True for column, (label, italic) in enumerate(headers): item = QtGui.QTableWidgetItem(label) update_font(item, italic=italic) self.setHorizontalHeaderItem(column, item) self.update()
def __init__(self, parent=None): super(ContextEnvironWidget, self).__init__(parent) self.table = ContextEnvironTable() self.split_combo = QtGui.QComboBox() for label, _ in self.split_entries: self.split_combo.addItem(label) label = QtGui.QLabel("split values by:") btn_pane = create_pane([None, label, self.split_combo], True) self.layout = QtGui.QVBoxLayout() self.layout.addWidget(self.table) self.layout.addWidget(btn_pane) self.setLayout(self.layout) self.split_combo.currentIndexChanged.connect(self._set_split_char) app.config.attach(self.split_combo, "split_char")
def __init__(self, graph_str, filepath, parent=None, prune_to=None): super(WriteGraphDialog, self).__init__(parent) self.setWindowTitle("Rendering graph...") self.writer = Writer(graph_str, filepath, prune_to) self.thread = None self._finished = False self.success = False self.busy_cursor = QtGui.QCursor(QtCore.Qt.WaitCursor) self.bar = QtGui.QProgressBar() self.bar.setRange(0, 0) self.cancel_btn = QtGui.QPushButton("Cancel") pane = create_pane([None, self.cancel_btn], True) create_pane([self.bar, pane], False, parent_widget=self) self.writer.graph_written.connect(self._graph_written) self.cancel_btn.clicked.connect(self._cancel)
def __init__(self, image_file, parent=None): super(ImageViewerWidget, self).__init__(parent) self.fit = False self.prev_scale = 1.0 self.scene = QtGui.QGraphicsScene() image = QtGui.QPixmap(image_file) self.image_item = self.scene.addPixmap(image) self.image_item.setTransformationMode(QtCore.Qt.SmoothTransformation) npix = max(image.width(), image.height()) max_scale = npix / 200.0 self.view = GraphicsView(self.scene, max_scale=max_scale) create_pane([self.view], False, parent_widget=self) self.view.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform) self.view.show() self._fit_in_view()
def __init__(self, context_model, package_text=None, parent=None, close_only=False, lock_package=False, package_selectable_callback=None): config_key = "layout/window/browse_package" super(BrowsePackageDialog, self).__init__(parent) StoreSizeMixin.__init__(self, app.config, config_key) self.setWindowTitle("Find Package") self.package = None self.widget = BrowsePackageWidget( context_model, self, lock_package=lock_package, package_selectable_callback=package_selectable_callback) self.ok_btn = QtGui.QPushButton("Ok") buttons = [self.ok_btn] if close_only: close_btn = QtGui.QPushButton("Close") buttons.insert(0, close_btn) close_btn.clicked.connect(self.close) self.ok_btn.hide() else: cancel_btn = QtGui.QPushButton("Cancel") cancel_btn.clicked.connect(self.close) buttons.insert(0, cancel_btn) self.ok_btn.setEnabled(False) btn_pane = create_pane([None] + buttons, True) layout = QtGui.QVBoxLayout() layout.addWidget(self.widget) layout.addWidget(btn_pane) self.setLayout(layout) self.ok_btn.clicked.connect(self._ok) self.widget.packageSelected.connect(self._set_package) self.widget.set_package_text(package_text)
def set_package(self, package): self.clear() if package is not None: self.setRowCount(package.num_variants) for i, variant_ in enumerate(package.iter_variants()): txt = "; ".join(str(x) for x in variant_.requires) item = QtGui.QTableWidgetItem(txt) self.setItem(i, 0, item) self.package = package self.variant = None
def __init__(self, parent=None): super(PackageLoadingWidget, self).__init__(parent) self.main_widget = None self.worker = None self.swap_delay = 0 self.threads = [] self.timer = None label = QtGui.QLabel("Loading Packages...") self.bar = QtGui.QProgressBar() self.loading_widget = create_pane([label, self.bar, None], False, compact=True) create_pane([self.loading_widget], True, compact=True, compact_spacing=0, parent_widget=self)
def __init__(self, context_model=None, parent=None): super(VariantHelpWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.variant = None self.help_1 = None self.help_2 = None self.table_1 = self._create_table() self.table_2 = self._create_table() self.tab = QtGui.QTabWidget() self.tab.addTab(self.table_1, "latest help") self.tab.addTab(self.table_2, "help") self.no_help_label = QtGui.QLabel("No help found.") self.no_help_label.setAlignment(QtCore.Qt.AlignCenter) pane = create_pane([self.no_help_label, self.tab], False, compact=True) self.set_main_widget(pane) self.set_loader_swap_delay(300) self.clear()
def create_toolbutton(entries, parent=None): """Create a toolbutton. Args: entries: List of (label, slot) tuples. Returns: `QtGui.QToolBar`. """ btn = QtGui.QToolButton(parent) menu = QtGui.QMenu() actions = [] for label, slot in entries: action = add_menu_action(menu, label, slot) actions.append(action) btn.setPopupMode(QtGui.QToolButton.MenuButtonPopup) btn.setDefaultAction(actions[0]) btn.setMenu(menu) return btn, actions
def __init__(self, parent=None): super(CellDelegate, self).__init__(parent) pal = self.parent().palette() col = pal.color(QtGui.QPalette.Active, QtGui.QPalette.Button) self.pen = QtGui.QPen(col) self.stale_color = QtGui.QColor("orange") self.stale_pen = QtGui.QPen(self.stale_color) self.stale_pen.setWidth(2) self.pen.setCosmetic(True) self.stale_pen.setCosmetic(True) self.path = QtGui.QPainterPath() self.path.moveTo(0, 0) self.path.cubicTo(0.6, 0, -0.2, 0.5, 1, 0.5) self.path.cubicTo(-0.2, 0.5, 0.6, 1, 0, 1) highlight_color = pal.color(QtGui.QPalette.Highlight) base_color = pal.color(QtGui.QPalette.Base) c1 = interp_color(highlight_color, base_color, 0.3) c2 = interp_color(highlight_color, base_color, 0.8) grad = QtGui.QLinearGradient(0, 1, 0, 0) grad.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode) grad.setColorAt(0, c1) grad.setColorAt(0.95, c2) grad.setColorAt(1, c1) self.highlight_brush = QtGui.QBrush(grad)
def __init__(self, parent=None): super(VariantSummaryWidget, self).__init__(parent) self.variant = None self.label = QtGui.QLabel() self.table = QtGui.QTableWidget(0, 1) self.table.setGridStyle(QtCore.Qt.DotLine) self.table.setFocusPolicy(QtCore.Qt.NoFocus) self.table.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.table.setAlternatingRowColors(True) hh = self.table.horizontalHeader() hh.setStretchLastSection(True) hh.setVisible(False) vh = self.table.verticalHeader() vh.setResizeMode(QtGui.QHeaderView.ResizeToContents) create_pane([self.label, self.table], False, compact=True, parent_widget=self) self.clear()
def __init__(self, context_model=None, attributes=None, parent=None): """ Args: attributes (list of str): Select only certain settings to expose. If None, all settings are exposed. """ super(ContextSettingsWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.schema_keys = set(self.schema_dict.iterkeys()) if attributes: self.schema_keys &= set(attributes) assert self.schema_keys schema_dict = dict((k, v) for k, v in self.schema_dict.iteritems() if k in self.schema_keys) self.schema = Schema(schema_dict) self.edit = QtGui.QTextEdit() self.edit.setStyleSheet("font: 12pt 'Courier'") self.default_btn = QtGui.QPushButton("Set To Defaults") self.discard_btn = QtGui.QPushButton("Discard Changes...") self.apply_btn = QtGui.QPushButton("Apply") self.discard_btn.setEnabled(False) self.apply_btn.setEnabled(False) btn_pane = create_pane([None, self.default_btn, self.discard_btn, self.apply_btn], True) layout = QtGui.QVBoxLayout() layout.addWidget(self.edit) layout.addWidget(btn_pane) self.setLayout(layout) self.apply_btn.clicked.connect(self.apply_changes) self.default_btn.clicked.connect(self.set_defaults) self.discard_btn.clicked.connect(partial(self.discard_changes, True)) self.edit.textChanged.connect(self._settingsChanged) self._update_text()
def _create_table(self): table = QtGui.QTableWidget(0, 1) table.setGridStyle(QtCore.Qt.DotLine) table.setFocusPolicy(QtCore.Qt.NoFocus) table.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) hh = table.horizontalHeader() hh.setStretchLastSection(True) hh.setVisible(False) vh = table.verticalHeader() vh.setVisible(False) return table
def __init__(self, help_, index, parent=None): super(HelpEntryWidget, self).__init__(parent) self.help_ = help_ self.index = index icon = get_icon_widget("help") label = self.help_.sections[self.index][0] label_widget = QtGui.QLabel(label) self.setCursor(QtCore.Qt.PointingHandCursor) create_pane([icon, label_widget, None], True, compact=True, parent_widget=self)
def __init__(self, context_model=None, parent=None): super(ContextDetailsWidget, self).__init__(parent) ContextViewMixin.__init__(self, context_model) self.code_pending = True self.overview_edit = StreamableTextEdit() self.overview_edit.setStyleSheet("font: 9pt 'Courier'") self.graph_btn = ViewGraphButton(context_model) btn_pane = create_pane([None, self.graph_btn], True) overview_pane = create_pane([self.overview_edit, btn_pane], False) self.code_edit = SearchableTextEdit() self.code_edit.setStyleSheet("font: 9pt 'Courier'") self.code_combo = QtGui.QComboBox() # strip out 'sh' and 'csh', they only differ from bash and tcsh in shell # startup behaviour, which is irrelevant here code_types = set(get_shell_types()) - set([system.shell, "sh", "csh"]) code_types = [system.shell] + sorted(code_types) + ["python dict"] for code_type in code_types: self.code_combo.addItem(code_type) label = QtGui.QLabel("Format:") btn_pane = create_pane([None, label, self.code_combo], True) code_pane = create_pane([self.code_edit, btn_pane], False) self.environ_widget = ContextEnvironWidget() self.addTab(overview_pane, "overview") self.addTab(code_pane, "shell code") self.addTab(self.environ_widget, "environment") self.code_combo.currentIndexChanged.connect(self._update_code) self.currentChanged.connect(self._currentTabChanged) self.refresh()