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
Exemple #3
0
class AdvComboBox(QComboBox):
    """
    Combo with autocomplete
    Found in Internet by Sergei
    """
    def __init__(self, parent=None):
        super(AdvComboBox, self).__init__(parent)

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

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

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

        self.setCompleter(self.completer)

        # connect signals

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

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

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(str(text))
            self.setCurrentIndex(index)
Exemple #4
0
class ObjListWindow(PBDialog):
    """Create a window managing a list (of bibtexs or of experiments)"""
    def __init__(self, parent=None, gridLayout=False):
        """Init using parent class and create common definitions

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.setMinimumHeight(600)

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

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

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

    def recreateTable(self):
        """Delete the previous table widget and other layout items,
        then create new ones
        """
        self.cleanLayout()
        self.createTable()
Exemple #5
0
class Ui_Main(object):
    def setupUi(self, Main):
        if not Main.objectName():
            Main.setObjectName(u"Main")
        Main.resize(718, 453)
        Main.setMinimumSize(QSize(2018, 1053))

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

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

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

        self.horizontalLayout_3.addWidget(self.slideMenuButton)

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

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

        self.verticalLayout_4.addWidget(self.titleLabel)

        self.horizontalLayout_2.addWidget(self.titlleFrame)

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

        self.horizontalLayout.addWidget(self.minimazeButton)

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

        self.horizontalLayout.addWidget(self.maximazeButton)

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

        self.horizontalLayout.addWidget(self.closeButton)

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

        self.verticalLayout.addWidget(self.topbar_menu)

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

        self.verticalLayout_2.addWidget(self.homeButton)

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

        self.verticalLayout_2.addWidget(self.listButton)

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

        self.verticalLayout_2.addWidget(self.addButton)

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

        self.verticalLayout_2.addWidget(self.removeButton)

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

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

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

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

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

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

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

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

        self.verticalLayout_11.addWidget(self.homeTitleLabel)

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

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

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

        self.horizontalLayout_8.addWidget(self.searchbarLineEdit)

        self.verticalLayout_9.addWidget(self.searchbarFrame)

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

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

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

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

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

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

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

        self.verticalLayout_9.addWidget(self.FilterCheckBoxFrame)

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

        self.clientsDataTableView = QTableView(self.SearchWidget)

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

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

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

        self.verticalLayout_12.addWidget(self.clientsDataTableView)

        self.verticalLayout_9.addWidget(self.tableFrame)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.verticalLayout_14.addLayout(self.gridLayout_4)

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

        self.verticalLayout_14.addWidget(self.Valid_InvalidLabel)

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

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

        self.verticalLayout_13.addWidget(self.ClientViewFrame)

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

        self.verticalLayout_5.addWidget(self.addTextLabel)

        self.verticalLayout_6.addWidget(self.addTextFrame)

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

        self.horizontalLayout_5.addWidget(self.addNameLabel)

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

        self.horizontalLayout_5.addWidget(self.addLineEdit)

        self.verticalLayout_6.addWidget(self.InsertNameFrame)

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

        self.horizontalLayout_6.addWidget(self.addPushBUtton)

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

        self.horizontalLayout_6.addWidget(self.quitPushButton)

        self.verticalLayout_6.addWidget(self.addButtonsFrame)

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

        self.verticalLayout_7.addWidget(self.removeLabel)

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

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

        self.horizontalLayout_10.addWidget(self.removeSearchbarLineEdit)

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

        self.verticalLayout_16.addLayout(self.verticalLayout_15)

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

        self.horizontalLayout_7.addWidget(self.removePushButton)

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

        self.horizontalLayout_7.addWidget(self.quitPushButton_2)

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

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

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

        self.remove_model = TableModel(data)

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

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

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

        self.verticalLayout_8.addWidget(self.removetableView)

        self.horizontalLayout_11.addWidget(self.removeTableFrame)

        self.containerPages.addWidget(self.RemoveWidget)

        self.horizontalLayout_4.addWidget(self.containerPages)

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

        self.verticalLayout.addLayout(self.gridLayout)

        Main.setCentralWidget(self.centralwidget)

        self.retranslateUi(Main)

        self.containerPages.setCurrentIndex(0)

        QMetaObject.connectSlotsByName(Main)

    # setupUi

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

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

        self.recentDateOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 recent\u0103",
                                       None))
        self.oldDateOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 vehce", None))
        self.alphabeticalOrderRadioButton.setText(
            QCoreApplication.translate("Main", u"Ordonare alfabetic\u0103",
                                       None))
        self.ViewClientButton.setText(
            QCoreApplication.translate("Main", u" Vizualizeaz\u0103 ", None))
        self.NameLabel.setText(
            QCoreApplication.translate("Main", u"Nume:", None))
        self.CreationDateLabel.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 creare: ", None))
        self.IdLabel.setText(QCoreApplication.translate("Main", u"ID:", None))
        self.ExpirationDateLabel.setText(
            QCoreApplication.translate("Main", u"Dat\u0103 expirare: ", None))
        self.Valid_InvalidLabel.setText(
            QCoreApplication.translate("Main", u"Client valid", None))
        self.PrintButton.setText(
            QCoreApplication.translate("Main", u"  Genereaz\u0103 PDF ", None))
        self.addTextLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p align=\"center\">Pentru a ad\u0103uga un client nou trebuie </p><p align=\"center\">s\u0103 introduce\u021bi numele:</p></body></html>",
                None))
        self.addNameLabel.setText(
            QCoreApplication.translate("Main", u"Nume: ", None))
        self.addPushBUtton.setText(
            QCoreApplication.translate("Main", u"Adaug\u0103", None))
        self.quitPushButton.setText(
            QCoreApplication.translate("Main", u"Renun\u021b\u0103", None))
        self.removeLabel.setText(
            QCoreApplication.translate(
                "Main",
                u"<html><head/><body><p align=\"center\">Pentru a \u0219terge un client trebuie s\u0103 </p><p align=\"center\">selecta\u021bi r\u00e2ndul corespunz\u0103tor</p></body></html>",
                None))
        self.removePushButton.setText(
            QCoreApplication.translate("Main", u"\u0218terge", None))
        self.quitPushButton_2.setText(
            QCoreApplication.translate("Main", u"Renun\u021b\u0103", None))
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()
Exemple #9
0
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_())
Exemple #13
0
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)
Exemple #15
0
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)