예제 #1
0
파일: gui.py 프로젝트: malekcellier/topapp
    def _build_left_dock(self):
        # QTreeView for the project view
        w_project_tree = QDockWidget("Project tree", self)
        w_project_tree.setFloating(False)
        self._docks['project tree'] = w_project_tree
        self.addDockWidget(Qt.LeftDockWidgetArea, w_project_tree)
        # Add the treeview
        treeview = QTreeView(w_project_tree)
        treedelegate = TreeDelegate()
        treeview.setItemDelegate(treedelegate)
        pm = ProjectModel()
        self._models["project"] = pm
        treeview.setModel(pm)
        treeview.expandAll()
        treeview.resizeColumnToContents(0)
        treeview.resizeColumnToContents(1)
        w_project_tree.setWidget(treeview)

        treeview.clicked.connect(self.treeItemClicked)

        # Formatting Editor
        w_properties = QDockWidget("Properties editor", self)
        w_properties.setFloating(False)
        self._docks['properties'] = w_properties
        self.addDockWidget(Qt.LeftDockWidgetArea, w_properties)
        # Create Container widget
        container = QWidget(w_properties)
        # Create a verticallayout in which we put a treeview and a tableview
        v_layout = QVBoxLayout(w_properties)
        # Positions Properties to start with
        # the treeview will contain the widgets for the properties of the selected item in the tree
        treeview = QTreeView(w_properties)
        v_layout.addWidget(treeview)
        v_layout.setStretchFactor(treeview, 2)
        treedelegate = PropertiesTreeDelegate()
        treeview.setItemDelegate(treedelegate)
        pm = PropertiesTreeModel()
        self._models['properties'] = pm
        treeview.setModel(pm)
        treeview.expandAll()
        # The tableview will only contain editable x,y shown as rows
        tableview = QTableView(w_properties)
        v_layout.addWidget(tableview)
        v_layout.setStretchFactor(tableview, 1)
        container.setLayout(v_layout)
        w_properties.setWidget(container)

        # Formatting Editor
        w_formatting = QDockWidget("Formatting editor", self)
        w_formatting.setFloating(False)
        self._docks['formatting'] = w_formatting
        self.addDockWidget(Qt.LeftDockWidgetArea, w_formatting)
예제 #2
0
class ConfigurationManager(SiriusMainWindow):
    """."""

    NAME_COL = None
    CONFIG_TYPE_COL = None

    def __init__(self, model, parent=None):
        """Constructor."""
        super().__init__(parent)
        self._model = model
        self._logger = logging.getLogger(__name__)
        self._logger.setLevel(logging.INFO)
        self._setup_ui()
        self.setWindowTitle("Configuration Manager")

    def _setup_ui(self):
        # self.setGeometry(0, 0, 1600, 900)
        self.main_widget = QFrame()
        self.main_widget.setObjectName('ServConf')
        self.setCentralWidget(self.main_widget)
        self.layout = QGridLayout()
        self.main_widget.setLayout(self.layout)

        # Basic widgets
        self.editor = QTableView()
        self.delete_button = QPushButton('Delete', self)
        self.delete_button.setObjectName('DeleteButton')
        self.rename_button = QPushButton('Rename', self)
        self.rename_button.setObjectName('RenameButton')
        self.d_editor = QTableView()
        self.retrieve_button = QPushButton('Retrieve', self)
        self.retrieve_button.setObjectName('RetrieveButton')
        self.tree = QTreeView(self)
        self.config_type = QComboBox(parent=self)
        self.config_type.setModel(
                ConfigTypeModel(self._model, self.config_type))

        # Tab widgets
        self.tab1 = QWidget()
        self.tab1.layout = QVBoxLayout(self.tab1)
        self.tab2 = QWidget()
        self.tab2.layout = QVBoxLayout(self.tab2)
        self.tab1.layout.addWidget(self.editor)
        hlay = QHBoxLayout()
        hlay.addWidget(self.rename_button)
        hlay.addWidget(self.delete_button)
        self.tab1.layout.addLayout(hlay)
        self.tab2.layout.addWidget(self.d_editor)
        self.tab2.layout.addWidget(self.retrieve_button)

        self.editor_tab = QTabWidget(self)
        self.editor_tab.addTab(self.tab1, 'Configurations')
        self.editor_tab.addTab(self.tab2, 'Discarded Configurations')
        self.config_viewer = QWidget(self)
        self.config_viewer.layout = QVBoxLayout(self.config_viewer)
        self.config_viewer.layout.addWidget(self.editor_tab)
        self.config_viewer.layout.addWidget(self.tree)

        # Header widget
        self.header = QFrame(self)
        self.header.setObjectName('Header')
        self.header.layout = QHBoxLayout(self.header)
        self.header.layout.addStretch()
        self.header.layout.addWidget(
            QLabel('Configuration Database Manager', self.header))
        self.header.layout.addStretch()

        # Sub header with database genral information
        self.sub_header = QFrame(self)
        self.sub_header.setObjectName('SubHeader')
        self.sub_header.layout = QVBoxLayout(self.sub_header)

        self.server_layout = QHBoxLayout()
        self.server_layout.addWidget(QLabel('<b>Server:</b>', self.sub_header))
        self.server_layout.addWidget(QLabel(self._model.url, self.sub_header))
        self.server_layout.addStretch()

        self.size_layout = QHBoxLayout()
        self.size_layout.addWidget(QLabel('<b>DB Size:</b>', self.sub_header))
        try:
            dbsize = self._model.get_dbsize()
            dbsize = '{:.2f} MB'.format(dbsize/(1024*1024))
        except ConfigDBException:
            dbsize = 'Failed to retrieve information'
        self.size_layout.addWidget(QLabel(dbsize, self.sub_header))
        self.size_layout.addStretch()

        self.sub_header.layout.addLayout(self.server_layout)
        self.sub_header.layout.addLayout(self.size_layout)

        # Query form
        self.query_form = QFrame()
        self.query_form.setObjectName("QueryForm")
        self.query_form.layout = QVBoxLayout()
        self.query_form.setLayout(self.query_form.layout)

        self.configs_layout = QGridLayout()
        self.configs_layout.addWidget(QLabel('Configurations:', self), 0, 0)
        self.nr_configs = QLabel(self)
        self.configs_layout.addWidget(self.nr_configs, 0, 1)
        self.configs_layout.addWidget(QLabel('Discarded:', self), 0, 2)
        self.nr_discarded = QLabel(self)
        self.configs_layout.addWidget(self.nr_discarded, 0, 3)

        self.query_form.layout.addWidget(self.config_type)
        self.query_form.layout.addLayout(self.configs_layout)

        # Main widget layout setup
        self.layout.addWidget(self.header, 0, 0, 1, 3)
        self.layout.addWidget(self.sub_header, 1, 0, 1, 2)
        self.layout.addWidget(self.query_form, 2, 0, 1, 2)
        self.layout.addWidget(self.config_viewer, 3, 0, 1, 2)
        self.layout.addWidget(self.tree, 1, 2, 4, 1)
        # self.layout.addWidget(self.delete_button, 4, 0, 1, 2)
        self.layout.setColumnStretch(0, 1)
        self.layout.setColumnStretch(1, 2)
        self.layout.setColumnStretch(2, 2)

        # Set table models and options
        self.editor_model = ConfigDbTableModel('notexist', self._model)
        self.d_editor_model = ConfigDbTableModel('notexist', self._model, True)
        self.editor.setModel(self.editor_model)
        self.editor.setSelectionBehavior(self.editor.SelectRows)
        self.editor.setSortingEnabled(True)
        self.editor.horizontalHeader().setResizeMode(QHeaderView.Stretch)
        self.d_editor.setModel(self.d_editor_model)
        self.d_editor.setSelectionBehavior(self.editor.SelectRows)
        self.d_editor.setSortingEnabled(True)
        self.d_editor.horizontalHeader().setResizeMode(QHeaderView.Stretch)
        self.d_editor.setSelectionMode(self.d_editor.SingleSelection)
        # Set tree model and options
        self.tree_model = JsonTreeModel(None, None, self._model)
        self.tree.setModel(self.tree_model)
        # Delete button
        self.delete_button.setEnabled(False)
        self.rename_button.setEnabled(True)
        self.retrieve_button.setEnabled(False)

        # Signals and slots

        # Tab
        self.editor_tab.currentChanged.connect(self._tab_changed)
        # Fill tables when configuration is selected
        self.config_type.currentTextChanged.connect(self._fill_table)
        # Fill tree when a configuration is selected
        self.editor.selectionModel().selectionChanged.connect(
            lambda x, y: self._fill_tree())
        self.d_editor.selectionModel().selectionChanged.connect(
            lambda x, y: self._fill_tree())
        # Connect database error to slot that show messages
        self.editor_model.connectionError.connect(self._database_error)
        self.d_editor_model.connectionError.connect(self._database_error)
        # Makes tree column extend automatically to show content
        self.tree.expanded.connect(
            lambda idx: self.tree.resizeColumnToContents(idx.column()))
        # Button action
        self.delete_button.pressed.connect(self._remove_configuration)
        self.rename_button.pressed.connect(self._rename_configuration)
        self.retrieve_button.pressed.connect(self._retrieve_configuration)
        # Set constants
        ConfigurationManager.NAME_COL = \
            self.editor_model.horizontalHeader.index('name')
        ConfigurationManager.CONFIG_TYPE_COL = \
            self.editor_model.horizontalHeader.index('config_type')

        self.editor.resizeColumnsToContents()
        self.d_editor.resizeColumnsToContents()

    @Slot(str)
    def _fill_table(self, config_type):
        """Fill table with configuration of `config_type`."""
        leng = len(self._model.find_configs(
            config_type=config_type, discarded=False))
        self.nr_configs.setText(str(leng))
        leng = len(self._model.find_configs(
            config_type=config_type, discarded=True))
        self.nr_discarded.setText(str(leng))

        self.editor_model.setupModelData(config_type)
        self.d_editor_model.setupModelData(config_type)
        self.editor.resizeColumnsToContents()
        self.d_editor.resizeColumnsToContents()
        self.editor_model.sort(2, Qt.DescendingOrder)
        self.d_editor_model.sort(2, Qt.DescendingOrder)

    @Slot()
    def _fill_tree(self):
        if self.editor_tab.currentIndex() == 0:
            configs = list()
            rows = self._get_selected_rows(self.editor)
            # Get selected rows
            for row in rows:
                # Get name and configuration type
                configs.append(self._type_name(row, self.editor_model))
            # Set tree data
            self.tree_model.setupModelData(configs)
            if len(configs) == 1:
                self.delete_button.setEnabled(True)
                self.delete_button.setText(
                    'Delete {} ({})'.format(configs[0][1], configs[0][0]))
                self.rename_button.setEnabled(True)
                self.rename_button.setText(
                    'Rename {} ({})'.format(configs[0][1], configs[0][0]))

            elif len(configs) > 1:
                self.rename_button.setEnabled(False)
                self.rename_button.setText('Rename')
                self.delete_button.setEnabled(True)
                self.delete_button.setText(
                    'Delete {} configurations'.format(len(configs)))
            else:
                self.rename_button.setEnabled(False)
                self.rename_button.setText('Rename')
                self.delete_button.setEnabled(False)
            self.delete_button.style().polish(self.delete_button)
            self.rename_button.style().polish(self.rename_button)
        else:
            try:
                row = self._get_selected_rows(self.d_editor).pop()
            except KeyError:
                self.retrieve_button.setEnabled(False)
                self.retrieve_button.style().polish(self.retrieve_button)
            else:
                config_type, name = self._type_name(row, self.d_editor_model)
                self.tree_model.setupModelData([(config_type, name)])
                self.retrieve_button.setEnabled(True)
                self.retrieve_button.style().polish(self.retrieve_button)
        # self.tree.resizeColumnsToContents()

    @Slot()
    def _remove_configuration(self):
        type = QMessageBox.Question
        title = 'Remove configuration?'
        buttons = QMessageBox.Ok | QMessageBox.Cancel

        # self.editor.selectRow(index.row())
        rows = list(self._get_selected_rows(self.editor))
        message = 'Remove configurations:\n'
        for row in rows:
            config_type = self.editor_model.createIndex(row, 0).data()
            name = self.editor_model.createIndex(row, 1).data()
            message += '- {} ({})\n'.format(name, config_type)

        msg = QMessageBox(type, title, message, buttons).exec_()
        if msg == QMessageBox.Ok:
            rows.sort(reverse=True)
            for row in rows:
                self.editor_model.removeRows(row)

        self.editor.selectionModel().clearSelection()
        self._fill_table(self.config_type.currentText())

    @Slot()
    def _rename_configuration(self):
        # self.editor.selectRow(index.row())
        rows = list(self._get_selected_rows(self.editor))
        if not rows:
            return
        config_type = self.editor_model.createIndex(rows[0], 0).data()
        name = self.editor_model.createIndex(rows[0], 1).data()

        wid = RenameConfigDialog(config_type, self)
        wid.setWindowTitle('Rename: {}'.format(name))
        wid.search_le.setText(name)
        newname, status = wid.exec_()
        if not newname or not status:
            return
        self._model.rename_config(
            name, newname, config_type=config_type)

        self.editor.selectionModel().clearSelection()
        self._fill_table(self.config_type.currentText())

    @Slot()
    def _retrieve_configuration(self):
        type = QMessageBox.Question
        title = 'Retrieve configuration?'
        buttons = QMessageBox.Ok | QMessageBox.Cancel

        try:
            row = self._get_selected_rows(self.d_editor).pop()
        except KeyError:
            pass
        else:
            config_type, name = self._type_name(row, self.d_editor_model)
            name = name[:-37]
            message = \
                'Retrieve configuration {} ({})?'.format(config_type, name)
            msg = QMessageBox(type, title, message, buttons).exec_()
            if msg == QMessageBox.Ok:
                try:
                    self.d_editor_model.removeRows(row)
                except TypeError:
                    self._database_error(
                        'Exception',
                        'Configuration no longer is in the correct format',
                        'retrieve configuration')

        self.editor.selectionModel().clearSelection()
        self._fill_table(self.config_type.currentText())

    @Slot(int)
    def _tab_changed(self, index):
        if index == 0:
            self.editor.selectionModel().clearSelection()
            self.delete_button.setText('Delete')
            self.delete_button.setEnabled(False)
            self.delete_button.style().polish(self.delete_button)
            self.rename_button.setText('Rename')
            self.rename_button.setEnabled(False)
            self.rename_button.style().polish(self.rename_button)
        else:
            self.d_editor.selectionModel().clearSelection()
            self.retrieve_button.setEnabled(False)
            self.retrieve_button.style().polish(self.retrieve_button)
        self.tree_model.setupModelData([])

    @Slot(int, str, str)
    def _database_error(self, code, message, operation):
        type = QMessageBox.Warning
        title = 'Something went wrong'
        msg = '{}: {}, while trying to {}'.format(code, message, operation)
        QMessageBox(type, title, msg).exec_()

    def _get_selected_rows(self, table):
        index_list = table.selectionModel().selectedIndexes()
        return {idx.row() for idx in index_list}

    def _type_name(self, row, model):
        # Return config_type and name given a row and a table model
        return (model.createIndex(row, self.CONFIG_TYPE_COL).data(),
                model.createIndex(row, self.NAME_COL).data())