LeechCraft 0.6.70-14794-g33744ae6ce
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
tagslineedit.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "tagslineedit.h"
10#include <QtDebug>
11#include <QTimer>
12#include <QCompleter>
13#include <QContextMenuEvent>
14#include <QHBoxLayout>
15#include <QPushButton>
16#include <QToolButton>
17#include <QAbstractItemView>
18#include <util/sll/qtutil.h>
20#include "tagscompletionmodel.h"
21#include "tagscompleter.h"
22#include "util.h"
23
24namespace LC::Util
25{
27 : QLineEdit (parent)
28 , Separator_ (GetDefaultTagsSeparator ())
29 {
30 }
31
33 {
34 auto selector = new CategorySelector (this);
35 selector->hide ();
36
37 AddSelector (selector);
38
39 if (!mgr)
40 mgr = new LineEditButtonManager { this };
41
42 auto button = new QToolButton { this };
43 button->setIconSize ({ 16, 16 });
44 button->setIcon (QIcon::fromTheme (QStringLiteral ("mail-tagged")));
45 button->setCursor (Qt::ArrowCursor);
46 button->setStyleSheet (QStringLiteral ("QToolButton { border: none; padding: 0px; }"));
47
48 mgr->Add (button);
49
50 connect (button,
51 &QToolButton::clicked,
52 this,
53 [selector]
54 {
55 selector->move (QCursor::pos ());
56 selector->show ();
57 });
58 }
59
61 {
62 CategorySelector_ = selector;
63 CategorySelector_->SetSeparator (Separator_);
64
65 QAbstractItemModel *model = Completer_->model ();
66
67 QStringList initialTags;
68 for (int i = 0; i < model->rowCount (); ++i)
69 initialTags << model->data (model->index (i, 0)).toString ();
70 CategorySelector_->SetPossibleSelections (initialTags);
71
72 connect (CategorySelector_,
74 this,
75 [this] (const QStringList& tags)
76 {
77 setText (tags.join (Separator_));
78 emit tagsChosen ();
79 });
80
81 connect (this,
82 &QLineEdit::textChanged,
83 CategorySelector_,
85 }
86
88 {
89 return Separator_;
90 }
91
92 void TagsLineEdit::SetSeparator (const QString& sep)
93 {
94 Separator_ = sep;
95 if (CategorySelector_)
96 CategorySelector_->SetSeparator (sep);
97 }
98
99 void TagsLineEdit::InsertTag (const QString& completion)
100 {
101 if (Completer_->widget () != this)
102 return;
103
104 QString wtext = text ();
105 if (completion.startsWith (wtext))
106 wtext.clear ();
107 int pos = wtext.lastIndexOf (Separator_);
108 if (pos >= 0)
109 wtext = wtext.left (pos).append (Separator_);
110 else
111 wtext.clear ();
112 wtext.append (completion);
113 wtext = wtext.simplified ();
114 setText (wtext);
115
116 emit tagsChosen ();
117 }
118
119 void TagsLineEdit::setTags (const QStringList& tags)
120 {
121 setText (tags.join (Separator_));
122 if (CategorySelector_)
123 CategorySelector_->SetSelections (tags);
124 }
125
126 void TagsLineEdit::keyPressEvent (QKeyEvent *e)
127 {
128 if (Completer_ && Completer_->popup ()->isVisible ())
129 switch (e->key ())
130 {
131 case Qt::Key_Enter:
132 case Qt::Key_Return:
133 case Qt::Key_Escape:
134 case Qt::Key_Tab:
135 case Qt::Key_Backtab:
136 e->ignore ();
137 return;
138 default:
139 break;
140 }
141
142 QLineEdit::keyPressEvent (e);
143
144 bool cos = e->modifiers () & (Qt::ControlModifier |
145 Qt::ShiftModifier |
146 Qt::AltModifier |
147 Qt::MetaModifier);
148 bool isShortcut = e->modifiers () & (Qt::ControlModifier |
149 Qt::AltModifier |
150 Qt::ShiftModifier);
151 if (!Completer_ ||
152 (cos && e->text ().isEmpty ()) ||
153 isShortcut)
154 return;
155
156 QString completionPrefix = textUnderCursor ();
157 Completer_->setCompletionPrefix (completionPrefix);
158 Completer_->popup ()->
159 setCurrentIndex (Completer_->completionModel ()->index (0, 0));
160 Completer_->complete ();
161 }
162
163 void TagsLineEdit::focusInEvent (QFocusEvent *e)
164 {
165 if (Completer_)
166 Completer_->setWidget (this);
167 QLineEdit::focusInEvent (e);
168 }
169
170 void TagsLineEdit::contextMenuEvent (QContextMenuEvent *e)
171 {
172 if (!CategorySelector_ || CategorySelector_->parentWidget () != this)
173 {
174 QLineEdit::contextMenuEvent (e);
175 return;
176 }
177
178 CategorySelector_->move (e->globalPos ());
179 CategorySelector_->show ();
180 }
181
183 {
184 if (Completer_)
185 disconnect (Completer_,
186 nullptr,
187 this,
188 nullptr);
189
190 Completer_ = c;
191
192 if (!Completer_)
193 return;
194
195 Completer_->setWidget (this);
196 Completer_->setCompletionMode (QCompleter::PopupCompletion);
197 connect (Completer_,
198 qOverload<const QString&> (&QCompleter::activated),
199 this,
200 &TagsLineEdit::InsertTag);
201 }
202
203 QString TagsLineEdit::textUnderCursor () const
204 {
205 auto rxStr = Separator_;
206 rxStr.replace (' ', R"(\s*)"_ql);
207
208 QRegExp rx (rxStr);
209
210 QString wtext = text ();
211 int pos = cursorPosition () - 1;
212 int last = wtext.indexOf (rx, pos);
213 int first = wtext.lastIndexOf (rx, pos);
214 if (first == -1)
215 first = 0;
216 if (last == -1)
217 last = wtext.size ();
218 return wtext.mid (first, last - first);
219 }
220}
The CategorySelector widget provides a way to select amongst a group of items.
void SetSelections(const QStringList &subset)
Selects some of the items.
void SetSeparator(const QString &)
Sets the separator for the tags.
void SetPossibleSelections(QStringList selections, bool sort=true)
Sets possible selections.
void SetSelectionsFromString(const QString &newText)
Notifies CategorySelector about logical selection changes.
void tagsSelectionChanged(const QStringList &newSelections)
Indicates that selections have changed.
Manages additional overlay buttons in a QLineEdit.
void Add(QToolButton *button)
Adds a button to the line edit.
Completer suitable for tag completion.
Definition: tagscompleter.h:39
void SetCompleter(TagsCompleter *)
void contextMenuEvent(QContextMenuEvent *) override
void SetSeparator(const QString &)
Sets the separator for the tags.
void focusInEvent(QFocusEvent *) override
QString GetSeparator() const
Returns the separator for the tags.
void AddSelector(LineEditButtonManager *manager=nullptr)
Adds the selector widget to the line edit.
void keyPressEvent(QKeyEvent *) override
void setTags(const QStringList &tags)
Sets the currently selected tags.
TagsLineEdit(QWidget *parent)
Constructs the line edit widget.
QString GetDefaultTagsSeparator()
Definition: util.cpp:14