File indexing completed on 2025-01-05 04:54:20
0001 /* 0002 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "knotefinddialog.h" 0007 #include "config-knotes.h" 0008 #include "widget/notelistwidget.h" 0009 0010 #include <TextUtils/ConvertText> 0011 0012 #include <PIM/notequery.h> 0013 #include <PIM/resultiterator.h> 0014 0015 #include <KLocalizedString> 0016 #include <QIcon> 0017 #include <QLineEdit> 0018 #include <QPushButton> 0019 0020 #include <KConfigGroup> 0021 #include <KSharedConfig> 0022 #include <KWindowConfig> 0023 #include <QDialogButtonBox> 0024 #include <QLabel> 0025 #include <QListWidget> 0026 #include <QMenu> 0027 #include <QVBoxLayout> 0028 #include <QWindow> 0029 0030 #include <KLineEditEventHandler> 0031 0032 KNoteFindDialog::KNoteFindDialog(QWidget *parent) 0033 : QDialog(parent) 0034 , mNoteFindWidget(new KNoteFindWidget(this)) 0035 { 0036 setWindowTitle(i18nc("@title:window", "Search Notes")); 0037 auto mainLayout = new QVBoxLayout(this); 0038 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this); 0039 connect(buttonBox, &QDialogButtonBox::rejected, this, &KNoteFindDialog::reject); 0040 setAttribute(Qt::WA_DeleteOnClose); 0041 connect(mNoteFindWidget, &KNoteFindWidget::noteSelected, this, &KNoteFindDialog::noteSelected); 0042 mainLayout->addWidget(mNoteFindWidget); 0043 mainLayout->addWidget(buttonBox); 0044 readConfig(); 0045 } 0046 0047 KNoteFindDialog::~KNoteFindDialog() 0048 { 0049 writeConfig(); 0050 } 0051 0052 void KNoteFindDialog::setExistingNotes(const QHash<Akonadi::Item::Id, Akonadi::Item> ¬es) 0053 { 0054 mNoteFindWidget->setExistingNotes(notes); 0055 } 0056 0057 namespace 0058 { 0059 static const char myKNoteFindDialogName[] = "KNoteFindDialog"; 0060 } 0061 void KNoteFindDialog::readConfig() 0062 { 0063 create(); // ensure a window is created 0064 windowHandle()->resize(QSize(600, 300)); 0065 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myKNoteFindDialogName)); 0066 KWindowConfig::restoreWindowSize(windowHandle(), group); 0067 resize(windowHandle()->size()); // workaround for QTBUG-40584 0068 } 0069 0070 void KNoteFindDialog::writeConfig() 0071 { 0072 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myKNoteFindDialogName)); 0073 KWindowConfig::saveWindowSize(windowHandle(), group); 0074 group.sync(); 0075 } 0076 0077 KNoteFindWidget::KNoteFindWidget(QWidget *parent) 0078 : QWidget(parent) 0079 , mResultSearch(new QLabel(this)) 0080 , mSearchLineEdit(new QLineEdit(this)) 0081 , mSearchButton(new QPushButton(QIcon::fromTheme(QStringLiteral("edit-find")), i18nc("@action:button Search notes", "Search..."), this)) 0082 , mNoteList(new NoteShared::NoteListWidget(this)) 0083 { 0084 auto vbox = new QVBoxLayout(this); 0085 vbox->setContentsMargins(0, 0, 0, 0); 0086 auto hbox = new QHBoxLayout; 0087 vbox->addLayout(hbox); 0088 auto lab = new QLabel(i18nc("@label:textbox", "Search notes:"), this); 0089 hbox->addWidget(lab); 0090 mSearchLineEdit->setClearButtonEnabled(true); 0091 KLineEditEventHandler::catchReturnKey(mSearchLineEdit); 0092 connect(mSearchLineEdit, &QLineEdit::returnPressed, this, &KNoteFindWidget::slotSearchNote); 0093 connect(mSearchLineEdit, &QLineEdit::textChanged, this, &KNoteFindWidget::slotTextChanged); 0094 hbox->addWidget(mSearchLineEdit); 0095 0096 connect(mSearchButton, &QPushButton::clicked, this, &KNoteFindWidget::slotSearchNote); 0097 hbox->addWidget(mSearchButton); 0098 mSearchButton->setEnabled(false); 0099 0100 // Result 0101 mNoteList->setContextMenuPolicy(Qt::CustomContextMenu); 0102 mNoteList->setSelectionMode(QAbstractItemView::SingleSelection); 0103 connect(mNoteList, &NoteShared::NoteListWidget::itemDoubleClicked, this, &KNoteFindWidget::slotItemDoubleClicked); 0104 connect(mNoteList, &NoteShared::NoteListWidget::customContextMenuRequested, this, &KNoteFindWidget::customContextMenuRequested); 0105 vbox->addWidget(mNoteList); 0106 0107 mResultSearch->setTextFormat(Qt::PlainText); 0108 vbox->addWidget(mResultSearch); 0109 0110 mSearchLineEdit->setFocus(); 0111 } 0112 0113 KNoteFindWidget::~KNoteFindWidget() = default; 0114 0115 void KNoteFindWidget::setExistingNotes(const QHash<Akonadi::Item::Id, Akonadi::Item> ¬es) 0116 { 0117 mNotes = notes; 0118 } 0119 0120 void KNoteFindWidget::slotItemDoubleClicked(QListWidgetItem *item) 0121 { 0122 Q_EMIT noteSelected(mNoteList->itemId(item)); 0123 } 0124 0125 void KNoteFindWidget::slotSearchNote() 0126 { 0127 const QString searchStr = mSearchLineEdit->text().trimmed(); 0128 if (searchStr.trimmed().isEmpty()) { 0129 return; 0130 } 0131 auto config = KConfig(QStringLiteral("akonadi_indexing_agent")); 0132 KConfigGroup cfg = config.group(QStringLiteral("General")); 0133 const bool respectDiacriticAndAccents = cfg.readEntry("respectDiacriticAndAccents", true); 0134 const QString searchString = respectDiacriticAndAccents ? searchStr : TextUtils::ConvertText::normalize(searchStr); 0135 Akonadi::Search::PIM::NoteQuery query; 0136 query.matchNote(searchString); 0137 query.matchTitle(searchString); 0138 0139 Akonadi::Search::PIM::ResultIterator it = query.exec(); 0140 0141 Akonadi::Item::List lst; 0142 while (it.next()) { 0143 const Akonadi::Item::Id id = it.id(); 0144 if (mNotes.contains(id)) { 0145 lst << mNotes.value(id); 0146 } 0147 } 0148 mNoteList->setNotes(lst); 0149 if (lst.isEmpty()) { 0150 mResultSearch->setText(i18nc("@label", "No Results found in search.")); 0151 } else { 0152 mResultSearch->clear(); 0153 } 0154 } 0155 0156 void KNoteFindWidget::slotTextChanged(const QString &text) 0157 { 0158 mSearchButton->setEnabled(!text.trimmed().isEmpty()); 0159 } 0160 0161 void KNoteFindWidget::customContextMenuRequested(const QPoint &) 0162 { 0163 QListWidgetItem *item = mNoteList->currentItem(); 0164 QMenu menu(this); 0165 if (item) { 0166 menu.addAction(i18n("Show Note"), this, [this, item]() { 0167 Q_EMIT noteSelected(mNoteList->itemId(item)); 0168 }); 0169 menu.exec(QCursor::pos()); 0170 } 0171 } 0172 0173 #include "moc_knotefinddialog.cpp"