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.")
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)
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)
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)
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")
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")
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)
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)
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.")
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)