aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/widgets/FindWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widgets/FindWidget.cpp')
-rw-r--r--src/ui/widgets/FindWidget.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/ui/widgets/FindWidget.cpp b/src/ui/widgets/FindWidget.cpp
new file mode 100644
index 00000000..58ceda7c
--- /dev/null
+++ b/src/ui/widgets/FindWidget.cpp
@@ -0,0 +1,171 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgFrontend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "FindWidget.h"
+
+namespace GpgFrontend::UI {
+
+FindWidget::FindWidget(QWidget* parent, PlainTextEditorPage* edit)
+ : QWidget(parent), m_text_page_(edit) {
+ find_edit_ = new QLineEdit(this);
+ auto* closeButton = new QPushButton(
+ this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), QString(),
+ this);
+ auto* nextButton = new QPushButton(QIcon(":button_next.png"), QString());
+ auto* previousButton = new QPushButton(QIcon(":button_previous.png"), "");
+
+ auto* notificationWidgetLayout = new QHBoxLayout(this);
+ notificationWidgetLayout->setContentsMargins(10, 0, 0, 0);
+ notificationWidgetLayout->addWidget(new QLabel(QString(_("Find")) + ": "));
+ notificationWidgetLayout->addWidget(find_edit_, 2);
+ notificationWidgetLayout->addWidget(nextButton);
+ notificationWidgetLayout->addWidget(previousButton);
+ notificationWidgetLayout->addWidget(closeButton);
+
+ this->setLayout(notificationWidgetLayout);
+ connect(find_edit_, &QLineEdit::textEdited, this, &FindWidget::slot_find);
+ connect(find_edit_, &QLineEdit::returnPressed, this, &FindWidget::slot_find_next);
+ connect(nextButton, &QPushButton::clicked, this, &FindWidget::slot_find_next);
+ connect(previousButton, &QPushButton::clicked, this, &FindWidget::slot_find_previous);
+ connect(closeButton, &QPushButton::clicked, this, &FindWidget::slot_close);
+
+ // The timer is necessary for setting the focus
+ QTimer::singleShot(0, find_edit_, SLOT(setFocus()));
+}
+
+void FindWidget::set_background() {
+ auto cursor = m_text_page_->GetTextPage()->textCursor();
+ // if match is found set background of QLineEdit to white, otherwise to red
+ QPalette bgPalette(find_edit_->palette());
+
+ if (!find_edit_->text().isEmpty() && m_text_page_->GetTextPage()
+ ->document()
+ ->find(find_edit_->text())
+ .position() < 0) {
+ bgPalette.setColor(QPalette::Base, "#ececba");
+ } else {
+ bgPalette.setColor(QPalette::Base, Qt::white);
+ }
+ find_edit_->setPalette(bgPalette);
+}
+
+void FindWidget::slot_find_next() {
+ QTextCursor cursor = m_text_page_->GetTextPage()->textCursor();
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), cursor, QTextDocument::FindCaseSensitively);
+
+ // if end of document is reached, restart search from beginning
+ if (cursor.position() == -1) {
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), cursor, QTextDocument::FindCaseSensitively);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ m_text_page_->GetTextPage()->setTextCursor(cursor);
+ }
+ this->set_background();
+}
+
+void FindWidget::slot_find() {
+ QTextCursor cursor = m_text_page_->GetTextPage()->textCursor();
+
+ if (cursor.anchor() == -1) {
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), cursor, QTextDocument::FindCaseSensitively);
+ } else {
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), cursor.anchor(),
+ QTextDocument::FindCaseSensitively);
+ }
+
+ // if end of document is reached, restart search from beginning
+ if (cursor.position() == -1) {
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), cursor, QTextDocument::FindCaseSensitively);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ m_text_page_->GetTextPage()->setTextCursor(cursor);
+ }
+ this->set_background();
+}
+
+void FindWidget::slot_find_previous() {
+ QTextDocument::FindFlags flags;
+ flags |= QTextDocument::FindBackward;
+ flags |= QTextDocument::FindCaseSensitively;
+
+ QTextCursor cursor = m_text_page_->GetTextPage()->textCursor();
+ cursor = m_text_page_->GetTextPage()->document()->find(find_edit_->text(),
+ cursor, flags);
+
+ // if begin of document is reached, restart search from end
+ if (cursor.position() == -1) {
+ cursor = m_text_page_->GetTextPage()->document()->find(
+ find_edit_->text(), QTextCursor::End, flags);
+ }
+
+ // cursor should not stay at -1, otherwise text is not editable
+ // todo: check how gedit handles this
+ if (cursor.position() != -1) {
+ m_text_page_->GetTextPage()->setTextCursor(cursor);
+ }
+ this->set_background();
+}
+
+void FindWidget::keyPressEvent(QKeyEvent* e) {
+ switch (e->key()) {
+ case Qt::Key_Escape:
+ this->slot_close();
+ break;
+ case Qt::Key_F3:
+ if (e->modifiers() & Qt::ShiftModifier) {
+ this->slot_find_previous();
+ } else {
+ this->slot_find_next();
+ }
+ break;
+ }
+}
+
+void FindWidget::slot_close() {
+ QTextCursor cursor = m_text_page_->GetTextPage()->textCursor();
+
+ if (cursor.position() == -1) {
+ cursor.setPosition(0);
+ m_text_page_->GetTextPage()->setTextCursor(cursor);
+ }
+ m_text_page_->setFocus();
+ close();
+}
+
+} // namespace GpgFrontend::UI