class MyWidget(QtWidgets.QWidget): @Slot() def run_report(self): dialog = ReportNameDialog() if dialog.exec_(): metadata_fields = {} item_model = self.list.model() for i in range(item_model.rowCount()): qmodel_index = item_model.index(i, 0) index_name = item_model.item(i, 0).text() if item_model.itemData(qmodel_index).get(10) == 2: metadata_fields[index_name] = "" if hasattr(item_model.item(i, 1), "text"): index_value = item_model.item(i, 1).text() if index_name == DOCUMENT_TYPE: if index_value == TYPE_ASSET: index_value = "IO" if index_value == TYPE_FOLDER: index_value = "SO" if index_value == TYPE_ANY: index_value = "" metadata_fields[index_name] = index_value self.progress = QProgressDialog( "Creating Report\n\nPlease Wait...", None, 0, 100) self.progress.setModal(True) self.progress.setWindowTitle("Report") self.progress.setAutoClose(True) self.progress.setAutoReset(True) self.callback = CallBack() worker = Worker(self.client, self.search_value.text(), dialog.report(), metadata_fields, self.callback, dialog.auto_report()) self.callback.change_value.connect(self.progress.setValue) self.callback.max_value.connect(self.progress.setMaximum) self.callback.reset_dialog.connect(self.progress.reset) self.threadpool.start(worker) self.progress.show() def __init__(self): super().__init__() self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(1) self.setWindowTitle("Preservica Solr Reporting") self.windowModality() self.progress = None self.callback = None self.search_label = QtWidgets.QLabel( "Main Search Term (% returns everything)") self.search_value = QtWidgets.QLineEdit("%") self.help_label = QtWidgets.QLabel( "Select from the list of indexed fields below to " "add columns to the output spreadsheet\n\n" "Indexes can have an optional filter term. Filters " "are only applied to selected fields") self.list = QTreeView() self.list.setSelectionBehavior(QAbstractItemView.SelectRows) model = QStandardItemModel() model.setHorizontalHeaderLabels(['Index Name', 'Index Filter Term']) self.list.setModel(model) self.list.setUniformRowHeights(True) self.list.setAlternatingRowColors(True) self.list.setColumnWidth(0, 350) self.list.setColumnWidth(1, 250) self.list.setItemDelegateForColumn( 1, ComboDelegate(self.list, DOCUMENT_TYPE, model)) if not os.path.isfile("credentials.properties"): dialog = PasswordDialog() if dialog.exec_(): self.client = ContentAPI(dialog.username(), dialog.password(), dialog.tenant(), dialog.server()) else: raise SystemExit else: self.client = ContentAPI() for index_name in self.client.indexed_fields(): if index_name == "xip.full_text": continue index = QStandardItem(index_name) index.setCheckable(True) index.setEditable(False) model.appendRow([index]) self.run_report_button = QtWidgets.QPushButton("Run Report") self.run_report_button.released.connect(self.run_report) self.list.setModel(model) self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.search_label) self.layout.addWidget(self.search_value) self.layout.addWidget(self.help_label) self.layout.addWidget(self.list) self.layout.addWidget(self.run_report_button) self.setLayout(self.layout)
class ApplicationPage(QWidget): host: "Host" def __init__(self, host: "Host", **kwargs): super().__init__(**kwargs) self.host = host self.model = AppStoreModel(self, self.host.app_store) self._layout() def _layout(self): layout = QHBoxLayout(self) self.setLayout(layout) self.tree = QTreeView(self) self.tree.setModel(self.model) self.tree.setUniformRowHeights(True) self.tree.setColumnWidth(0, 200) self.tree.setDragEnabled(True) self.tree.setDragDropMode(QAbstractItemView.InternalMove) self.tree.viewport().setAcceptDrops(True) layout.addWidget(self.tree, 1) buttons = QVBoxLayout() buttons.setAlignment(Qt.AlignTop) add_button = QPushButton(QIcon.fromTheme("list-add"), "", self) add_button.setToolTip("Add application") add_button.clicked.connect(self.on_add) buttons.addWidget(add_button) mkdir_button = QPushButton(QIcon.fromTheme("folder-new"), "", self) mkdir_button.setToolTip("Make directory") mkdir_button.clicked.connect(self.on_mkdir) buttons.addWidget(mkdir_button) delete_button = QPushButton(QIcon.fromTheme("list-remove"), "", self) delete_button.setToolTip("Remove selected item") delete_button.clicked.connect(self.on_delete) buttons.addWidget(delete_button) layout.addLayout(buttons) def on_add(self): dialog = QInputDialog(self) dialog.setLabelText("Enter appconfig.json URL") if dialog.exec_() == QInputDialog.Rejected: return app_url = dialog.textValue().strip() self.host.app_store.add_app_ui([app_url]) def on_mkdir(self): dialog = QInputDialog(self) dialog.setLabelText("Directory name") if dialog.exec_() == QInputDialog.Rejected: return dirname = dialog.textValue().strip() if not dirname or "/" in dirname: QMessageBox.critical(self, "Invalid input", "This directory name cannot be used") return self.host.app_store.mkdir(dirname) def on_delete(self): data = self.model.mimeData(self.tree.selectedIndexes()) if not data: return data = json.loads( data.data("application/x-qabstractitemmodeldatalist").data()) if data["type"] == "dir": confirm = QMessageBox.question( self, "Remove folder", f"Remove {data['id']}?\n\nAll applications will be moved to the top level", ) if confirm == QMessageBox.StandardButton.No: return self.host.app_store.rmdir(data["id"]) else: app = self.host.app_store[data["id"]] confirm = QMessageBox.question( self, "Remove application", f"Remove {app['appName']}?", ) if confirm == QMessageBox.StandardButton.No: return self.host.app_store.remove_app(data["id"])
def create_ui(self): """Setup main UI elements, dock widgets, UI-related elements, etc. """ log.debug('Loading UI') # Undo Stack self.undo_stack = QUndoStack(self) self.undo_stack.setUndoLimit(100) # Object navigation history self.obj_history = deque([], config.MAX_OBJ_HISTORY) app = QApplication.instance() base_font = QFont() base_font.fromString(self.prefs['base_font']) app.setFont(base_font) # Object class table widget # classTable = QTableView(self) classTable = classtable.TableView(self) classTable.setObjectName("classTable") classTable.setAlternatingRowColors(True) classTable.setFrameShape(QFrame.StyledPanel) classTable_font = QFont() classTable_font.fromString(self.prefs['class_table_font']) classTable.setFont(classTable_font) fm = classTable.fontMetrics() classTable.setWordWrap(True) classTable.setEditTriggers(QAbstractItemView.EditKeyPressed | QAbstractItemView.DoubleClicked | QAbstractItemView.AnyKeyPressed | QAbstractItemView.SelectedClicked) # classTable.horizontalHeader().setMovable(True) # classTable.verticalHeader().setMovable(False) classTable.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive) classTable.verticalHeader().setSectionResizeMode(QHeaderView.Interactive) classTable.horizontalHeader().setDefaultSectionSize(self.prefs['default_column_width']) classTable.verticalHeader().setDefaultSectionSize(fm.height() + 0) classTable.setSelectionMode(QAbstractItemView.ExtendedSelection) classTable.setContextMenuPolicy(Qt.CustomContextMenu) classTable.customContextMenuRequested.connect(self.custom_table_context_menu) # Create table model and proxy layers for transposing and filtering self.classTableModel = classtable.IDFObjectTableModel(classTable) self.transposeableModel = classtable.TransposeProxyModel(self.classTableModel) self.transposeableModel.setSourceModel(self.classTableModel) self.sortableModel = classtable.SortFilterProxyModel(self.transposeableModel) self.sortableModel.setSourceModel(self.transposeableModel) # Assign model to table (enable sorting FIRST) # table.setSortingEnabled(True) # Disable for now, CRUD actions won't work! classTable.setModel(self.sortableModel) # Connect some signals selection_model = classTable.selectionModel() selection_model.selectionChanged.connect(self.table_selection_changed) scroll_bar = classTable.verticalScrollBar() scroll_bar.valueChanged.connect(self.scroll_changed) # These are currently broken # classTable.horizontalHeader().sectionMoved.connect(self.moveObject) # classTable.verticalHeader().sectionMoved.connect(self.moveObject) # Object class tree widget classTreeDockWidget = QDockWidget("Object Classes and Counts", self) classTreeDockWidget.setObjectName("classTreeDockWidget") classTreeDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) classTree = QTreeView(classTreeDockWidget) classTree.setUniformRowHeights(True) classTree.setAllColumnsShowFocus(True) classTree.setRootIsDecorated(False) classTree.setExpandsOnDoubleClick(True) classTree.setIndentation(15) classTree.setAnimated(True) classTree_font = QFont() classTree_font.fromString(self.prefs['class_tree_font']) classTree.setFont(classTree_font) classTree.setAlternatingRowColors(True) classTree.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel) palette = classTree.palette() palette.setColor(QPalette.Highlight, Qt.darkCyan) classTree.setPalette(palette) class_tree_window = QWidget(classTreeDockWidget) class_tree_dock_layout_v = QVBoxLayout() class_tree_dock_layout_h = QHBoxLayout() class_tree_dock_layout_v.setContentsMargins(0, 8, 0, 0) class_tree_dock_layout_h.setContentsMargins(0, 0, 0, 0) class_tree_filter_edit = QLineEdit(classTreeDockWidget) class_tree_filter_edit.setPlaceholderText("Filter Classes") class_tree_filter_edit.textChanged.connect(self.treeFilterRegExpChanged) class_tree_filter_cancel = QPushButton("Clear", classTreeDockWidget) class_tree_filter_cancel.setMaximumWidth(45) class_tree_filter_cancel.clicked.connect(self.clearTreeFilterClicked) class_tree_dock_layout_h.addWidget(class_tree_filter_edit) class_tree_dock_layout_h.addWidget(class_tree_filter_cancel) class_tree_dock_layout_v.addLayout(class_tree_dock_layout_h) class_tree_dock_layout_v.addWidget(classTree) class_tree_window.setLayout(class_tree_dock_layout_v) classTreeDockWidget.setWidget(class_tree_window) classTreeDockWidget.setContentsMargins(0,0,0,0) # Comments widget commentDockWidget = QDockWidget("Comments", self) commentDockWidget.setObjectName("commentDockWidget") commentDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) commentView = UndoRedoTextEdit(commentDockWidget, self) commentView.setLineWrapMode(QTextEdit.FixedColumnWidth) commentView.setLineWrapColumnOrWidth(499) commentView.setFrameShape(QFrame.StyledPanel) commentView_font = QFont() commentView_font.fromString(self.prefs['comments_font']) commentView.setFont(commentView_font) commentDockWidget.setWidget(commentView) # Info and help widget infoDockWidget = QDockWidget("Info", self) infoDockWidget.setObjectName("infoDockWidget") infoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) infoView = QTextEdit(infoDockWidget) infoView.setFrameShape(QFrame.StyledPanel) infoView.setReadOnly(True) infoDockWidget.setWidget(infoView) # Node list and jump menu widget refDockWidget = QDockWidget("Field References", self) refDockWidget.setObjectName("refDockWidget") refDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) ref_model = reftree.ReferenceTreeModel(None, refDockWidget) refView = QTreeView(refDockWidget) refView.setModel(ref_model) refView.setUniformRowHeights(True) refView.setRootIsDecorated(False) refView.setIndentation(15) refView.setColumnWidth(0, 160) refView.setFrameShape(QFrame.StyledPanel) refDockWidget.setWidget(refView) refView.doubleClicked.connect(self.ref_tree_double_clicked) # Logging and debugging widget logDockWidget = QDockWidget("Log Viewer", self) logDockWidget.setObjectName("logDockWidget") logDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) logView = QPlainTextEdit(logDockWidget) logView.setLineWrapMode(QPlainTextEdit.NoWrap) logView.setReadOnly(True) logView_font = QFont() logView_font.fromString(self.prefs['base_font']) logView.setFont(logView_font) logView.ensureCursorVisible() logDockWidget.setWidget(logView) # Undo view widget undoDockWidget = QDockWidget("Undo History", self) undoDockWidget.setObjectName("undoDockWidget") undoDockWidget.setAllowedAreas(Qt.AllDockWidgetAreas) undoView = QUndoView(self.undo_stack) undoDockWidget.setWidget(undoView) # Define corner docking behaviour self.setDockNestingEnabled(True) self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea) self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea) # Assign main widget and dock widgets to QMainWindow self.setCentralWidget(classTable) self.addDockWidget(Qt.LeftDockWidgetArea, classTreeDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, commentDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, infoDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, refDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget) self.addDockWidget(Qt.RightDockWidgetArea, undoDockWidget) # Store widgets for access by other objects self.classTable = classTable self.commentView = commentView self.infoView = infoView self.classTree = classTree self.logView = logView self.undoView = undoView self.refView = refView self.filterTreeBox = class_tree_filter_edit # Store docks for access by other objects self.commentDockWidget = commentDockWidget self.infoDockWidget = infoDockWidget self.classTreeDockWidget = classTreeDockWidget self.logDockWidget = logDockWidget self.undoDockWidget = undoDockWidget self.refDockWidget = refDockWidget # Perform other UI-related initialization tasks self.center() self.setUnifiedTitleAndToolBarOnMac(True) self.setWindowIcon(QIcon(':/images/logo.png')) # Status bar setup self.statusBar().showMessage('Status: Ready') self.unitsLabel = QLabel() self.unitsLabel.setAlignment(Qt.AlignCenter) self.unitsLabel.setMinimumSize(self.unitsLabel.sizeHint()) self.unitsLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.statusBar().addPermanentWidget(self.unitsLabel) self.pathLabel = QLabel() self.pathLabel.setAlignment(Qt.AlignCenter) self.pathLabel.setMinimumSize(self.pathLabel.sizeHint()) self.pathLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.statusBar().addPermanentWidget(self.pathLabel) self.versionLabel = QLabel() self.versionLabel.setAlignment(Qt.AlignCenter) self.versionLabel.setMinimumSize(self.versionLabel.sizeHint()) self.versionLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.statusBar().addPermanentWidget(self.versionLabel) self.progressBarIDF = QProgressBar() self.progressBarIDF.setAlignment(Qt.AlignCenter) self.progressBarIDF.setMaximumWidth(200) self.statusBar().addPermanentWidget(self.progressBarIDF) self.clipboard = QApplication.instance().clipboard() self.obj_clipboard = [] self.setStyleSheet(""" QToolTip { background-color: gray; color: white; border: black solid 1px } # QMenu { # background-color: rgbf(0.949020, 0.945098, 0.941176); # color: rgb(255,255,255); # } # QMenu::item::selected { # background-color: rgbf(0.949020, 0.945098, 0.941176); # } """)
def import_accounts_dialog(self): self.import_accounts_window.setWindowTitle(_("Import accounts")) self.import_accounts_window.setWindowIcon(self.switcher_logo) self.import_accounts_window.setMinimumWidth(400) layout = QVBoxLayout() self.import_accounts_window.setLayout(layout) text_label = QLabel(_("Select accounts to import")) import_accounts_list = QTreeView() import_button = QPushButton() model = QStandardItemModel() model.setHorizontalHeaderLabels( [_('Login name'), _('Steam name'), _('Steam UID')]) import_accounts_list.setModel(model) import_accounts_list.setUniformRowHeights(True) import_accounts_list.setEditTriggers(QAbstractItemView.NoEditTriggers) import_accounts_list.setSelectionMode(QTreeView.MultiSelection) layout.addWidget(text_label) layout.addWidget(import_accounts_list) layout.addWidget(import_button) installed_accounts = self.switcher.settings.get("users").keys() disabled = [] for uid, steam_user in self.switcher.load_loginusers().items(): account_row = [ QStandardItem(steam_user.get("AccountName")), QStandardItem(steam_user.get("PersonaName")), QStandardItem(uid) ] # account_row[0].setCheckable(True) account_row[2].setEnabled(False) if steam_user.get("AccountName") in installed_accounts: # account_row = [ x.setEnabled(False) for x in account_row] disabled.append(account_row) else: model.appendRow(account_row) # model.appendRows(disabled) #Existing accounts grayed out import_accounts_list.resizeColumnToContents(0) def import_accounts(): selected_accounts = import_accounts_list.selectionModel( ).selectedRows() for account in selected_accounts: self.switcher.add_account(account.data(0)) self.steamapi_refresh() self.import_accounts_window.hide() def button_enabled(): num_selected = len( import_accounts_list.selectionModel().selectedRows()) import_button.setText( _("Import {0} accounts").format(num_selected)) if num_selected: import_button.setEnabled(True) else: import_button.setEnabled(False) button_enabled() import_accounts_list.selectionModel().selectionChanged.connect( button_enabled) import_button.clicked.connect(import_accounts) self.import_accounts_window.show()