1 /*
2 Copyright © 2015-2019 by The qTox Project Contributors
3
4 This file is part of qTox, a Qt-based graphical interface for Tox.
5
6 qTox is libre software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 qTox is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "searchform.h"
21 #include "form/searchsettingsform.h"
22 #include "src/widget/style.h"
23
24 #include <QVBoxLayout>
25 #include <QHBoxLayout>
26 #include <QPushButton>
27 #include <QLabel>
28 #include <QKeyEvent>
29
30 #include <array>
31
32 static std::array<QString, 3> STATE_NAME = {
33 QString{},
34 QStringLiteral("green"),
35 QStringLiteral("red"),
36 };
37
SearchForm(QWidget * parent)38 SearchForm::SearchForm(QWidget* parent) : QWidget(parent)
39 {
40 QVBoxLayout* layout = new QVBoxLayout();
41 QHBoxLayout* layoutNavigation = new QHBoxLayout();
42 QHBoxLayout* layoutMessage = new QHBoxLayout();
43 QSpacerItem *lSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored);
44 QSpacerItem *rSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored);
45 searchLine = new LineEdit();
46 settings = new SearchSettingsForm();
47 messageLabel = new QLabel();
48
49 settings->setVisible(false);
50 messageLabel->setProperty("state", QStringLiteral("red"));
51 messageLabel->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/labels.css")));
52 messageLabel->setText(tr("The text could not be found."));
53 messageLabel->setVisible(false);
54
55 settingsButton = createButton("searchSettingsButton", "green");
56 upButton = createButton("searchUpButton", "green");
57 downButton = createButton("searchDownButton", "green");
58 hideButton = createButton("searchHideButton", "red");
59 startButton = createButton("startButton", "green");
60 startButton->setText(tr("Start"));
61
62 layoutNavigation->setMargin(0);
63 layoutNavigation->addWidget(settingsButton);
64 layoutNavigation->addWidget(searchLine);
65 layoutNavigation->addWidget(startButton);
66 layoutNavigation->addWidget(upButton);
67 layoutNavigation->addWidget(downButton);
68 layoutNavigation->addWidget(hideButton);
69
70 layout->addLayout(layoutNavigation);
71 layout->addWidget(settings);
72
73 layoutMessage->addSpacerItem(lSpacer);
74 layoutMessage->addWidget(messageLabel);
75 layoutMessage->addSpacerItem(rSpacer);
76 layout->addLayout(layoutMessage);
77
78 startButton->setHidden(true);
79
80 setLayout(layout);
81
82 connect(searchLine, &LineEdit::textChanged, this, &SearchForm::changedSearchPhrase);
83 connect(searchLine, &LineEdit::clickEnter, this, &SearchForm::clickedUp);
84 connect(searchLine, &LineEdit::clickShiftEnter, this, &SearchForm::clickedDown);
85 connect(searchLine, &LineEdit::clickEsc, this, &SearchForm::clickedHide);
86
87 connect(upButton, &QPushButton::clicked, this, &SearchForm::clickedUp);
88 connect(downButton, &QPushButton::clicked, this, &SearchForm::clickedDown);
89 connect(hideButton, &QPushButton::clicked, this, &SearchForm::clickedHide);
90 connect(startButton, &QPushButton::clicked, this, &SearchForm::clickedStart);
91 connect(settingsButton, &QPushButton::clicked, this, &SearchForm::clickedSearch);
92
93 connect(settings, &SearchSettingsForm::updateSettings, this, &SearchForm::changedState);
94 }
95
removeSearchPhrase()96 void SearchForm::removeSearchPhrase()
97 {
98 searchLine->setText("");
99 }
100
getSearchPhrase() const101 QString SearchForm::getSearchPhrase() const
102 {
103 return searchPhrase;
104 }
105
getParameterSearch()106 ParameterSearch SearchForm::getParameterSearch()
107 {
108 return parameter;
109 }
110
setFocusEditor()111 void SearchForm::setFocusEditor()
112 {
113 searchLine->setFocus();
114 }
115
insertEditor(const QString & text)116 void SearchForm::insertEditor(const QString &text)
117 {
118 searchLine->insert(text);
119 }
120
reloadTheme()121 void SearchForm::reloadTheme()
122 {
123 settingsButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
124 upButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
125 downButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
126 hideButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
127 startButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
128
129 settings->reloadTheme();
130 }
131
showEvent(QShowEvent * event)132 void SearchForm::showEvent(QShowEvent* event)
133 {
134 QWidget::showEvent(event);
135 emit visibleChanged();
136 }
137
createButton(const QString & name,const QString & state)138 QPushButton *SearchForm::createButton(const QString& name, const QString& state)
139 {
140 QPushButton* btn = new QPushButton();
141 btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
142 btn->setObjectName(name);
143 btn->setProperty("state", state);
144 btn->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
145
146 return btn;
147 }
148
getAndCheckParametrSearch()149 ParameterSearch SearchForm::getAndCheckParametrSearch()
150 {
151 if (isActiveSettings) {
152 auto sendParam = settings->getParameterSearch();
153 if (!isChangedPhrase && !sendParam.isUpdate) {
154 sendParam.period = PeriodSearch::None;
155 }
156
157 isChangedPhrase = false;
158 parameter = sendParam;
159
160 return sendParam;
161 }
162
163 return ParameterSearch();
164 }
165
setStateName(QPushButton * btn,ToolButtonState state)166 void SearchForm::setStateName(QPushButton *btn, ToolButtonState state)
167 {
168 const auto index = static_cast<unsigned long>(state);
169 btn->setProperty("state", STATE_NAME[index]);
170 btn->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css")));
171 btn->setEnabled(index != 0);
172 }
173
useBeginState()174 void SearchForm::useBeginState()
175 {
176 setStateName(upButton, ToolButtonState::Common);
177 setStateName(downButton, ToolButtonState::Common);
178 messageLabel->setVisible(false);
179 isPrevSearch = false;
180 }
181
changedSearchPhrase(const QString & text)182 void SearchForm::changedSearchPhrase(const QString& text)
183 {
184 useBeginState();
185
186 if (searchPhrase == text) {
187 return;
188 }
189
190 QString l = text.right(1);
191 if (!l.isEmpty() && l != " " && l[0].isSpace()) {
192 searchLine->setText(searchPhrase);
193 return;
194 }
195
196 searchPhrase = text;
197 isChangedPhrase = true;
198 if (isActiveSettings) {
199 if (startButton->isHidden()) {
200 changedState(true);
201 }
202 } else {
203 isSearchInBegin = true;
204 emit searchInBegin(searchPhrase, getAndCheckParametrSearch());
205 }
206 }
207
clickedUp()208 void SearchForm::clickedUp()
209 {
210 if (downButton->isEnabled()) {
211 isPrevSearch = false;
212 } else {
213 isPrevSearch = true;
214 setStateName(downButton, ToolButtonState::Common);
215 messageLabel->setVisible(false);
216 }
217
218 if (startButton->isHidden()) {
219 isSearchInBegin = false;
220 emit searchUp(searchPhrase, getAndCheckParametrSearch());
221 } else {
222 clickedStart();
223 }
224 }
225
clickedDown()226 void SearchForm::clickedDown()
227 {
228 if (upButton->isEnabled()) {
229 isPrevSearch = false;
230 } else {
231 isPrevSearch = true;
232 setStateName(upButton, ToolButtonState::Common);
233 messageLabel->setVisible(false);
234 }
235
236 if (startButton->isHidden()) {
237 isSearchInBegin = false;
238 emit searchDown(searchPhrase, getAndCheckParametrSearch());
239 } else {
240 clickedStart();
241 }
242 }
243
clickedHide()244 void SearchForm::clickedHide()
245 {
246 hide();
247 emit visibleChanged();
248 }
249
clickedStart()250 void SearchForm::clickedStart()
251 {
252 changedState(false);
253 isSearchInBegin = true;
254 emit searchInBegin(searchPhrase, getAndCheckParametrSearch());
255 }
256
clickedSearch()257 void SearchForm::clickedSearch()
258 {
259 isActiveSettings = !isActiveSettings;
260 settings->setVisible(isActiveSettings);
261 useBeginState();
262
263 if (isActiveSettings) {
264 setStateName(settingsButton, ToolButtonState::Active);
265 } else {
266 setStateName(settingsButton, ToolButtonState::Common);
267 changedState(false);
268 }
269 }
270
changedState(bool isUpdate)271 void SearchForm::changedState(bool isUpdate)
272 {
273 if (isUpdate) {
274 startButton->setHidden(false);
275 upButton->setHidden(true);
276 downButton->setHidden(true);
277 } else {
278 startButton->setHidden(true);
279 upButton->setHidden(false);
280 downButton->setHidden(false);
281 }
282
283 useBeginState();
284 }
285
showMessageNotFound(SearchDirection direction)286 void SearchForm::showMessageNotFound(SearchDirection direction)
287 {
288 if (isSearchInBegin) {
289 if (parameter.period == PeriodSearch::AfterDate) {
290 setStateName(downButton, ToolButtonState::Disabled);
291 } else if (parameter.period == PeriodSearch::BeforeDate) {
292 setStateName(upButton, ToolButtonState::Disabled);
293 } else {
294 setStateName(upButton, ToolButtonState::Disabled);
295 setStateName(downButton, ToolButtonState::Disabled);
296 }
297 } else if (isPrevSearch) {
298 setStateName(upButton, ToolButtonState::Disabled);
299 setStateName(downButton, ToolButtonState::Disabled);
300 } else if (direction == SearchDirection::Up) {
301 setStateName(upButton, ToolButtonState::Disabled);
302 } else {
303 setStateName(downButton, ToolButtonState::Disabled);
304 }
305 messageLabel->setVisible(true);
306 }
307
LineEdit(QWidget * parent)308 LineEdit::LineEdit(QWidget* parent) : QLineEdit(parent)
309 {
310 }
311
keyPressEvent(QKeyEvent * event)312 void LineEdit::keyPressEvent(QKeyEvent* event)
313 {
314 int key = event->key();
315
316 if ((key == Qt::Key_Enter || key == Qt::Key_Return)) {
317 if ((event->modifiers() & Qt::ShiftModifier)) {
318 emit clickShiftEnter();
319 } else {
320 emit clickEnter();
321 }
322 } else if (key == Qt::Key_Escape) {
323 emit clickEsc();
324 }
325
326 QLineEdit::keyPressEvent(event);
327 }
328
329
330