widgets.text: Allow changing the hint text dynamically
[git-cola.git] / cola / widgets / text.py
blob3f4845c27c7cc56fed0e14042bd0cf8df8c44582
1 from PyQt4 import QtGui
2 from PyQt4 import QtCore
3 from PyQt4.QtCore import SIGNAL
6 class HintedTextWidgetEventFilter(QtCore.QObject):
7 def __init__(self, parent):
8 super(HintedTextWidgetEventFilter, self).__init__(parent)
9 self.widget = parent
11 def eventFilter(self, obj, event):
12 if event.type() == QtCore.QEvent.FocusIn:
13 self.widget.emit_position()
14 if self.widget.is_hint():
15 self.widget.enable_hint(False)
17 elif event.type() == QtCore.QEvent.FocusOut:
18 if not bool(self.widget.value()):
19 self.widget.enable_hint(True)
21 return False
24 class HintedTextWidgetMixin(object):
25 def __init__(self, hint):
26 self._hint = unicode(self.tr(hint))
27 self._event_filter = HintedTextWidgetEventFilter(self)
28 self.installEventFilter(self._event_filter)
30 # Palette for normal text
31 self.default_palette = QtGui.QPalette(self.palette())
33 # Palette used for the placeholder text
34 self.hint_palette = pal = QtGui.QPalette(self.palette())
35 color = self.hint_palette.text().color()
36 color.setAlpha(128)
37 pal.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
38 pal.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Text, color)
40 def emit_position(self):
41 pass
43 def reset_cursor(self):
44 pass
46 def set_hint(self, hint):
47 is_hint = self.is_hint()
48 self._hint = hint
49 if is_hint:
50 self.enable_hint(True)
52 def hint(self):
53 return self._hint
55 def is_hint(self):
56 return self.strip() == self._hint
58 def value(self):
59 text = self.strip()
60 if text == self._hint:
61 return u''
62 else:
63 return text
65 def strip(self):
66 return self.as_unicode().strip()
68 def enable_hint(self, hint):
69 blocksignals = self.blockSignals(True)
70 if hint:
71 self.set_value(self.hint())
72 else:
73 self.clear()
74 self.reset_cursor()
75 self.blockSignals(blocksignals)
76 self.enable_hint_palette(hint)
78 def enable_hint_palette(self, hint):
79 if hint:
80 self.setPalette(self.hint_palette)
81 else:
82 self.setPalette(self.default_palette)
84 def refresh_palette(self):
85 self.enable_hint_palette(self.is_hint())
88 class HintedTextEdit(QtGui.QTextEdit, HintedTextWidgetMixin):
89 def __init__(self, hint, parent=None):
90 QtGui.QTextEdit.__init__(self, parent)
91 HintedTextWidgetMixin.__init__(self, hint)
93 self.setLineWrapMode(QtGui.QTextEdit.NoWrap)
94 self.setAcceptRichText(False)
96 self.connect(self, SIGNAL('cursorPositionChanged()'),
97 self.emit_position)
99 def as_unicode(self):
100 return unicode(self.toPlainText())
102 def set_value(self, value):
103 self.setPlainText(value)
104 self.refresh_palette()
106 def emit_position(self):
107 cursor = self.textCursor()
108 position = cursor.position()
109 txt = self.as_unicode()
110 rows = txt[:position].count('\n') + 1
111 cols = cursor.columnNumber()
112 self.emit(SIGNAL('cursorPosition(int,int)'), rows, cols)
115 class HintedLineEdit(QtGui.QLineEdit, HintedTextWidgetMixin):
116 def __init__(self, hint, parent=None):
117 QtGui.QLineEdit.__init__(self, parent)
118 HintedTextWidgetMixin.__init__(self, hint)
120 self.connect(self,
121 SIGNAL('cursorPositionChanged(int,int)'),
122 lambda x, y: self.emit_position())
124 def emit_position(self):
125 cols = self.cursorPosition()
126 self.emit(SIGNAL('cursorPosition(int,int)'), 1, cols)
128 def set_value(self, value):
129 self.setText(value)
130 self.refresh_palette()
132 def as_unicode(self):
133 return unicode(self.text())
135 def reset_cursor(self):
136 self.setCursorPosition(0)