Beispiel #1
0
    def updateMapCompleters(self):
        """Update the auto completers for maps."""
        for i in range(self.max_no_sets):
            map_list = scctool.settings.maps.copy()
            try:
                map_list.remove("TBD")
            except Exception:
                pass
            finally:
                map_list.sort()
                map_list.append("TBD")
            completer = QCompleter(map_list, self.le_map[i])
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setFilterMode(Qt.MatchContains)
            completer.setCompletionMode(
                QCompleter.UnfilteredPopupCompletion)
            completer.setWrapAround(True)
            completer.activated.connect(self.le_map[i].completerFinished)
            self.le_map[i].setCompleter(completer)

        for i in range(self.max_no_vetoes):
            map_list = scctool.settings.maps.copy()
            if 'TBD' in map_list:
                map_list.remove('TBD')
            map_list.sort()
            map_list.append('TBD')
            completer = QCompleter(map_list, self.le_veto_maps[i])
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setFilterMode(Qt.MatchContains)
            completer.setCompletionMode(
                QCompleter.UnfilteredPopupCompletion)
            completer.setWrapAround(True)
            completer.activated.connect(self.le_veto_maps[i].completerFinished)
            self.le_veto_maps[i].setCompleter(completer)
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.createMenu()

        self.completingTextEdit = TextEdit()
        self.completer = QCompleter(self)
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.completingTextEdit.setCompleter(self.completer)

        self.setCentralWidget(self.completingTextEdit)
        self.resize(500, 300)
        self.setWindowTitle("Completer")

    def createMenu(self):
        exitAction = QAction("Exit", self)
        aboutAct = QAction("About", self)
        aboutQtAct = QAction("About Qt", self)

        exitAction.triggered.connect(QApplication.instance().quit)
        aboutAct.triggered.connect(self.about)
        aboutQtAct.triggered.connect(QApplication.instance().aboutQt)

        fileMenu = self.menuBar().addMenu("File")
        fileMenu.addAction(exitAction)

        helpMenu = self.menuBar().addMenu("About")
        helpMenu.addAction(aboutAct)
        helpMenu.addAction(aboutQtAct)

    def modelFromFile(self, fileName):
        f = QFile(fileName)
        if not f.open(QFile.ReadOnly):
            return QStringListModel(self.completer)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        words = []
        while not f.atEnd():
            line = f.readLine().trimmed()
            if line.length() != 0:
                try:
                    line = str(line, encoding='ascii')
                except TypeError:
                    line = str(line)

                words.append(line)

        QApplication.restoreOverrideCursor()

        return QStringListModel(words, self.completer)

    def about(self):
        QMessageBox.about(self, "About",
                "This example demonstrates the different features of the "
                "QCompleter class.")
Beispiel #3
0
class LineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.completer = QCompleter(g.insModel.getInstrumentsName())
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(True)

        self.setCompleter(self.completer)
Beispiel #4
0
class SQLiteCompleterText(QTextEdit):
    def __init__(self, parent=None):
        super(SQLiteCompleterText, self).__init__(parent)
        self.cp = QCompleter(words)
        self.cp.setWrapAround(False)
        self.cp.setWidget(self)
        self.cp.setCompletionMode(QCompleter.PopupCompletion)
        self.cp.activated.connect(self.insertCompletion)

    def insertCompletion(self, completion):
        tc = self.textCursor()
        extra = len(completion) - len(self.cp.completionPrefix())
        tc.movePosition(QTextCursor.Left)
        tc.movePosition(QTextCursor.EndOfWord)
        tc.insertText(completion[-extra:])
        self.setTextCursor(tc)

    def textUnderCursor(self):
        tc = self.textCursor()
        tc.select(QTextCursor.WordUnderCursor)
        return tc.selectedText()

    def focusInEvent(self, e):
        self.cp.setWidget(self)
        super(SQLiteCompleterText, self).focusInEvent(e)

    def keyPressEvent(self, e):
        if self.cp.popup().isVisible():
            if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab):
                e.ignore()
                return

        is_shortcut = ((e.modifiers() & Qt.ControlModifier) != 0 and e.key() == Qt.Key_E & Qt.ControlModifier)
        if not is_shortcut:
            super(SQLiteCompleterText, self).keyPressEvent(e)

        ctrl_or_shift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)
        if ctrl_or_shift and len(e.text()) == 0:
            return

        eo = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
        has_modifier = (e.modifiers() != Qt.NoModifier) and not ctrl_or_shift
        cp = self.textUnderCursor()

        if not is_shortcut and (cp in words or has_modifier or len(e.text()) == 0 or len(cp) < 1 or e.text()[-1] in eo):
            self.cp.popup().hide()
            return

        if cp != self.cp.completionPrefix():
            self.cp.setCompletionPrefix(cp)
            self.cp.popup().setCurrentIndex(self.cp.completionModel().index(0, 0))

        cr = self.cursorRect()
        cr.setWidth(self.cp.popup().sizeHintForColumn(0) + self.cp.popup().verticalScrollBar().sizeHint().width())
        self.cp.complete(cr)
 def updatePlayerCompleters(self):
     """Refresh the completer for the player line edits."""
     list = ["TBD"] + self.controller.historyManager.getPlayerList()
     for player_idx in range(self.max_no_sets):
         for team_idx in range(2):
             completer = QCompleter(list,
                                    self.le_player[team_idx][player_idx])
             completer.setCaseSensitivity(Qt.CaseInsensitive)
             completer.setCompletionMode(QCompleter.InlineCompletion)
             completer.setWrapAround(True)
             self.le_player[team_idx][player_idx].setCompleter(completer)
Beispiel #6
0
class Completer(object):
    """Comleter class to use in the query text editor."""

    # ----------------------------------------------------------------------
    def __init__(self):
        """Initialize Completer class with the keywords and functions."""
        with io.open(
                r'completer_data\keywords.txt', 'r', encoding='utf-8') as f:
            lowercase_keywords = [k.rstrip().lower() for k in f.readlines()]
            uppercase_keywords = [k.upper() for k in lowercase_keywords]
            titlecase_keywords = [k.title() for k in lowercase_keywords]

        with io.open(
                r'completer_data\functions.txt', 'r', encoding='utf-8') as f:
            titlecase_funcs = [f.rstrip() for f in f.readlines()]
            uppercase_funcs = [f.upper() for f in titlecase_funcs]
            lowercase_funcs = [f.lower() for f in titlecase_funcs]

        all_keywords_and_funcs = [
            lowercase_keywords,
            uppercase_keywords,
            titlecase_keywords,
            lowercase_funcs,
            uppercase_funcs,
            titlecase_funcs,
        ]

        self.standard_items = [
            keyword for sublist in all_keywords_and_funcs for keyword in sublist
        ]

        self.completer = QCompleter(self.standard_items)

        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        return

    # ----------------------------------------------------------------------
    def update_completer_string_list(self, items):
        """Update completer string list to include additional strings.

        The list of additional strings include geodatabase items.
        """
        cur_items = []
        titlecase_items = [i.title() for i in items]
        uppercase_items = [i.upper() for i in items]
        lowercase_items = [i.lower() for i in items]

        cur_items.extend(self.standard_items)
        cur_items.extend(titlecase_items + uppercase_items + lowercase_items)
        self.completer.model().setStringList(cur_items)
        return
 def updateTeamCompleters(self):
     """Refresh the completer for the team line edits."""
     list = scctool.settings.config.getMyTeams() + \
         ["TBD"] + self.controller.historyManager.getTeamList()
     for team_idx in range(2):
         completer = QCompleter(list, self.le_team[team_idx])
         completer.setCaseSensitivity(Qt.CaseInsensitive)
         completer.setCompletionMode(QCompleter.InlineCompletion)
         completer.setFilterMode(Qt.MatchContains)
         completer.setWrapAround(True)
         completer.activated.connect(
             self.le_team[team_idx].completerFinished)
         self.le_team[team_idx].setCompleter(completer)
 def updatePlayerCompleters(self):
     """Refresh the completer for the player line edits."""
     list = scctool.settings.config.getMyPlayers(True) + [
         "TBD"
     ] + self.controller.historyManager.getPlayerList()
     for player_idx in range(self.max_no_sets):
         for team_idx in range(2):
             completer = QCompleter(list,
                                    self.le_player[team_idx][player_idx])
             completer.setCaseSensitivity(Qt.CaseInsensitive)
             completer.setCompletionMode(QCompleter.InlineCompletion)
             completer.setFilterMode(Qt.MatchContains)
             completer.setWrapAround(True)
             completer.activated.connect(
                 self.le_player[team_idx][player_idx].completerFinished)
             self.le_player[team_idx][player_idx].setCompleter(completer)
Beispiel #9
0
class DialogDelegueViewChild(Ui_DialogDelegue):
    def __init__(self):
        Ui_DialogDelegue.__init__(self)
        self.idee = None
        self.completer_text_delegue: QCompleter = None

    def setup_ui_with_idee(self, dialog_delegue, idee: Idee):
        """
        Affiche les éléments de la fenêtre
        :param dialog_delegue: la boite de dialogue
        :param idee: l'idée devant être délégué
        :return:
        """
        Ui_DialogDelegue.setupUi(self, dialog_delegue)

        self.completer_text_delegue = QCompleter(self.textDelegue)
        self.completer_text_delegue.setCaseSensitivity(
            QtCore.Qt.CaseInsensitive)
        self.completer_text_delegue.setCompletionMode(
            QCompleter.PopupCompletion)
        self.completer_text_delegue.setWrapAround(False)
        self.textDelegue.setCompleter(self.completer_text_delegue)

        self.textDelegue.textEdited.connect(self.__autocomplete_delegue)
        self.buttonDelegue.accepted.connect(self.__action_delegue)

        self.idee = idee

    def __autocomplete_delegue(self):
        """
        Event d'autocomplete de la saisie de délègue
        :return:
        """
        result = ControllerView.rechercher_personne_delegue(
            self.textDelegue.text())
        self.completer_text_delegue.setModel(QStringListModel(result))

    def __action_delegue(self):
        """
        Délègue une idée
        :return:
        """
        ControllerView.valider_delegation(self.idee, self.textDelegue.text())
    def createTabs(self):
        """Create tabs in main window."""
        try:
            # Initialize tab screen
            self.tabs = QTabWidget()
            self.tab2 = QWidget()
            # self.tabs.resize(300,200)

            # Add tabs
            self.tabs.addTab(self.tab2, _("Custom Match"))

            # Create second tab

            self.tab2.layout = QVBoxLayout()

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match Format:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            container.addWidget(QLabel(_("Best of")), 0)

            self.cb_bestof = QComboBox()
            for idx in range(0, hwctool.settings.max_no_sets):
                self.cb_bestof.addItem(str(idx + 1))
            self.cb_bestof.setCurrentIndex(3)
            string = _('"Best of 6/4": First, a Bo5/3 is played and the'
                       ' ace map gets extended to a Bo3 if needed;'
                       ' Best of 2: Bo3 with only two maps played.')
            self.cb_bestof.setToolTip(string)
            self.cb_bestof.setMaximumWidth(40)
            self.cb_bestof.currentIndexChanged.connect(self.changeBestOf)
            container.addWidget(self.cb_bestof, 0)

            container.addWidget(QLabel(_(" but at least")), 0)

            self.cb_minSets = QComboBox()

            self.cb_minSets.setToolTip(
                _('Minimum number of maps played (even if the match'
                  ' is decided already)'))
            self.cb_minSets.setMaximumWidth(40)
            container.addWidget(self.cb_minSets, 0)
            container.addWidget(QLabel(" " + _("maps") + "  "), 0)
            self.cb_minSets.currentIndexChanged.connect(
                lambda idx: self.highlightApplyCustom())

            label = QLabel("")
            container.addWidget(label, 1)

            self.applycustom_is_highlighted = False

            self.pb_applycustom = QToolButton()
            action = QAction(_("Apply Format"))
            action.triggered.connect(self.applycustom_click)
            self.pb_applycustom.setDefaultAction(action)

            self.pb_applycustom.setFixedWidth(150)
            container.addWidget(self.pb_applycustom, 0)

            self.defaultButtonPalette = self.pb_applycustom.palette()

            self.tab2.layout.addLayout(container)

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match-URL:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            self.le_url_custom = MonitoredLineEdit()
            self.le_url_custom.setAlignment(Qt.AlignCenter)
            self.le_url_custom.setToolTip(
                _('Optionally specify the Match-URL,'
                  ' e.g., for Nightbot commands'))
            self.le_url_custom.setPlaceholderText(
                _("Specify the Match-URL of your Custom Match"))

            completer = QCompleter(["http://"], self.le_url_custom)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
            completer.setWrapAround(True)
            self.le_url_custom.setCompleter(completer)
            self.le_url_custom.setMinimumWidth(360)
            self.le_url_custom.textModified.connect(self.highlightApplyCustom)

            container.addWidget(self.le_url_custom, 11)

            label = QLabel("")
            container.addWidget(label, 1)

            self.pb_resetdata = QPushButton(_("Reset Match Data"))
            self.pb_resetdata.setFixedWidth(150)
            self.pb_resetdata.clicked.connect(self.resetdata_click)
            container.addWidget(self.pb_resetdata, 0)

            self.tab2.layout.addLayout(container)

            self.tab2.setLayout(self.tab2.layout)

        except Exception as e:
            module_logger.exception("message")
Beispiel #11
0
    def createTabs(self):
        """Create tabs in main window."""
        try:
            # Initialize tab screen
            self.tabs = QTabWidget()
            self.tab1 = QWidget()
            self.tab2 = QWidget()
            # self.tabs.resize(300,200)

            # Add tabs
            self.tabs.addTab(self.tab1, _("Match Grabber for AlphaTL && RSTL"))
            self.tabs.addTab(self.tab2, _("Custom Match"))

            # Create first tab
            self.tab1.layout = QVBoxLayout()

            self.le_url = MatchComboBox(self)
            self.le_url.returnPressed.connect(self.refresh_click)

            minWidth = self.scoreWidth + 2 * self.raceWidth + \
                2 * self.mimumLineEditWidth + 4 * 6
            self.le_url.setMinimumWidth(minWidth)

            self.pb_openBrowser = QPushButton(_("Open in Browser"))
            self.pb_openBrowser.clicked.connect(self.openBrowser_click)
            width = (self.scoreWidth + 2 * self.raceWidth +
                     2 * self.mimumLineEditWidth + 4 * 6) / 2 - 2
            self.pb_openBrowser.setMinimumWidth(width)

            container = QHBoxLayout()
            label = QLabel()
            label.setFixedWidth(self.labelWidth)
            container.addWidget(label, 0)
            label = QLabel(_("Match-URL:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)
            container.addWidget(self.le_url, 1)
            button = QPushButton()
            pixmap = QIcon(scctool.settings.getResFile('alpha.png'))
            button.setIcon(pixmap)
            button.clicked.connect(
                lambda: self.controller.openURL("https://alpha.tl/"))
            container.addWidget(button, 0)
            button = QPushButton()
            pixmap = QIcon(scctool.settings.getResFile('rstl.png'))
            button.setIcon(pixmap)
            button.clicked.connect(
                lambda: self.controller.openURL("http://hdgame.net/en/"))
            container.addWidget(button, 0)

            self.tab1.layout = QFormLayout()
            self.tab1.layout.addRow(container)

            container = QHBoxLayout()

            # self.pb_download = QPushButton("Download Images from URL")
            # container.addWidget(self.pb_download)
            label = QLabel()
            label.setFixedWidth(self.labelWidth)
            container.addWidget(label, 0)
            label = QLabel()
            label.setMinimumWidth(80)
            container.addWidget(label, 0)
            self.pb_refresh = QPushButton(_("Load Data from URL"))
            self.pb_refresh.clicked.connect(self.refresh_click)
            container.addWidget(self.pb_openBrowser, 3)
            container.addWidget(self.pb_refresh, 3)

            self.tab1.layout.addRow(container)
            self.tab1.setLayout(self.tab1.layout)

            # Create second tab

            self.tab2.layout = QVBoxLayout()

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match Format:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            container.addWidget(QLabel(_("Best of")), 0)

            self.cb_bestof = QComboBox()
            for idx in range(0, scctool.settings.max_no_sets):
                self.cb_bestof.addItem(str(idx + 1))
            self.cb_bestof.setCurrentIndex(3)
            string = _('"Best of 6/4": First, a Bo5/3 is played and the'
                       ' ace map gets extended to a Bo3 if needed;'
                       ' Best of 2: Bo3 with only two maps played.')
            self.cb_bestof.setToolTip(string)
            self.cb_bestof.setMaximumWidth(40)
            self.cb_bestof.currentIndexChanged.connect(self.changeBestOf)
            container.addWidget(self.cb_bestof, 0)

            container.addWidget(QLabel(_(" but at least")), 0)

            self.cb_minSets = QComboBox()

            self.cb_minSets.setToolTip(
                _('Minimum number of maps played (even if the match'
                  ' is decided already)'))
            self.cb_minSets.setMaximumWidth(40)
            container.addWidget(self.cb_minSets, 0)
            container.addWidget(QLabel(" " + _("maps") + "  "), 0)
            self.cb_minSets.currentIndexChanged.connect(
                lambda idx: self.highlightApplyCustom())

            self.cb_allkill = QCheckBox(_("All-Kill Format"))
            self.cb_allkill.setChecked(False)
            self.cb_allkill.setToolTip(
                _('Winner stays and is automatically'
                  ' placed into the next set'))
            self.cb_allkill.stateChanged.connect(self.allkill_change)
            container.addWidget(self.cb_allkill, 0)

            self.cb_solo = QCheckBox(_("1vs1"))
            self.cb_solo.setChecked(False)
            self.cb_solo.setToolTip(_('Select for solo (non-team matches)'))
            container.addWidget(self.cb_solo, 0)
            self.cb_solo.stateChanged.connect(
                lambda idx: self.highlightApplyCustom())

            label = QLabel("")
            container.addWidget(label, 1)

            self.applycustom_is_highlighted = False

            self.pb_applycustom = QToolButton()
            action = QAction(_("Apply Format"))
            action.triggered.connect(self.applycustom_click)
            self.pb_applycustom.setDefaultAction(action)
            self.custom_menu = QMenu(self.pb_applycustom)
            for format, icon in \
                    self.controller.matchControl.getCustomFormats():
                if icon:
                    action = self.custom_menu.addAction(
                        QIcon(scctool.settings.getResFile(icon)), format)
                else:
                    action = self.custom_menu.addAction(format)
                action.triggered.connect(
                    lambda x, format=format: self.applyCustomFormat(format))
            self.pb_applycustom.setMenu(self.custom_menu)
            self.pb_applycustom.setPopupMode(QToolButton.MenuButtonPopup)

            self.pb_applycustom.setFixedWidth(150)
            container.addWidget(self.pb_applycustom, 0)

            self.defaultButtonPalette = self.pb_applycustom.palette()

            self.tab2.layout.addLayout(container)

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match-URL:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            self.le_url_custom = MonitoredLineEdit()
            self.le_url_custom.setAlignment(Qt.AlignCenter)
            self.le_url_custom.setToolTip(
                _('Optionally specify the Match-URL,'
                  ' e.g., for Nightbot commands'))
            self.le_url_custom.setPlaceholderText(
                _("Specify the Match-URL of your Custom Match"))

            completer = QCompleter(["http://"], self.le_url_custom)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
            completer.setWrapAround(True)
            self.le_url_custom.setCompleter(completer)
            self.le_url_custom.setMinimumWidth(360)
            self.le_url_custom.textModified.connect(self.highlightApplyCustom)

            container.addWidget(self.le_url_custom, 11)

            label = QLabel("")
            container.addWidget(label, 1)

            self.pb_resetdata = QPushButton(_("Reset Match Data"))
            self.pb_resetdata.setFixedWidth(150)
            self.pb_resetdata.clicked.connect(self.resetdata_click)
            container.addWidget(self.pb_resetdata, 0)

            self.tab2.layout.addLayout(container)

            self.tab2.setLayout(self.tab2.layout)

        except Exception as e:
            module_logger.exception("message")
Beispiel #12
0
class TextStatusEditComplete(TextStatusEdit):
    """ Adds Completion functions to the base class

    This class extends 'TextStatusEdit' by:

    1.  providing a QCompleter to validate lines for the
        'fixupText' and 'lineChanged' signals
    2.  providing a popup for suggested completions as
        the user is typing
    3.  auto-completing the line when the user selects
        a suggestion.

    The task of auto completion and providing suggestions
    is provided directly by this class.

    The task validating and cleaning up text is provided by
    the PluginFinder.
    """
    def __init__(self, parent: QWidget = None):
        super().__init__(parent)
        self._dataModel = None
        self._monitorDbChanges = False
        self._enableAutoCompletion = False
        self._completedAndSelected = False
        self._completer = QCompleter(self)

        self._completer.setWidget(self)
        self._completer.setWrapAround(False)
        self._completer.setCompletionMode(QCompleter.PopupCompletion)
        self._completer.setCaseSensitivity(Qt.CaseInsensitive)
        self._completer.setFilterMode(Qt.MatchStartsWith)
        self._completer.setModelSorting(
            QCompleter.CaseInsensitivelySortedModel)
        self._completer.activated.connect(self.replaceLine)

        self._pluginFinder = PluginFinder(self._completer, self)
        self.fixupText.connect(self._pluginFinder.fixupText)
        self.lineChanged.connect(self._pluginFinder.setRowForLine)

        QShortcut(Qt.CTRL + Qt.Key_E, self, self.toggleAutoCompletion)
        QShortcut(Qt.CTRL + Qt.Key_T, self, self.suggestCompletions)

    # --- Methods related to the completer's underlying data model

    def setModel(self, model: QAbstractItemModel):
        self._completer.setModel(model)

    def _updateModelSignals(self):
        """ We do not need to check for column changes due to
        the way our PluginModel is structured. """

        if self._dataModel is not None:
            self._dataModel.rowsMoved.disconnect(self.resetData)
            self._dataModel.rowsInserted.disconnect(self.resetData)
            self._dataModel.rowsRemoved.disconnect(self.resetData)
            self._dataModel.modelReset.disconnect(self.resetData)
            self._dataModel.dataChanged.disconnect(self.resetData)
            self._dataModel.layoutChanged.disconnect(self.resetData)

        if self._monitorDbChanges:
            self._dataModel = self._completer.model()
            if self._dataModel is not None:
                self._dataModel.rowsMoved.connect(self.resetData)
                self._dataModel.rowsInserted.connect(self.resetData)
                self._dataModel.rowsRemoved.connect(self.resetData)
                self._dataModel.modelReset.connect(self.resetData)
                self._dataModel.dataChanged.connect(self.resetData)
                self._dataModel.layoutChanged.connect(self.resetData)
        else:
            self._dataModel = None

    def monitorDbChanges(self, enable: bool):
        """ Enable invalidating line status when
        the data model changes.

        Depending on the underlying data model, it may
        be unnecessary to monitor these changes, or, a
        higher level class can monitor specific signals
        more efficiently.  So, this is not enabled
        by default.  """

        if self._monitorDbChanges == enable:
            return

        self._monitorDbChanges = enable
        if enable:
            self._dataModel = self._completer.model()
            self._completer.completionModel().sourceModelChanged.connect(
                self._updateModelSignals)
        else:
            self._completer.completionModel().sourceModelChanged.disconnect(
                self._updateModelSignals)
        self._updateModelSignals()

    # ---- Methods related to line completion

    def completer(self):
        return self._completer

    def enableAutoCompletion(self, enable: bool):
        self._enableAutoCompletion = enable

    def toggleAutoCompletion(self):
        self.enableAutoCompletion(not self._enableAutoCompletion)

    def _textUnderCursor(self):
        tc = self.textCursor()
        if tc.positionInBlock() == 0 and len(tc.block().text()) > 1:
            tc.movePosition(QTextCursor.NextCharacter)
        tc.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor)
        return tc.selectedText().lstrip()

    def suggestCompletions(self):
        if self.isLineInvalid(self.textCursor().blockNumber()):
            self._suggestCompletionsForText(self._textUnderCursor())

    def _suggestCompletionsForText(self, prefix: str):
        if not prefix:
            return
        if prefix != self._completer.completionPrefix():
            self._completer.setCompletionPrefix(prefix)
            self._completer.popup().setCurrentIndex(
                self._completer.completionModel().index(0, 0))
        if self._completer.completionCount() == 1:
            self._insertSuggestion(self._completer.currentCompletion())
        else:
            rect = self.cursorRect()
            rect.moveRight(self.statusAreaWidth())
            rect.setWidth(
                self._completer.popup().sizeHintForColumn(
                    self._completer.completionColumn()) +
                self._completer.popup().verticalScrollBar().sizeHint().width())
            self._completer.complete(rect)

    def _insertSuggestion(self, text: str):
        """ Only one suggestion matched, prefill line """

        cursor = self.textCursor()
        # handle when cursor is in middle of line
        if not cursor.atBlockEnd():
            cursor.beginEditBlock()
            cursor.select(QTextCursor.LineUnderCursor)
            cursor.removeSelectedText()
            cursor.insertText(text)
            cursor.movePosition(QTextCursor.StartOfLine)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            self._completedAndSelected = True
            self.setTextCursor(cursor)
            cursor.endEditBlock()
            return

        # handle when cursor at end of line
        cursor.beginEditBlock()
        numCharsToComplete = len(text) - len(
            self._completer.completionPrefix())
        insertionPosition = cursor.position()
        cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
        cursor.removeSelectedText()
        cursor.insertText(text[-numCharsToComplete:])
        cursor.setPosition(insertionPosition)
        cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
        self._completedAndSelected = True
        self.setTextCursor(cursor)
        cursor.endEditBlock()

    def keyPressEvent(self, event: QKeyEvent):
        if self._completedAndSelected and self.handledCompletedAndSelected(
                event):
            return

        self._completedAndSelected = False
        if self._completer.popup().isVisible():
            ignoredKeys = [
                Qt.Key_Up,
                Qt.Key_Down,
                Qt.Key_Enter,
                Qt.Key_Return,
                Qt.Key_Tab,
                Qt.Key_Escape,
            ]
            if event.key() in ignoredKeys:
                event.ignore()
                return
            self._completer.popup().hide()

        super().keyPressEvent(event)
        if not self._enableAutoCompletion:
            return

        ctrlOrShift = (event.modifiers() & Qt.ShiftModifier == Qt.ShiftModifier
                       or event.modifiers() & Qt.ControlModifier
                       == Qt.ControlModifier)

        if ctrlOrShift and not event.text():
            return

        if self.textCursor().atBlockEnd():
            self.suggestCompletions()

    def mousePressEvent(self, event: QMouseEvent):
        if self._completedAndSelected:
            self._completedAndSelected = False
            self.document().undo()
        super().mousePressEvent(event)

    def handledCompletedAndSelected(self, event: QKeyEvent):
        """ The line is prefilled when only one completion matches. The user
        can accept the suggestion by pressing 'Enter'. The user can reject
        the suggestion by pressing 'Esc' or by continuing to type. """

        self._completedAndSelected = False
        cursor = self.textCursor()
        acceptKeys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Tab]
        if event.key() in acceptKeys:
            self.replaceLine(self._completer.currentCompletion())
        elif event.key() == Qt.Key_Escape:
            self.document().undo()
        else:
            self.document().undo()
            return False

        self.setTextCursor(cursor)
        event.accept()
        return True

    def replaceLine(self, text: str):
        cursor = self.textCursor()
        cursor.beginEditBlock()
        cursor.select(QTextCursor.LineUnderCursor)
        cursor.removeSelectedText()
        cursor.insertText(text)
        cursor.movePosition(QTextCursor.EndOfLine)
        self.setTextCursor(cursor)
        cursor.endEditBlock()

    # ---- Methods related to Context Menu

    def createStandardContextMenu(self, pos: QPoint):
        menu = super().createStandardContextMenu(pos)
        menu.addSeparator()
        autoCompletionAction = menu.addAction(
            QIcon(),
            self.tr("Enable Auto Complete"),
            self.toggleAutoCompletion,
            QKeySequence(Qt.CTRL + Qt.Key_E),
        )
        autoCompletionAction.setCheckable(True)
        autoCompletionAction.setChecked(self._enableAutoCompletion)

        completionAction = menu.addAction(
            QIcon(),
            self.tr("Suggest Completions"),
            self.suggestCompletions,
            QKeySequence(Qt.CTRL + Qt.Key_T),
        )
        completionAction.setEnabled(
            self.isLineInvalid(self.textCursor().blockNumber()))
        return menu
class mainGUI(QMainWindow):
    def __init__(self, parent=None):
        # super().__init__()
        # QMainWindow.__init__(self, None)
        super(mainGUI, self).__init__(parent)
        self.initUI()

    def initUI(self):

        # -------- Window Settings -------------------------------------------
        # self.setGeometry(100,100,700,700)
        self.setFixedSize(700, 700)
        self.setWindowTitle("AutoComplete Sentence Tool")
        # self.show()

        # -------- Status Bar -------------------------------------------
        self.status = self.statusBar()

        # -------- Sentence List -------------------------------------------
        self.sentencelabel = QLabel(self)
        self.sentencelabel.setText('Sentence List')
        self.sentencelabel.setStyleSheet("color: blue;"
                                         "font: bold 18pt 'Times New Roman';")
        self.sentencelabel.setAlignment(Qt.AlignCenter)
        self.sentencelabel.setGeometry(50, 70, 400, 30)

        # self.sentencelist = QTextEdit(self)
        font = QFont()
        font.setFamily('Courier')
        font.setFixedPitch(True)
        font.setPointSize(10)

        self.sentencelist = TextEdit(self)
        # self.sentencelist.setFont(font)
        self.sentencelist.setStyleSheet("color: rgb(255, 0, 0);")
        self.completer = QCompleter(self)
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.sentencelist.setCompleter(self.completer)
        self.sentencelist.setGeometry(50, 100, 400, 550)
        # self.sentencelist.textChanged.connect(self.updateSentenceList)

        # -------- Word List -------------------------------------------
        self.wordlabel = QLabel(self)
        self.wordlabel.setText('Word List')
        self.wordlabel.setStyleSheet("color: blue;"
                                     "font: bold 18pt 'Times New Roman';")
        self.wordlabel.setAlignment(Qt.AlignCenter)
        self.wordlabel.setGeometry(500, 70, 150, 30)

        self.wordlist = QTextEdit(self)
        self.wordlist.setGeometry(500, 100, 150, 550)
        infile = open('resources/wordlist.txt', 'r')
        self.wordlist.setPlainText(infile.read())
        infile.close()
        self.wordlist.textChanged.connect(self.updateWordsList)
        self.words = self.wordlist.document().toPlainText()
        keywordPatterns = self.words.split('\n')

        while '' in keywordPatterns:
            keywordPatterns.remove('')

        for i, wd in enumerate(keywordPatterns):
            keywordPatterns[i] = "\\b" + keywordPatterns[i] + "\\b"

        self.highlighter = Highlighter(keywordPatterns,
                                       self.sentencelist.document())

        # -------- Statusbar -------------------------------------------
        self.status = self.statusBar()
        self.sentencelist.cursorPositionChanged.connect(self.CursorPosition)

    def updateWordsList(self):
        self.words = self.wordlist.document().toPlainText()
        outfile = open('resources/wordlist.txt', 'w')
        outfile.write(self.words)
        outfile.close()
        # print(self.words.split('\n'))
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))

        keywordPatterns = self.words.split('\n')
        while '' in keywordPatterns:
            keywordPatterns.remove('')

        for i, wd in enumerate(keywordPatterns):
            keywordPatterns[i] = "\\b" + keywordPatterns[i].upper() + "\\b"

        self.highlighter.updateKeywordPatterns(keywordPatterns)

    def updateSentenceList(self):
        self.sentences = self.sentencelist.document().toPlainText()

        if len(self.sentences.split('\n')):
            for sentence in self.sentences.split('\n'):
                pass

    def modelFromFile(self, fileName):
        f = QFile(fileName)
        if not f.open(QFile.ReadOnly):
            return QStringListModel(self.completer)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        words = []
        while not f.atEnd():
            line = f.readLine().trimmed()
            if line.length() != 0:
                try:
                    line = str(line, encoding='ascii')
                except TypeError:
                    line = str(line)

                words.append(line)

        QApplication.restoreOverrideCursor()

        return QStringListModel(words, self.completer)

    def CursorPosition(self):
        line = self.sentencelist.textCursor().blockNumber()
        col = self.sentencelist.textCursor().columnNumber()
        linecol = ("Line: " + str(line) + " | " + "Column: " + str(col))
        self.status.showMessage(linecol)
class TabController(QWidget):

    # Adding signal
    catCreated = pyqtSignal(Tag)
    catClicked = pyqtSignal(Tag)
    catUpdated = pyqtSignal(Tag)
    childClicked = pyqtSignal(str)

    def __init__(self, parent, docker, window, editSpace_theme='light'):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)
        self.editSpace = None  # Used for displaying source code
        self.graphview = None  # Used for the graphical display
        self.aiml = None  # THIS SHOULD BE THE ONLY MODEL IN THE SYSTEM
        self.docker = docker
        self.window = window
        self.up_to_date = True
        self.editSpace_theme = editSpace_theme

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(300, 200)

        # Add tabs
        self.tabs.addTab(self.tab1, "Text Display")
        self.tabs.addTab(self.tab2, "Graph Display")

        # Create tabs
        self.add_editspace(self.tab1)
        self.add_graphview(self.tab2)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

        # Make Connection
        self.docker.catCreated.connect(self.categoryCreated)
        self.window.catCreated.connect(self.categoryCreated)
        self.docker.catUpdated.connect(
            self.categoryUpdated
        )  # connecting signal from EditorWindow to update Node
        self.editSpace.textChanged.connect(self.editsMade)

    def editsMade(self):
        self.tabs.setStyleSheet('QTabBar::tab {background-color: red;}')
        self.up_to_date = False
        if DEBUG: print("Text has been changed!!")

    def add_editspace(self, tab):
        tab.layout = QVBoxLayout(self)
        # Setting main editing area where Files will be displayed and can be edited
        self.editSpace = QCodeEditor(self, theme_color=self.editSpace_theme)

        # list for Completer model
        words = [
            "<aiml></aiml>", "<topic></topic>", "<category></category>",
            "<pattern></pattern>", "<template></template>",
            "<condition></condition>", "<li></li>", "<random></random>",
            "<set></set>", "<think></think>", "<that></that>", "<oob></oob>",
            "<robot></robot>", "<options></options>", "<option></option>",
            "<image></image>", "<video></video>", "<filename></filename>",
            "<get name=\"\" />", "<srai/>", "<star/>"
        ]

        # Setting completer
        self.completer = QCompleter(self.editSpace)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        # self.completer.setCompletionMode(QCompleter.PopupCompletion)
        print(
            f"modelFromFile returning: {QStringListModel(words, self.completer).stringList()}"
        )
        # self.completer.setModel(self.modelFromFile('GUI/style/keywords.txt'))
        self.completer.setModel(QStringListModel(words, self.completer))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.editSpace.setCompleter(self.completer)

        self.tab1.layout.addWidget(self.editSpace)
        tab.setLayout(tab.layout)

    def modelFromFile(self, fileName):
        if getattr(sys, 'frozen', False):
            path = os.path.dirname(sys.executable)
            path = path[:-4] + fileName
        else:
            path = os.path.abspath(os.path.dirname(
                os.path.abspath(__file__))) + fileName

        if DEBUG: print(f"path: {path}")
        with open(path, "r") as f:
            words = f.read().splitlines()

        QApplication.restoreOverrideCursor()
        if DEBUG:
            print(
                f"modelFromFile returning: {QStringListModel(words, self.completer).stringList()}"
            )
        return QStringListModel(words, self.completer)

    def add_graphview(self, tab):
        tab.layout = QGridLayout(self)
        # Setting of backdrop for view categories as nodes.
        self.graphview = EditorWidget(self)

        # Building legend and zoom buttons
        self.add_legend()

        # Adding widgets to layout
        self.tab2.layout.addWidget(self.legendLabel, 0, 0)
        self.tab2.layout.addWidget(self.zoom_out, 0, 1)
        self.tab2.layout.addWidget(self.zoom_in, 0, 2)
        self.tab2.layout.addWidget(self.graphview, 1, 0, 1, 3)

        # Making button connections
        self.zoom_out.clicked.connect(self.zoom_out_clicked)
        self.zoom_in.clicked.connect(self.zoom_in_clicked)

        # Setting layout
        tab.setLayout(tab.layout)

    def add_legend(self):
        # Creating buttons to zoom in and out of the graph scene
        self.zoom_out = QPushButton("-")
        self.zoom_out.resize(50, 50)
        self.zoom_in = QPushButton("+")
        self.zoom_in.resize(50, 50)

        # Creating legend to clarify what fields in nodes mean
        self.legendLabel = QLabel()
        self.legendLabel.setFont(QFont("Sanserif", 10))
        self.legendLabel.setText(
            "1st textbox represents the Pattern Tag\n"
            "2nd textbox represents the That Tag\n"
            "3rd textbox represents the Template Tag\n"
            "Yellow node is node currently selected, Red nodes are children, Turquoise nodes are parents."
        )
        self.legendLabel.setStyleSheet(
            "QLabel {background-color: black; color: white; border: 1px solid "
            "#01DFD7; border-radius: 5px;}")

    def zoom_in_clicked(self):
        if DEBUG: print("Zoom In Clicked")
        zoomFactor = self.graphview.view.zoomInFactor
        zoomFactor += (self.graphview.view.zoomStep * 0.25)
        self.graphview.view.scale(zoomFactor, zoomFactor)

    def zoom_out_clicked(self):
        if DEBUG: print("Zoom Out Clicked")
        zoomFactor = self.graphview.view.zoomInFactor
        zoomFactor -= (self.graphview.view.zoomStep * 0.5)
        self.graphview.view.scale(zoomFactor, zoomFactor)

    def create_category_code_editor(self, cat):
        try:
            if self.aiml is not None:
                if DEBUG: print(f"Current aiml Model:\n{self.aiml}")
                if DEBUG: print("Ok to add category")
                self.aiml.append(cat)
                if DEBUG: print("appended category to AIML object")
                self.catCreated.emit(self.aiml)
                return cat
            else:
                if DEBUG: print("CodeEditor is equal to None")
                self.aiml = AIML()
                # self.clear()
                self.aiml.append(cat)
                if DEBUG: print("appended category to AIML object")
                self.catCreated.emit(self.aiml)
                return cat
        except Exception as ex:
            handleError(ex)
            print(
                "Exception caught in TabController - create_category_code_editor()"
            )
            print(ex)

    def create_category_graph_view(self, cat):
        try:
            if cat.type == "topic":
                # Iterate through topic and place categories
                for category in cat.tags:
                    thatToCheck = self.graphview.getLastSentence(category)
                    if DEBUG: print("got last sentence of category")
                    title = "Category: " + category.cat_id
                    aNode = Node(self.graphview.scene, title, category)
                    if DEBUG: print("created node")
                    aNode.content.wdg_label.displayVisuals(category)
                    if DEBUG: print("displayed contents on node")

                    if thatToCheck is not None:
                        for that in thatToCheck:
                            self.graphview.findChildNodes(aNode, that)

                    # FIXME: Nodes only get placed if there are <that> tags otherwise get stacked in default place.
                    self.graphview.findParentNodes(aNode)
                    self.graphview.placeNodes(self.graphview.scene.nodes)

                    for node in self.graphview.scene.nodes:
                        node.updateConnectedEdges()

                    aNode.content.catClicked.connect(
                        self.graphview.categoryClicked
                    )  # connecting signals coming from Content Widget

                    # NOTE: When addChildClicked has been implemented then this can be uncommented
                    # if DEBUG: print("trying to connect addChild button")
                    # aNode.content.childClicked.connect(self.graphview.addChildClicked) # connecting signals coming from Content Widget
            elif cat.type == "comment":
                print("Comment found, don't display comments on graphview.")
            else:
                thatToCheck = self.graphview.getLastSentence(cat)
                if DEBUG: print("got last sentence of category")
                title = "Category: " + cat.cat_id
                aNode = Node(self.graphview.scene, title, cat)
                if DEBUG: print("created node")
                aNode.content.wdg_label.displayVisuals(cat)
                if DEBUG: print("displayed contents on node")

                if thatToCheck is not None:
                    for that in thatToCheck:
                        self.graphview.findChildNodes(aNode, that)

                self.graphview.findParentNodes(aNode)
                self.graphview.placeNodes(self.graphview.scene.nodes)

                for node in self.graphview.scene.nodes:
                    node.updateConnectedEdges()

                aNode.content.catClicked.connect(
                    self.graphview.categoryClicked
                )  # connecting signals coming from Content Widget
        except Exception as ex:
            print(
                "Exception caught in TabController - create_category_graph_view()"
            )
            print(ex)
            handleError(ex)

    # slot function for a category being created and displaying on editSpace
    @pyqtSlot(Tag)
    def categoryCreated(self, cat):
        try:
            if DEBUG: print("In TabController Slot - categoryCreated()")
            cat = self.create_category_code_editor(cat)
            self.create_category_graph_view(cat)
        except Exception as ex:
            print("Exception caught in TabController - categoryCreated()")
            print(ex)
            handleError(ex)

    # Slot function for updating categories.
    @pyqtSlot(Tag)
    def categoryUpdated(self, cat):
        if DEBUG: print("slot in TabController - categoryUpdated()")
        try:
            updatedCat = self.aiml.update(cat)

            # NOTE: This should be a safer alternative rather than updating
            #       then requiring user to manually compile. But this still
            #       runs into the same issue as compiling manually after
            #       moving and updating nodes.
            # self.editSpace.setPlainText(str(self.aiml))
            # self.window.onCompile()

            if DEBUG: print(f'Updated aiml object:\n{self.aiml}')
            self.graphview.updateNode(cat)  # Updating graphview display
            if DEBUG: print("EditorWidget successfully updated")
            if DEBUG:
                print(f"aiml object to set (TabController):\n{self.aiml}")
            self.catUpdated.emit(
                self.aiml
            )  # Sending the updated aiml object to the CodeEditor.
        except Exception as ex:
            print("Exception caught in TabController - categoryUpdated()")
            print(ex)
            handleError(ex)
Beispiel #15
0
class TextEditTechnique(QTextEdit):
    def __init__(self, text_file, input_trigger=None, active=True):
        super(TextEditTechnique, self).__init__()
        self._completer = None
        self.isActive = active
        word_list = self.get_suggestion_words(text_file)
        self.input_trigger = input_trigger
        # connects the text textChanged event
        self.textChanged.connect(self.handle_input)
        self.char_length = 1
        self.set_completer(word_list)
        self.technique_used = False
        self.no_suggestion_input = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-= "

    # gets words for suggestion
    def get_suggestion_words(self, text_file):
        words = []
        file = open(text_file)
        for line in file:
            for word in line.split(' '):
                word = word.strip().lower().replace('.', '').replace(
                    ',', '').replace(':', '').replace('?', '')
                if word and word not in words:
                    words.append(word)
        file.close()
        return words

    # initializes the completer
    def set_completer(self, words):
        if self._completer is not None:
            self._completer.activated.disconnect()
        self._completer = QCompleter(words, self)
        self._completer.setCaseSensitivity(Qt.CaseInsensitive)
        self._completer.setWrapAround(False)
        self._completer.setWidget(self)
        self._completer.setCompletionMode(QCompleter.PopupCompletion)
        self._completer.activated.connect(self.insert_sel_suggestion)

    # insert the selected suggestion and moves the text cursor
    def insert_sel_suggestion(self, suggestion):
        if self._completer.widget() is not self:
            return
        text_cursor = self.textCursor()
        extra = len(suggestion) - len(self._completer.completionPrefix())
        text_cursor.movePosition(QTextCursor.Left)
        text_cursor.movePosition(QTextCursor.EndOfWord)
        text_cursor.insertText(suggestion[-extra:])
        self.setTextCursor(text_cursor)

    # returns the current typed word
    def text_under_cursor(self):
        text_cursor = self.textCursor()
        text_cursor.select(QTextCursor.WordUnderCursor)
        return text_cursor.selectedText()

    # sets the widget
    def focusInEvent(self, e):
        if self._completer is not None and self.isActive:
            self._completer.setWidget(self)
        super(TextEditTechnique, self).focusInEvent(e)

    def keyPressEvent(self, e):

        # behaves like a normal input field!
        if not self.isActive or self._completer is None:
            super(TextEditTechnique, self).keyPressEvent(e)
            return

        # ignore events funktion keys on Textedit if popup is visible --> popup behaves default
        if self._completer.popup().isVisible():
            if e.key() in (Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape,
                           Qt.Key_Tab, Qt.Key_Backtab):
                e.ignore()
                self.technique_used = True
                return
        # writes text in the editfield
        super(TextEditTechnique, self).keyPressEvent(e)

        ctrl_or_shift = e.modifiers() & (Qt.ControlModifier | Qt.ShiftModifier)
        if self._completer is None or (ctrl_or_shift and len(e.text()) == 0):
            return

        has_modifier = (e.modifiers() != Qt.NoModifier) and not ctrl_or_shift
        completion_prefix = self.text_under_cursor()
        # hide the popup for no chars, modifiers, shift and no text
        if (has_modifier or len(e.text()) == 0
                or len(completion_prefix) < self.char_length
                or e.text()[-1] in self.no_suggestion_input):
            self._completer.popup().hide()
            return

        # shows the popup with the suggested words
        if completion_prefix != self._completer.completionPrefix():
            self._completer.setCompletionPrefix(completion_prefix)
            self._completer.popup().setCurrentIndex(
                self._completer.completionModel().index(0, 0))

        cursor = self.cursorRect()
        cursor.setWidth(
            self._completer.popup().sizeHintForColumn(0) +
            self._completer.popup().verticalScrollBar().sizeHint().width())
        self._completer.complete(cursor)

    # event called if textedit input has changed
    def handle_input(self):
        timestamp = time.time()
        self.input_trigger.emit(self.toPlainText(), timestamp)

    # clears the text input
    def clear_input(self):
        self.setHtml('')

    # deactivates the completer
    def deactivate_completer(self):
        self.isActive = False

    # activates the completer
    def activate_completer(self):
        self.isActive = True
    def createWindow(self, mainWindow, placeholder, team):
        """Create readme sub window."""
        super().__init__(None)
        self.mainWindow = mainWindow
        self.controller = mainWindow.controller
        self.team = team
        self.liquipediaGrabber = LiquipediaGrabber()
        self.setWindowIcon(QIcon(
            scctool.settings.getResFile("liquipedia.png")))

        self.setWindowModality(Qt.ApplicationModal)

        mainLayout = QGridLayout()
        self.qle_search = QLineEdit(placeholder)
        self.qle_search.setAlignment(Qt.AlignCenter)
        self.qle_search.returnPressed.connect(self.search)
        completer = QCompleter(
            scctool.settings.config.getMyTeams() +
            self.controller.historyManager.getTeamList(), self.qle_search)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        completer.setWrapAround(True)
        self.qle_search.setCompleter(completer)

        mainLayout.addWidget(self.qle_search, 0, 0, 1, 2)
        searchButton = QPushButton(_("Search"))
        searchButton.clicked.connect(self.search)
        mainLayout.addWidget(searchButton, 0, 2)

        self.box = QGroupBox(_("Results"))
        layout = QHBoxLayout()
        self.result_list = QListWidget()
        self.result_list.setViewMode(QListWidget.IconMode)
        self.result_list.itemDoubleClicked.connect(self.doubleClicked)
        self.result_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.result_list.customContextMenuRequested.connect(
            self.listItemRightClicked)

        self.result_list.setIconSize(QSize(75, 75))
        # list.setWrapping(False)
        # list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.result_list.setAcceptDrops(False)
        self.result_list.setDragEnabled(False)
        layout.addWidget(self.result_list)
        self.box.setLayout(layout)

        mainLayout.addWidget(self.box, 1, 0, 1, 3)

        selectButton = QPushButton(" " + _("Use Selected Logo") + " ")
        selectButton.clicked.connect(self.applyLogo)
        closeButton = QPushButton(_("Cancel"))
        closeButton.clicked.connect(self.close)
        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum), 2,
            0)
        mainLayout.addWidget(closeButton, 2, 1)
        mainLayout.addWidget(selectButton, 2, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle(_("Liquipedia Image Search"))

        self.resize(
            QSize(mainWindow.size().width() * 0.9,
                  self.sizeHint().height()))
        relativeChange = QPoint(mainWindow.size().width() / 2,
                                mainWindow.size().height() / 3)\
            - QPoint(self.size().width() / 2,
                     self.size().height() / 3)
        self.move(mainWindow.pos() + relativeChange)
Beispiel #17
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.createMenu()

        self.completingTextEdit = TextEdit()
        self.completer = QCompleter(self)
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.completingTextEdit.setCompleter(self.completer)

        self.setCentralWidget(self.completingTextEdit)
        self.resize(500, 300)
        self.setWindowTitle("Completer")

    def createMenu(self):
        exitAction = QAction("Exit", self)
        aboutAct = QAction("About", self)
        aboutQtAct = QAction("About Qt", self)

        exitAction.triggered.connect(QApplication.instance().quit)
        aboutAct.triggered.connect(self.about)
        aboutQtAct.triggered.connect(QApplication.instance().aboutQt)

        fileMenu = self.menuBar().addMenu("File")
        fileMenu.addAction(exitAction)

        helpMenu = self.menuBar().addMenu("About")
        helpMenu.addAction(aboutAct)
        helpMenu.addAction(aboutQtAct)

    def modelFromFile(self, fileName):
        f = QFile(fileName)
        if not f.open(QFile.ReadOnly):
            return QStringListModel(self.completer)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        words = []
        while not f.atEnd():
            line = f.readLine().trimmed()
            if line.length() != 0:
                try:
                    line = str(line, encoding='ascii')
                except TypeError:
                    line = str(line)

                words.append(line)

        QApplication.restoreOverrideCursor()

        return QStringListModel(words, self.completer)

    def about(self):
        QMessageBox.about(
            self, "About",
            "This example demonstrates the different features of the "
            "QCompleter class.")
Beispiel #18
0
class EditerIdeeViewChild(Ui_DialogEditerIdee):

    role_etat = Qt.UserRole + 5

    def __init__(self):
        self.dialog = None
        self.idee: Idee = None
        self.completer_text_delegue: QCompleter = None

    def setup_ui_with_idee(self, dialog_editer_idee, idee: Idee):
        """
        Caharge la fenetre
        :param dialog_editer_idee: la boite de dialogue
        :param idee: l'idée devant être modifiée
        :return:
        """
        Ui_DialogEditerIdee.setupUi(self, dialog_editer_idee)

        # Evenements
        self.buttonEditerEtapes.clicked.connect(self.__open_etape)
        self.buttonValider.clicked.connect(self.__editer_action)
        self.textDelegue.textEdited.connect(self.__autocomplete_delegue)

        # AutoComplete Deleguation
        self.completer_text_delegue = QCompleter(self.textDelegue)
        self.completer_text_delegue.setCaseSensitivity(
            QtCore.Qt.CaseInsensitive)
        self.completer_text_delegue.setCompletionMode(
            QCompleter.PopupCompletion)
        self.completer_text_delegue.setWrapAround(False)
        self.textDelegue.setCompleter(self.completer_text_delegue)

        # populate QComboBox
        model = QStandardItemModel(self.comboEtat)
        model.clear()
        for etat in Etat:
            item = QStandardItem(etat.name)
            item.setData(etat, self.role_etat)
            model.appendRow(item)
        self.comboEtat.setModel(model)
        self.comboEtat.show()

        # mise en mémoire des infos récuéré
        self.dialog = dialog_editer_idee
        self.idee = ControllerView.get_idee_fm_db(idee)

        # affichage
        self.__afficher_idee()

    def __afficher_idee(self):
        """
        Rempli les élements à partir de l'idée demandée
        :return:
        """
        self.__select_etat_combobox(Etat(self.idee.etat))
        self.labelDate.setText(
            self.idee.dateCreation.strftime('%d/%m/%Y %H:%M:%S'))
        self.textIdee.setPlainText(self.idee.texte)
        self.textCommentaire.setPlainText(self.idee.commentaire)
        if self.idee.delegue and self.idee.delegue.nom:
            self.textDelegue.setText(self.idee.delegue.nom)

    def __open_etape(self):
        """
        Ouvre la dialgoue des étapes
        :return:
        """
        dialog_etapes = QtWidgets.QDialog(self.dialog)
        ui = GererActionViewChild()
        ui.setup_ui_with_idee(dialog_etapes, self.idee)
        dialog_etapes.exec_()

    def __autocomplete_delegue(self):
        """
        Autocomplete sur le champ Délègue
        :return:
        """
        result = controllerDelegue.rechercher_personne_delegue(
            self.textDelegue.text())
        self.completer_text_delegue.setModel(QStringListModel(result))
        if self.textDelegue.text():
            self.__select_etat_combobox(Etat.DELEGUER)

    def __editer_action(self):
        """
        Modifie une idée en controlant les champs
        :return:
        """
        if not self.textIdee.toPlainText():
            error = QMessageBox()
            error.setIcon(QMessageBox.Warning)
            error.setText("Le champ idée doit être rempli")
            error.setWindowTitle("Erreur")
            error.setStandardButtons(QMessageBox.Ok)
            error.exec_()
            return

        if (self.textDelegue.text() and self.comboEtat.currentText() != Etat.DELEGUER.name) or \
                (not self.textDelegue.text() and self.comboEtat.currentText() == Etat.DELEGUER.name):
            error = QMessageBox()
            error.setIcon(QMessageBox.Warning)
            error.setText(
                "Si la tâche est déléguée, son état doit être à l'état délégué"
            )
            error.setWindowTitle("Erreur")
            error.setStandardButtons(QMessageBox.Ok)
            error.exec_()
            return

        ControllerView.modifier_idee(
            self.idee.id, self.textIdee.toPlainText(), self.textDelegue.text(),
            self.textCommentaire.toPlainText(),
            self.comboEtat.currentData(self.role_etat))
        self.dialog.close()

    def __select_etat_combobox(self, etat: Etat):
        """
        Chnage l'état sélectionné par la comboBox
        :param etat: l'état à sélectionner
        :return:
        """
        index = self.comboEtat.findText(etat.name, QtCore.Qt.MatchFixedString)
        if index >= 0:
            self.comboEtat.setCurrentIndex(index)