Example #1
0
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)
Example #2
0
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"])
Example #3
0
    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()