summaryrefslogtreecommitdiffstats
path: root/src/savequerydialog.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-13 20:16:43 +0200
committerDanilo M. <danix@danix.xyz>2026-08-13 20:16:43 +0200
commitc9eb6fc86c947aea0075c1e9d279695cd9f9b7ee (patch)
tree7e5339fbb7e71d29498405f9d4b1c4188f5ab4c3 /src/savequerydialog.h
parentf389db3aad498d46c95c2a95b4280ffb541043b2 (diff)
parent9be1b13b91188cf44a40c6786a83de034988cdbd (diff)
downloadqtmaildir-c9eb6fc86c947aea0075c1e9d279695cd9f9b7ee.tar.gz
qtmaildir-c9eb6fc86c947aea0075c1e9d279695cd9f9b7ee.zip
Merge branch 'saved-queries': saved queries in a file of their own
Items 23 and 82. Saved queries move out of the [queries] INI section into ~/.config/qtmaildir/queries.json, gaining the three things the INI could not express: an order, a pinned flag, and a per-query account scope. They can now be created, edited, reordered, unpinned and deleted from the UI rather than only by hand-editing a config file. The INI could not carry order at all: QSettings reads a section through childKeys(), which sorts alphabetically and never follows the file, so the buttons could not be arranged. Migration reads the old section once, marks every entry pinned so nothing moves on the first launch, and leaves the config file byte-identical, since rewriting it with QSettings would drop the user's comments and key order. Sent stops being a hardcoded button and becomes an ordinary entry carrying "generated": "sent". Its query is still composed from the accounts every time it runs, so correcting a folder name still needs no edit here, but the row now follows one rule instead of having one member the user could not move, rename or remove. Item 82 was found by hand-testing item 23 and fixed on the same branch: saving worked and nothing else did, so a saved query could be created and never changed. It also uncovered a defect that predated it, where rebuilding the row with deleteLater() left the stale row answering findChild(), which was already reachable from the save path. Hand-tested throughout: the migration against the real config, saving, unpinning, deleting, reordering, the read-only query field on a generated entry, and an unpin surviving a restart.
Diffstat (limited to 'src/savequerydialog.h')
-rw-r--r--src/savequerydialog.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/savequerydialog.h b/src/savequerydialog.h
new file mode 100644
index 0000000..d859254
--- /dev/null
+++ b/src/savequerydialog.h
@@ -0,0 +1,79 @@
+/*
+ * qtmaildir - a Qt6 mail client for notmuch-indexed Maildirs
+ * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#pragma once
+
+#include <QDialog>
+
+#include "config.h"
+
+class QCheckBox;
+class QComboBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+/// Names a query and keeps it in queries.json.
+///
+/// Pure UI: it is handed the config and returns a SavedQuery. It writes
+/// nothing, so it can be tested without touching a file, and the caller owns
+/// the decision of what to do with the result.
+class SaveQueryDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ /// `query` is the text to store, `accountKey` the scope to preselect,
+ /// which is the account the user is already looking at.
+ SaveQueryDialog(const Config &config, const QString &query,
+ const QString &accountKey, QWidget *parent = nullptr);
+
+ /// Edits an entry that already exists, prefilled from it rather than from
+ /// the query bar.
+ SaveQueryDialog(const Config &config, const SavedQuery &existing,
+ QWidget *parent = nullptr);
+
+ /// The query as edited. Only meaningful after exec() returned Accepted.
+ SavedQuery savedQuery() const;
+
+ /// Whether `name` already names a stored query. Case-insensitive, matching
+ /// how startup_query resolves, so "inbox" and "Inbox" cannot both exist and
+ /// leave the user unable to tell which one a button ran.
+ static bool namesAnExistingQuery(const Config &config, const QString &name);
+
+private:
+ void build(const SavedQuery &initial);
+ void updateOkState();
+
+ /// The name the dialog was opened on, empty when creating. The caller
+ /// matches on this rather than on the returned name, so a rename replaces
+ /// the entry instead of adding a second one beside it.
+ QString m_originalName;
+
+ /// Set for a generated entry, whose query is composed from the accounts
+ /// and cannot be edited here.
+ QString m_generated;
+ bool m_flat = false;
+
+ const Config &m_config;
+ QLineEdit *m_name = nullptr;
+ QLineEdit *m_query = nullptr;
+ QComboBox *m_account = nullptr;
+ QCheckBox *m_pinned = nullptr;
+ QPushButton *m_ok = nullptr;
+ QLabel *m_notice = nullptr;
+};