electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

completion_text_edit.py (4417B)


      1 #!/usr/bin/env python
      2 #
      3 # Electrum - lightweight Bitcoin client
      4 # Copyright (C) 2018 The Electrum developers
      5 #
      6 # Permission is hereby granted, free of charge, to any person
      7 # obtaining a copy of this software and associated documentation files
      8 # (the "Software"), to deal in the Software without restriction,
      9 # including without limitation the rights to use, copy, modify, merge,
     10 # publish, distribute, sublicense, and/or sell copies of the Software,
     11 # and to permit persons to whom the Software is furnished to do so,
     12 # subject to the following conditions:
     13 #
     14 # The above copyright notice and this permission notice shall be
     15 # included in all copies or substantial portions of the Software.
     16 #
     17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     21 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     22 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     23 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     24 # SOFTWARE.
     25 
     26 from PyQt5.QtGui import QTextCursor
     27 from PyQt5.QtCore import Qt
     28 from PyQt5.QtWidgets import QCompleter, QPlainTextEdit, QApplication
     29 
     30 from .util import ButtonsTextEdit
     31 
     32 
     33 class CompletionTextEdit(ButtonsTextEdit):
     34 
     35     def __init__(self):
     36         ButtonsTextEdit.__init__(self)
     37         self.completer = None
     38         self.moveCursor(QTextCursor.End)
     39         self.disable_suggestions()
     40 
     41     def set_completer(self, completer):
     42         self.completer = completer
     43         self.initialize_completer()
     44 
     45     def initialize_completer(self):
     46         self.completer.setWidget(self)
     47         self.completer.setCompletionMode(QCompleter.PopupCompletion)
     48         self.completer.activated.connect(self.insert_completion)
     49         self.enable_suggestions()
     50 
     51     def insert_completion(self, completion):
     52         if self.completer.widget() != self:
     53             return
     54         text_cursor = self.textCursor()
     55         extra = len(completion) - len(self.completer.completionPrefix())
     56         text_cursor.movePosition(QTextCursor.Left)
     57         text_cursor.movePosition(QTextCursor.EndOfWord)
     58         if extra == 0:
     59             text_cursor.insertText(" ")
     60         else:
     61             text_cursor.insertText(completion[-extra:] + " ")
     62         self.setTextCursor(text_cursor)
     63 
     64     def text_under_cursor(self):
     65         tc = self.textCursor()
     66         tc.select(QTextCursor.WordUnderCursor)
     67         return tc.selectedText()
     68 
     69     def enable_suggestions(self):
     70         self.suggestions_enabled = True
     71 
     72     def disable_suggestions(self):
     73         self.suggestions_enabled = False
     74 
     75     def keyPressEvent(self, e):
     76         if self.isReadOnly():
     77             return
     78 
     79         if self.is_special_key(e):
     80             e.ignore()
     81             return
     82 
     83         QPlainTextEdit.keyPressEvent(self, e)
     84 
     85         ctrlOrShift = e.modifiers() and (Qt.ControlModifier or Qt.ShiftModifier)
     86         if self.completer is None or (ctrlOrShift and not e.text()):
     87             return
     88 
     89         if not self.suggestions_enabled:
     90             return
     91 
     92         eow = "~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="
     93         hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift
     94         completionPrefix = self.text_under_cursor()
     95 
     96         if hasModifier or not e.text() or len(completionPrefix) < 1 or eow.find(e.text()[-1]) >= 0:
     97             self.completer.popup().hide()
     98             return
     99 
    100         if completionPrefix != self.completer.completionPrefix():
    101             self.completer.setCompletionPrefix(completionPrefix)
    102             self.completer.popup().setCurrentIndex(self.completer.completionModel().index(0, 0))
    103 
    104         cr = self.cursorRect()
    105         cr.setWidth(self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width())
    106         self.completer.complete(cr)
    107 
    108     def is_special_key(self, e):
    109         if self.completer and self.completer.popup().isVisible():
    110             if e.key() in (Qt.Key_Enter, Qt.Key_Return):
    111                 return True
    112         if e.key() == Qt.Key_Tab:
    113             return True
    114         return False
    115 
    116 if __name__ == "__main__":
    117     app = QApplication([])
    118     completer = QCompleter(["alabama", "arkansas", "avocado", "breakfast", "sausage"])
    119     te = CompletionTextEdit()
    120     te.set_completer(completer)
    121     te.show()
    122     app.exec_()