19 |
19 |
20 #include <QStringList> |
20 #include <QStringList> |
21 |
21 |
22 #include "SmartLineEdit.h" |
22 #include "SmartLineEdit.h" |
23 |
23 |
24 SmartLineEdit::SmartLineEdit(QWidget * parent) |
24 SmartLineEdit::SmartLineEdit(QWidget * parent, int maxHistorySize) |
25 : QLineEdit(parent) |
25 : QLineEdit(parent) |
26 { |
26 { |
|
27 m_curHistEntryIdx = 0; |
|
28 m_maxHistorySize = maxHistorySize; |
|
29 |
27 m_whitespace = QRegExp("\\s"); |
30 m_whitespace = QRegExp("\\s"); |
28 |
31 |
29 m_cmds = new QStringList(); |
32 m_cmds = new QStringList(); |
30 m_nicks = new QStringList(); |
33 m_nicks = new QStringList(); |
|
34 |
|
35 m_history = new QStringList(); |
31 |
36 |
32 resetAutoCompletionStatus(); |
37 resetAutoCompletionStatus(); |
33 |
38 |
34 // reset autocompletion status when cursor is moved or content is changed |
39 // reset autocompletion status when cursor is moved or content is changed |
35 connect(this, SIGNAL(cursorPositionChanged(int, int)), |
40 connect(this, SIGNAL(cursorPositionChanged(int, int)), |
39 } |
44 } |
40 |
45 |
41 |
46 |
42 void SmartLineEdit::addCommands(const QStringList & commands) |
47 void SmartLineEdit::addCommands(const QStringList & commands) |
43 { |
48 { |
44 m_mutex.lock(); |
49 m_keywordMutex.lock(); |
45 |
50 |
46 m_cmds->append(commands); |
51 m_cmds->append(commands); |
47 |
52 |
48 m_mutex.unlock(); |
53 m_keywordMutex.unlock(); |
49 } |
54 } |
50 |
55 |
51 |
56 |
52 void SmartLineEdit::removeCommands(const QStringList & commands) |
57 void SmartLineEdit::removeCommands(const QStringList & commands) |
53 { |
58 { |
54 m_mutex.lock(); |
59 m_keywordMutex.lock(); |
55 |
60 |
56 foreach (const QString & cmd, commands) |
61 foreach (const QString & cmd, commands) |
57 { |
62 { |
58 m_cmds->removeAll(cmd); |
63 m_cmds->removeAll(cmd); |
59 } |
64 } |
60 |
65 |
61 m_mutex.unlock(); |
66 m_keywordMutex.unlock(); |
62 } |
67 } |
63 |
68 |
64 |
69 |
65 void SmartLineEdit::addNickname(const QString & name) |
70 void SmartLineEdit::addNickname(const QString & name) |
66 { |
71 { |
67 m_mutex.lock(); |
72 m_keywordMutex.lock(); |
68 |
73 |
69 m_nicks->append(name); |
74 m_nicks->append(name); |
70 |
75 |
71 m_mutex.unlock(); |
76 m_keywordMutex.unlock(); |
72 } |
77 } |
73 |
78 |
74 |
79 |
75 void SmartLineEdit::removeNickname(const QString & name) |
80 void SmartLineEdit::removeNickname(const QString & name) |
76 { |
81 { |
77 m_mutex.lock(); |
82 m_keywordMutex.lock(); |
78 |
83 |
79 m_nicks->removeAll(name); |
84 m_nicks->removeAll(name); |
80 |
85 |
81 m_mutex.unlock(); |
86 m_keywordMutex.unlock(); |
|
87 } |
|
88 |
|
89 void SmartLineEdit::rememberCurrentText() |
|
90 { |
|
91 m_historyMutex.lock(); |
|
92 |
|
93 rememberCurrentTextUnsynced(); |
|
94 |
|
95 m_historyMutex.unlock(); |
|
96 } |
|
97 |
|
98 void SmartLineEdit::rememberCurrentTextUnsynced() |
|
99 { |
|
100 QString newEntry = text(); |
|
101 |
|
102 // don't store whitespace-only/empty text |
|
103 if (newEntry.trimmed().isEmpty()) |
|
104 return; |
|
105 |
|
106 m_history->removeOne(newEntry); // no duplicates please |
|
107 m_history->append(newEntry); |
|
108 |
|
109 // do not keep more entries than allowed |
|
110 if (m_history->size() > m_maxHistorySize) |
|
111 m_history->removeFirst(); |
|
112 |
|
113 // we're looking at the latest entry |
|
114 m_curHistEntryIdx = m_history->size() - 1; |
|
115 } |
|
116 |
|
117 void SmartLineEdit::clear() |
|
118 { |
|
119 m_historyMutex.lock(); |
|
120 |
|
121 QLineEdit::clear(); |
|
122 m_curHistEntryIdx = m_history->size(); |
|
123 |
|
124 m_historyMutex.unlock(); |
82 } |
125 } |
83 |
126 |
84 void SmartLineEdit::forgetEverything() |
127 void SmartLineEdit::forgetEverything() |
85 { |
128 { |
86 m_mutex.lock(); |
129 // forget keywords |
|
130 m_keywordMutex.lock(); |
87 |
131 |
88 m_cmds->clear(); |
132 m_cmds->clear(); |
89 m_nicks->clear(); |
133 m_nicks->clear(); |
90 |
134 |
91 m_mutex.unlock(); |
135 m_keywordMutex.unlock(); |
|
136 |
|
137 // forget history |
|
138 m_historyMutex.lock(); |
|
139 |
|
140 m_history->clear(); |
|
141 m_curHistEntryIdx = 0; |
|
142 |
|
143 m_historyMutex.unlock(); |
92 |
144 |
93 resetAutoCompletionStatus(); |
145 resetAutoCompletionStatus(); |
|
146 } |
|
147 |
|
148 void SmartLineEdit::navigateHistory(bool isGoingUp) |
|
149 { |
|
150 m_historyMutex.lock(); |
|
151 |
|
152 // save possible changes to new entry |
|
153 if ((m_curHistEntryIdx >= m_history->size() || |
|
154 (text() != m_history->at(m_curHistEntryIdx)))) |
|
155 { |
|
156 rememberCurrentTextUnsynced(); |
|
157 } |
|
158 |
|
159 if (isGoingUp) |
|
160 m_curHistEntryIdx--; |
|
161 else |
|
162 m_curHistEntryIdx++; |
|
163 |
|
164 // if Idx higher than valid range |
|
165 if (m_curHistEntryIdx >= m_history->size()) |
|
166 { |
|
167 QLineEdit::clear(); |
|
168 m_curHistEntryIdx = m_history->size(); |
|
169 } |
|
170 // if Idx in valid range |
|
171 else if (m_curHistEntryIdx >= 0) |
|
172 { |
|
173 setText(m_history->at(m_curHistEntryIdx)); |
|
174 } |
|
175 // if Idx below 0 |
|
176 else |
|
177 m_curHistEntryIdx = 0; |
|
178 |
|
179 |
|
180 m_historyMutex.unlock(); |
94 } |
181 } |
95 |
182 |
96 bool SmartLineEdit::event(QEvent * event) |
183 bool SmartLineEdit::event(QEvent * event) |
97 { |
184 { |
98 // we only want special treatment for key press events |
185 // we only want special treatment for key press events |
119 if ((key == Qt::Key_Tab) && (!text().trimmed().isEmpty())) |
206 if ((key == Qt::Key_Tab) && (!text().trimmed().isEmpty())) |
120 { |
207 { |
121 autoComplete(); |
208 autoComplete(); |
122 event->accept(); |
209 event->accept(); |
123 } |
210 } |
124 // clear contents on pressed ESC |
211 // clear contents on pressed ESC, navigate history with arrow keys |
125 else if ((event->key() == Qt::Key_Escape) && |
212 else if (event->modifiers() == Qt::NoModifier) |
126 (event->modifiers() == Qt::NoModifier) |
213 switch (key) |
127 ) |
214 { |
128 clear(); |
215 case Qt::Key_Escape: |
|
216 clear(); |
|
217 event->accept(); |
|
218 break; |
|
219 |
|
220 case Qt::Key_Up: |
|
221 navigateHistory(true); |
|
222 event->accept(); |
|
223 break; |
|
224 |
|
225 case Qt::Key_Down: |
|
226 navigateHistory(false); |
|
227 event->accept(); |
|
228 break; |
|
229 |
|
230 default: |
|
231 QLineEdit::keyPressEvent(event); |
|
232 break; |
|
233 } |
129 // otherwise forward keys to parent |
234 // otherwise forward keys to parent |
130 else |
235 else |
131 QLineEdit::keyPressEvent(event); |
236 QLineEdit::keyPressEvent(event); |
132 } |
237 } |
133 |
238 |