qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
tabcompleter.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2005-2014 by the Quassel Project
3  devel@quassel-irc.org
4 
5  Copyright © 2014-2019 by The qTox Project Contributors
6 
7  This file is part of qTox, a Qt-based graphical interface for Tox.
8 
9  qTox is libre software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  qTox is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with qTox. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "tabcompleter.h"
24 
25 #include <QKeyEvent>
26 #include <QRegExp>
27 
28 #include "src/model/group.h"
30 
38 const QString TabCompleter::nickSuffix = QString(": ");
39 
41  : QObject{msgEdit}
42  , msgEdit{msgEdit}
43  , group{group}
44  , enabled{false}
45  , lastCompletionLength{0}
46 {
47 }
48 
49 /* from quassel/src/uisupport/multilineedit.h
50  // Compatibility methods with the rest of the classes which still expect this to be a QLineEdit
51  inline QString text() const { return toPlainText(); }
52  inline QString html() const { return toHtml(); }
53  inline int cursorPosition() const { return textCursor().position(); }
54  inline void insert(const QString &newText) { insertPlainText(newText); }
55  inline void backspace() { keyPressEvent(new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace,
56  Qt::NoModifier)); }
57 */
58 
60 {
61  // ensure a safe state in case we return early.
62  completionMap.clear();
63  nextCompletion = completionMap.begin();
64 
65  // split the string on the given RE (not chars, nums or braces/brackets) and take the last
66  // section
67  QString tabAbbrev = msgEdit->toPlainText()
68  .left(msgEdit->textCursor().position())
69  .section(QRegExp("[^\\w\\d\\$:@--_\\[\\]{}|`^.\\\\]"), -1, -1);
70  // that section is then used as the completion regex
71  QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)),
72  Qt::CaseInsensitive);
73 
74  const QString ownNick = group->getSelfName();
75  for (const auto& name : group->getPeerList()) {
76  if (name == ownNick) {
77  continue; // don't auto complete own name
78  }
79  if (regex.indexIn(name) > -1) {
80  SortableString lower = SortableString(name.toLower());
81  completionMap[lower] = name;
82  }
83  }
84 
85  nextCompletion = completionMap.begin();
86  lastCompletionLength = tabAbbrev.length();
87 }
88 
89 
91 {
92  if (!enabled) {
94  enabled = true;
95  }
96 
97  if (nextCompletion != completionMap.end()) {
98  // clear previous completion
99  auto cur = msgEdit->textCursor();
100  cur.setPosition(cur.selectionEnd());
101  msgEdit->setTextCursor(cur);
102  for (int i = 0; i < lastCompletionLength; ++i) {
103  msgEdit->textCursor().deletePreviousChar();
104  }
105 
106  // insert completion
107  msgEdit->insertPlainText(*nextCompletion);
108 
109  // remember charcount to delete next time and advance to next completion
111  ++nextCompletion;
112 
113  // we're completing the first word of the line
114  if (msgEdit->textCursor().position() == lastCompletionLength) {
115  msgEdit->insertPlainText(nickSuffix);
116  lastCompletionLength += nickSuffix.length();
117  }
118  } else { // we're at the end of the list -> start over again
119  if (!completionMap.isEmpty()) {
120  nextCompletion = completionMap.begin();
121  complete();
122  }
123  }
124 }
125 
127 {
128  enabled = false;
129 }
130 
131 // this determines the sort order
133 {
134  /* QDateTime thisTime = thisUser->lastChannelActivity(_currentBufferId);
135  QDateTime thatTime = thatUser->lastChannelActivity(_currentBufferId);
136 
137 
138  if (thisTime.isValid() || thatTime.isValid())
139  return thisTime > thatTime;
140 */ // this could be a
141  // useful feature at
142  // some point
143 
144  return QString::localeAwareCompare(this->contents, other.contents) < 0;
145 }
Group::getPeerList
const QMap< ToxPk, QString > & getPeerList() const
Gets the PKs and names of all peers.
Definition: group.cpp:159
TabCompleter::SortableString
Definition: tabcompleter.h:41
group.h
TabCompleter::TabCompleter
TabCompleter(ChatTextEdit *msgEdit, Group *group)
Definition: tabcompleter.cpp:40
TabCompleter::SortableString::contents
QString contents
Definition: tabcompleter.h:48
TabCompleter::complete
void complete()
Definition: tabcompleter.cpp:90
TabCompleter::msgEdit
ChatTextEdit * msgEdit
Definition: tabcompleter.h:51
chattextedit.h
TabCompleter::buildCompletionList
void buildCompletionList()
Definition: tabcompleter.cpp:59
TabCompleter::SortableString::operator<
bool operator<(const SortableString &other) const
Definition: tabcompleter.cpp:132
TabCompleter::completionMap
QMap< SortableString, QString > completionMap
Definition: tabcompleter.h:56
TabCompleter::nextCompletion
QMap< SortableString, QString >::Iterator nextCompletion
Definition: tabcompleter.h:57
Group
Definition: group.h:34
ChatTextEdit
Definition: chattextedit.h:24
tabcompleter.h
TabCompleter::enabled
bool enabled
Definition: tabcompleter.h:53
TabCompleter::group
Group * group
Definition: tabcompleter.h:52
TabCompleter::reset
void reset()
Definition: tabcompleter.cpp:126
TabCompleter::nickSuffix
const static QString nickSuffix
Definition: tabcompleter.h:54
TabCompleter::lastCompletionLength
int lastCompletionLength
Definition: tabcompleter.h:58
Group::getSelfName
QString getSelfName() const
Definition: group.cpp:200