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)
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
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)
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()
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 "Vizualizeaz\u0103"</span></p><p><span style=\"background-color:#333;\">dup\u0103 care, ap\u0103sa\u021bi "Printare client".</span></p><p><span style=\"background-color:#333;\">Pentru a ad\u0103uga/\u0219terge un client ap\u0103sa\u021bi pe iconi\u021ba cu plus, respectiv "x".</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))
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.")
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)
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()
class FE14ChapterEditor(Ui_FE14ChapterEditor): def __init__(self): super().__init__() self.setWindowTitle("Chapter Editor") self.setWindowIcon(QIcon("paragon.ico")) self.error_dialog = None module_service = locator.get_scoped("ModuleService") self.chapter_module = module_service.get_module("Chapters") self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.chapter_module.entries_model) self.proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) self.chapter_list_view.setModel(self.proxy_model) self.chapter_search_bar.textChanged.connect(self._update_filter) self.chapter_list_view.selectionModel().currentRowChanged.connect( self._update_selection) self.add_chapter_action.triggered.connect( self._on_add_chapter_triggered) self.hide_selector_action.triggered.connect( self._on_toggle_selector_triggered) self._update_selection(QModelIndex()) def _update_filter(self): self.proxy_model.setFilterRegExp(self.search_field.text()) def _update_selection(self, index): service = locator.get_scoped("ChapterService") data = self.proxy_model.data(index, QtCore.Qt.UserRole) chapter_data: Optional[ ChapterData] = service.get_chapter_data_from_chapter( data) if data else None person_module = chapter_data.person if chapter_data else None message_archive = chapter_data.conversation_data if chapter_data else None self.config_tab.update_chapter_data(chapter_data) self.map_tab.update_chapter_data(chapter_data) self.characters_tab.set_module(person_module) self.conversation_tab.set_archive(message_archive) def _on_add_chapter_triggered(self): # Get the chapter to use as a base choices = self._create_chapter_choice_list() (choice, ok) = QInputDialog.getItem(self, "Select Base Chapter", "Base Chapter", choices) if not ok: return source_chapter = self._get_chapter_from_choice(choice, choices) # Get the desired CID. (desired_cid, ok) = QInputDialog.getText(self, "Enter a CID for the new chapter.", "CID") if not ok: return # Validate the CID. service = locator.get_scoped("ChapterService") if service.is_cid_in_use(desired_cid): self.error_dialog = ErrorDialog("The CID \"" + desired_cid + "\" is already in use.") self.error_dialog.show() return if not desired_cid.startswith("CID_"): self.error_dialog = ErrorDialog("CID must start with the \"CID_\"") self.error_dialog.show() return # Create the chapter service.create_chapter(source_chapter, desired_cid) def _create_chapter_choice_list(self): choices = [] for i in range(0, len(self.chapter_module.entries)): chapter = self.chapter_module.entries[i] cid = chapter["CID"].value choices.append(str(i) + ". " + cid) return choices def _get_chapter_from_choice(self, choice, choices_list): for i in range(0, len(choices_list)): if choice == choices_list[i]: return self.chapter_module.entries[i] raise ValueError def _on_toggle_selector_triggered(self): self.selector_widget.setVisible(not self.selector_widget.isVisible()) self.visual_splitter.setVisible(not self.visual_splitter.isVisible())
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)
class MainWindow(QMainWindow): createUpload = Signal(list, htauthcontroller.HTAuthorizationController, str, list) def __init__(self): super(MainWindow, self).__init__() self.hyperthoughtui = HyperthoughtDialogImpl() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.TabWidget.setCurrentWidget(self.ui.CreateTemplateTab) self.ui.actionHelp.triggered.connect(self.help) self.ui.actionOpenPackage.triggered.connect(self.openPackage) self.ui.actionSave_Package.triggered.connect(self.savePackageAs) self.ui.actionClose.triggered.connect(self.close) self.ui.actionSave_Template.triggered.connect(self.saveTemplate) self.ui.actionOpen_Template.triggered.connect(self.restoreTemplate) self.ui.dataFileSelect.clicked.connect(self.selectFile) self.ui.hyperthoughtTemplateSelect.clicked.connect(self.selectTemplate) self.ui.saveTemplateButton.clicked.connect(self.saveTemplate) self.ui.otherDataFileSelect.clicked.connect(self.extractFile) self.ui.hyperthoughtUploadButton.clicked.connect( self.uploadToHyperthought) self.setAcceptDrops(True) self.numCustoms = 0 self.customInputs = [] self.templateFilePath = "" aTree = {} self.createtablemodel = TableModelC(aTree, self) self.filterModel = FilterModel(self) self.filterModel.setSourceModel(self.createtablemodel) self.ui.metadataTableView.setModel(self.filterModel) self.ui.metadataTableView.horizontalHeader().setSectionResizeMode( self.createtablemodel.K_SOURCE_COL_INDEX, QHeaderView.ResizeToContents) self.ui.metadataTableView.horizontalHeader().setSectionResizeMode( self.createtablemodel.K_HTNAME_COL_INDEX, QHeaderView.ResizeToContents) self.ui.metadataTableView.horizontalHeader().setSectionResizeMode( self.createtablemodel.K_SOURCEVAL_COL_INDEX, QHeaderView.ResizeToContents) self.ui.metadataTableView.horizontalHeader().setSectionResizeMode( self.createtablemodel.K_HTVALUE_COL_INDEX, QHeaderView.ResizeToContents) self.ui.metadataTableView.setColumnWidth( self.createtablemodel.K_USESOURCE_COL_INDEX, self.width() * .1) self.checkboxDelegate = CheckBoxDelegate() self.createtrashDelegate = TrashDelegate() self.ui.metadataTableView.setItemDelegateForColumn( self.createtablemodel.K_USESOURCE_COL_INDEX, self.checkboxDelegate) self.ui.metadataTableView.setItemDelegateForColumn( self.createtablemodel.K_EDITABLE_COL_INDEX, self.checkboxDelegate) self.ui.metadataTableView.setItemDelegateForColumn( self.createtablemodel.K_REMOVE_COL_INDEX, self.createtrashDelegate) self.ui.metadataTableView.setColumnWidth( self.createtablemodel.K_REMOVE_COL_INDEX, self.width() * .05) self.treeModel = TreeModel(["Available File Metadata"], aTree, self.createtablemodel) self.ui.metadataTreeView.setModel(self.treeModel) self.treeModel.checkChanged.connect(self.filterModel.checkList) self.createtrashDelegate.pressed.connect(self.handleRemoveCreate) self.editableKeys = [] self.usetablemodel = TableModelU(self, [], self.editableKeys) self.usefilterModel = FilterModelU(self) self.usefilterModel.setSourceModel(self.usetablemodel) self.ui.useTemplateTableView.setModel(self.usefilterModel) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_HTKEY_COL_INDEX, self.width() * .25) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_HTVALUE_COL_INDEX, self.width() * .25) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_SOURCE_COL_INDEX, self.width() * .25) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_USESOURCE_COL_INDEX, self.width() * .1) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_HTANNOTATION_COL_INDEX, self.width() * .1) self.usetrashDelegate = TrashDelegate() self.ui.useTemplateTableView.setItemDelegateForColumn( self.usetablemodel.K_USESOURCE_COL_INDEX, self.checkboxDelegate) self.ui.useTemplateTableView.setItemDelegateForColumn( self.usetablemodel.K_REMOVE_COL_INDEX, self.usetrashDelegate) self.ui.useTemplateTableView.setColumnWidth( self.usetablemodel.K_REMOVE_COL_INDEX, self.width() * .075) self.usetrashDelegate.pressed.connect(self.handleRemoveUse) self.uselistmodel = ListModel(self, self.usetablemodel, []) self.ui.useTemplateListView.setModel(self.uselistmodel) self.uselistmodel.rowRemoved.connect(self.toggleButtons) self.uselistmodel.rowAdded.connect(self.toggleButtons) self.useFileDelegate = UseFileDelegate(self) self.ui.useTemplateListView.setItemDelegate(self.useFileDelegate) self.ui.useTemplateListView.clicked.connect( self.removeRowfromUsefileType) self.addAppendButton() self.ui.TabWidget.currentChanged.connect(self.movethedamnbutton) self.appendSourceFilesButton.clicked.connect(self.addFile) self.ui.appendCreateTableRowButton.clicked.connect( self.addCreateTableRow) self.ui.appendUseTableRowButton.clicked.connect(self.addUseTableRow) self.ui.hyperthoughtLocationButton.clicked.connect( self.hyperthoughtui.exec) self.ui.usetableSearchBar.textChanged.connect(self.filterUseTable) self.ui.createTemplateListSearchBar.textChanged.connect( self.filterCreateTable) self.ui.createTemplateTreeSearchBar.textChanged.connect( self.filterCreateTree) self.ui.addMetadataFileCheckBox.stateChanged.connect( self.checkFileList) self.fileType = "" self.accessKey = "" self.folderuuid = "" self.mThread = QThread() self.uploader = Uploader() self.uploader.moveToThread(self.mThread) self.mThread.start() self.createUpload.connect(self.uploader.performUpload) self.hyperthoughtui.apiSubmitted.connect(self.acceptKey) self.hyperthoughtui.finished.connect(self.getLocation) self.ui.hyperthoughtTemplateLineEdit.installEventFilter(self) self.ui.otherDataFileLineEdit.installEventFilter(self) self.ui.dataFileLineEdit.installEventFilter(self) def acceptKey(self, apikey): self.accessKey = apikey def addCreateTableRow(self): self.createtablemodel.addEmptyRow(self.numCustoms) self.numCustoms += 1 def addFile(self): linetexts = QFileDialog.getOpenFileNames( self, self.tr("Select File"), QStandardPaths.displayName(QStandardPaths.HomeLocation), self.tr("Files (*.ctf *.xml *.ang)"))[0] for line in linetexts: self.uselistmodel.addRow(line) self.toggleButtons() def addAppendButton(self): self.appendSourceFilesButton = QToolButton(self.ui.useTemplateListView) icon = QApplication.style().standardIcon(QStyle.SP_FileIcon) def addUseTableRow(self): self.usetablemodel.addEmptyRow() def checkFileList(self, checked): if checked == Qt.Checked: if self.ui.otherDataFileLineEdit.text() != "": self.uselistmodel.addRow(self.ui.otherDataFileLineEdit.text()) elif checked == Qt.Unchecked: if self.ui.otherDataFileLineEdit.text( ) in self.uselistmodel.metadataList: rowIndex = self.uselistmodel.metadataList.index( self.ui.otherDataFileLineEdit.text()) self.uselistmodel.removeRow(rowIndex) def closeEvent(self, event): self.mThread.quit() self.mThread.wait(250) def extractFile(self, fileLink=False): if fileLink == False: linetext = QFileDialog.getOpenFileName( self, self.tr("Select File"), QStandardPaths.displayName(QStandardPaths.HomeLocation), self.tr("Files (*" + self.fileType + ")"))[0] else: linetext = fileLink if linetext != "": self.setWindowTitle(linetext) self.ui.dataTypeText.setText(linetext.split(".")[1].upper()) self.ui.otherDataFileLineEdit.setText(linetext) if self.ui.addMetadataFileCheckBox.checkState() == Qt.Checked: self.uselistmodel.removeAllRows() self.uselistmodel.addRow(linetext) self.toggleButtons() if self.ui.fileParserCombo.findText( linetext.split(".")[1].upper() + " Parser") != -1: headerDict = {} self.ui.fileParserCombo.setCurrentIndex( self.ui.fileParserCombo.findText( linetext.split(".")[1].upper() + " Parser")) if linetext.split(".")[1].upper() == "CTF": headerDict = ctf.parse_header_as_dict(linetext) elif linetext.split(".")[1].upper() == "ANG": headerDict = ang.parse_header_as_dict(linetext) elif linetext.split(".")[1].upper() == "XML": print("XML Parser used") if self.templatedata: self.usetablemodel.metadataList = [] self.usefilterModel = FilterModelU(self) self.usefilterModel.setSourceModel(self.usetablemodel) self.unusedTreeModel = TreeModelU(["Available File Metadata"], headerDict, self.usetablemodel, self.editableKeys) self.templatelist = [] self.templatesources = [] for i in range(len(self.templatedata)): self.templatelist.append(self.templatedata[i]) if "Custom Input" not in self.templatedata[i]["Source"]: self.templatesources.append("/".join( self.templatedata[i]['Source'].split("/")[1:])) else: self.usetablemodel.addExistingRow(self.templatedata[i]) self.usesearchFilterModel = QSortFilterProxyModel(self) self.usesearchFilterModel.setSourceModel(self.usefilterModel) self.usesearchFilterModel.setFilterKeyColumn(0) self.usesearchFilterModel.setDynamicSortFilter(True) self.ui.useTemplateTableView.setModel( self.usesearchFilterModel) self.toggleButtons() def eventFilter(self, object, event): if object == self.ui.hyperthoughtTemplateLineEdit: if event.type() == QEvent.DragEnter: if str(event.mimeData().urls()[0])[-5:-2] == ".ez": event.acceptProposedAction() if (event.type() == QEvent.Drop): if str(event.mimeData().urls()[0])[-5:-2] == ".ez": event.acceptProposedAction() self.loadTemplateFile( event.mimeData().urls()[0].toLocalFile()) if object == self.ui.otherDataFileLineEdit: if event.type() == QEvent.DragEnter: if str(event.mimeData().urls()[0])[-6:-2] == self.fileType: event.acceptProposedAction() if (event.type() == QEvent.Drop): if str(event.mimeData().urls()[0])[-6:-2] == self.fileType: event.acceptProposedAction() self.extractFile(event.mimeData().urls()[0].toLocalFile()) if object == self.ui.dataFileLineEdit: if event.type() == QEvent.DragEnter: if str(event.mimeData().urls()[0])[-6:-2] == ".ctf" or str( event.mimeData().urls()[0])[-6:-2] == ".ang": event.acceptProposedAction() if (event.type() == QEvent.Drop): if str(event.mimeData().urls()[0])[-6:-2] == ".ctf" or str( event.mimeData().urls()[0])[-6:-2] == ".ang": event.acceptProposedAction() self.selectFile(event.mimeData().urls()[0].toLocalFile()) return QMainWindow.eventFilter(self, object, event) def filterCreateTable(self): self.createTableSearchFilterModel.invalidate() self.createTableSearchFilterModel.setFilterCaseSensitivity( Qt.CaseInsensitive) self.createTableSearchFilterModel.setFilterWildcard( "*" + self.ui.createTemplateListSearchBar.text() + "*") def filterCreateTree(self): self.createTreeSearchFilterModel.invalidate() self.createTreeSearchFilterModel.setFilterCaseSensitivity( Qt.CaseInsensitive) self.createTreeSearchFilterModel.setFilterWildcard( "*" + self.ui.createTemplateTreeSearchBar.text() + "*") def filterUseTable(self): self.usesearchFilterModel.invalidate() self.usesearchFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.usesearchFilterModel.setFilterWildcard( "*" + self.ui.usetableSearchBar.text() + "*") def getLocation(self): remoteDirPath = self.hyperthoughtui.getUploadDirectory() self.folderuuid = ht_requests.get_ht_id_path_from_ht_path( self.hyperthoughtui.authcontrol, ht_path=remoteDirPath) self.ui.hyperthoughtLocationLineEdit.setText(remoteDirPath) self.toggleButtons() def handleRemoveCreate(self, source, filterIndex, tableIndex): if "Custom Input" in source: for i in range(len(self.createtablemodel.metadataList)): if self.createtablemodel.metadataList[i]["Source"] == source: self.createtablemodel.beginRemoveRows(QModelIndex(), i, i) del self.createtablemodel.metadataList[i] self.createtablemodel.endRemoveRows() break else: self.treeModel.changeLeafCheck(source) def handleRemoveUse(self, source, listIndex, filterIndex): self.usetablemodel.beginRemoveRows(QModelIndex(), listIndex.row(), listIndex.row()) del self.usetablemodel.metadataList[listIndex.row()] self.usetablemodel.endRemoveRows() def help(self): QDesktopServices.openUrl("http://www.bluequartz.net/") def movethedamnbutton(self): self.appendSourceFilesButton.move( self.ui.useTemplateListView.width() - self.appendSourceFilesButton.width() - 15, self.ui.useTemplateListView.height() - self.appendSourceFilesButton.height()) def openPackage(self): linetext = QFileDialog.getOpenFileName( self, self.tr("Select File"), QStandardPaths.displayName(QStandardPaths.HomeLocation), self.tr("Files (*.ezpak)"))[0] if linetext != "": infile = open(linetext, "r") self.loadTemplateFile(infile.readline()[1:-2]) extractedFile = infile.readline()[1:-2] fileList = infile.readline() fileList = json.loads(fileList) self.fileList = fileList[:] self.uselistmodel = ListModel(self, self.usetablemodel, self.fileList) self.ui.useTemplateListView.setModel(self.uselistmodel) self.extractFile(extractedFile) self.uselistmodel.removeAllRows() for i in range(len(fileList)): self.uselistmodel.addRow(fileList[i]) self.toggleButtons() infile.close() self.ui.TabWidget.setCurrentIndex(1) def restoreTemplate(self): #Clear data on create side self.createtablemodel.metadataList = [] self.createtablemodel.hiddenList = [] self.filterModel.displayed = [] #open template linetext = QFileDialog.getOpenFileName( self, self.tr("Select File"), QStandardPaths.displayName(QStandardPaths.HomeLocation), self.tr("Files (*.ez)"))[0] if linetext != "": infile = open(linetext, "r") infile.readline() fileType = infile.readline() self.fileType = json.loads(fileType) infile.readline() newList = infile.readline() newList = json.loads(newList) newDict = infile.readline() newDict = json.loads(newDict) self.ui.dataTypeText.setText(self.fileType[0][-3:].upper()) self.ui.fileParserCombo.setCurrentIndex( self.ui.fileParserCombo.findText( self.fileType[0][-3:].upper() + " Parser")) self.ui.dataFileLineEdit.setText(self.fileType[0]) self.createtablemodel = TableModelC(newDict, self) self.filterModel.displayed = [] self.filterModel.setSourceModel(self.createtablemodel) self.filterModel.fileType = self.fileType self.createTableSearchFilterModel = QSortFilterProxyModel(self) self.createTableSearchFilterModel.setSourceModel(self.filterModel) self.createTableSearchFilterModel.setFilterKeyColumn(1) self.createTableSearchFilterModel.setDynamicSortFilter(True) self.ui.metadataTableView.setModel( self.createTableSearchFilterModel) self.treeModel = TreeModelR(["Available File Metadata"], newDict, self.createtablemodel, newList, self.filterModel) for i in range(len(newList)): if "Custom Input" in newList[i]["Source"]: self.numCustoms += 1 self.customInputs.append(newList[i]) self.createtablemodel.beginInsertRows( self.createtablemodel.index( len(self.createtablemodel.metadataList), 0), i, i) self.createtablemodel.metadataList.append(newList[i]) self.createtablemodel.endInsertRows() self.createTreeSearchFilterModel = QSortFilterProxyModel(self) self.createTreeSearchFilterModel.setSourceModel(self.treeModel) self.createTreeSearchFilterModel.setFilterKeyColumn(0) self.createTreeSearchFilterModel.setDynamicSortFilter(True) self.createTreeSearchFilterModel.setRecursiveFilteringEnabled(True) self.ui.metadataTreeView.setModel(self.createTreeSearchFilterModel) self.treeModel.checkChanged.connect(self.filterModel.checkList) self.createtrashDelegate.pressed.connect(self.handleRemoveCreate) self.ui.TabWidget.setCurrentIndex(0) def removeRowfromUsefileType(self, index): if self.ui.useTemplateListView.width( ) - 64 < self.ui.useTemplateListView.mapFromGlobal(QCursor.pos()).x(): #this is where to remove the row self.uselistmodel.removeRow(index.row()) def resizeEvent(self, event): super().resizeEvent(event) self.movethedamnbutton() def savePackageAs(self): fileName = QFileDialog.getSaveFileName(self, "Save File", "/Packages/", "Packages (*.ezpak)")[0] if fileName != "": myDir = QDir() myDir.mkpath(fileName) for file in self.uselistmodel.metadataList: QFile.copy(file, fileName + "/" + file.split("/")[-1]) oldtemplate = open(self.templateFilePath, 'r') oldtemplatelist = oldtemplate.readline() filetype = oldtemplate.readline() oldtemplate.readline() oldlist = oldtemplate.readline() oldtree = oldtemplate.readline() oldtemplate.close() with open(fileName + "/" + self.currentTemplate, 'w') as outfile: outfile.write(oldtemplatelist) outfile.write(filetype) json.dump(self.editableKeys, outfile) outfile.write("\n") outfile.write(oldlist) outfile.write(oldtree) with open(fileName + "/" + self.currentTemplate + "pak", 'w') as outfile: json.dump(fileName + "/" + self.currentTemplate, outfile) outfile.write("\n") json.dump(self.ui.otherDataFileLineEdit.text(), outfile) outfile.write("\n") json.dump(self.uselistmodel.metadataList, outfile) def saveTemplate(self): dialog = QFileDialog(self, "Save File", "", "Templates (*.ez)") dialog.setDefaultSuffix(".ez") dialog.setAcceptMode(QFileDialog.AcceptSave) fileName = "" if dialog.exec(): fileName = dialog.selectedFiles()[0] if fileName != "": with open(fileName, 'w') as outfile: json.dump(self.filterModel.displayed, outfile) outfile.write("\n") json.dump(self.filterModel.fileType, outfile) outfile.write("\n") self.createtablemodel.editableList = [] for i in range(len(self.createtablemodel.metadataList)): if self.createtablemodel.metadataList[i][ "Editable"] == 2 and ( self.createtablemodel.metadataList[i] ["Checked"] == 2 or self.createtablemodel. metadataList[i]["Checked"] == 1): self.createtablemodel.editableList.append( self.createtablemodel.metadataList[i]["Key"]) json.dump(self.createtablemodel.editableList, outfile) outfile.write("\n") json.dump(self.createtablemodel.metadataList, outfile) outfile.write("\n") json.dump(self.treeModel.treeDict, outfile) def selectFile(self, fileLink=None): if fileLink == False: linetext = QFileDialog.getOpenFileName( self, self.tr("Select File"), QStandardPaths.displayName(QStandardPaths.HomeLocation), self.tr("Files (*.*)"))[0] else: linetext = fileLink if linetext != "": self.setWindowTitle(linetext) self.ui.dataFileLineEdit.setText(linetext) self.ui.dataTypeText.setText(linetext.split(".")[1].upper()) if self.ui.fileParserCombo.findText( linetext.split(".")[1].upper() + " Parser") != -1: headerDict = {} self.ui.fileParserCombo.setCurrentIndex( self.ui.fileParserCombo.findText( linetext.split(".")[1].upper() + " Parser")) if linetext.split(".")[1].upper() == "CTF": headerDict = ctf.parse_header_as_dict(linetext) elif linetext.split(".")[1].upper() == "ANG": headerDict = ang.parse_header_as_dict(linetext) elif linetext.split(".")[1].upper() == "XML": print("XML Parser used") self.createtablemodel = TableModelC(headerDict, self) self.filterModel.displayed = [] self.filterModel.setSourceModel(self.createtablemodel) self.filterModel.fileType.append(linetext) self.createTableSearchFilterModel = QSortFilterProxyModel(self) self.createTableSearchFilterModel.setSourceModel(self.filterModel) self.createTableSearchFilterModel.setFilterKeyColumn(1) self.createTableSearchFilterModel.setDynamicSortFilter(True) self.ui.metadataTableView.setModel( self.createTableSearchFilterModel) self.treeModel = TreeModel(["Available File Metadata"], headerDict, self.createtablemodel) if len(self.customInputs) != 0: for i in range(len(self.customInputs)): self.createtablemodel.beginInsertRows( self.createtablemodel.index( len(self.createtablemodel.metadataList), 0), i, i) self.createtablemodel.metadataList.append( self.customInputs[i]) self.createtablemodel.endInsertRows() self.createTreeSearchFilterModel = QSortFilterProxyModel(self) self.createTreeSearchFilterModel.setSourceModel(self.treeModel) self.createTreeSearchFilterModel.setFilterKeyColumn(0) self.createTreeSearchFilterModel.setDynamicSortFilter(True) self.createTreeSearchFilterModel.setRecursiveFilteringEnabled(True) self.ui.metadataTreeView.setModel(self.createTreeSearchFilterModel) self.treeModel.checkChanged.connect(self.filterModel.checkList) self.createtrashDelegate.pressed.connect(self.handleRemoveCreate) self.toggleButtons() return True def selectTemplate(self): startLocation = self.ui.hyperthoughtTemplateLineEdit.text() if startLocation == "": startLocation = QStandardPaths.writableLocation( QStandardPaths.HomeLocation) templateFilePath = QFileDialog.getOpenFileName( self, self.tr("Select File"), startLocation, self.tr("Files (*.ez)"))[0] self.loadTemplateFile(templateFilePath) def loadTemplateFile(self, templateFilePath=None): if templateFilePath == "": return False self.templateFilePath = templateFilePath self.usetablemodel.metadataList = [] self.usefilterModel.displayed = [] self.currentTemplate = templateFilePath.split("/")[-1] self.ui.displayedFileLabel.setText(templateFilePath.split("/")[-1]) self.ui.hyperthoughtTemplateLineEdit.setText(templateFilePath) self.ui.otherDataFileLineEdit.setText("") infile = open(templateFilePath, "r") data = infile.readline() fileType = infile.readline() fileType = json.loads(fileType) self.fileType = fileType[0][-4:] editables = infile.readline() self.editableKeys = json.loads(editables) self.usetablemodel.editableKeys = self.editableKeys self.toggleButtons() self.templatedata = json.loads(data) self.usetablemodel.addTemplateList(self.templatedata) self.usefilterModel.setFilterRegExp(QRegExp()) infile.close() return True def showEvent(self, event): super().showEvent(event) self.movethedamnbutton() def toggleButtons(self): if (self.ui.hyperthoughtTemplateLineEdit.text() != "" and self.ui.otherDataFileLineEdit.text() != "" and self.ui.useTemplateListView.model().rowCount() > 0 and self.ui.hyperthoughtLocationLineEdit.text() != ""): self.ui.hyperthoughtUploadButton.setEnabled(True) def uploadToHyperthought(self): auth_control = htauthcontroller.HTAuthorizationController( self.accessKey) metadataJson = ht_utilities.dict_to_ht_metadata( self.usefilterModel.displayed) progress = QProgressDialog("Uploading files...", "Abort Upload", 0, len(self.uselistmodel.metadataList), self) progress.setWindowFlags(Qt.Window | Qt.CustomizeWindowHint | Qt.WindowTitleHint) progress.setAttribute(Qt.WA_DeleteOnClose) self.createUpload.emit(self.uselistmodel.metadataList, auth_control, self.folderuuid, metadataJson) self.uploader.currentUploadDone.connect(progress.setValue) self.uploader.currentlyUploading.connect(progress.setLabelText) self.uploader.allUploadsDone.connect(progress.accept) progress.canceled.connect(lambda: self.uploader.interruptUpload()) progress.setFixedSize(500, 100) progress.exec()
class ExtendedComboBox(QComboBox): def __init__(self, parent=None): super(ExtendedComboBox, self).__init__(parent) #self.setFocusPolicy(Qt.StrongFocus) #self.setSizeAdjustPolicy(QComboBox.AdjustToContents) # self.setStyleSheet(''' #QComboBox { min-width: 1px} #QComboBox QAbstractItemView::item { min-width: 200px;}" #''') self.setEditable(True) self.setVisible(True) # add a filter model to filter matching items self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(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 self.lineEdit().textEdited.connect( self.pFilterModel.setFilterFixedString) 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(text) self.setCurrentIndex(index) self.activated[str].emit(self.itemText(index)) # on model change, update the models of the filter and completer as well def setModel(self, model): super(ExtendedComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) # on model column change, update the model column of the filter and completer as well def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ExtendedComboBox, self).setModelColumn(column) #if __name__ == "__main__": # app = QApplication(sys.argv) # string_list = ['hola muchachos', 'adios amigos', 'hello world', 'good bye'] # combo = ExtendedComboBox() # # either fill the standard model of the combobox # combo.addItems(string_list) # # or use another model # #combo.setModel(QStringListModel(string_list)) # combo.resize(300, 40) # combo.show() # sys.exit(app.exec_())
class Completer(QWidget): """docstring for ClassName Attributes: delegate (CompleterDelegate): the delegate use by the view model (CompleterModel): the model proxy_model (QSortFilterProxyModel ): the proxy model used to filter model panel (QLabel): The description widget view (QListView): the view Signals: activated (str): return the keyword selected """ activated = Signal(str) def __init__(self, parent=None): super().__init__(parent) self._target = None self._completion_prefix = "" self.setWindowFlag(Qt.Popup) self.setFocusPolicy(Qt.NoFocus) # create model self.model = CompleterModel() self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(self.model) self.proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) # create delegate self.delegate = CompleterDelegate() # create view self.view = QListView() self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.view.setFocusPolicy(Qt.NoFocus) self.view.installEventFilter(self) self.view.setModel(self.proxy_model) self.view.setItemDelegate(self.delegate) self.view.setMinimumWidth(200) self.view.setUniformItemSizes(True) self.view.setSpacing(0) self.view.selectionModel().currentRowChanged.connect( self._on_row_changed) self.setFocusProxy(self.view) # create panel info self.panel = QLabel() self.panel.setAlignment(Qt.AlignTop) self.panel.setMinimumWidth(300) self.panel.setWordWrap(True) self.panel.setFrameShape(QFrame.StyledPanel) # Create layout vlayout = QHBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) vlayout.setSpacing(0) vlayout.addWidget(self.view) vlayout.addWidget(self.panel) self.setLayout(vlayout) def set_target(self, target): """Set CodeEdit Args: target (CodeEdit): The CodeEdit """ self._target = target self.installEventFilter(self._target) def eventFilter(self, obj: QObject, event: QEvent) -> bool: """Filter event from CodeEdit and QListView Args: obj (QObject): Description event (QEvent): Description Returns: bool """ # Intercept CodeEdit event if obj == self._target: if event.type() == QEvent.FocusOut: # Ignore lost focus! return True else: obj.event(event) return True # Intercept QListView event if obj == self.view: # Redirect event to QTextExit if event.type() == QEvent.KeyPress and self._target: current = self.view.selectionModel().currentIndex() # emit signal when user press return if event.key() == Qt.Key_Return: word = current.data() self.activated.emit(word) self.hide() event.ignore() return True # use tab to move down/up in the list if event.key() == Qt.Key_Tab: if current.row() < self.proxy_model.rowCount() - 1: self.view.setCurrentIndex( self.proxy_model.index(current.row() + 1, 0)) if event.key() == Qt.Key_Backtab: if current.row() > 0: self.view.setCurrentIndex( self.proxy_model.index(current.row() - 1, 0)) # Route other key event to the target ! This make possible to write text when completer is visible self._target.event(event) return super().eventFilter(obj, event) def complete(self, rect: QRect): """Show completer as popup Args: rect (QRect): the area where to display the completer """ if self.proxy_model.rowCount() == 0: self.hide() return if self._target: pos = self._target.mapToGlobal(rect.bottomRight()) self.move(pos) self.setFocus() if not self.isVisible(): width = 400 #height = self.view.sizeHintForRow(0) * self.proxy_model.rowCount() + 3 # HACK.. TODO better ! #height = min(self._target.height() / 2, height) #self.resize(width, height) self.adjustSize() self.show() def set_completion_prefix(self, prefix: str): """Set prefix and filter model Args: prefix (str): A prefix keyword used to filter model """ self.view.clearSelection() self._completion_prefix = prefix self.proxy_model.setFilterRegularExpression( QRegularExpression(f"^{prefix}.*", QRegularExpression.CaseInsensitiveOption)) if self.proxy_model.rowCount() > 0: self.select_row(0) def select_row(self, row: int): """Select a row in the model Args: row (int): a row number """ index = self.proxy_model.index(row, 0) self.view.selectionModel().setCurrentIndex(index, QItemSelectionModel.Select) def completion_prefix(self) -> str: """getter of completion_prefix TODO: use getter / setter Returns: str: Return the completion_prefix """ return self._completion_prefix def hide(self): """Override from QWidget Hide the completer """ self.set_completion_prefix("") super().hide() def _on_row_changed(self, current: QModelIndex, previous: QModelIndex): """Slot received when user select a new item in the list. This is used to update the panel Args: current (QModelIndex): the selection index previous (QModelIndex): UNUSED """ description = current.data(Qt.ToolTipRole) self.panel.setText(description)
class InstallPluginDialog(QDialog): item_selected = Signal(str) def __init__(self, parent): """Initialize class""" super().__init__(parent) self.setWindowTitle('Install plugin') QVBoxLayout(self) self._line_edit = QLineEdit(self) self._line_edit.setPlaceholderText("Search registry...") self._list_view = QListView(self) self._model = QSortFilterProxyModel(self) self._source_model = _InstallPluginModel(self) self._model.setSourceModel(self._source_model) self._model.setFilterCaseSensitivity(Qt.CaseInsensitive) self._list_view.setModel(self._model) self._timer = QTimer(self) self._timer.setInterval(200) self._button_box = QDialogButtonBox(self) self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.layout().addWidget(self._line_edit) self.layout().addWidget(self._list_view) self.layout().addWidget(self._button_box) self.setAttribute(Qt.WA_DeleteOnClose) self.setMinimumWidth(400) self._button_box.button(QDialogButtonBox.Cancel).clicked.connect( self.close) self._button_box.button(QDialogButtonBox.Ok).clicked.connect( self._handle_ok_clicked) self._list_view.doubleClicked.connect(self._emit_item_selected) self._list_view.selectionModel().selectionChanged.connect( self._update_ok_button_enabled) self._line_edit.textEdited.connect(self._handle_search_text_changed) self._timer.timeout.connect(self._filter_model) def populate_list(self, names): for name in names: self._source_model.appendRow(QStandardItem(name)) @Slot(str) def _handle_search_text_changed(self, _text): self._timer.start() def _filter_model(self): self._model.setFilterRegExp(self._line_edit.text()) @Slot(bool) def _handle_ok_clicked(self, _=False): index = self._list_view.currentIndex() self._emit_item_selected(index) @Slot("QModelIndex") def _emit_item_selected(self, index): if not index.isValid(): return self.item_selected.emit(index.data(Qt.DisplayRole)) self.close() @Slot("QItemSelection", "QItemSelection") def _update_ok_button_enabled(self, _selected, _deselected): on = self._list_view.selectionModel().hasSelection() self._button_box.button(QDialogButtonBox.Ok).setEnabled(on)
class ExtendedComboBox(QComboBox): def __init__(self, table_name="", update_field="", database=None, parent=None): super(ExtendedComboBox, self).__init__(parent) self.__type = Types.TEXT self.setMinimumHeight(30) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self._table_name = table_name self._update_field = update_field self._database = database # add a filter model to filter matching items self.pFilterModel = QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(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 self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.on_completer_activated) def setDatabase(self, database): self._database = database def getType(self): return self.__type # 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(text) self.setCurrentIndex(index) self.activated[str].emit(self.itemText(index)) # on model change, update the models of the filter and completer as well def setModel(self, model): super(ExtendedComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) # on model column change, update the model column of the filter and completer as well def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ExtendedComboBox, self).setModelColumn(column) def updateListValues(self): if self._update_field and self._database != None: self.clear() self._database.openDatabase() items = list(set(self._database.getValuesFromField(self._table_name, self._update_field))) self._database.closeDatabase() self.addItems(items) def setValue(self, value): if self._update_field and self._table_name and self._database != None: self.updateListValues() index = self.findText(value) if index == -1: self.setCurrentIndex(0) else: self.setCurrentIndex(index) def getValue(self): return self.currentText() def clearValue(self): self.setCurrentIndex(0) def connectFunction(self, function): self.activated.connect(function)