Example #1
0
def main():
    # Try to close any existing dialogs so there aren't
    # duplicates open.
    global pyAssetTrackerDialog
    try:
        pyAssetTrackerDialog.ui.close()
    except:
        pass

    # Instantiate the main dialog
    pyAssetTrackerDialog = AssetTrackerDialog()
    ui = pyAssetTrackerDialog.ui

    # Create the source model, but map it to a proxy model to enable
    # sorting, filtering, etc.
    sourceModel = model.Model()
    proxyModel = QSortFilterProxyModel()
    proxyModel.setSourceModel(sourceModel)

    # Assign the proxy model to the tree view
    ui.treeView.setModel(proxyModel)

    # Show the UI
    ui.show()
    ui.setWindowTitle("Better Asset Tracker")
Example #2
0
    def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only
            # allowing this tab to display items where the name starts with
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0) # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash)
            viewselectionmodel = tableView.selectionModel()
            tableView.selectionModel().selectionChanged.connect(self.selectionChanged)

            self.addTab(tableView, group)
Example #3
0
    def __init__(self, parent: QObject, manager: Manager):
        super().__init__(parent)
        self._manager = manager

        self.setWindowTitle("Tasks")

        # Build widget
        self.search_field = QLineEdit(self)
        self.table = _base.ExcelLikeTableView(self)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.button_add = QPushButton("Add", self)
        self.button_remove = QPushButton("Remove", self)
        self.button_import = QPushButton("Import", self)
        self.button_export = QPushButton("Export", self)

        # Build layout
        layout_footer = QHBoxLayout()
        layout_footer.addWidget(self.search_field)
        layout_footer.addWidget(self.button_add)
        layout_footer.addWidget(self.button_remove)
        layout_footer.addWidget(self.button_import)
        layout_footer.addWidget(self.button_export)
        layout_content = QVBoxLayout()
        layout_content.addLayout(layout_footer)
        layout_content.addWidget(self.table)

        main_widget = QWidget()
        main_widget.setLayout(layout_content)
        self.setWidget(main_widget)

        # Configure model
        self.model = TasksListModel(self, self._manager.context)
        model_table = TasksListToTableProxyModel(self)
        model_table.setSourceModel(self.model)
        model_table_proxy = QSortFilterProxyModel(self)
        model_table_proxy.setSourceModel(model_table)

        # Configure view
        self.table.setModel(model_table_proxy)
        self.artist_delegate = ArtistDelegate(self, self._manager)
        self.table.setItemDelegateForColumn(2, self.artist_delegate)
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Connect signals
        for signal, callback in (
            (self.model.dataChanged, self._on_data_changed),
            (self.button_add.pressed, self.add_task),
            (self.button_remove.pressed, self.remove_tasks),
            (self.button_export.pressed, self.export_tasks),
            (self.button_import.pressed, self.import_tasks),
            (
                self.search_field.textChanged,
                model_table_proxy.setFilterWildcard,
            ),
        ):
            signal.connect(callback)
Example #4
0
    def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only
            # allowing this tab to display items where the name starts with
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash)
            viewselectionmodel = tableView.selectionModel()
            tableView.selectionModel().selectionChanged.connect(
                self.selectionChanged)

            self.addTab(tableView, group)
class QFilteredComboBox(QComboBox):
    def __init__(
        self,
        parent=None,
        include_targets=True,
        include_airbases=True,
        include_frontlines=True,
        include_units=True,
        include_enemy=True,
        include_friendly=True,
    ):
        super(QFilteredComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)

        self.include_targets = include_targets
        self.include_airbases = include_airbases
        self.include_frontlines = include_frontlines
        self.include_units = include_units
        self.include_enemy = include_enemy
        self.include_friendly = include_friendly

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())

        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setModel(self, model):
        super(QFilteredComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)
        self.model().sort(0)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(QFilteredComboBox, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
Example #6
0
    def __init__(self, data_list, header, *args):
        QWidget.__init__(self, *args)

        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle('Click on column title to sort')

        # Setup the model and view
        '''tmodel = MyTableModel(self, data_list, header)
        tview = QTableView()
        tview.setModel(tmodel)
        delegate = MyDelegate()
        tview.setItemDelegate(delegate)'''

        # Setup the proxy model for sorting and filtering
        tmodel = MyTableModel(self, data_list, header)
        pmodel = QSortFilterProxyModel()
        pmodel.setSourceModel(tmodel)

        tview = QTableView()
        tview.setModel(pmodel)
        delegate = MyDelegate()
        tview.setItemDelegate(delegate)

        # TableView properties
        tview.resizeColumnsToContents()  # set column width to fit contents
        tview.setShowGrid(False)  # hide gridlines
        #tview.verticalHeader().hide() # row labels
        #tview.horizontalHeader().hide() # column labels

        # Select a single row at a time
        tview.setSelectionBehavior(QTableView.SelectRows)
        tview.setSelectionMode(QTableView.SingleSelection)

        # Enable sorting
        tview.setSortingEnabled(True)

        # Drag and drop reordering using header labels
        '''tview.verticalHeader().setSectionsMovable(True)
        tview.verticalHeader().setDragEnabled(True)
        tview.verticalHeader().setDragDropMode(QAbstractItemView.InternalMove)

        tview.horizontalHeader().setSectionsMovable(True)
        tview.horizontalHeader().setDragEnabled(True)
        tview.horizontalHeader().setDragDropMode(QAbstractItemView.InternalMove)'''

        # Drag and drop reordering using rows
        tview.setDragEnabled(True)
        tview.setAcceptDrops(True)
        tview.setDragDropMode(QTableView.InternalMove)
        tview.setDragDropOverwriteMode(False)

        layout = QVBoxLayout(self)
        layout.addWidget(tview)
        self.setLayout(layout)
Example #7
0
 def __init__(self, blocksModel, filename, parent):
     super().__init__()
     self.setupUi(self)
     self._blocksModel = blocksModel
     if len(filename) > 33:
         windowTitle = filename[:15] + ' ... ' + filename[-15:]
     else:
         windowTitle = filename
     self.setWindowTitle(windowTitle)
     sortModel = QSortFilterProxyModel()
     sortModel.setSourceModel(blocksModel)
     self.blocksTableView.setModel(sortModel)
     self.blocksTableView.resizeColumnsToContents()
     self.blocksTableView.addAction(
         CopySelectedCellsAction(self.blocksTableView))
     self.setParent(parent)
     self.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint)
    def setupTable(self):
        proxyModel = QSortFilterProxyModel(self)
        proxyModel.setSourceModel(self.tableModel)
        proxyModel.setDynamicSortFilter(True)

        self.tableView.setModel(proxyModel)
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.verticalHeader().hide()
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)

        proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
        proxyModel.sort(0, Qt.AscendingOrder)
        viewselectionmodel = self.tableView.selectionModel()
        self.tableView.selectionModel().selectionChanged.connect(self.selectionChanged)
    def setupTable(self):
        proxyModel = QSortFilterProxyModel(self)
        proxyModel.setSourceModel(self.tableModel)
        proxyModel.setDynamicSortFilter(True)

        self.tableView.setModel(proxyModel)
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.verticalHeader().hide()
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)

        proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
        proxyModel.sort(0, Qt.AscendingOrder)
        viewselectionmodel = self.tableView.selectionModel()
        self.tableView.selectionModel().selectionChanged.connect(
            self.selectionChanged)
Example #10
0
    def _update_document_view(self) -> KnechtTreeView:
        """ Update current view to search in and update search tree view accordingly """
        view = self.ui.tree_with_focus()
        self.last_view = view
        self.last_view.destroyed.connect(self._last_view_deleted)

        if view.model().sourceModel() != self.search_view.model().sourceModel(
        ):
            proxy_model = QSortFilterProxyModel()
            proxy_model.setFilterCaseSensitivity(
                self.view_filter_case_sensitivity)
            proxy_model.setSourceModel(view.model().sourceModel())
            proxy_model.setRecursiveFilteringEnabled(True)
            self.search_view.setModel(proxy_model)

            for c in (Kg.REF, Kg.ID):
                self.search_view.hideColumn(c)

            LOGGER.debug('Search Dialog Document View updated.')

        return view
Example #11
0
    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout(self)
        self.splitter = QSplitter(self)
        self.cats = QTreeView(self)
        self.cats.setSortingEnabled(True)
        self.cat_model = RssCategoryModel()
        proxy = QSortFilterProxyModel()
        proxy.setSourceModel(self.cat_model)
        self.cats.setModel(proxy)
        self.splitter.addWidget(self.cats)
        self.t = QTableWidget(0, 4, self)
        self.splitter.addWidget(self.t)
        self.stats = [QLabel('{}'.format(datetime.now())) for _ in range(8)]

        stat: QLabel
        for stat in self.stats:
            stat.setFont(QFont(pointSize=14))
            layout.addWidget(stat, 0, Qt.AlignTop)

        layout.addWidget(self.splitter, 0, Qt.AlignTop)

        self.ds = DataSource()
        self.f_model = ForumsModel(self.ds.get_forums())
        self.forums = QTableView(self)
        self.forums.setModel(self.f_model)
        self.forums.resizeColumnsToContents()
        layout.addWidget(self.forums, 10, Qt.AlignTop)

        self.setLayout(layout)

        self.worker = RssWorker()
        self.worker_thread = QThread()
        self.worker_thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.worker_thread.quit)
        self.worker.moveToThread(self.worker_thread)
        self.worker_thread.start()
        self.worker.processed.connect(self.processed)
        self.worker.current.connect(self.current)
Example #12
0
 def __init__(self):
     QWidget.__init__(self)
     layout = QVBoxLayout(self)
     self.splitter = QSplitter(self)
     self.list = QTreeView(self)
     self.list.setSortingEnabled(True)
     self.model = NewTorrentModel()
     proxy = QSortFilterProxyModel()
     proxy.setSourceModel(self.model)
     self.list.setModel(proxy)
     self.splitter.addWidget(self.list)
     self.t = QTableWidget(0, 4, self)
     self.splitter.addWidget(self.t)
     layout.addWidget(self.splitter)
     self.setLayout(layout)
     self.ds = DataSource()
     self.worker = UpdateTorrentWorker()
     self.worker_thread = QThread()
     self.worker_thread.started.connect(self.worker.run)
     self.worker.finished.connect(self.worker_thread.quit)
     self.worker.moveToThread(self.worker_thread)
     self.worker_thread.start()
     self.worker.processed.connect(self.processed)
Example #13
0
class AdvComboBox(QComboBox):
    """
    Combo with autocomplete
    Found in Internet by Sergei
    """
    def __init__(self, parent=None):
        super(AdvComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)

        # connect signals

        def filter_function(text):
            self.pFilterModel.setFilterFixedString(str(text))

        self.lineEdit().textEdited.connect(filter_function)
        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(str(text))
            self.setCurrentIndex(index)
Example #14
0
class IconColorEditor(QDialog):
    """An editor to let the user select an icon and a color for an object_class.
    """
    def __init__(self, parent):
        """Init class."""
        super().__init__(parent)  # , Qt.Popup)
        icon_size = QSize(32, 32)
        self.icon_mngr = IconListManager(icon_size)
        self.setWindowTitle("Select icon and color")
        self.icon_widget = QWidget(self)
        self.icon_list = QListView(self.icon_widget)
        self.icon_list.setViewMode(QListView.IconMode)
        self.icon_list.setIconSize(icon_size)
        self.icon_list.setResizeMode(QListView.Adjust)
        self.icon_list.setItemDelegate(_IconPainterDelegate(self))
        self.icon_list.setMovement(QListView.Static)
        self.icon_list.setMinimumHeight(400)
        icon_widget_layout = QVBoxLayout(self.icon_widget)
        icon_widget_layout.addWidget(QLabel("Font Awesome icons"))
        self.line_edit = QLineEdit()
        self.line_edit.setPlaceholderText("Search icons for...")
        icon_widget_layout.addWidget(self.line_edit)
        icon_widget_layout.addWidget(self.icon_list)
        self.color_dialog = QColorDialog(self)
        self.color_dialog.setWindowFlags(Qt.Widget)
        self.color_dialog.setOption(QColorDialog.NoButtons, True)
        self.color_dialog.setOption(QColorDialog.DontUseNativeDialog, True)
        self.button_box = QDialogButtonBox(self)
        self.button_box.setStandardButtons(QDialogButtonBox.Cancel
                                           | QDialogButtonBox.Ok)
        top_widget = QWidget(self)
        top_layout = QHBoxLayout(top_widget)
        top_layout.addWidget(self.icon_widget)
        top_layout.addWidget(self.color_dialog)
        layout = QVBoxLayout(self)
        layout.addWidget(top_widget)
        layout.addWidget(self.button_box)
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.icon_mngr.model)
        self.proxy_model.filterAcceptsRow = self._proxy_model_filter_accepts_row
        self.icon_list.setModel(self.proxy_model)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.connect_signals()

    def _proxy_model_filter_accepts_row(self, source_row, source_parent):
        """Overridden method to filter icons according to search terms.
        """
        text = self.line_edit.text()
        if not text:
            return QSortFilterProxyModel.filterAcceptsRow(
                self.proxy_model, source_row, source_parent)
        searchterms = self.icon_mngr.model.index(
            source_row, 0, source_parent).data(Qt.UserRole + 1)
        return any([text in term for term in searchterms])

    def connect_signals(self):
        """Connect signals to slots."""
        self.line_edit.textEdited.connect(self.proxy_model.invalidateFilter)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

    def set_data(self, data):
        icon_code, color_code = interpret_icon_id(data)
        self.icon_mngr.init_model()
        for i in range(self.proxy_model.rowCount()):
            index = self.proxy_model.index(i, 0)
            if index.data(Qt.UserRole) == icon_code:
                self.icon_list.setCurrentIndex(index)
                break
        self.color_dialog.setCurrentColor(QColor(color_code))

    def data(self):
        icon_code = self.icon_list.currentIndex().data(Qt.UserRole)
        color_code = self.color_dialog.currentColor().rgb()
        return make_icon_id(icon_code, color_code)
Example #15
0
class SearchBarEditor(QTableView):
    """A Google-like search bar, implemented as a QTableView with a _CustomLineEditDelegate in the first row.
    """

    data_committed = Signal()

    def __init__(self, parent, tutor=None):
        """Initializes instance.

        Args:
            parent (QWidget): parent widget
            tutor (QWidget, NoneType): another widget used for positioning.
        """
        super().__init__(parent)
        self._tutor = tutor
        self._base_size = QSize()
        self._base_offset = QPoint()
        self._original_text = None
        self._orig_pos = None
        self.first_index = QModelIndex()
        self.model = QStandardItemModel(self)
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.filterAcceptsRow = self._proxy_model_filter_accepts_row
        self.setModel(self.proxy_model)
        self.verticalHeader().hide()
        self.horizontalHeader().hide()
        self.setShowGrid(False)
        self.setMouseTracking(True)
        self.setTabKeyNavigation(False)
        delegate = _CustomLineEditDelegate(self)
        delegate.text_edited.connect(self._handle_delegate_text_edited)
        self.setItemDelegateForRow(0, delegate)

    def set_data(self, current, items):
        """Populates model.

        Args:
            current (str)
            items (Sequence(str))
        """
        item_list = [QStandardItem(current)]
        for item in items:
            qitem = QStandardItem(item)
            item_list.append(qitem)
            qitem.setFlags(~Qt.ItemIsEditable)
        self.model.invisibleRootItem().appendRows(item_list)
        self.first_index = self.proxy_model.mapFromSource(
            self.model.index(0, 0))

    def set_base_size(self, size):
        self._base_size = size

    def set_base_offset(self, offset):
        self._base_offset = offset

    def update_geometry(self):
        """Updates geometry.
        """
        self.horizontalHeader().setDefaultSectionSize(self._base_size.width())
        self.verticalHeader().setDefaultSectionSize(self._base_size.height())
        self._orig_pos = self.pos() + self._base_offset
        if self._tutor:
            self._orig_pos += self._tutor.mapTo(self.parent(),
                                                self._tutor.rect().topLeft())
        self.refit()

    def refit(self):
        self.move(self._orig_pos)
        table_height = self.verticalHeader().length()
        size = QSize(self._base_size.width(),
                     table_height + 2).boundedTo(self.parent().size())
        self.resize(size)
        # Adjust position if widget is outside parent's limits
        bottom_right = self.mapToGlobal(self.rect().bottomRight())
        parent_bottom_right = self.parent().mapToGlobal(
            self.parent().rect().bottomRight())
        x_offset = max(0, bottom_right.x() - parent_bottom_right.x())
        y_offset = max(0, bottom_right.y() - parent_bottom_right.y())
        self.move(self.pos() - QPoint(x_offset, y_offset))

    def data(self):
        return self.first_index.data(Qt.EditRole)

    @Slot("QString")
    def _handle_delegate_text_edited(self, text):
        """Filters model as the first row is being edited."""
        self._original_text = text
        self.proxy_model.setFilterRegExp("^" + text)
        self.proxy_model.setData(self.first_index, text)
        self.refit()

    def _proxy_model_filter_accepts_row(self, source_row, source_parent):
        """Always accept first row.
        """
        if source_row == 0:
            return True
        return QSortFilterProxyModel.filterAcceptsRow(self.proxy_model,
                                                      source_row,
                                                      source_parent)

    def keyPressEvent(self, event):
        """Sets data from current index into first index as the user navigates
        through the table using the up and down keys.
        """
        super().keyPressEvent(event)
        event.accept(
        )  # Important to avoid unhandled behavior when trying to navigate outside view limits
        # Initialize original text. TODO: Is there a better place for this?
        if self._original_text is None:
            self.proxy_model.setData(self.first_index, event.text())
            self._handle_delegate_text_edited(event.text())
        # Set data from current index in model
        if event.key() in (Qt.Key_Up, Qt.Key_Down):
            current = self.currentIndex()
            if current.row() == 0:
                self.proxy_model.setData(self.first_index, self._original_text)
            else:
                self.proxy_model.setData(self.first_index, current.data())

    def currentChanged(self, current, previous):
        super().currentChanged(current, previous)
        self.edit_first_index()

    def edit_first_index(self):
        """Edits first index if valid and not already being edited.
        """
        if not self.first_index.isValid():
            return
        if self.isPersistentEditorOpen(self.first_index):
            return
        self.edit(self.first_index)

    def mouseMoveEvent(self, event):
        """Sets the current index to the one hovered by the mouse."""
        if not self.currentIndex().isValid():
            return
        index = self.indexAt(event.pos())
        if index.row() == 0:
            return
        self.setCurrentIndex(index)

    def mousePressEvent(self, event):
        """Commits data."""
        index = self.indexAt(event.pos())
        if index.row() == 0:
            return
        self.proxy_model.setData(self.first_index, index.data(Qt.EditRole))
        self.data_committed.emit()
Example #16
0
class ABDataFrameView(QTableView):
    """ Base class for showing pandas dataframe objects as tables.
    """
    ALL_FILTER = "All Files (*.*)"
    CSV_FILTER = "CSV (*.csv);; All Files (*.*)"
    TSV_FILTER = "TSV (*.tsv);; All Files (*.*)"
    EXCEL_FILTER = "Excel (*.xlsx);; All Files (*.*)"

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setVerticalScrollMode(QTableView.ScrollPerPixel)
        self.setHorizontalScrollMode(QTableView.ScrollPerPixel)
        self.setWordWrap(True)
        self.setAlternatingRowColors(True)
        self.setSortingEnabled(True)
        self.verticalHeader().setDefaultSectionSize(22)  # row height
        self.verticalHeader().setVisible(True)
        # Use a custom ViewOnly delegate by default.
        # Can be overridden table-wide or per column in child classes.
        self.setItemDelegate(ViewOnlyDelegate(self))

        self.table_name = 'LCA results'
        # Initialize attributes which are set during the `sync` step.
        # Creating (and typing) them here allows PyCharm to see them as
        # valid attributes.
        self.model: Optional[PandasModel] = None
        self.proxy_model: Optional[QSortFilterProxyModel] = None

    def get_max_height(self) -> int:
        return (self.verticalHeader().count())*self.verticalHeader().defaultSectionSize() + \
                 self.horizontalHeader().height() + self.horizontalScrollBar().height() + 5

    def sizeHint(self) -> QSize:
        return QSize(self.width(), self.get_max_height())

    def rowCount(self) -> int:
        return 0 if self.model is None else self.model.rowCount()

    @Slot(name="updateProxyModel")
    def update_proxy_model(self) -> None:
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.setModel(self.proxy_model)

    @Slot(name="resizeView")
    def custom_view_sizing(self) -> None:
        """ Custom table resizing to perform after setting new (proxy) model.
        """
        self.setMaximumHeight(self.get_max_height())

    @Slot(name="exportToClipboard")
    def to_clipboard(self):
        """ Copy dataframe to clipboard
        """
        rows = list(range(self.model.rowCount()))
        cols = list(range(self.model.columnCount()))
        self.model.to_clipboard(rows, cols, include_header=True)

    def savefilepath(self,
                     default_file_name: str,
                     caption: str = None,
                     file_filter: str = None):
        """ Construct and return default path where data is stored

        Uses the application directory for AB
        """
        safe_name = safe_filename(default_file_name, add_hash=False)
        caption = caption or "Choose location to save lca results"
        filepath, _ = QFileDialog.getSaveFileName(
            parent=self,
            caption=caption,
            dir=os.path.join(ab_settings.data_dir, safe_name),
            filter=file_filter or self.ALL_FILTER,
        )
        # getSaveFileName can now weirdly return Path objects.
        return str(filepath) if filepath else filepath

    @Slot(name="exportToCsv")
    def to_csv(self):
        """ Save the dataframe data to a CSV file.
        """
        filepath = self.savefilepath(self.table_name,
                                     file_filter=self.CSV_FILTER)
        if filepath:
            if not filepath.endswith('.csv'):
                filepath += '.csv'
            self.model.to_csv(filepath)

    @Slot(name="exportToExcel")
    def to_excel(self, caption: str = None):
        """ Save the dataframe data to an excel file.
        """
        filepath = self.savefilepath(self.table_name,
                                     caption,
                                     file_filter=self.EXCEL_FILTER)
        if filepath:
            if not filepath.endswith('.xlsx'):
                filepath += '.xlsx'
            self.model.to_excel(filepath)

    @Slot(QKeyEvent, name="copyEvent")
    def keyPressEvent(self, e):
        """ Allow user to copy selected data from the table

        NOTE: by default, the table headers (column names) are also copied.
        """
        if e.modifiers() & Qt.ControlModifier:
            # Should we include headers?
            headers = e.modifiers() & Qt.ShiftModifier
            if e.key() == Qt.Key_C:  # copy
                selection = [
                    self.model.proxy_to_source(p)
                    for p in self.selectedIndexes()
                ]
                rows = [index.row() for index in selection]
                columns = [index.column() for index in selection]
                rows = sorted(set(rows), key=rows.index)
                columns = sorted(set(columns), key=columns.index)
                self.model.to_clipboard(rows, columns, headers)
Example #17
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, close_handler, driver: Driver):
        super().__init__()
        self.setupUi(self)
        self.driver = driver
        self.open_editors = {}
        self.close_handler = close_handler
        self.setWindowTitle("Paragon")
        self.setWindowIcon(QIcon("paragon.ico"))

        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.driver.module_model)
        self.module_list_view.setModel(self.proxy_model)
        self.editors_list_view.setModel(self.driver.services_model)

        self.open_file_model = OpenFilesModel()
        self.file_list_view.setModel(self.open_file_model)

        self.search_field.textChanged.connect(self.proxy_model.setFilterRegExp)
        self.module_list_view.activated.connect(self._on_module_activated)
        self.editors_list_view.activated.connect(self._on_editor_activated)
        self.file_list_view.selectionModel().currentRowChanged.connect(
            self._on_file_list_selection_change)
        self.close_button.clicked.connect(self._on_close_file_pressed)
        self.action_save.triggered.connect(self.save)
        self.action_close.triggered.connect(self.close)
        self.action_quit.triggered.connect(self.quit_application)

        logging.info("Opened main window.")

    def save(self):
        self.driver.save()

    def close(self):
        self.hide()
        self.close_handler()

    @staticmethod
    def quit_application():
        exit(0)

    def _on_file_list_selection_change(self, index):
        self.close_button.setEnabled(
            self.open_file_model.can_close(index.row()))

    def _on_close_file_pressed(self):
        self.open_file_model.close(self.file_list_view.currentIndex().row())

    def _on_module_activated(self, index):
        logging.info("Module " + str(index.row()) + " activated.")

        # First, see if the module is already open.
        module: Module = self.proxy_model.data(index, QtCore.Qt.UserRole)
        if module in self.open_editors:
            logging.info(module.name + " is cached. Reopening editor...")
            self.driver.set_module_used(module)
            self.open_editors[module].show()
            return

        # Next, handle common modules.
        if not module.unique:
            logging.info(module.name +
                         " is a common module. Prompting for a file...")
            target_file = QFileDialog.getOpenFileName(self)
            if not target_file[0]:
                logging.info("No file selected - operation aborted.")
                return
            logging.info("File selected. Opening common module...")
            module = self.driver.handle_open_for_common_module(
                module, target_file[0])

            # Hack to keep the display for the open file model consistent.
            self.open_file_model.beginResetModel()
            self.open_file_model.endResetModel()

        if module.type == "table":
            logging.info("Opening " + module.name + " as a TableModule.")
            editor = SimpleEditor(self.driver, cast(TableModule, module))
        elif module.type == "object":
            logging.info("Opening " + module.name + " as an ObjectModule.")
            editor = ObjectEditor(self.driver, module)
        else:
            logging.error("Attempted to open an unsupported module type.")
            raise NotImplementedError

        self.driver.set_module_used(module)
        self.open_editors[module] = editor
        editor.show()

    def _on_editor_activated(self, index):
        model = self.driver.services_model
        service = model.data(index, QtCore.Qt.UserRole)
        service.editor.show()
Example #18
0
class TreeCard(QDialog):
    def __init__(self, db=0, mode=0):
        super().__init__()

        layout = QGridLayout()
        #self.central_widget.setLayout(layout)
        self.resize(800, self.height())
        self.lb_find = QInvisibleButton('Поиск')
        self.lb_find.setFont(mainfont)
        self.te_find = QLineEdit()
        self.te_find.setFont(mainfont)
        self.pid = 0

        layout.addWidget(self.te_find, 0, 0, 1, 1)
        layout.addWidget(self.lb_find, 0, 0, 1, 1)
        #if mode:
        #   te.setReadOnly(False)
        self.lb_find.clicked.connect(self.button_pressed)
        self.te_find.returnPressed.connect(self.line_edit_return_pressed)

        self.database = db

        self.table = QTableView()  # Создаём таблицу
        self.table.doubleClicked.connect(self.viewPerson)
        #self.table = table

        self.model = TableModel(self.database.get_peoples())
        self.table.setModel(self.model)
        self.table.resizeRowsToContents()
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        #self.table.setSelectionMode(QAbstractItemView.SingleSelection);
        self.model.dataChanged.connect(self.table.update)

        layout.addWidget(self.table)
        self.setLayout(layout)

    def viewPerson(self):
        select = self.table.selectionModel()
        pid_list = [
            index.data()
            for index in self.table.selectionModel().selection().indexes()
            if index.column() == 0
        ]
        if len(pid_list) == 1:
            self.pid = int(pid_list[0])
            print(int(pid_list[0]))
            self.accept()
        return 0

    def button_pressed(self):
        #sender = self.sender()
        self.lb_find.stackUnder(self.te_find)
        self.te_find.setFocus()

    def line_edit_return_pressed(self):
        print(self.te_find.text())

        self.model = TableModel(self.database.get_peoples())

        self.proxy_model = QSortFilterProxyModel(self.model)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setFilterFixedString(self.te_find.text())
        self.proxy_model.setFilterKeyColumn(-1)
        #print(self.proxy_model.filterKeyColumn())

        self.table.setModel(self.proxy_model)
        self.table.update()
        self.table.resizeRowsToContents()

        #sender = self.sender()
        self.te_find.stackUnder(self.lb_find)
        self.lb_find.setFocus()
Example #19
0
class QStringTable(QTableView):
    def __init__(self, parent, selection_callback=None):
        super(QStringTable, self).__init__(parent)

        self._selected = selection_callback
        self._filter = None

        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setShowGrid(False)
        self.verticalHeader().setVisible(False)
        self.verticalHeader().setDefaultSectionSize(24)
        self.setHorizontalScrollMode(self.ScrollPerPixel)

        self._model = QStringModel(None)
        self._proxy = QSortFilterProxyModel(self)
        self._proxy.setSourceModel(self._model)
        self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.setModel(self._proxy)

        self.setSortingEnabled(True)
        self.setSelectionMode(QAbstractItemView.SingleSelection)

        # let the last column (string) fill table width
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)

        self.doubleClicked.connect(self._on_string_selected)

    #
    # Properties
    #

    @property
    def cfg(self):
        return self._model.cfg

    @cfg.setter
    def cfg(self, v):
        self._model.cfg = v
        self.fast_resize()

    @property
    def xrefs(self):
        return self._model.xrefs

    @xrefs.setter
    def xrefs(self, v):
        self._model.xrefs = v

    @property
    def function(self):
        return self._model.function

    @function.setter
    def function(self, v):
        self._model.function = v
        self.fast_resize()

    @property
    def filter_string(self):
        return self._filter

    @filter_string.setter
    def filter_string(self, v):
        self._filter = v
        if isinstance(v, re.Pattern):
            self._proxy.setFilterRegExp(self._filter.pattern)
        else:
            self._proxy.setFilterWildcard(self._filter)
        self._proxy.setFilterKeyColumn(2)

    #
    # Public methods
    #

    def fast_resize(self):
        self.setVisible(False)
        self.resizeColumnsToContents()
        self.setVisible(True)

    #
    # Event handlers
    #

    def _on_string_selected(self, model_index):
        model_index = self._proxy.mapToSource(model_index)
        selected_index = model_index.row()
        if self._model is None:
            return
        if 0 <= selected_index < len(self._model.values):
            selected_item = self._model.values[selected_index]
        else:
            selected_item = None

        if self._selected is not None:
            self._selected(selected_item)
Example #20
0
class PlaylistView(QTableView):

    current_index_changed = Signal(QModelIndex)
    playlist_double_clicked = Signal()
    filtering = Signal(str)
    unfiltered = Signal(str)
    next = Slot(int)
    previous = Slot(int)

    @property
    def mime_Index(self):
        return 'application/x-original_index'

    @property
    def mime_URLS(self):
        return 'application/x-file-urls'

    @property
    def mime_url_count(self):
        return 'application/x-urls-count'

    @property
    def url_delimiter(self):
        return '\n'

    @property
    def open_file_filter(self):
        return '*.mp4 *.m4v *.mov *.mpg *.mpeg *. mp3 *.m4a *.wmv *.aiff *.wav'

    def __init__(self, parent=None):
        super(PlaylistView, self).__init__(parent)

        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.setDragDropMode(QAbstractItemView.DragDrop)
        self.setDropIndicatorShown(True)

        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(PlaylistModel(self))
        self.setModel(self.proxy_model)
        # self.setModel(PlaylistModel())

        self.setShowGrid(False)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.verticalHeader().setDefaultSectionSize(16)
        self.verticalHeader().hide()
        self.horizontalHeader().setMinimumSectionSize(30)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)

        self.current_index = QModelIndex()
        self.previousIndex = QModelIndex()
        self.rubberBand: QRubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.isDragging = False
        self.wasSelected = False

        self.context_menu = QMenu(self)
        self.create_context_menu()

        # self.current_index_changed.connect(self.proxy_model.sourceModel().set_current_index)
        self.current_index_changed.connect(
            self.proxy_model.sourceModel().set_current_index)

    def create_context_menu(self):
        add_file = createAction(self, 'Add File(s)', self.open)
        delete_selected = createAction(self, 'Delete selected',
                                       self.delete_items)
        sort_action = createAction(self, 'Sort',
                                   self.proxy_model.sourceModel().sort)
        pickup_dup_action = createAction(self, 'Filter by same title',
                                         self.filter_same_title)
        stop_filtering_action = createAction(self, 'Stop Filtering',
                                             self.unfilter)
        self.context_menu.addActions([
            add_file, delete_selected, sort_action, pickup_dup_action,
            stop_filtering_action
        ])

    def contextMenuEvent(self, event):
        self.context_menu.exec_(event.globalPos())

    def count(self):
        return self.proxy_model.sourceModel().rowCount()

    def open(self):
        list, _ = QFileDialog.getOpenFileNames(self, 'Open File',
                                               QDir.homePath())

        for path in list:
            if path[-3:] == 'm3u':
                self.load(path)
            else:
                self.add_item(path)

    def open_directory(self):
        directory_url = QFileDialog.getExistingDirectory(
            self, '0Open directory', QDir.homePath())
        dir = QDir(directory_url)
        filters = [
            '*.mp4', '*.m4v', '*.mov', '*.mpg', '*.mpeg', '*.mp3', '*.m4a',
            '*.wmv', '*.wav', '*.aiff'
        ]
        dir.setNameFilters(filters)
        file_list = dir.entryList()

        path = dir.absolutePath() + '/'
        for file in file_list:
            self.add_item(path + file)

    def save(self, path=None):
        """プレイリストを保存する。

        :param file :QFile 出力するようのファイル
        fileが指定されていれば、fileに内容を書き込み、
        指定がなければ、ダイアログで名前を指定してそこにファイルを保存。
        """
        if path is None:
            return

        with open(path, 'wt') as fout:
            for i in range(self.proxy_model.sourceModel().rowCount()):
                index = self.proxy_model.sourceModel().index(i, 0)
                print(self.url(index).toLocalFile(), file=fout)
        return True

    def load(self, path=None):
        """プレイリストを読み込む

        pathが与えられた場合は、そこから読み込み、
        ない場合は、何も読み込まない。"""

        with open(path, 'rt') as fin:
            for line in fin:
                self.add_item(line[:-1])  # 最後の改行文字を取り除く

    def add_item(self, path):
        if is_media(path):
            self.proxy_model.sourceModel().add(QUrl.fromLocalFile(path))
            return True
        return False

    def current_url(self):
        return self.url(self.current_index)

    def current_title(self):
        return self.title(self.current_index)

    def next(self, step=1):
        if self.current_row() + step < self.count():
            self.set_current_index_from_row(self.current_row() + step)
            return self.url(self.current_index)
        else:
            return None

    def previous(self, step=1):
        if self.current_row() - step >= 0:
            self.set_current_index_from_row(self.current_row() - step)
            return self.url(self.current_index)
        else:
            return None

    def selected(self):
        selected_indexes = self.selectedIndexes()
        if len(selected_indexes) > 0:
            return selected_indexes[0]
        else:
            return None

    def current_row(self):
        return self.current_index.row()

    def url(self, index):
        if isinstance(index, int):
            row = index
            if 0 <= row < self.count():
                index = self.proxy_model.sourceModel().index(row, 0)
        if isinstance(index, QModelIndex):
            return self.proxy_model.sourceModel().data(index)
        else:
            return None

    def title(self, index):
        if isinstance(index, int):
            row = index
            if 0 <= row < self.count():
                index = self.proxy_model.sourceModel().index(row, 0)
        if isinstance(index, QModelIndex):
            return self.proxy_model.sourceModel().data(index, Qt.DisplayRole)
        else:
            return None

    def set_current_index_from_row(self, row):
        new_index = self.proxy_model.sourceModel().index(row, 0)
        return self.set_current_index(new_index)

    def set_current_index(self, new_index: QModelIndex):
        self.current_index = new_index
        self.current_index_changed.emit(new_index)

    def deactivate(self):
        self.set_current_index(QModelIndex())

    def auto_resize_header(self):
        """auto resize Header width on table view.
        """
        width = self.viewport().width()
        duration_width = 120
        self.horizontalHeader().resizeSection(0, width - duration_width)
        self.horizontalHeader().resizeSection(1, duration_width)

    def mousePressEvent(self, event):
        """左クリックされたらカーソル下にある要素を選択し、ドラッグを認識するために現在の位置を保存する。
        :param event: QMousePressEvent
        :return: nothing
        """
        self.isDragging = False
        if Qt.LeftButton == event.button():
            self.dragStartPosition = event.pos()

            index = self.indexAt(self.dragStartPosition)
            if index in self.selectedIndexes():
                self.isDragging = True
                self.wasSelected = True
                return

            self.rubberBand.setGeometry(QRect(self.dragStartPosition, QSize()))
            self.rubberBand.show()

        super(PlaylistView, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        """start Drag and prepare for Drop.

        :type event: QMoveEvent
        マウスを動かした嶺がQApplication.startDragDistance()を超えると、Drag開始されたと認識し、
        そのための準備を行う。QMimeDataを使って、データをやりとりする。
        """
        if not (event.buttons() & Qt.LeftButton):
            return
        if (event.pos() - self.dragStartPosition).manhattanLength() \
                < QApplication.startDragDistance():
            return

        if self.isDragging:
            indexes = self.selectedIndexes()
            urls = self.url_list(indexes)

            mimeData = QMimeData()
            # mimeData.setData(self.mime_URLS, convert_to_bytearray(urls))
            mimeData.setUrls(urls)

            file_icon = self.style().standardIcon(QStyle.SP_FileIcon)
            pixmap = file_icon.pixmap(32, 32)

            drag = QDrag(self)
            drag.setMimeData(mimeData)
            drag.setPixmap(pixmap)
            drag.setHotSpot(QPoint(0, 0))

            dropAction = drag.exec_(Qt.CopyAction | Qt.MoveAction,
                                    Qt.CopyAction)
            if dropAction == Qt.MoveAction:
                pass

        else:
            self.rubberBand.setGeometry(
                QRect(self.dragStartPosition, event.pos()).normalized())
            super(PlaylistView, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        '''マウスを離したときにQRubberBandを隠す。
        左クリックをpress と release がだいたい同じ位置であれば、その要素を1つだけ選択する。

        :param event:
        '''
        self.rubberBand.hide()
        if Qt.LeftButton == event.button(
        ) and Qt.NoModifier == event.modifiers():
            if self.indexAt(event.pos()).row() == -1 and \
               self.indexAt(self.dragStartPosition).row() == -1:
                self.clearSelection()
            elif len(self.selectedIndexes()
                     ) / 2 == 1 and self.wasSelected == True:
                self.clearSelection()
            elif (event.pos() - self.dragStartPosition).manhattanLength() \
                 < QApplication.startDragDistance():
                self.setCurrentIndex(self.indexAt(event.pos()))
        self.wasSelected = False
        super(PlaylistView, self).mouseReleaseEvent(event)

    def dragEnterEvent(self, event):
        """ドラッグした状態でWidgetに入った縁で呼ばれる関数。
        :param event: QDragEvent
        :return: nothing

        イベントが発生元と発生しているWidgetが同一の場合はMoveActionにする。それ以外はCopyAction。
        その二つの場合は受け入れられるように、accept()もしくはacceptProposedAction()を呼ぶ。
        """

        if event.mimeData().hasUrls() or event.mimeData().hasFormat(
                self.mime_URLS):
            if event.source() is self:
                event.setDropAction(Qt.MoveAction)
                event.accept()
            else:
                event.acceptProposedAction()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        """ドラッグした状態でWidget内を移動したときに呼ばれる。
        :param event: QDragMoveEvent
        :return: nothing

        ドラッグしている要素の背景の色を変えて、どこにファイルがDropされるかをグラデーションした背景で
        表現する。
        """
        if event.mimeData().hasUrls() or event.mimeData().hasFormat(
                self.mime_URLS):
            self.rubberBand.setGeometry(
                self.rectForDropIndicator(
                    self.index_for_dropping_pos(event.pos())))
            self.rubberBand.show()
            self.previousIndex = self.indexAt(event.pos())
            if event.source() is self:
                event.setDropAction(Qt.MoveAction)
                event.accept()
            else:
                event.acceptProposedAction()
        else:
            event.ignore()

    def dragLeaveEvent(self, event):
        """ドラッグしたままWidget内を出たときにドラッグ下にあった要素の背景色の色を元に戻す。
        :param event: QDragLeaveEvent
        :return: nothing
        """
        self.rubberBand.hide()

    def dropEvent(self, event):
        """Dropされたらデータを取り出して、新たに登録する。
        :param event: QDropEvent
        :return: nothing

        ファイルへのパスと移動前に登録してあった要素のindexを取り出す。
        """
        self.rubberBand.hide()
        if event.mimeData().hasUrls() or event.mimeData().hasFormat(
                self.mime_URLS):
            if event.mimeData().hasUrls():
                urls = event.mimeData().urls()
            else:
                urls = convert_from_bytearray(event.mimeData().data(
                    self.mime_URLS))
            index = self.index_for_dropping_pos(event.pos())
            if event.source() is self:
                self.move_items(self.selectedIndexes(), index)
                event.setDropAction(Qt.MoveAction)
                event.accept()
            else:
                self.add_items(urls)
                event.acceptProposedAction()
        else:
            event.ignore()

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            new_index = self.indexAt(event.pos())
            if not new_index.isValid():
                return
            self.selectRow(new_index.row())
            self.playlist_double_clicked.emit()

    def add_items(self, items: [QUrl], start: int = -1):
        """渡された要素をmodelに追加する。

        :param items: 追加する項目
        :param start: 追加するindexを表す。初期値は-1
        start に −1を渡すと一番後ろに追加する。
        """
        if isinstance(items, QUrl):
            self.proxy_model.sourceModel().add(items)
        elif start == -1:
            for item in items:
                self.proxy_model.sourceModel().add(item)
        else:
            for item, i in items, range(start, len(items)):
                self.proxy_model.sourceModel().add(item, i)

    def delete_items(self):
        """渡されたインデックスを順番に消していく。

        :param indexes: 消すためのインデックス
        """
        indexes = self.selectedIndexes()
        if indexes:
            self.proxy_model.sourceModel().remove_items(indexes)
        else:
            return

    def move_items(self, indexes: [QModelIndex], dest: QModelIndex):
        self.proxy_model.sourceModel().move(indexes, dest.row())

    def filter_same_title(self):
        dup = self.proxy_model.sourceModel().pickup_same_title()
        re = QRegularExpression('|'.join(dup))
        self.proxy_model.setFilterRegularExpression(re)
        self.filtering.emit(' - filtered')

    def unfilter(self):
        self.proxy_model.setFilterWildcard('*')
        self.unfiltered.emit('')

    def index_for_dropping_pos(self, pos: QPoint) -> QModelIndex:
        """dropした場所のindexを返す。ただし、要素の高さ半分より下にある場合は、下の要素を返す。

        :param pos:
        :return: posから導き出されたindex
        挿入や移動のために、要素の間を意識している。
        """
        index = self.indexAt(pos)
        if index.row() < 0:
            new_index = self.proxy_model.sourceModel().index(
                self.proxy_model.sourceModel().rowCount(), 0)
            return new_index

        item_rect = self.visualRect(index)
        pos_in_rect = pos.y() - item_rect.top()
        if pos_in_rect < (item_rect.height() / 2):
            return index
        else:
            return self.proxy_model.sourceModel().index(index.row() + 1, 0)

    def rectForDropIndicator(self, index: QModelIndex) -> QRect:
        """QRubberBand を DropIndicatorとして表示するためのQRectを返す。
        Geometryに渡されるので、表示位置となるようにQRectを作成する。
        幅が表示領域、縦1pixelの棒で表示する。
        """
        item_rect = self.visualRect(index)
        top_left = item_rect.topLeft()
        size = QSize(item_rect.width(), 3)
        return QRect(top_left, size)

    def url_list(self, indexes):
        urls = []
        for index in indexes:
            urls.append(self.proxy_model.sourceModel().data(index))
        return sorted(set(urls), key=urls.index)
class FE14CharacterEditor(Ui_FE14CharacterEditor):
    def __init__(self, is_person=False, parent=None):
        super().__init__(parent)
        self.is_person = is_person
        self.module: TableModule = locator.get_scoped(
            "ModuleService").get_module("Characters")
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.proxy_model.setSourceModel(self.module.entries_model)
        self.characters_list_view.setModel(self.proxy_model)
        self.selection: Optional[PropertyContainer] = None

        self.character_details_form_1 = PropertyForm(
            self.module.element_template, category="character_description_1")
        self.character_details_form_contents_1.setLayout(
            self.character_details_form_1)
        self.character_details_form_2 = PropertyForm(
            self.module.element_template, category="character_description_2")
        self.character_details_form_contents_2.setLayout(
            self.character_details_form_2)
        self.character_details_form_2.fix_editor_width(100)
        self.stats_editor = MergedStatsEditor(
            ["Bases", "Growths", "Modifiers", "Penalties", "Bonuses"])
        self.stats_form = PropertyForm(self.module.element_template,
                                       category="stats")
        self.stats_layout.addWidget(self.stats_editor)
        self.stats_layout.addLayout(self.stats_form)
        self.skills_form = PropertyForm(self.module.element_template,
                                        category="skills",
                                        sort_editors=True)
        self.skills_contents.setLayout(self.skills_form)
        self.flags_editor = MergedFlagsEditor(
            ["Bitflags (1)", "Bitflags (2)", "Bitflags (3)", "Bitflags (4)"],
            self.module.element_template)
        self.flags_editor_2 = MergedFlagsEditor(
            ["Bitflags (5)", "Bitflags (6)", "Bitflags (7)", "Bitflags (8)"],
            self.module.element_template)
        self.misc_form = PropertyForm(self.module.element_template,
                                      category="misc")
        self.misc_layout.addWidget(self.flags_editor)
        self.misc_layout.addWidget(self.flags_editor_2)
        self.misc_layout.addLayout(self.misc_form)
        self.ids_form = PropertyForm(self.module.element_template,
                                     category="ids")
        self.ids_tab.setLayout(self.ids_form)
        self.classes_form = PropertyForm(self.module.element_template,
                                         category="classes",
                                         sort_editors=True)
        self.classes_tab.setLayout(self.classes_form)
        if not self.is_person:
            self.dialogue_tab = DialogueEditor()
            self.supports_tab = QWidget()
            self.supports_layout = QHBoxLayout()
            self.supports_widget = FE14SupportWidget()
            self.supports_scroll = QScrollArea()
            self.supports_scroll_contents = QWidget()
            self.supports_scroll.setWidget(self.supports_scroll_contents)
            self.supports_scroll.setWidgetResizable(True)
            self.supports_layout.addWidget(self.supports_widget)
            self.supports_layout.addWidget(self.supports_scroll)
            self.supports_tab.setLayout(self.supports_layout)
            self.supports_form = PropertyForm(self.module.element_template,
                                              category="supports")
            self.supports_scroll_contents.setLayout(self.supports_form)
            self.tab_widget.addTab(self.supports_tab, "Supports")
            self.tab_widget.addTab(self.dialogue_tab, "Dialogue")

        self.context_menu = QMenu(self)
        self.context_menu.addActions(
            [self.action_add, self.action_remove, self.action_copy_to])
        self.clear_selection_shortcut = QShortcut(QKeySequence.Cancel, self)

        self._install_signals()
        self._clear()

    def set_module(self, module: TableModule):
        self.module = module
        if self.module:
            self.proxy_model.setSourceModel(self.module.entries_model)
        else:
            self.proxy_model.setSourceModel(None)
        self.setEnabled(self.module is not None)
        self._clear()

    def _on_context_menu_requested(self, point: QPoint):
        self.context_menu.exec_(self.characters_list_view.mapToGlobal(point))

    def _install_signals(self):
        self.characters_list_view.selectionModel().currentRowChanged.connect(
            self._update_selection)
        self.characters_list_view.customContextMenuRequested.connect(
            self._on_context_menu_requested)
        self.search_bar.textChanged.connect(self._update_filter)
        self.action_add.triggered.connect(self._on_add_character_triggered)
        self.action_remove.triggered.connect(
            self._on_remove_character_triggered)
        self.action_copy_to.triggered.connect(self._on_copy_to_triggered)
        self.clear_selection_shortcut.activated.connect(self._clear)
        if self.character_details_form_1.editors['Name'] != None:
            self.character_details_form_1.editors[
                'Name'].value_editor.editingFinished.connect(
                    self._update_conversation_widget)

    def _clear(self):
        self.characters_list_view.clearSelection()
        self.characters_list_view.selectionModel().clearCurrentIndex()

    def _update_selection(self, index: QModelIndex):
        self.selection = self.proxy_model.data(index, QtCore.Qt.UserRole)
        self.portraits_tab.update_target(self.selection)
        self.character_details_form_1.update_target(self.selection)
        self.character_details_form_2.update_target(self.selection)
        self.stats_editor.update_target(self.selection)
        self.ids_form.update_target(self.selection)
        self.classes_form.update_target(self.selection)
        self.stats_form.update_target(self.selection)
        self.skills_form.update_target(self.selection)
        self.flags_editor.update_target(self.selection)
        self.flags_editor_2.update_target(self.selection)
        self.misc_form.update_target(self.selection)
        if not self.is_person:
            self.dialogue_tab.update_target(self.selection)
            self.supports_widget.update_target(self.selection)
            self.supports_form.update_target(self.selection)
        if self.selection:
            locator.get_scoped("SpriteService").get_sprite_for_character(
                self.selection, 0)
        self.action_remove.setEnabled(self.selection is not None)
        self.action_copy_to.setEnabled(self.selection is not None)
        self._update_portrait_box()

    def _update_portrait_box(self):
        portrait_service = locator.get_scoped("PortraitService")
        mini_portraits = portrait_service.get_sorted_portraits_for_character(
            self.selection, "bu")
        if mini_portraits:
            _, texture = mini_portraits[0]
            scene = QGraphicsScene()
            scene.addPixmap(QPixmap.fromImage(texture.image()))
            self.portrait_display.setScene(scene)
        else:
            self.portrait_display.setScene(None)

    def _update_filter(self):
        self.proxy_model.setFilterRegExp(self.search_bar.text())

    def _on_add_character_triggered(self):
        model = self.module.entries_model
        model.insertRow(model.rowCount())
        source = self.module.entries[0]
        destination = self.module.entries[-1]
        source.copy_to(destination)
        # Update any present conversation widget with the new obj list
        self._update_conversation_widget()

    def _on_remove_character_triggered(self):
        if self.characters_list_view.currentIndex().isValid():
            model = self.module.entries_model
            model.removeRow(self.characters_list_view.currentIndex().row())
            model.beginResetModel()
            model.endResetModel()
            # Update any present conversation widget with the new obj list
            self._update_conversation_widget()

    def _update_conversation_widget(self):
        for editor in self.supports_widget.service._conversation_editors:
            editor: FE14ConversationEditor
            character_list = list()
            [
                character_list.append(child[1])
                for child in self.module.children()
            ]
            editor.text_area._character_list = character_list

    def _on_copy_to_triggered(self):
        if not self.selection:
            return

        logging.info("Beginning copy to for " + self.module.name)
        choices = []
        for i in range(0, len(self.module.entries)):
            choices.append(
                str(i + 1) + ". " + self.module.entries[i].get_display_name())
        choice = QInputDialog.getItem(self, "Select Destination",
                                      "Destination", choices)
        if choice[1]:
            for i in range(0, len(choices)):
                if choice[0] == choices[i]:
                    self.selection.copy_to(self.module.entries[i])
            # Update any present conversation widget with the new obj list
            self._update_conversation_widget()
        else:
            logging.info("No choice selected for " + self.module.name +
                         " copy to. Aborting.")
Example #22
0
class ArtistsWidget(QDockWidget):
    """Widget displaying a list of artists."""

    artistDeleted = Signal()

    def __init__(self, parent: QObject, manager: Manager):
        super().__init__(parent)
        self.setWindowTitle("Artists")
        self._manager = manager

        # Build widgets
        self.search_field = QLineEdit(self)
        self.table = _base.ExcelLikeTableView(self)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.button_add = QPushButton("Add", self)
        self.button_remove = QPushButton("Remove", self)
        self.button_import = QPushButton("Import", self)
        self.button_export = QPushButton("Export", self)

        # Build layout
        layout_main = QVBoxLayout()
        layout_footer = QHBoxLayout()
        layout_footer.addWidget(self.search_field)
        layout_footer.addWidget(self.button_add)
        layout_footer.addWidget(self.button_remove)
        layout_footer.addWidget(self.button_import)
        layout_footer.addWidget(self.button_export)
        layout_main.addLayout(layout_footer)
        layout_main.addWidget(self.table)

        main_widget = QWidget(self)
        main_widget.setLayout(layout_main)
        self.setWidget(main_widget)

        # Configure model
        self.model = ArtistsListModel(self, self._manager.context)
        self._model_table = ArtistListToTableProxyModel(self)
        self._model_table.setSourceModel(self.model)
        self._model_table_proxy = QSortFilterProxyModel(self)
        self._model_table_proxy.setSourceModel(self._model_table)

        # Configure view
        self.table.setModel(self._model_table_proxy)

        # Connect signals
        for signal, callback in (
            (self.model.dataChanged, self._on_data_changed),
            (self.button_add.pressed, self._on_add),
            (self.button_remove.pressed, self._on_remove),
            (self.button_export.pressed, self._on_export),
            (self.button_import.pressed, self._on_import),
            (
                self.search_field.textChanged,
                self._model_table_proxy.setFilterWildcard,
            ),
        ):
            signal.connect(callback)

    def _on_add(self):
        """Add an artist to the list."""
        with context_reset_model(self.model):
            self._manager.add_artist()

    def _on_remove(self):
        """Remove selected artists from the list."""
        artists = tuple(self._iter_selected())
        if not artists:
            return

        with context_reset_model(self.model):
            self._manager.remove_artists(artists)
        self.artistDeleted.emit()

    def _on_export(self):
        """Export the list of artists to a .csv file."""
        path = show_save_dialog(self, "Export Artist", "CSV (*.csv)")
        if not path:
            return
        self._manager.export_artists(path)

    def _on_import(self):
        """Import the list of artists from a .csv file."""
        path = show_open_dialog(self, "Import Artists", "CSV (*.csv)")
        if not path:
            return

        with context_reset_model(self.model):
            self._manager.import_artists(path)

    def _on_data_changed(self, top_left, bottom_right, roles):  # pylint: disable=unused-argument
        """Called when the internal data changed. Notify if the change affect the solve."""
        if {RoleArtistAvailability, RoleArtistTags} & set(roles):
            self._manager.set_dirty()

    def _iter_selected(self):
        return iter_selected_rows_data(self.table)
Example #23
0
class TdisMainForm(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.setWindowTitle("Родословная")
        self.resize(800, self.height())
        self.distance = 1000

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        layout = QGridLayout()
        self.central_widget.setLayout(layout)

        self.lb_find = QInvisibleButton('Поиск')
        self.lb_find.setFont(mainfont)
        self.te_find = QLineEdit()
        self.te_find.setFont(mainfont)

        layout.addWidget(self.te_find, 0, 0, 1, 1)
        layout.addWidget(self.lb_find, 0, 0, 1, 1)
        #if mode:
        #   te.setReadOnly(False)
        self.lb_find.clicked.connect(self.button_pressed)
        self.te_find.returnPressed.connect(self.line_edit_return_pressed)

        self.table = QTableView()  # Создаём таблицу
        self.table.doubleClicked.connect(self.viewPerson)
        layout.addWidget(self.table)
        self.table.setFocus()
        timer = QTimer(self)
        timer.singleShot(0, self.async_init)

    def async_init(self):
        self.database = AllTables('database/objects')

        self.model = TableModel(self.database.get_peoples())
        self.table.setModel(self.model)
        self.table.resizeRowsToContents()
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.model.dataChanged.connect(self.table.update)

        # Работаем с выпадающим меню
        def openMenu(position):
            menu = QMenu()
            relAction = menu.addAction('Связи')
            menu.addSeparator()
            albAction = menu.addAction('Альбомы')
            menu.addSeparator()
            miniatureAction = menu.addAction('Миниатюра')
            menu.addSeparator()
            viewAction = menu.addAction('Просмотреть')
            addAction = menu.addAction('Добавить')
            editAction = menu.addAction('Редактировать')
            delAction = menu.addAction('Удалить')
            menu.addSeparator()
            drawGraphAction = menu.addAction('Построить дерево')
            menu.addSeparator()
            quitAction = menu.addAction('Выход')
            action = menu.exec_(self.table.mapToGlobal(position))

            if action == viewAction:
                self.viewPerson()

            if action == miniatureAction:
                p = self.get_selected_people()
                print('p = ' + str(p))
                if p is not None:
                    photo_ids = self.database.get_all_photo_ids(p['pid'])
                    path = 0
                    if photo_ids and type(photo_ids) == type(
                        []) and len(photo_ids) > 0:
                        path = self.database.get_photo_path(
                            p['pid'], photo_ids[0])
                    gm = GalleryMiniature(p['pid'], path)
                    gm.exec()

            if action == albAction:
                p = self.get_selected_people()
                if p is not None:
                    self.albuns = AlbumViewer(p['pid'], self.database, 1)
                    self.albuns.show()

            if action == addAction:
                self.personal_card = PersonalCard(
                    self.database.get_people(self.database.add_people({})),
                    self.database, 1)
                self.personal_card.exec_()

                self.line_edit_return_pressed()

            if action == editAction:
                p = self.get_selected_people()
                if p is not None:
                    self.personal_card = PersonalCard(p, self.database, 1)
                    self.personal_card.exec_()

                    self.line_edit_return_pressed()

            if action == delAction:
                res = QMessageBox.question(
                    self, 'ВНИМАНИЕ!!!',
                    "Вы действительно хотите выполнить удаление?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if res == QMessageBox.Yes:
                    select = self.table.selectionModel()
                    if select.hasSelection():
                        id_list = [
                            index.data() for index in
                            self.table.selectionModel().selection().indexes()
                            if index.column() == 0
                        ]
                        print(id_list)
                        self.database.del_people(id_list)
                        self.database.peoples.save()
                        for pid in id_list:
                            print('remove = ' + str(self.model.removeRow(pid)))

                    self.line_edit_return_pressed()

            if action == relAction:
                pid = self.get_selected_pid()
                backup_relations = copy.deepcopy(self.database.relations)
                self.relation_card = RelationCard(pid, self.database, 2)
                if not self.relation_card.exec_():
                    self.database.relations = backup_relations

            if action == drawGraphAction:
                print('draw graph')
                #dialog = MyDialog()
                #dialog.exec_()
                #engine = dialog.engine
                engine = 'dot'
                self.gd = GraphDrawer(self.database, engine)

            if action == quitAction:
                qApp.quit()

        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(openMenu)

    def get_selected_pid(self):
        pid_list = [
            index.data()
            for index in self.table.selectionModel().selection().indexes()
            if index.column() == 0
        ]
        if len(pid_list) == 1:
            return int(pid_list[0])
        return None

    def get_selected_people(self):
        pid_list = [
            index.data()
            for index in self.table.selectionModel().selection().indexes()
            if index.column() == 0
        ]
        if len(pid_list) == 1:
            return self.database.get_people(int(pid_list[0]))
        return None

    def viewPerson(self):
        p = self.get_selected_people()
        if p is not None:
            self.personal_card = PersonalCard(p, self.database, 0)
            self.personal_card.show()

    def button_pressed(self):
        self.lb_find.stackUnder(self.te_find)
        self.te_find.setFocus()

    def line_edit_return_pressed(self):
        print(self.te_find.text())

        self.model = TableModel(self.database.get_peoples())

        self.proxy_model = QSortFilterProxyModel(self.model)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setFilterFixedString(self.te_find.text())
        self.proxy_model.setFilterKeyColumn(-1)

        self.table.setModel(self.proxy_model)
        self.table.update()
        self.table.resizeRowsToContents()

        #sender = self.sender()
        self.te_find.stackUnder(self.lb_find)
        self.lb_find.setFocus()
class LayersList(QWidget):
    '''
    LayerList class which acts as collapsable list.
    '''
    def __init__(self, name, layers, filter, expand=True):
        super().__init__()
        self.setWindowModality(QtCore.Qt.WindowModal)
        self.currently_expanded = True
        self.main_layout = QVBoxLayout()
        self.main_layout.setMargin(0)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        self.expand_button = QPushButton(name)
        self.expand_button.setToolTip(f"List of {name} Layers")
        self.expand_button.setIcon(
            QIcon(os.path.join(PATH, 'LayersList_Down.png')))

        self.layer_list = QListView()
        self.layer_list.setDragEnabled(True)
        self.layer_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.layer_list.setWrapping(False)
        self.layer_list.setViewMode(self.layer_list.ListMode)

        self.container_model = QStandardItemModel()
        self.model = QSortFilterProxyModel()
        self.model.setSourceModel(self.container_model)
        self.model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        #self.model.cas
        filter.textChanged.connect(self.filter_model)

        for l in layers:
            self.container_model.appendRow(
                QStandardItem(
                    QIcon(os.path.join(PATH, 'LayersList_Layer_Icon.png')), l))

        self.layer_list.setModel(self.model)

        self.main_layout.addWidget(self.expand_button, 0, Qt.AlignTop)
        self.main_layout.addWidget(self.layer_list, 0, Qt.AlignTop)
        self.expand_button.clicked.connect(self.expand)

        self.setLayout(self.main_layout)
        self.resized_size = len(layers) * (self.layer_list.sizeHintForRow(0) +
                                           self.layer_list.frameWidth())

        self.layer_list.setMaximumHeight(self.resized_size)
        self.layer_list.setMinimumHeight(self.resized_size)

        self.setMinimumWidth(self.layer_list.frameWidth())

        self.set_styling()

        if not expand:
            self.expand()

    @QtCore.Slot()
    def expand(self):
        if self.currently_expanded:
            self.layer_list.setMinimumHeight(0)
            self.currently_expanded = False
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Up2.png')))
            self.layer_list.setMaximumHeight(0)
        else:
            self.layer_list.setMinimumHeight(self.resized_size)
            self.currently_expanded = True
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Down.png')))
            self.layer_list.setMaximumHeight(self.resized_size)

    def set_styling(self):
        self.setStyleSheet('''
                           background-color:white;
                           ''')
        self.expand_button.setStyleSheet('''
                                        background-color:#d6d2d2;
                                        text-align:left;
                                        ''')

    @QtCore.Slot()
    def filter_model(self, text):
        self.show()
        self.model.setFilterRegExp(QRegExp(text, QtCore.Qt.CaseInsensitive))
        if not self.currently_expanded:
            self.expand()
        if self.model.rowCount() == 0:
            self.hide()
Example #25
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        hlayout = QHBoxLayout()

        layout = QVBoxLayout()

        self.filtert = QLineEdit()
        self.filtert.setPlaceholderText("Search...")
        self.table = QTableView()

        vlayout = QVBoxLayout()
        vlayout.addWidget(self.filtert)
        vlayout.addWidget(self.table)

        # Left/right pane.
        hlayout.addLayout(vlayout)
        hlayout.addLayout(layout)

        form = QFormLayout()

        self.track_id = QSpinBox()
        self.track_id.setDisabled(True)
        self.track_id.setRange(0, 2147483647)
        self.name = QLineEdit()
        self.album = QComboBox()
        self.media_type = QComboBox()
        self.genre = QComboBox()
        self.composer = QLineEdit()

        self.milliseconds = QSpinBox()
        self.milliseconds.setRange(0, 2147483647)
        self.milliseconds.setSingleStep(1)

        self.bytes = QSpinBox()
        self.bytes.setRange(0, 2147483647)
        self.bytes.setSingleStep(1)

        self.unit_price = QDoubleSpinBox()
        self.unit_price.setRange(0, 999)
        self.unit_price.setSingleStep(0.01)
        self.unit_price.setPrefix("$")

        form.addRow(QLabel("Track ID"), self.track_id)
        form.addRow(QLabel("Track name"), self.name)
        form.addRow(QLabel("Composer"), self.composer)
        form.addRow(QLabel("Milliseconds"), self.milliseconds)
        form.addRow(QLabel("Bytes"), self.bytes)
        form.addRow(QLabel("Unit Price"), self.unit_price)

        self.model = QSqlTableModel(db=db)

        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.sort(1, Qt.AscendingOrder)
        self.proxy_model.setFilterKeyColumn(-1)  # all columns
        self.table.setModel(self.proxy_model)

        # Update search when filter changes.
        self.filtert.textChanged.connect(self.proxy_model.setFilterFixedString)

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy_model)

        self.mapper.addMapping(self.track_id, 0)
        self.mapper.addMapping(self.name, 1)
        self.mapper.addMapping(self.composer, 5)
        self.mapper.addMapping(self.milliseconds, 6)
        self.mapper.addMapping(self.bytes, 7)
        self.mapper.addMapping(self.unit_price, 8)

        self.model.setTable("Track")
        self.model.select()

        # Change the mapper selection using the table.
        self.table.selectionModel().currentRowChanged.connect(
            self.mapper.setCurrentModelIndex)

        self.mapper.toFirst()

        # tag::controls[]
        self.setMinimumSize(QSize(800, 400))

        controls = QHBoxLayout()

        prev_rec = QPushButton("Previous")
        prev_rec.clicked.connect(self.mapper.toPrevious)

        next_rec = QPushButton("Next")
        next_rec.clicked.connect(self.mapper.toNext)

        save_rec = QPushButton("Save Changes")
        save_rec.clicked.connect(self.mapper.submit)

        controls.addWidget(prev_rec)
        controls.addWidget(next_rec)
        controls.addWidget(save_rec)

        layout.addLayout(form)
        layout.addLayout(controls)

        widget = QWidget()
        widget.setLayout(hlayout)
        self.setCentralWidget(widget)
Example #26
0
    def setup_p_view(self) -> None:
        """inits stacked widget page widget

        Returns:
            None"""
        self.p_view = QtWidgets.QWidget()
        self.stacked_widget.addWidget(self.p_view)

        self.model = QStandardItemModel(self.p_view)
        self.model.setHorizontalHeaderLabels(labels)

        self.filters = []
        source_model = self.model
        for filter_num in range(7):
            filter = QSortFilterProxyModel()
            filter.setSourceModel(source_model)
            filter.setFilterKeyColumn(filter_num)
            source_model = filter
            self.filters.append(filter)

        delegate = ComboDelegate()
        self.table = QtWidgets.QTableView(self.p_view)
        self.table.setModel(self.filters[-1])
        self.table.setItemDelegateForColumn(2, delegate)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.header = FilterHeader(self.table)
        self.header.set_filter_boxes()
        self.header.setMaximumHeight(50)
        self.table.setHorizontalHeader(self.header)

        self.bt_burger = QPushButton(self.p_view)
        self.bt_burger.setIcon(QIcon("./data/menu2.svg"))
        self.bt_burger.setIconSize(QSize(30, 30))
        self.bt_burger.setToolTip('slide out description')
        l_burger = QLabel("menu", self.p_view)

        self.bt_register_new = QPushButton(self.p_view)
        self.bt_register_new.setIcon(QIcon("./data/add.ico"))
        self.bt_register_new.setIconSize(QSize(30, 30))
        self.bt_register_new.setToolTip("register new")
        l_register_new = QLabel("register new", self.p_view)

        self.bt_delete_column = QPushButton(self.p_view)
        self.bt_delete_column.setIcon(QIcon("./data/remove.ico"))
        self.bt_delete_column.setIconSize(QSize(30, 30))
        self.bt_delete_column.setToolTip(
            "delete columns with min 1 cell selected")
        l_delete = QLabel("delete column", self.p_view)

        self.bt_hide_show_filter = QPushButton(self.p_view)
        self.bt_hide_show_filter.setIcon(QIcon("./data/show_hide.ico"))
        self.bt_hide_show_filter.setIconSize(QSize(30, 30))
        self.bt_hide_show_filter.setToolTip("hide/show filter input")
        l_hide_show = QLabel("hide/show", self.p_view)

        self.left_btn_frame = QFrame(self.p_view)
        self.left_btn_frame.setMaximumWidth(40)
        self.left_btn_frame.setContentsMargins(0, 0, 0, 0)

        self.left_menu_frame = QFrame(self.p_view)
        self.left_menu_frame.setMaximumWidth(0)
        self.left_menu_frame.setContentsMargins(0, 0, 0, 0)

        p_view_layout2 = QtWidgets.QVBoxLayout(self.left_btn_frame)
        p_view_layout2.addWidget(self.bt_burger)
        p_view_layout2.addWidget(self.bt_register_new)
        p_view_layout2.addWidget(self.bt_delete_column)
        p_view_layout2.addWidget(self.bt_hide_show_filter)
        p_view_layout2.setAlignment(Qt.AlignTop)
        p_view_layout2.setContentsMargins(0, 0, 0, 0)

        self.p_view_layout3 = QtWidgets.QVBoxLayout(self.left_menu_frame)
        self.p_view_layout3.addWidget(l_burger)
        self.p_view_layout3.addWidget(l_register_new)
        self.p_view_layout3.addWidget(l_delete)
        self.p_view_layout3.addWidget(l_hide_show)
        self.p_view_layout3.setAlignment(Qt.AlignTop | Qt.AlignCenter)
        self.p_view_layout3.setContentsMargins(0, 0, 0, 0)
        self.p_view_layout3.setSpacing(25)

        p_view_layout = QHBoxLayout(self.p_view)
        p_view_layout.setContentsMargins(0, 0, 0, 0)
        p_view_layout.addWidget(self.left_btn_frame)
        p_view_layout.addWidget(self.left_menu_frame)
        p_view_layout.addWidget(self.table)
        self.p_view.setLayout(p_view_layout)

        self.p_view.addAction(self.action_open)
        self.p_view.addAction(self.action_save)
        self.p_view.addAction(self.action_new)
        self.p_view.addAction(self.action_print)
        self.p_view.addAction(self.action_register)
        self.p_view.addAction(self.action_hide_menu_bar)
Example #27
0
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setDynamicSortFilter(True)

        self.sourceGroupBox = QGroupBox("Original Model")
        self.proxyGroupBox = QGroupBox("Sorted/Filtered Model")

        self.sourceView = QTreeView()
        self.sourceView.setRootIsDecorated(False)
        self.sourceView.setAlternatingRowColors(True)

        self.proxyView = QTreeView()
        self.proxyView.setRootIsDecorated(False)
        self.proxyView.setAlternatingRowColors(True)
        self.proxyView.setModel(self.proxyModel)
        self.proxyView.setSortingEnabled(True)

        self.sortCaseSensitivityCheckBox = QCheckBox("Case sensitive sorting")
        self.filterCaseSensitivityCheckBox = QCheckBox("Case sensitive filter")

        self.filterPatternLineEdit = QLineEdit()
        self.filterPatternLineEdit.setClearButtonEnabled(True)
        self.filterPatternLabel = QLabel("&Filter pattern:")
        self.filterPatternLabel.setBuddy(self.filterPatternLineEdit)

        self.filterSyntaxComboBox = QComboBox()
        self.filterSyntaxComboBox.addItem("Regular expression",
                                          REGULAR_EXPRESSION)
        self.filterSyntaxComboBox.addItem("Wildcard",
                                          WILDCARD)
        self.filterSyntaxComboBox.addItem("Fixed string",
                                          FIXED_STRING)
        self.filterSyntaxLabel = QLabel("Filter &syntax:")
        self.filterSyntaxLabel.setBuddy(self.filterSyntaxComboBox)

        self.filterColumnComboBox = QComboBox()
        self.filterColumnComboBox.addItem("Subject")
        self.filterColumnComboBox.addItem("Sender")
        self.filterColumnComboBox.addItem("Date")
        self.filterColumnLabel = QLabel("Filter &column:")
        self.filterColumnLabel.setBuddy(self.filterColumnComboBox)

        self.filterPatternLineEdit.textChanged.connect(self.filterRegExpChanged)
        self.filterSyntaxComboBox.currentIndexChanged.connect(self.filterRegExpChanged)
        self.filterColumnComboBox.currentIndexChanged.connect(self.filterColumnChanged)
        self.filterCaseSensitivityCheckBox.toggled.connect(self.filterRegExpChanged)
        self.sortCaseSensitivityCheckBox.toggled.connect(self.sortChanged)

        sourceLayout = QHBoxLayout()
        sourceLayout.addWidget(self.sourceView)
        self.sourceGroupBox.setLayout(sourceLayout)

        proxyLayout = QGridLayout()
        proxyLayout.addWidget(self.proxyView, 0, 0, 1, 3)
        proxyLayout.addWidget(self.filterPatternLabel, 1, 0)
        proxyLayout.addWidget(self.filterPatternLineEdit, 1, 1, 1, 2)
        proxyLayout.addWidget(self.filterSyntaxLabel, 2, 0)
        proxyLayout.addWidget(self.filterSyntaxComboBox, 2, 1, 1, 2)
        proxyLayout.addWidget(self.filterColumnLabel, 3, 0)
        proxyLayout.addWidget(self.filterColumnComboBox, 3, 1, 1, 2)
        proxyLayout.addWidget(self.filterCaseSensitivityCheckBox, 4, 0, 1, 2)
        proxyLayout.addWidget(self.sortCaseSensitivityCheckBox, 4, 2)
        self.proxyGroupBox.setLayout(proxyLayout)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.sourceGroupBox)
        mainLayout.addWidget(self.proxyGroupBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Basic Sort/Filter Model")
        self.resize(500, 450)

        self.proxyView.sortByColumn(1, Qt.AscendingOrder)
        self.filterColumnComboBox.setCurrentIndex(1)

        self.filterPatternLineEdit.setText("Andy|Grace")
        self.filterCaseSensitivityCheckBox.setChecked(True)
        self.sortCaseSensitivityCheckBox.setChecked(True)

    def setSourceModel(self, model):
        self.proxyModel.setSourceModel(model)
        self.sourceView.setModel(model)

    def filterRegExpChanged(self):
        syntax_nr = self.filterSyntaxComboBox.currentData()
        pattern = self.filterPatternLineEdit.text()
        if syntax_nr == WILDCARD:
            pattern = QRegularExpression.wildcardToRegularExpression(pattern)
        elif syntax_nr == FIXED_STRING:
            pattern = QRegularExpression.escape(pattern)

        regExp = QRegularExpression(pattern)
        if not self.filterCaseSensitivityCheckBox.isChecked():
            options = regExp.patternOptions()
            options |= QRegularExpression.CaseInsensitiveOption
            regExp.setPatternOptions(options)
        self.proxyModel.setFilterRegularExpression(regExp)

    def filterColumnChanged(self):
        self.proxyModel.setFilterKeyColumn(self.filterColumnComboBox.currentIndex())

    def sortChanged(self):
        if self.sortCaseSensitivityCheckBox.isChecked():
            caseSensitivity = Qt.CaseSensitive
        else:
            caseSensitivity = Qt.CaseInsensitive

        self.proxyModel.setSortCaseSensitivity(caseSensitivity)
Example #28
0
class DictWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__()

        self.view = QTableView()
        self.model = DictModel()
        self.proxy_model = QSortFilterProxyModel()
        self.search_bar = QLineEdit()
        self._show_loading = False

        self.proxy_model.setSourceModel(self.model)

        self.view.setModel(self.proxy_model)
        self.view.setAlternatingRowColors(True)
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.view.setSortingEnabled(True)
        self.view.verticalHeader().hide()

        self.search_bar.textChanged.connect(
            self.proxy_model.setFilterRegularExpression)
        self.search_bar.setVisible(False)

        self._show_search_action = QAction("show search bar")
        self._show_search_action.setCheckable(True)
        self._show_search_action.setShortcutContext(Qt.WidgetShortcut)
        self._show_search_action.setShortcut(QKeySequence.Find)
        self._show_search_action.triggered.connect(self._on_show_search)

        self._close_search_action = QAction()
        self._close_search_action.setShortcut(QKeySequence(Qt.Key_Escape))
        self._close_search_action.setShortcutContext(Qt.WidgetShortcut)
        self._close_search_action.triggered.connect(self._on_close_search)

        self.view.addAction(self._show_search_action)
        self.search_bar.addAction(self._close_search_action)

        _layout = QVBoxLayout()
        _layout.addWidget(self.view)
        _layout.addWidget(self.search_bar)
        _layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(_layout)
        print("init")

    def set_dict(self, data: dict):

        self.model.set_dict(data)

    def _on_show_search(self):
        self.search_bar.setVisible(True)
        self.search_bar.setFocus(Qt.ShortcutFocusReason)

    def _on_close_search(self):
        self.search_bar.hide()
        self.search_bar.clear()
        self.view.setFocus(Qt.ShortcutFocusReason)

    def set_header_visible(self, visible=True):
        self.view.horizontalHeader().setVisible(visible)

    def clear(self):
        self.model.clear()

    def paintEvent(self, event: QPaintEvent):

        if self._show_loading:
            painter = QPainter(self)
            painter.drawText(self.rect(), Qt.AlignCenter,
                             self.tr("Loading ..."))
        else:
            super().paintEvent(event)

    def set_loading(self, show=True):
        self._show_loading = True
        self.view.setVisible(not show)
        self.update()
Example #29
0
class Ui_Main(object):
    def setupUi(self, Main):
        if not Main.objectName():
            Main.setObjectName(u"Main")
        Main.resize(718, 453)
        Main.setMinimumSize(QSize(2018, 1053))

        Main.setStyleSheet(u"")
        self.centralwidget = QWidget(Main)
        self.centralwidget.setObjectName(u"centralwidget")

        self.centralwidget.setMinimumSize(QSize(2018, 1053))

        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.topbar_menu = QFrame(self.centralwidget)
        self.topbar_menu.setObjectName(u"topbar_menu")
        self.topbar_menu.setMinimumSize(QSize(20, 148))
        self.topbar_menu.setMaximumSize(QSize(16777215, 148))
        self.topbar_menu.setCursor(QCursor(Qt.ArrowCursor))
        self.topbar_menu.setStyleSheet(u"background-color: black;")
        self.topbar_menu.setFrameShape(QFrame.WinPanel)
        self.topbar_menu.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_2 = QHBoxLayout(self.topbar_menu)
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.slideMenuFrame = QFrame(self.topbar_menu)
        self.slideMenuFrame.setObjectName(u"slideMenuFrame")
        self.slideMenuFrame.setMinimumSize(QSize(156, 160))
        self.slideMenuFrame.setMaximumSize(QSize(1999, 1999))
        self.slideMenuFrame.setStyleSheet(u"background-color: black;")
        self.slideMenuFrame.setFrameShape(QFrame.StyledPanel)
        self.slideMenuFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_3 = QHBoxLayout(self.slideMenuFrame)
        self.horizontalLayout_3.setSpacing(5)
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
        self.horizontalLayout_3.setContentsMargins(9, 6, 6, 6)
        self.slideMenuButton = QPushButton(self.slideMenuFrame)
        self.slideMenuButton.setObjectName(u"slideMenuButton")
        self.slideMenuButton.setMinimumSize(QSize(153, 100))
        self.slideMenuButton.setMaximumSize(QSize(400, 500))
        self.slideMenuButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.slideMenuButton.setStyleSheet(
            u"QPushButton{\n"
            "	border-radius: 16px;\n"
            "}\n"
            "QPushButton:hover{\n"
            "	background-color: rgb(208, 116, 53);\n"
            "}\n"
            "\n"
            "")
        icon = QIcon()
        icon.addFile(u":/Icons/Icons/Menu.svg", QSize(), QIcon.Normal,
                     QIcon.Off)
        self.slideMenuButton.setIcon(icon)
        self.slideMenuButton.setIconSize(QSize(70, 70))

        self.horizontalLayout_3.addWidget(self.slideMenuButton)

        self.horizontalLayout_2.addWidget(self.slideMenuFrame, 0, Qt.AlignLeft)

        self.titlleFrame = QFrame(self.topbar_menu)
        self.titlleFrame.setObjectName(u"titlleFrame")
        self.titlleFrame.setStyleSheet(u"margin-left: 20%;")
        self.titlleFrame.setFrameShape(QFrame.StyledPanel)
        self.titlleFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_4 = QVBoxLayout(self.titlleFrame)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
        self.verticalLayout_4.setContentsMargins(0, 6, 0, -1)
        self.titleLabel = QLabel(self.titlleFrame)
        self.titleLabel.setObjectName(u"titleLabel")
        font = QFont()
        font.setFamily(u"Bahnschrift")
        font.setPointSize(24)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.titleLabel.setFont(font)
        self.titleLabel.setStyleSheet(u"color: #bd6e38;\n" "")
        self.titleLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_4.addWidget(self.titleLabel)

        self.horizontalLayout_2.addWidget(self.titlleFrame)

        self.window_buttons = QFrame(self.topbar_menu)
        self.window_buttons.setObjectName(u"window_buttons")
        self.window_buttons.setStyleSheet(u"border: none;\n"
                                          "margin-right: 5%;\n"
                                          "")
        self.window_buttons.setFrameShape(QFrame.WinPanel)
        self.window_buttons.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self.window_buttons)
        self.horizontalLayout.setSpacing(2)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 9)
        self.minimazeButton = QPushButton(self.window_buttons)
        self.minimazeButton.setObjectName(u"minimazeButton")
        self.minimazeButton.setMinimumSize(QSize(90, 90))
        self.minimazeButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.minimazeButton.setStyleSheet(
            u"QPushButton:hover{\n"
            "	background-color: rgb(154, 154, 154);\n"
            "}")
        icon1 = QIcon()
        icon1.addFile(u":/Icons/Icons/Minimaze-Icon.svg", QSize(),
                      QIcon.Normal, QIcon.Off)
        self.minimazeButton.setIcon(icon1)
        self.minimazeButton.setIconSize(QSize(41, 41))

        self.horizontalLayout.addWidget(self.minimazeButton)

        self.maximazeButton = QPushButton(self.window_buttons)
        self.maximazeButton.setObjectName(u"maximazeButton")
        self.maximazeButton.setMinimumSize(QSize(95, 95))
        self.maximazeButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.maximazeButton.setStyleSheet(
            u"QPushButton:hover{\n"
            "	background-color: rgb(154, 154, 154);\n"
            "}")
        icon2 = QIcon()
        icon2.addFile(u":/Icons/Icons/MaximazeButton_2.svg", QSize(),
                      QIcon.Normal, QIcon.Off)
        self.maximazeButton.setIcon(icon2)
        self.maximazeButton.setIconSize(QSize(56, 56))

        self.horizontalLayout.addWidget(self.maximazeButton)

        self.closeButton = QPushButton(self.window_buttons)
        self.closeButton.setObjectName(u"closeButton")
        self.closeButton.setMinimumSize(QSize(100, 100))
        self.closeButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.closeButton.setStyleSheet(u"QPushButton:hover{\n"
                                       "	background-color: rgb(170, 0, 0);\n"
                                       "}")
        icon3 = QIcon()
        icon3.addFile(u":/Icons/Icons/WindowCloseButton.svg", QSize(),
                      QIcon.Normal, QIcon.Off)
        self.closeButton.setIcon(icon3)
        self.closeButton.setIconSize(QSize(52, 52))

        self.horizontalLayout.addWidget(self.closeButton)

        self.horizontalLayout_2.addWidget(self.window_buttons, 0,
                                          Qt.AlignRight | Qt.AlignVCenter)

        self.verticalLayout.addWidget(self.topbar_menu)

        self.gridLayout = QGridLayout()
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName(u"gridLayout")
        self.left_side_menu = QFrame(self.centralwidget)
        self.left_side_menu.setObjectName(u"left_side_menu")
        self.left_side_menu.setMinimumSize(QSize(170, 0))
        self.left_side_menu.setMaximumSize(QSize(170, 16777215))
        self.left_side_menu.setStyleSheet(u"QFrame{\n"
                                          "	background-color: black;\n"
                                          "}\n"
                                          "QPushButton{\n"
                                          "	background: transparent;\n"
                                          "	color: white;\n"
                                          "}")
        self.left_side_menu.setFrameShape(QFrame.WinPanel)
        self.left_side_menu.setFrameShadow(QFrame.Raised)
        self.verticalLayout_3 = QVBoxLayout(self.left_side_menu)
        self.verticalLayout_3.setSpacing(0)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.left_menu_buttons = QFrame(self.left_side_menu)
        self.left_menu_buttons.setObjectName(u"left_menu_buttons")
        self.left_menu_buttons.setStyleSheet(u"margin-top: 10%;\n")
        self.left_menu_buttons.setFrameShape(QFrame.StyledPanel)
        self.left_menu_buttons.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.left_menu_buttons)
        self.verticalLayout_2.setSpacing(55)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(0, 28, 0, 20)
        self.homeButton = QPushButton(self.left_menu_buttons)
        self.homeButton.setObjectName(u"homeButton")
        self.homeButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.homeButton.setStyleSheet(u"margin-left: 0%;")
        icon4 = QIcon()
        icon4.addFile(u":/Icons/Icons/New-Home-Icon.svg", QSize(),
                      QIcon.Normal, QIcon.Off)
        self.homeButton.setIcon(icon4)
        self.homeButton.setIconSize(QSize(88, 88))

        self.verticalLayout_2.addWidget(self.homeButton)

        self.listButton = QPushButton(self.left_menu_buttons)
        self.listButton.setObjectName(u"listButton")
        self.listButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.listButton.setStyleSheet(u"margin-left: 0%;")
        icon5 = QIcon()
        icon5.addFile(u":/Icons/Icons/New-Search-Icon.svg", QSize(),
                      QIcon.Normal, QIcon.Off)
        self.listButton.setIcon(icon5)
        self.listButton.setIconSize(QSize(85, 85))

        self.verticalLayout_2.addWidget(self.listButton)

        self.addButton = QPushButton(self.left_menu_buttons)
        self.addButton.setObjectName(u"addButton")
        self.addButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.addButton.setStyleSheet(u"margin-left: 0%;")
        icon6 = QIcon()
        icon6.addFile(u":/Icons/Icons/New_Add.svg", QSize(), QIcon.Normal,
                      QIcon.Off)
        self.addButton.setIcon(icon6)
        self.addButton.setIconSize(QSize(85, 85))

        self.verticalLayout_2.addWidget(self.addButton)

        self.removeButton = QPushButton(self.left_menu_buttons)
        self.removeButton.setObjectName(u"removeButton")
        self.removeButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.removeButton.setStyleSheet(u"margin-left: 0%;")
        icon7 = QIcon()
        icon7.addFile(u":/Icons/Icons/New_Delete.svg", QSize(), QIcon.Normal,
                      QIcon.Off)
        self.removeButton.setIcon(icon7)
        self.removeButton.setIconSize(QSize(85, 85))

        self.verticalLayout_2.addWidget(self.removeButton)

        self.verticalLayout_3.addWidget(self.left_menu_buttons, 0,
                                        Qt.AlignHCenter | Qt.AlignTop)

        self.versionLabel = QLabel(self.left_side_menu)
        self.versionLabel.setMinimumSize(QSize(100, 100))
        self.versionLabel.setObjectName(u"versionLabel")
        self.versionLabel.setStyleSheet(u"color: white;\n"
                                        "margin-left: 10%;\n"
                                        "font-size: 30px;\n")

        self.verticalLayout_3.addWidget(self.versionLabel, 0,
                                        Qt.AlignHCenter | Qt.AlignBottom)

        self.gridLayout.addWidget(self.left_side_menu, 0, 0, 2, 1)

        self.footer = QFrame(self.centralwidget)
        self.footer.setObjectName(u"footer")
        self.footer.setMinimumSize(QSize(0, 40))
        self.footer.setMaximumSize(QSize(16777215, 40))
        self.footer.setStyleSheet(u"background-color: black;\n" "")
        self.footer.setFrameShape(QFrame.WinPanel)
        self.footer.setFrameShadow(QFrame.Raised)
        self.verticalLayout_10 = QVBoxLayout(self.footer)
        self.verticalLayout_10.setObjectName(u"verticalLayout_10")
        self.verticalLayout_10.setContentsMargins(0, 0, 0, 0)
        self.size_grip = QFrame(self.footer)
        self.size_grip.setObjectName(u"size_grip")
        self.size_grip.setMinimumSize(QSize(40, 30))
        self.size_grip.setFrameShape(QFrame.StyledPanel)
        self.size_grip.setFrameShadow(QFrame.Raised)

        self.verticalLayout_10.addWidget(self.size_grip, 0,
                                         Qt.AlignRight | Qt.AlignBottom)

        self.gridLayout.addWidget(self.footer, 1, 1, 1, 1)

        self.content_menu = QFrame(self.centralwidget)
        self.content_menu.setObjectName(u"content_menu")
        self.content_menu.setMinimumSize(QSize(30, 60))
        self.content_menu.setStyleSheet(u"background-color: #333;")
        self.content_menu.setFrameShape(QFrame.WinPanel)
        self.content_menu.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_4 = QHBoxLayout(self.content_menu)
        self.horizontalLayout_4.setSpacing(0)
        self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.containerPages = QStackedWidget(self.content_menu)
        self.containerPages.setObjectName(u"containerPages")
        font1 = QFont()
        font1.setFamily(u"Bahnschrift")
        font1.setPointSize(30)
        self.containerPages.setFont(font1)
        self.containerPages.setStyleSheet(u"background: #333;\n"
                                          "QcheckBox{\n"
                                          "	font: 12pt \"Bahnschript\";\n"
                                          "	font-style: italic;\n"
                                          "	color: white;\n"
                                          "}")
        self.HomeWWidget = QWidget()
        self.HomeWWidget.setObjectName(u"HomeWWidget")
        self.HomeWWidget.setStyleSheet(
            u"border-image: url(:/Icons/Icons/new_background.svg)")
        self.verticalLayout_11 = QVBoxLayout(self.HomeWWidget)
        self.verticalLayout_11.setObjectName(u"verticalLayout_11")
        self.verticalLayout_11.setContentsMargins(0, 0, 0, 0)
        self.homeTitleLabel = QLabel(self.HomeWWidget)
        self.homeTitleLabel.setObjectName(u"homeTitleLabel")
        font2 = QFont()
        font2.setFamily(u"Bahnschrift")
        font2.setPointSize(60)
        font2.setBold(True)
        font2.setWeight(75)
        self.homeTitleLabel.setFont(font2)
        self.homeTitleLabel.setStyleSheet(u"border-image: none;\n"
                                          "background: transparent;\n"
                                          "color: white;")
        self.homeTitleLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_11.addWidget(self.homeTitleLabel)

        self.homeintroLabel = QLabel(self.HomeWWidget)
        self.homeintroLabel.setObjectName(u"homeintroLabel")
        font3 = QFont()
        font3.setFamily(u"Bahnschrift")
        font3.setPointSize(12)
        self.homeintroLabel.setFont(font3)
        self.homeintroLabel.setStyleSheet(u"border-image: none;\n"
                                          "background: transparent;\n"
                                          "color: white;\n")
        self.homeintroLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_11.addWidget(self.homeintroLabel, 0,
                                         Qt.AlignHCenter | Qt.AlignTop)

        self.containerPages.addWidget(self.HomeWWidget)
        self.SearchWidget = QWidget()
        self.SearchWidget.setObjectName(u"SearchWidget")
        self.verticalLayout_9 = QVBoxLayout(self.SearchWidget)
        self.verticalLayout_9.setSpacing(7)
        self.verticalLayout_9.setObjectName(u"verticalLayout_9")
        self.verticalLayout_9.setContentsMargins(5, 0, 5, 5)
        self.searchbarFrame = QFrame(self.SearchWidget)
        self.searchbarFrame.setObjectName(u"searchbarFrame")
        self.searchbarFrame.setFrameShape(QFrame.StyledPanel)
        self.searchbarFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_8 = QHBoxLayout(self.searchbarFrame)
        self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
        self.searchbarLineEdit = QLineEdit(self.searchbarFrame)
        self.searchbarLineEdit.setObjectName(u"searchbarLineEdit")
        self.searchbarLineEdit.setStyleSheet(u"color: white;\n"
                                             "border: 1px solid white;\n"
                                             "border-radius: 30%;\n"
                                             "font-size: 45px;\n")
        self.searchbarLineEdit.setMinimumHeight(70)
        self.searchbarLineEdit.setPlaceholderText("Căutați aici...")
        self.searchbarLineEdit.setAlignment(Qt.AlignCenter)

        self.horizontalLayout_8.addWidget(self.searchbarLineEdit)

        self.verticalLayout_9.addWidget(self.searchbarFrame)

        self.FilterCheckBoxFrame = QFrame(self.SearchWidget)
        self.FilterCheckBoxFrame.setObjectName(u"FilterCheckBoxFrame")
        self.FilterCheckBoxFrame.setStyleSheet(u"QRadioButton{\n"
                                               "	font: 9pt \"Bahnschript\";\n"
                                               "	font-style: italic;\n"
                                               "	color: white;\n"
                                               "}")
        self.FilterCheckBoxFrame.setFrameShape(QFrame.StyledPanel)
        self.FilterCheckBoxFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_9 = QHBoxLayout(self.FilterCheckBoxFrame)
        self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")

        self.recentDateOrderRadioButton = QRadioButton(
            self.FilterCheckBoxFrame)
        self.recentDateOrderRadioButton.setObjectName(
            u"recentDateOrderRadioButton")

        self.horizontalLayout_9.addWidget(self.recentDateOrderRadioButton, 0,
                                          Qt.AlignHCenter)

        self.oldDateOrderRadioButton = QRadioButton(self.FilterCheckBoxFrame)
        self.oldDateOrderRadioButton.setObjectName(u"oldDateOrderRadioButton")

        self.horizontalLayout_9.addWidget(self.oldDateOrderRadioButton, 0,
                                          Qt.AlignHCenter)

        self.alphabeticalOrderRadioButton = QRadioButton(
            self.FilterCheckBoxFrame)
        self.alphabeticalOrderRadioButton.setObjectName(
            u"alphabeticalOrderRadioButton")

        self.horizontalLayout_9.addWidget(self.alphabeticalOrderRadioButton, 0,
                                          Qt.AlignHCenter)

        self.verticalLayout_9.addWidget(self.FilterCheckBoxFrame)

        self.tableFrame = QFrame(self.SearchWidget)
        self.tableFrame.setObjectName(u"tableFrame")
        self.tableFrame.setStyleSheet(u"border: 1px solid white;\n"
                                      "border-radius: 4px;\n"
                                      "margin-right:20%;\n"
                                      "margin-left:20%;\n")
        self.tableFrame.setFrameShape(QFrame.StyledPanel)
        self.tableFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_12 = QVBoxLayout(self.tableFrame)
        self.verticalLayout_12.setSpacing(0)
        self.verticalLayout_12.setObjectName(u"verticalLayout_12")
        self.verticalLayout_12.setContentsMargins(0, 0, 0, 0)

        self.clientsDataTableView = QTableView(self.SearchWidget)

        data = pd.DataFrame(service.repository,
                            columns=['Nume', 'ID', 'Creat la', 'Expiră la'])
        self.model = TableModel(data)
        # filter proxy model
        self.filter_proxy_model = QSortFilterProxyModel()
        self.filter_proxy_model.setSourceModel(self.model)
        self.filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filter_proxy_model.setFilterKeyColumn(
            -1)  # -1 is for searching in all columns

        self.clientsDataTableView.setModel(self.filter_proxy_model)
        self.clientsDataTableView.verticalHeader().hide(
        )  # REMOVE VERTICAL HEADER
        self.clientsDataTableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Interactive)
        self.clientsDataTableView.setHorizontalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.clientsDataTableView.horizontalHeader().setStretchLastSection(
            True)
        self.clientsDataTableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.clientsDataTableView.setSelectionBehavior(QTableView.SelectRows)

        self.clientsDataTableView.setObjectName(u"clientsDataTableView")
        self.clientsDataTableView.setStyleSheet(u"border: none;\n"
                                                "margin-right:0%;\n"
                                                "margin-left:0%;\n"
                                                "font: 9pt 'Bahnschript';\n"
                                                "font-style: bold italic;\n")

        self.verticalLayout_12.addWidget(self.clientsDataTableView)

        self.verticalLayout_9.addWidget(self.tableFrame)

        self.ViewClientButton = QPushButton(self.SearchWidget)
        self.ViewClientButton.setObjectName(u"ViewClientButton")
        self.ViewClientButton.setMinimumSize(QSize(100, 50))
        self.ViewClientButton.setCursor(QCursor(Qt.PointingHandCursor))
        font4 = QFont()
        font4.setPointSize(15)
        self.ViewClientButton.setFont(font4)
        self.ViewClientButton.setStyleSheet(u"QPushButton{\n"
                                            "   background-color: #bd6e38;\n"
                                            "   color: white;\n"
                                            "   border: 4px solid white;\n"
                                            "   border-radius: 15px;\n"
                                            "   margin-bottom: 5%;\n"
                                            "}\n"
                                            "QPushButton:hover{\n"
                                            "   background-color: black;\n"
                                            "   border-color: #bd6e38;\n"
                                            "}\n")

        self.verticalLayout_9.addWidget(self.ViewClientButton, 0,
                                        Qt.AlignHCenter)

        self.containerPages.addWidget(self.SearchWidget)
        self.ViewClientWidget = QWidget()
        self.ViewClientWidget.setObjectName(u"ViewClientWidget")
        self.verticalLayout_13 = QVBoxLayout(self.ViewClientWidget)
        self.verticalLayout_13.setObjectName(u"verticalLayout_13")
        self.ClientViewFrame = QFrame(self.ViewClientWidget)
        self.ClientViewFrame.setObjectName(u"ClientViewFrame")
        self.ClientViewFrame.setStyleSheet(u"QLabel{\n"
                                           "	font: 12pt \"Bahnschript\";\n"
                                           "	font-style: italic;\n"
                                           "	color: white;\n"
                                           "}\n"
                                           "\n"
                                           "QLineEdit{\n"
                                           "	border-right: none;\n"
                                           "	border-top: none;\n"
                                           "	border-left: none;\n"
                                           "	border-bottom: 1px solid white;\n"
                                           "}")
        self.ClientViewFrame.setFrameShape(QFrame.StyledPanel)
        self.ClientViewFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_14 = QVBoxLayout(self.ClientViewFrame)
        self.verticalLayout_14.setObjectName(u"verticalLayout_14")
        self.verticalLayout_14.setContentsMargins(-1, 15, 0, 0)
        self.gridLayout_4 = QGridLayout()
        self.gridLayout_4.setObjectName(u"gridLayout_4")
        self.gridLayout_4.setHorizontalSpacing(35)
        self.gridLayout_4.setVerticalSpacing(20)
        self.gridLayout_4.setContentsMargins(20, -1, 20, -1)
        self.NameLabel = QLabel(self.ClientViewFrame)
        self.NameLabel.setObjectName(u"NameLabel")

        self.gridLayout_4.addWidget(self.NameLabel, 0, 0, 1, 1)

        self.nameLineEdit = QLineEdit(self.ClientViewFrame)
        self.nameLineEdit.setObjectName(u"nameLineEdit")
        self.nameLineEdit.setStyleSheet(u"	font: 12pt \"Bahnschript\";\n"
                                        "	font-style: italic;\n"
                                        "	color: white;")
        self.nameLineEdit.setAlignment(Qt.AlignCenter)

        self.gridLayout_4.addWidget(self.nameLineEdit, 0, 1, 1, 1)

        self.CreationDateLabel = QLabel(self.ClientViewFrame)
        self.CreationDateLabel.setObjectName(u"CreationDateLabel")

        self.gridLayout_4.addWidget(self.CreationDateLabel, 0, 2, 1, 1)

        self.crationDateLineEdit = QLineEdit(self.ClientViewFrame)
        self.crationDateLineEdit.setObjectName(u"creationDateLineEdit")
        self.crationDateLineEdit.setStyleSheet(
            u"	font: 12pt \"Bahnschript\";\n"
            "	font-style: italic;\n"
            "	color: white;")
        self.crationDateLineEdit.setAlignment(Qt.AlignCenter)

        self.gridLayout_4.addWidget(self.crationDateLineEdit, 0, 3, 1, 1)

        self.IdLabel = QLabel(self.ClientViewFrame)
        self.IdLabel.setObjectName(u"IdLabel")

        self.gridLayout_4.addWidget(self.IdLabel, 1, 0, 1, 1)

        self.IdLineEdit = QLineEdit(self.ClientViewFrame)
        self.IdLineEdit.setObjectName(u"IdLineEdit")
        self.IdLineEdit.setStyleSheet(u"	font: 12pt \"Bahnschript\";\n"
                                      "	font-style: italic;\n"
                                      "	color: white;")
        self.IdLineEdit.setAlignment(Qt.AlignCenter)

        self.gridLayout_4.addWidget(self.IdLineEdit, 1, 1, 1, 1)

        self.ExpirationDateLabel = QLabel(self.ClientViewFrame)
        self.ExpirationDateLabel.setObjectName(u"ExpirationDateLabel")

        self.gridLayout_4.addWidget(self.ExpirationDateLabel, 1, 2, 1, 1)

        self.expirationDateLineEdit = QLineEdit(self.ClientViewFrame)
        self.expirationDateLineEdit.setObjectName(u"expirationDateLineEdit")
        self.expirationDateLineEdit.setStyleSheet(
            u"	font: 12pt \"Bahnschript\";\n"
            "	font-style: italic;\n"
            "	color: white;")
        self.expirationDateLineEdit.setAlignment(Qt.AlignCenter)

        self.gridLayout_4.addWidget(self.expirationDateLineEdit, 1, 3, 1, 1)

        self.verticalLayout_14.addLayout(self.gridLayout_4)

        self.Valid_InvalidLabel = QLabel(self.ClientViewFrame)
        self.Valid_InvalidLabel.setObjectName(u"Valid_InvalidLabel")
        font5 = QFont()
        font5.setFamily(u"Bahnschript")
        font5.setPointSize(25)
        font5.setBold(False)
        font5.setItalic(True)
        font5.setWeight(50)
        self.Valid_InvalidLabel.setFont(font5)
        self.Valid_InvalidLabel.setStyleSheet(u"font: 25pt \"Bahnschript\";\n"
                                              "font-style: italic;\n"
                                              "color: white;")
        self.Valid_InvalidLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_14.addWidget(self.Valid_InvalidLabel)

        self.PrintButton = QPushButton(self.ClientViewFrame)
        self.PrintButton.setObjectName(u"PrintButton")
        self.PrintButton.setMinimumSize(QSize(180, 130))
        self.PrintButton.setCursor(QCursor(Qt.PointingHandCursor))
        font6 = QFont()
        font6.setPointSize(11)
        font6.setBold(True)
        font6.setWeight(75)
        self.PrintButton.setFont(font6)
        self.PrintButton.setStyleSheet(u"QPushButton{\n"
                                       "background-color: #bd6e38;\n"
                                       "color: white;\n"
                                       "border: 4px solid white;\n"
                                       "border-radius: 30%;\n"
                                       "margin-bottom: 40%;\n"
                                       "}\n"
                                       "QPushButton:hover{\n"
                                       "   background-color: black;\n"
                                       "   border-color: #bd6e38;\n"
                                       "}\n")

        self.verticalLayout_14.addWidget(self.PrintButton, 0, Qt.AlignHCenter)

        self.verticalLayout_13.addWidget(self.ClientViewFrame)

        self.containerPages.addWidget(self.ViewClientWidget)
        self.AddWidget = QWidget()
        self.AddWidget.setObjectName(u"AddWidget")
        self.verticalLayout_6 = QVBoxLayout(self.AddWidget)
        self.verticalLayout_6.setObjectName(u"verticalLayout_6")
        self.addTextFrame = QFrame(self.AddWidget)
        self.addTextFrame.setObjectName(u"addTextFrame")
        self.addTextFrame.setStyleSheet(u"border-bottom: 1px solid #bd6e38;\n"
                                        "border-top: 2px solid #bd6e38;")
        self.addTextFrame.setFrameShape(QFrame.StyledPanel)
        self.addTextFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_5 = QVBoxLayout(self.addTextFrame)
        self.verticalLayout_5.setObjectName(u"verticalLayout_5")
        self.verticalLayout_5.setContentsMargins(0, -1, 0, -1)
        self.addTextLabel = QLabel(self.addTextFrame)
        self.addTextLabel.setObjectName(u"addTextLabel")
        font7 = QFont()
        font7.setFamily(u"Bahnschrift")
        font7.setPointSize(15)
        font7.setItalic(True)
        self.addTextLabel.setFont(font7)
        self.addTextLabel.setStyleSheet(u"color: white;\n" "border: none;")
        self.addTextLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_5.addWidget(self.addTextLabel)

        self.verticalLayout_6.addWidget(self.addTextFrame)

        self.InsertNameFrame = QFrame(self.AddWidget)
        self.InsertNameFrame.setObjectName(u"InsertNameFrame")
        self.InsertNameFrame.setFrameShape(QFrame.StyledPanel)
        self.InsertNameFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_5 = QHBoxLayout(self.InsertNameFrame)
        self.horizontalLayout_5.setSpacing(13)
        self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.addNameLabel = QLabel(self.InsertNameFrame)
        self.addNameLabel.setObjectName(u"addNameLabel")
        font8 = QFont()
        font8.setFamily(u"Bahnschrift")
        font8.setPointSize(17)
        font8.setItalic(True)
        self.addNameLabel.setFont(font8)
        self.addNameLabel.setStyleSheet(u"color: white;\n"
                                        "margin-left:  70%;\n"
                                        "margin-bottom: 10%;\n"
                                        "")
        self.addNameLabel.setAlignment(Qt.AlignCenter)
        self.addNameLabel.setMargin(0)

        self.horizontalLayout_5.addWidget(self.addNameLabel)

        self.addLineEdit = QLineEdit(self.InsertNameFrame)
        self.addLineEdit.setObjectName(u"addLineEdit")
        self.addLineEdit.setMinimumSize(QSize(50, 0))
        font9 = QFont()
        font9.setFamily(u"Bahnschrift")
        font9.setPointSize(17)
        self.addLineEdit.setFont(font9)
        self.addLineEdit.setStyleSheet(u"margin-right: 70%;\n"
                                       "color: white;\n"
                                       "border-top: none;\n"
                                       "border-left: none;\n"
                                       "border-right: none;\n"
                                       "border-bottom: 1px solid white;\n"
                                       "\n"
                                       "")
        self.addLineEdit.setAlignment(Qt.AlignCenter)
        self.addLineEdit.setDragEnabled(False)

        self.horizontalLayout_5.addWidget(self.addLineEdit)

        self.verticalLayout_6.addWidget(self.InsertNameFrame)

        self.addButtonsFrame = QFrame(self.AddWidget)
        self.addButtonsFrame.setObjectName(u"addButtonsFrame")
        self.addButtonsFrame.setFrameShape(QFrame.StyledPanel)
        self.addButtonsFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_6 = QHBoxLayout(self.addButtonsFrame)
        self.horizontalLayout_6.setSpacing(40)
        self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
        self.addPushBUtton = QPushButton(self.addButtonsFrame)
        self.addPushBUtton.setObjectName(u"addPushBUtton")
        self.addPushBUtton.setCursor(QCursor(Qt.PointingHandCursor))
        self.addPushBUtton.setMinimumSize(QSize(0, 30))
        font10 = QFont()
        font10.setFamily(u"Bahnschrift")
        font10.setPointSize(14)
        self.addPushBUtton.setFont(font10)
        self.addPushBUtton.setStyleSheet(u"QPushButton{\n"
                                         "  background-color: #bd6e38;\n"
                                         "  color: white;\n"
                                         "  border: 4px solid white;\n"
                                         "  border-radius: 15px;\n"
                                         "  margin-left: 70%;\n"
                                         "  margin-right: 50%;\n"
                                         "}\n"
                                         "QPushButton:hover{\n"
                                         "      background-color: black;\n"
                                         "      border-color: #bd6e38;\n "
                                         "}\n")

        self.horizontalLayout_6.addWidget(self.addPushBUtton)

        self.quitPushButton = QPushButton(self.addButtonsFrame)
        self.quitPushButton.setObjectName(u"quitPushButton")
        self.quitPushButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.quitPushButton.setMinimumSize(QSize(0, 34))
        self.quitPushButton.setFont(font10)
        self.quitPushButton.setStyleSheet(u"QPushButton{\n"
                                          "  background-color: #bd6e38;\n"
                                          "  color: white;\n"
                                          "  border: 4px solid white;\n"
                                          "  border-radius: 15px;\n"
                                          "  margin-left: 70%;\n"
                                          "  margin-right: 50%;\n"
                                          "}\n"
                                          "QPushButton:hover{\n"
                                          "   background-color: black;\n"
                                          "   border-color: #bd6e38;\n "
                                          "}\n")

        self.horizontalLayout_6.addWidget(self.quitPushButton)

        self.verticalLayout_6.addWidget(self.addButtonsFrame)

        self.containerPages.addWidget(self.AddWidget)
        self.RemoveWidget = QWidget()
        self.RemoveWidget.setObjectName(u"RemoveWidget")
        self.horizontalLayout_11 = QHBoxLayout(self.RemoveWidget)
        self.horizontalLayout_11.setSpacing(2)
        self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
        self.horizontalLayout_11.setContentsMargins(0, 2, 2, 3)
        self.removeElementsFrame = QFrame(self.RemoveWidget)
        self.removeElementsFrame.setObjectName(u"removeElementsFrame")
        self.verticalLayout_16 = QVBoxLayout(self.removeElementsFrame)
        self.verticalLayout_16.setSpacing(0)
        self.verticalLayout_16.setObjectName(u"verticalLayout_16")
        self.verticalLayout_16.setContentsMargins(0, -1, -1, -1)
        self.verticalLayout_15 = QVBoxLayout()
        self.verticalLayout_15.setObjectName(u"verticalLayout_15")
        self.removeTextFrame = QFrame(self.removeElementsFrame)
        self.removeTextFrame.setObjectName(u"removeTextFrame")
        self.removeTextFrame.setStyleSheet(
            u"border-right: 4px solid #bd6e38;\n"
            "border-bottom: 4px solid #bd6e38;\n"
            "border: 4px solid #bd6e38;\n"
            "border-top-right-radius: 5%;\n"
            "border-bottom-right-radius: 5%;\n"
            "border-left: none;\n")
        self.removeTextFrame.setFrameShape(QFrame.StyledPanel)
        self.removeTextFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_7 = QVBoxLayout(self.removeTextFrame)
        self.verticalLayout_7.setObjectName(u"verticalLayout_7")
        self.verticalLayout_7.setContentsMargins(0, -1, 0, -1)
        self.removeLabel = QLabel(self.removeTextFrame)
        self.removeLabel.setObjectName(u"removeLabel")
        self.removeLabel.setFont(font7)
        self.removeLabel.setStyleSheet(u"color: white;\n" "border: none;")
        self.removeLabel.setAlignment(Qt.AlignCenter)

        self.verticalLayout_7.addWidget(self.removeLabel)

        self.verticalLayout_15.addWidget(self.removeTextFrame, 0,
                                         Qt.AlignLeft | Qt.AlignTop)

        self.removeSearchbarFrame = QFrame(self.removeElementsFrame)
        self.removeSearchbarFrame.setObjectName(u"removeSearchbarFrame")
        self.removeSearchbarFrame.setStyleSheet(u"")
        self.removeSearchbarFrame.setFrameShape(QFrame.StyledPanel)
        self.removeSearchbarFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_10 = QHBoxLayout(self.removeSearchbarFrame)
        self.horizontalLayout_10.setObjectName(u"horizontalLayout_10")
        self.removeSearchbarLineEdit = QLineEdit(self.removeSearchbarFrame)
        self.removeSearchbarLineEdit.setObjectName(u"removeSearchbarLineEdit")
        self.removeSearchbarLineEdit.setStyleSheet(
            u"color: white;\n"
            "border: 1px solid white;\n"
            "border-radius: 30%;\n"
            "font: 15pt 'BahnSchrift'\n")
        self.removeSearchbarLineEdit.setPlaceholderText("Căutați aici...")
        self.removeSearchbarLineEdit.setAlignment(Qt.AlignCenter)

        self.horizontalLayout_10.addWidget(self.removeSearchbarLineEdit)

        self.verticalLayout_15.addWidget(self.removeSearchbarFrame, 0,
                                         Qt.AlignTop)

        self.verticalLayout_16.addLayout(self.verticalLayout_15)

        self.removeButtonsFrame = QFrame(self.removeElementsFrame)
        self.removeButtonsFrame.setObjectName(u"removeButtonsFrame")
        self.removeButtonsFrame.setFrameShape(QFrame.StyledPanel)
        self.removeButtonsFrame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_7 = QHBoxLayout(self.removeButtonsFrame)
        self.horizontalLayout_7.setSpacing(40)
        self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
        self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0)
        self.removePushButton = QPushButton(self.removeButtonsFrame)
        self.removePushButton.setObjectName(u"removePushButton")
        self.removePushButton.setCursor(QCursor(Qt.PointingHandCursor))
        self.removePushButton.setMinimumSize(QSize(0, 34))
        self.removePushButton.setFont(font10)
        self.removePushButton.setStyleSheet(u"QPushButton{\n"
                                            "   background-color: #bd6e38;\n"
                                            "   color: white;\n"
                                            "   border: 4px solid white;\n"
                                            "   border-radius: 15px;\n"
                                            "   margin-right: 20%;\n"
                                            "   margin-left:40%;\n"
                                            "}\n"
                                            "QPushButton:hover{\n"
                                            "   background-color: black;\n"
                                            "   border-color: #bd6e38;\n"
                                            "}\n")

        self.horizontalLayout_7.addWidget(self.removePushButton)

        self.quitPushButton_2 = QPushButton(self.removeButtonsFrame)
        self.quitPushButton_2.setObjectName(u"quitPushButton_2")
        self.quitPushButton_2.setCursor(QCursor(Qt.PointingHandCursor))
        self.quitPushButton_2.setMinimumSize(QSize(0, 34))
        self.quitPushButton_2.setFont(font10)
        self.quitPushButton_2.setStyleSheet(u"QPushButton{\n"
                                            "   background-color: #bd6e38;\n"
                                            "   color: white;\n"
                                            "   border: 4px solid white;\n"
                                            "   border-radius: 15px;\n"
                                            "   margin-right: 20%;\n"
                                            "   margin-left: 20%;\n"
                                            "}\n"
                                            "QPushButton:hover{\n"
                                            "   background-color: black;\n"
                                            "   border-color: #bd6e38;\n"
                                            "}\n")

        self.horizontalLayout_7.addWidget(self.quitPushButton_2)

        self.verticalLayout_16.addWidget(self.removeButtonsFrame, 0,
                                         Qt.AlignBottom)

        self.horizontalLayout_11.addWidget(self.removeElementsFrame, 0,
                                           Qt.AlignLeft)

        self.removeTableFrame = QFrame(self.RemoveWidget)
        self.removeTableFrame.setObjectName(u"removeTableFrame")
        self.removeTableFrame.setStyleSheet(u"border: 1px solid white;\n"
                                            "border-radius: 4px;\n")
        self.removeTableFrame.setFrameShape(QFrame.StyledPanel)
        self.removeTableFrame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_8 = QVBoxLayout(self.removeTableFrame)
        self.verticalLayout_8.setObjectName(u"verticalLayout_8")
        self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
        self.removetableView = QTableView(self.removeTableFrame)

        self.remove_model = TableModel(data)

        self.remove_filter_proxy_model = QSortFilterProxyModel()
        self.remove_filter_proxy_model.setSourceModel(self.remove_model)
        self.remove_filter_proxy_model.setFilterCaseSensitivity(
            Qt.CaseInsensitive)
        self.remove_filter_proxy_model.setFilterKeyColumn(-1)

        self.removetableView.setModel(self.remove_filter_proxy_model)
        self.removetableView.verticalHeader().hide()  # REMOVE VERTICAL HEADER
        self.removetableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Interactive)
        self.removetableView.setHorizontalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.removetableView.horizontalHeader().setStretchLastSection(True)
        self.removetableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.removetableView.setSelectionBehavior(QTableView.SelectRows)

        self.removetableView.setObjectName(u"removetableView")
        self.removetableView.setStyleSheet(u"border: none;\n"
                                           "margin-right:0%;\n"
                                           "margin-left:0%;\n"
                                           "font: 9pt 'Bahnschript';\n"
                                           "font-style: bold italic;\n")

        self.verticalLayout_8.addWidget(self.removetableView)

        self.horizontalLayout_11.addWidget(self.removeTableFrame)

        self.containerPages.addWidget(self.RemoveWidget)

        self.horizontalLayout_4.addWidget(self.containerPages)

        self.gridLayout.addWidget(self.content_menu, 0, 1, 1, 1)

        self.verticalLayout.addLayout(self.gridLayout)

        Main.setCentralWidget(self.centralwidget)

        self.retranslateUi(Main)

        self.containerPages.setCurrentIndex(0)

        QMetaObject.connectSlotsByName(Main)

    # setupUi

    def retranslateUi(self, Main):
        Main.setWindowTitle(
            QCoreApplication.translate("Main", u"MainWindow", None))
        self.slideMenuButton.setText("")
        self.titleLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p>STIHL SERVER</p></body></html>", None))
        self.minimazeButton.setText("")
        self.maximazeButton.setText("")
        self.closeButton.setText("")

        self.versionLabel.setText(
            QCoreApplication.translate("Main", u"v 1.2", None))
        self.homeTitleLabel.setText(
            QCoreApplication.translate("Main", u"HOME", None))
        self.homeintroLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p><span style=\"background-color:#333;\">Aceasta este aplica\u021bia pentru gestionarea clien\u021bilor.</span></p><p><span style=\"background-color:#333;\">Pentru a vizuliza un client da-\u021bi click pe iconi\u021ba cu lup\u0103.</span></p><p><span style=\"background-color:#333;\">Pentru a filtra datele bifa\u021bi, \u00een func\u021bie de preferin\u021b\u0103, c\u0103su\u021bele de sub bara de c\u0103utare.</span></p><p><span style=\"background-color:#333;\">Pentru a genera un pdf voucher selecta\u021bi clientul dorit, da\u021bi click pe butonul &quot;Vizualizeaz\u0103&quot;</span></p><p><span style=\"background-color:#333;\">dup\u0103 care, ap\u0103sa\u021bi &quot;Printare client&quot;.</span></p><p><span style=\"background-color:#333;\">Pentru a ad\u0103uga/\u0219terge un client ap\u0103sa\u021bi pe iconi\u021ba cu plus, respectiv &quot;x&quot;.</span></p></body></html>",
                None))

        self.recentDateOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 recent\u0103",
                                       None))
        self.oldDateOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 vehce", None))
        self.alphabeticalOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Ordonare alfabetic\u0103",
                                       None))
        self.ViewClientButton.setText(
            QCoreApplication.translate("Main", u" Vizualizeaz\u0103 ", None))
        self.NameLabel.setText(
            QCoreApplication.translate("Main", u"Nume:", None))
        self.CreationDateLabel.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 creare: ", None))
        self.IdLabel.setText(QCoreApplication.translate("Main", u"ID:", None))
        self.ExpirationDateLabel.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 expirare: ", None))
        self.Valid_InvalidLabel.setText(
            QCoreApplication.translate("Main", u"Client valid", None))
        self.PrintButton.setText(
            QCoreApplication.translate("Main", u"  Genereaz\u0103 PDF ", None))
        self.addTextLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p align=\"center\">Pentru a ad\u0103uga un client nou trebuie </p><p align=\"center\">s\u0103 introduce\u021bi numele:</p></body></html>",
                None))
        self.addNameLabel.setText(
            QCoreApplication.translate("Main", u"Nume: ", None))
        self.addPushBUtton.setText(
            QCoreApplication.translate("Main", u"Adaug\u0103", None))
        self.quitPushButton.setText(
            QCoreApplication.translate("Main", u"Renun\u021b\u0103", None))
        self.removeLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p align=\"center\">Pentru a \u0219terge un client trebuie s\u0103 </p><p align=\"center\">selecta\u021bi r\u00e2ndul corespunz\u0103tor</p></body></html>",
                None))
        self.removePushButton.setText(
            QCoreApplication.translate("Main", u"\u0218terge", None))
        self.quitPushButton_2.setText(
            QCoreApplication.translate("Main", u"Renun\u021b\u0103", None))
Example #30
0
class FE14SupportEditor(QWidget, Ui_support_editor):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)
        self.comboBox.setEnabled(False)
        self.setWindowTitle("Support Editor")
        self.setWindowIcon(QIcon("paragon.ico"))
        self.error_dialog = None

        module_service = locator.get_scoped("ModuleService")
        self.service = None
        self.current_character = None
        self.current_supports = None
        self.current_support = None
        self.model = module_service.get_module("Characters").entries_model
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.characters_list_view.setModel(self.proxy_model)

        self.characters_list_view.selectionModel().currentRowChanged.connect(self._update_selection)
        self.listWidget.selectionModel().currentRowChanged.connect(self._on_target_character_changed)
        self.listWidget_2.selectionModel().currentRowChanged.connect(self._update_support_selection)
        self.lineEdit.textChanged.connect(self._update_filter)
        self.pushButton_2.clicked.connect(self._on_add_support_pressed)
        self.pushButton_3.clicked.connect(self._on_remove_support_pressed)
        self.comboBox.currentIndexChanged.connect(self._on_support_type_changed)

    def show(self):
        super().show()
        self.service = locator.get_scoped("SupportsService")
        self.service.set_in_use()
        success = True
        try:
            self.service.check_support_id_validity()
        except:
            logging.exception("Support IDs are invalid.")
            self.error_dialog = ErrorDialog("Support IDs are invalid. This could mean an ID was out of bounds or not "
                                            "unique. See the log for details.")
            self.error_dialog.show()
            success = False
        self.setDisabled(not success)

    def _update_filter(self):
        self.proxy_model.setFilterRegExp(self.lineEdit.text())

    def _update_selection(self, index: QtCore.QModelIndex):
        if index.isValid():
            character = self.proxy_model.data(index, QtCore.Qt.UserRole)
            self._refresh_lists(character)
            self.current_character = character

    def _refresh_lists(self, character):
        self._update_supports_list(character)
        self._update_add_list(character)
        self.current_support = None
        self.comboBox.setEnabled(False)
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)

    def _update_add_list(self, character):
        supported_characters = self._create_supported_characters_set(character)
        module_service = locator.get_scoped("ModuleService")

        self.listWidget.clear()
        characters = module_service.get_module("Characters").entries
        for target_character in characters:
            if target_character["PID"] not in supported_characters:
                model_index = self._get_model_index_of_character(target_character)
                display_name = self.model.data(model_index, QtCore.Qt.DisplayRole)
                item = QListWidgetItem(display_name)
                item.setData(QtCore.Qt.UserRole, target_character)
                self.listWidget.addItem(item)

    # Dict is not hashable. PIDs should be unique, so we'll use those instead.
    # Might be able to use IDs instead.
    def _create_supported_characters_set(self, character):
        supports = self.service.get_supports_for_character(character)
        result = set()
        for support in supports:
            result.add(support.character["PID"])
        return result

    def _update_supports_list(self, character):
        supports = self.service.get_supports_for_character(character)
        self.listWidget_2.clear()
        for support in supports:
            model_index = self._get_model_index_of_character(support.character)
            display_name = self.model.data(model_index, QtCore.Qt.DisplayRole)
            item = QListWidgetItem(display_name)
            item.setData(QtCore.Qt.UserRole, support)
            self.listWidget_2.addItem(item)
        self.current_supports = supports

    def _get_model_index_of_character(self, character):
        module_service = locator.get_scoped("ModuleService")
        entries = module_service.get_module("Characters").entries
        for i in range(0, len(entries)):
            if entries[i] == character:
                return self.model.index(i)
        return QModelIndex()

    def _update_support_selection(self, index):
        if not index.isValid() or not self.current_supports:
            return
        self.current_support = self.current_supports[index.row()]
        index = SUPPORT_TYPE_TO_INDEX[self.current_support.support_type]
        self.comboBox.setCurrentIndex(index)
        self.comboBox.setEnabled(True)
        self.pushButton_3.setEnabled(True)

    def _on_support_type_changed(self, index):
        if not self.current_character or not self.current_support:
            return
        support_type = INDEX_TO_SUPPORT_TYPE[index]
        self.service.set_support_type(self.current_character, self.current_support, support_type)

    def _on_target_character_changed(self):
        self.pushButton_2.setEnabled(self.listWidget.currentIndex().isValid())

    def _on_add_support_pressed(self):
        if not self.current_character or not self.listWidget.currentIndex().isValid():
            return
        other_character = self.listWidget.currentItem().data(QtCore.Qt.UserRole)
        support_type = INDEX_TO_SUPPORT_TYPE[0]  # Default to romantic.
        self.service.add_support_between_characters(self.current_character, other_character, support_type)
        self._refresh_lists(self.current_character)

    def _on_remove_support_pressed(self):
        if not self.current_character or not self.current_support:
            return
        self.service.remove_support(self.current_character, self.current_support)
        self._refresh_lists(self.current_character)
Example #31
0
class ObjListWindow(PBDialog):
    """Create a window managing a list (of bibtexs or of experiments)"""
    def __init__(self, parent=None, gridLayout=False):
        """Init using parent class and create common definitions

        Parameters:
            parent: the parent object
            gridLayout (boolean, default False):
                if True, use a QGridLayout, otherwise a QVBoxLayout
        """
        super(ObjListWindow, self).__init__(parent)
        self.tableWidth = None
        self.proxyModel = None
        self.gridLayout = gridLayout
        self.filterInput = None
        self.proxyModel = None
        self.tableview = None
        if gridLayout:
            self.currLayout = QGridLayout()
        else:
            self.currLayout = QVBoxLayout()
        self.setLayout(self.currLayout)

    def triggeredContextMenuEvent(self, row, col, event):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def handleItemEntered(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def cellClick(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def cellDoubleClick(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def createTable(self, *args, **kwargs):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def changeFilter(self, string):
        """Change the filter of the current view.

        Parameter:
            string: the filter string to be matched
        """
        self.proxyModel.setFilterRegExp(str(string))

    def addFilterInput(self, placeholderText, gridPos=(1, 0)):
        """Add a `QLineEdit` to change the filter of the list.

        Parameter:
            placeholderText: the text to be shown
                when no filter is present
            gridPos (tuple): if gridLayout is active,
                the position of the `QLineEdit` in the `QGridLayout`
        """
        self.filterInput = QLineEdit("", self)
        self.filterInput.setPlaceholderText(placeholderText)
        self.filterInput.textChanged.connect(self.changeFilter)

        if self.gridLayout:
            self.currLayout.addWidget(self.filterInput, *gridPos)
        else:
            self.currLayout.addWidget(self.filterInput)
        self.filterInput.setFocus()

    def setProxyStuff(self, sortColumn, sortOrder):
        """Prepare the proxy model to filter and sort the view.

        Parameter:
            sortColumn: the index of the column to use
                for sorting at the beginning
            sortOrder: the order for sorting
                (`Qt.AscendingOrder` or `Qt.DescendingOrder`)
        """
        self.proxyModel = QSortFilterProxyModel(self)
        self.proxyModel.setSourceModel(self.tableModel)
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setFilterKeyColumn(-1)

        self.tableview = PBTableView(self)
        self.tableview.setModel(self.proxyModel)
        self.tableview.setSortingEnabled(True)
        self.tableview.setMouseTracking(True)
        self.tableview.setSelectionBehavior(QAbstractItemView.SelectRows)
        try:
            self.tableview.sortByColumn(self.tableModel.header.index("bibkey"),
                                        Qt.AscendingOrder)
        except (IndexError, ValueError):
            pass
        self.tableview.sortByColumn(sortColumn, sortOrder)
        try:
            self.proxyModel.sort(self.tableModel.header.index("bibkey"),
                                 Qt.AscendingOrder)
        except (IndexError, ValueError):
            pass
        self.proxyModel.sort(sortColumn, sortOrder)
        self.currLayout.addWidget(self.tableview)

    def finalizeTable(self, gridPos=(1, 0)):
        """Resize the table to fit the contents,
        connect functions, add to layout

        Parameter:
            gridPos (tuple): if gridLayout is active,
            the position of the `QLineEdit` in the `QGridLayout`
        """
        self.tableview.resizeColumnsToContents()

        maxh = QDesktopWidget().availableGeometry().height()
        maxw = QDesktopWidget().availableGeometry().width()
        self.setMaximumHeight(maxh)
        self.setMaximumWidth(maxw)

        hwidth = self.tableview.horizontalHeader().length()
        swidth = self.tableview.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        fwidth = self.tableview.frameWidth() * 2

        if self.tableWidth is None:
            if hwidth > maxw - (swidth + fwidth):
                self.tableWidth = maxw - (swidth + fwidth)
            else:
                self.tableWidth = hwidth + swidth + fwidth
        self.tableview.setFixedWidth(self.tableWidth)

        self.setMinimumHeight(600)

        self.tableview.resizeColumnsToContents()
        self.tableview.resizeRowsToContents()

        self.tableview.entered.connect(self.handleItemEntered)
        self.tableview.clicked.connect(self.cellClick)
        self.tableview.doubleClicked.connect(self.cellDoubleClick)

        if self.gridLayout:
            self.currLayout.addWidget(self.tableview, *gridPos)
        else:
            self.currLayout.addWidget(self.tableview)

    def recreateTable(self):
        """Delete the previous table widget and other layout items,
        then create new ones
        """
        self.cleanLayout()
        self.createTable()
Example #32
0
class BaseList(BasePage):
    """
    Generic table viewer widget. Subclasses should set the model_class
    attribute to a subclass of BaseListModel.

    If a subclass defines an open_item method that accepts one argument, when
    an item in the table is clicked on, that method will be called with the ID
    of the clicked item. Alternatively, if the details_class attribute is set
    to a tab page widget class, that will be used to open the item.

    """
    def __init__(self, *args, **kwargs):
        self._model = self.model_class()
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self._model)
        layout = QVBoxLayout()
        self.table_view = QTableView()
        self.table_view.setModel(self.proxy_model)
        self.table_view.setSortingEnabled(True)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.doubleClicked.connect(self.table_double_clicked)
        layout.addWidget(self.table_view)
        self.extra_data = dict()
        super().__init__(*args, **kwargs)
        self.setLayout(layout)

    def table_double_clicked(self, index):
        """
        Called when the QTableView is double clicked. If the open_item() method
        is defined, call it and pass the ID of the item that was clicked on.

        Args:
            The QModelIndex passed by the table_view.doubleClicked signal.

        """
        if hasattr(self, "open_item"):
            # TODO: Figure out a better way to get the ID besides assuming that
            # it's in the first (or any) column
            id_index = index.siblingAtColumn(0)
            try:
                data_id = int(index.model().itemData(id_index)[0])
                self.open_item(data_id)
            except ValueError:
                pass

    def open_item(self, data_id):
        """
        If the details_class attribute is defined, use it to open a Details tab
        for the specified item.

        """
        if hasattr(self, "details_class"):
            self.details_class.create_or_focus(self.gui, data_id)

    @property
    def data(self):
        """The page's current data set (a 2-dimensional sequence)."""
        return self._model.dataset

    @data.setter
    def data(self, data):
        self._model.populate(data)
        self.proxy_model.invalidate()

    @property
    def tab_name(self):
        """
        The name of the tab page. Determined by the tab_name_fmt attribute and
        the widget's current supplemental data set.

        """
        return self.tab_name_fmt.format(**self.extra_data)