aboutsummaryrefslogtreecommitdiffstats
path: root/src/finddialog.cpp
diff options
context:
space:
mode:
authorConfuSomu2023-08-02 01:56:58 +0200
committerConfuSomu2023-08-02 01:56:58 +0200
commit42434314d65cdc29402c7adcb08c2fa5113f7ca2 (patch)
tree703e792905b16d02c7137dd8cf7b60ed8d911890 /src/finddialog.cpp
parentcdd08523b9af7afda906766d22197a066c9264f3 (diff)
downloadActorViewer-42434314d65cdc29402c7adcb08c2fa5113f7ca2.tar
ActorViewer-42434314d65cdc29402c7adcb08c2fa5113f7ca2.tar.gz
ActorViewer-42434314d65cdc29402c7adcb08c2fa5113f7ca2.zip
Implement find dialog
This dialog consolidates options for searching through textual elements in lists which simplifies the logic present in the MainWindow class.
Diffstat (limited to 'src/finddialog.cpp')
-rw-r--r--src/finddialog.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/finddialog.cpp b/src/finddialog.cpp
new file mode 100644
index 0000000..4de17d0
--- /dev/null
+++ b/src/finddialog.cpp
@@ -0,0 +1,134 @@
+#include "finddialog.h"
+#include "./ui_finddialog.h"
+
+#include <QListWidgetItem>
+#include <QTimer>
+#include <QDebug>
+#include <qnamespace.h>
+#include <qtimer.h>
+
+FindDialog::FindDialog(QWidget* parent)
+ : QDialog(parent, Qt::Tool), ui(new Ui::FindDialog)
+{
+ ui->setupUi(this);
+}
+
+FindDialog::~FindDialog() {
+ delete ui;
+}
+
+void FindDialog::on_buttonSearchPrev_clicked() {
+ if (--selected_match < 0) {
+ selected_match = total_matches - 1;
+ ui->statusLabel->setText(tr("Reached top, continued from bottom."));
+ } else update_status();
+ select_match();
+}
+
+void FindDialog::on_buttonSearchNext_clicked() {
+ if (++selected_match >= total_matches) {
+ selected_match = 0;
+ ui->statusLabel->setText(tr("Reached bottom, continued from top."));
+ } else update_status();
+ select_match();
+}
+
+// Update the textbox in the main window and search after 400 ms of no typing
+void FindDialog::on_textInputSearch_textEdited(const QString &text) {
+ emit search_text_changed(text);
+ static QTimer* differed_search = new QTimer(this);
+ if (static bool timer_init_done = false; not timer_init_done) {
+ differed_search->setTimerType(Qt::CoarseTimer);
+ differed_search->setSingleShot(true);
+ differed_search->setInterval(400);
+ connect(differed_search, &QTimer::timeout, this, &FindDialog::run_search);
+ timer_init_done = true;
+ }
+ differed_search->start();
+}
+
+void FindDialog::set_search_text(const QString &text) {
+ ui->textInputSearch->setText(text);
+}
+
+inline void FindDialog::run_search() {
+ init_search();
+}
+
+void FindDialog::on_hSlider_valueChanged(int value) {
+ selected_match = value;
+ update_status();
+ select_match();
+}
+
+void FindDialog::on_spinBox_valueChanged(int value) {
+ // Avoids repeatedly changing the selected_match as the valueChanged signal is a notifier for the spin box's value
+ if (not value_changed_processed) {
+ selected_match = value - 1;
+ update_status();
+ select_match();
+ }
+ value_changed_processed = false;
+}
+
+void FindDialog::set_qlist_widget(QListWidget* widget) {
+ list_widget = widget;
+}
+
+// Start a new search only if the search text input has changed
+void FindDialog::init_search() {
+ QString current_search = ui->textInputSearch->text();
+ if (*last_search == current_search or not list_widget) return;
+
+ matches = list_widget->findItems(current_search, Qt::MatchContains);
+
+ *last_search = current_search;
+ selected_match = 0;
+ total_matches = matches.size();
+
+ if (total_matches > 0) {
+ ui->hSlider->setEnabled(true);
+ ui->spinBox->setEnabled(true);
+ ui->buttonSearchPrev->setEnabled(true);
+ ui->buttonSearchNext->setEnabled(true);
+ } else {
+ ui->spinBox->setEnabled(false);
+ ui->hSlider->setEnabled(false);
+ ui->buttonSearchPrev->setEnabled(false);
+ ui->buttonSearchNext->setEnabled(false);
+ }
+
+ // Set the minimum as when there are no matches, the widget would return out of range index values to having an out of range minimum.
+ ui->hSlider->setMinimum(0);
+ ui->spinBox->setMinimum(1);
+ ui->hSlider->setMaximum(total_matches - 1);
+ ui->spinBox->setMaximum(total_matches);
+
+ select_match();
+ update_status();
+}
+
+// Activate the match requested by the user
+void FindDialog::select_match() {
+ if (list_widget and total_matches != 0 and selected_match >= 0) {
+ list_widget->scrollToItem(matches[selected_match], QAbstractItemView::EnsureVisible);
+ list_widget->setCurrentItem(matches[selected_match]);
+ emit item_selected(matches[selected_match]);
+ }
+
+ // Best place to update these sliders as select_match is always called by each input
+ ui->hSlider->setValue(selected_match);
+ ui->spinBox->setValue(selected_match + 1);
+ value_changed_processed = true;
+}
+
+// Update the status line with current search information
+void FindDialog::update_status() {
+ if (total_matches > 0) {
+ ui->statusLabel->setText(tr("Search result %1 out of %2.")
+ .arg(selected_match+1)
+ .arg(total_matches));
+ } else ui->statusLabel->setText(tr("No search results."));
+}
+
+