diff options
Diffstat (limited to 'src/ui/widgets/FindWidget.cpp')
-rw-r--r-- | src/ui/widgets/FindWidget.cpp | 171 |
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 |