• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kalarm

  • sources
  • kde-4.14
  • kdepim
  • kalarm
find.cpp
Go to the documentation of this file.
1 /*
2  * find.cpp - search facility
3  * Program: kalarm
4  * Copyright © 2005-2013 by David Jarvie <djarvie@kde.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include "kalarm.h"
22 #include "find.h"
23 
24 #ifndef USE_AKONADI
25 #include "alarmlistfiltermodel.h"
26 #endif
27 #include "alarmlistview.h"
28 #include "eventlistview.h"
29 #include "messagebox.h"
30 #include "preferences.h"
31 
32 #include <kalarmcal/kaevent.h>
33 
34 #include <kfinddialog.h>
35 #include <kfind.h>
36 #include <kseparator.h>
37 #include <kwindowsystem.h>
38 #include <klocale.h>
39 #include <kdebug.h>
40 
41 #include <QGroupBox>
42 #include <QCheckBox>
43 #include <QVBoxLayout>
44 #include <QGridLayout>
45 #include <QRegExp>
46 
47 using namespace KAlarmCal;
48 
49 // KAlarm-specific options for Find dialog
50 enum {
51  FIND_LIVE = KFind::MinimumUserOption,
52  FIND_ARCHIVED = KFind::MinimumUserOption << 1,
53  FIND_MESSAGE = KFind::MinimumUserOption << 2,
54  FIND_FILE = KFind::MinimumUserOption << 3,
55  FIND_COMMAND = KFind::MinimumUserOption << 4,
56  FIND_EMAIL = KFind::MinimumUserOption << 5,
57  FIND_AUDIO = KFind::MinimumUserOption << 6
58 };
59 static long FIND_KALARM_OPTIONS = FIND_LIVE | FIND_ARCHIVED | FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL | FIND_AUDIO;
60 
61 
62 class FindDlg : public KFindDialog
63 {
64  public:
65  FindDlg(QWidget* parent, long options = 0, const QStringList& findStrings = QStringList(), bool hasSelection = false)
66  : KFindDialog(parent, options, findStrings, hasSelection) {}
67  protected slots:
68  void slotButtonClicked(int button)
69  {
70  if (button == Ok)
71  emit okClicked();
72  else
73  KFindDialog::slotButtonClicked(button);
74  }
75 };
76 
77 
78 Find::Find(EventListView* parent)
79  : QObject(parent),
80  mListView(parent),
81  mDialog(0),
82  mFind(0),
83  mOptions(0),
84  mFound(false)
85 {
86  connect(mListView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(slotSelectionChanged()));
87 }
88 
89 Find::~Find()
90 {
91  delete mDialog; // automatically set to 0
92  delete mFind;
93  mFind = 0;
94 }
95 
96 void Find::slotSelectionChanged()
97 {
98  if (mDialog)
99  mDialog->setHasCursor(mListView->selectionModel()->currentIndex().isValid());
100 }
101 
102 /******************************************************************************
103 * Display the Find dialog.
104 */
105 void Find::display()
106 {
107  if (!mOptions)
108  // Set defaults the first time the Find dialog is activated
109  mOptions = FIND_LIVE | FIND_ARCHIVED | FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL | FIND_AUDIO;
110  bool noArchived = !Preferences::archivedKeepDays();
111  bool showArchived = qobject_cast<AlarmListView*>(mListView)
112 #ifdef USE_AKONADI
113  && (static_cast<AlarmListModel*>(mListView->model())->eventTypeFilter() & CalEvent::ARCHIVED);
114 #else
115  && (static_cast<AlarmListFilterModel*>(mListView->model())->statusFilter() & CalEvent::ARCHIVED);
116 #endif
117  if (noArchived || !showArchived) // these settings could change between activations
118  mOptions &= ~FIND_ARCHIVED;
119 
120  if (mDialog)
121  {
122 #ifdef Q_WS_X11
123  KWindowSystem::activateWindow(mDialog->winId());
124 #endif
125  }
126  else
127  {
128  mDialog = new FindDlg(mListView, mOptions, mHistory, (mListView->selectionModel()->selectedRows().count() > 1));
129  mDialog->setModal(false);
130  mDialog->setObjectName(QLatin1String("FindDlg"));
131  mDialog->setHasSelection(false);
132  QWidget* kalarmWidgets = mDialog->findExtension();
133 
134  // Alarm types
135  QVBoxLayout* layout = new QVBoxLayout(kalarmWidgets);
136  layout->setMargin(0);
137  layout->setSpacing(KDialog::spacingHint());
138  QGroupBox* group = new QGroupBox(i18nc("@title:group", "Alarm Type"), kalarmWidgets);
139  layout->addWidget(group);
140  QGridLayout* grid = new QGridLayout(group);
141  grid->setMargin(KDialog::marginHint());
142  grid->setSpacing(KDialog::spacingHint());
143  grid->setColumnStretch(1, 1);
144 
145  // Live & archived alarm selection
146  mLive = new QCheckBox(i18nc("@option:check Alarm type", "Active"), group);
147  mLive->setFixedSize(mLive->sizeHint());
148  mLive->setWhatsThis(i18nc("@info:whatsthis", "Check to include active alarms in the search."));
149  grid->addWidget(mLive, 1, 0, Qt::AlignLeft);
150 
151  mArchived = new QCheckBox(i18nc("@option:check Alarm type", "Archived"), group);
152  mArchived->setFixedSize(mArchived->sizeHint());
153  mArchived->setWhatsThis(i18nc("@info:whatsthis", "Check to include archived alarms in the search. "
154  "This option is only available if archived alarms are currently being displayed."));
155  grid->addWidget(mArchived, 1, 2, Qt::AlignLeft);
156 
157  mActiveArchivedSep = new KSeparator(Qt::Horizontal, kalarmWidgets);
158  grid->addWidget(mActiveArchivedSep, 2, 0, 1, 3);
159 
160  // Alarm actions
161  mMessageType = new QCheckBox(i18nc("@option:check Alarm action = text display", "Text"), group);
162  mMessageType->setFixedSize(mMessageType->sizeHint());
163  mMessageType->setWhatsThis(i18nc("@info:whatsthis", "Check to include text message alarms in the search."));
164  grid->addWidget(mMessageType, 3, 0);
165 
166  mFileType = new QCheckBox(i18nc("@option:check Alarm action = file display", "File"), group);
167  mFileType->setFixedSize(mFileType->sizeHint());
168  mFileType->setWhatsThis(i18nc("@info:whatsthis", "Check to include file alarms in the search."));
169  grid->addWidget(mFileType, 3, 2);
170 
171  mCommandType = new QCheckBox(i18nc("@option:check Alarm action", "Command"), group);
172  mCommandType->setFixedSize(mCommandType->sizeHint());
173  mCommandType->setWhatsThis(i18nc("@info:whatsthis", "Check to include command alarms in the search."));
174  grid->addWidget(mCommandType, 4, 0);
175 
176  mEmailType = new QCheckBox(i18nc("@option:check Alarm action", "Email"), group);
177  mEmailType->setFixedSize(mEmailType->sizeHint());
178  mEmailType->setWhatsThis(i18nc("@info:whatsthis", "Check to include email alarms in the search."));
179  grid->addWidget(mEmailType, 4, 2);
180 
181  mAudioType = new QCheckBox(i18nc("@option:check Alarm action", "Audio"), group);
182  mAudioType->setFixedSize(mAudioType->sizeHint());
183  mAudioType->setWhatsThis(i18nc("@info:whatsthis", "Check to include audio alarms in the search."));
184  grid->addWidget(mAudioType, 5, 0);
185 
186  // Set defaults
187  mLive->setChecked(mOptions & FIND_LIVE);
188  mArchived->setChecked(mOptions & FIND_ARCHIVED);
189  mMessageType->setChecked(mOptions & FIND_MESSAGE);
190  mFileType->setChecked(mOptions & FIND_FILE);
191  mCommandType->setChecked(mOptions & FIND_COMMAND);
192  mEmailType->setChecked(mOptions & FIND_EMAIL);
193  mAudioType->setChecked(mOptions & FIND_AUDIO);
194 
195  connect(mDialog, SIGNAL(okClicked()), this, SLOT(slotFind()));
196  }
197 
198  // Only display active/archived options if archived alarms are being kept
199  if (noArchived)
200  {
201  mLive->hide();
202  mArchived->hide();
203  mActiveArchivedSep->hide();
204  }
205  else
206  {
207  mLive->show();
208  mArchived->show();
209  mActiveArchivedSep->show();
210  }
211 
212  // Disable options where no displayed alarms match them
213  bool live = false;
214  bool archived = false;
215  bool text = false;
216  bool file = false;
217  bool command = false;
218  bool email = false;
219  bool audio = false;
220  int rowCount = mListView->model()->rowCount();
221  for (int row = 0; row < rowCount; ++row)
222  {
223 #ifdef USE_AKONADI
224  KAEvent viewEvent = mListView->event(row);
225  const KAEvent* event = &viewEvent;
226 #else
227  const KAEvent* event = mListView->event(row);
228 #endif
229  if (event->expired())
230  archived = true;
231  else
232  live = true;
233  switch (event->actionTypes())
234  {
235  case KAEvent::ACT_EMAIL: email = true; break;
236  case KAEvent::ACT_AUDIO: audio = true; break;
237  case KAEvent::ACT_COMMAND: command = true; break;
238  case KAEvent::ACT_DISPLAY:
239  if (event->actionSubType() == KAEvent::FILE)
240  {
241  file = true;
242  break;
243  }
244  // fall through to ACT_DISPLAY_COMMAND
245  case KAEvent::ACT_DISPLAY_COMMAND:
246  default:
247  text = true;
248  break;
249  }
250  }
251  mLive->setEnabled(live);
252  mArchived->setEnabled(archived);
253  mMessageType->setEnabled(text);
254  mFileType->setEnabled(file);
255  mCommandType->setEnabled(command);
256  mEmailType->setEnabled(email);
257  mAudioType->setEnabled(audio);
258 
259  mDialog->setHasCursor(mListView->selectionModel()->currentIndex().isValid());
260  mDialog->show();
261 }
262 
263 /******************************************************************************
264 * Called when the user requests a search by clicking the dialog OK button.
265 */
266 void Find::slotFind()
267 {
268  if (!mDialog)
269  return;
270  mHistory = mDialog->findHistory(); // save search history so that it can be displayed again
271  mOptions = mDialog->options() & ~FIND_KALARM_OPTIONS;
272  if ((mOptions & KFind::RegularExpression) && !QRegExp(mDialog->pattern()).isValid())
273  return;
274  mOptions |= (mLive->isEnabled() && mLive->isChecked() ? FIND_LIVE : 0)
275  | (mArchived->isEnabled() && mArchived->isChecked() ? FIND_ARCHIVED : 0)
276  | (mMessageType->isEnabled() && mMessageType->isChecked() ? FIND_MESSAGE : 0)
277  | (mFileType->isEnabled() && mFileType->isChecked() ? FIND_FILE : 0)
278  | (mCommandType->isEnabled() && mCommandType->isChecked() ? FIND_COMMAND : 0)
279  | (mEmailType->isEnabled() && mEmailType->isChecked() ? FIND_EMAIL : 0)
280  | (mAudioType->isEnabled() && mAudioType->isChecked() ? FIND_AUDIO : 0);
281  if (!(mOptions & (FIND_LIVE | FIND_ARCHIVED))
282  || !(mOptions & (FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL | FIND_AUDIO)))
283  {
284  KAMessageBox::sorry(mDialog, i18nc("@info", "No alarm types are selected to search"));
285  return;
286  }
287 
288  // Supply KFind with only those options which relate to the text within alarms
289  long options = mOptions & (KFind::WholeWordsOnly | KFind::CaseSensitive | KFind::RegularExpression);
290  bool newFind = !mFind;
291  bool newPattern = (mDialog->pattern() != mLastPattern);
292  mLastPattern = mDialog->pattern();
293  if (mFind)
294  {
295  mFind->resetCounts();
296  mFind->setPattern(mLastPattern);
297  mFind->setOptions(options);
298  }
299  else
300  {
301  mFind = new KFind(mLastPattern, options, mListView, mDialog);
302  connect(mFind, SIGNAL(destroyed()), SLOT(slotKFindDestroyed()));
303  mFind->closeFindNextDialog(); // prevent 'Find Next' dialog appearing
304  }
305 
306  // Set the starting point for the search
307  mStartID.clear();
308  mNoCurrentItem = newPattern;
309  bool checkEnd = false;
310  if (newPattern)
311  {
312  mFound = false;
313  if (mOptions & KFind::FromCursor)
314  {
315  QModelIndex index = mListView->selectionModel()->currentIndex();
316  if (index.isValid())
317  {
318 #ifdef USE_AKONADI
319  mStartID = mListView->event(index).id();
320 #else
321  mStartID = mListView->event(index)->id();
322 #endif
323  mNoCurrentItem = false;
324  checkEnd = true;
325  }
326  }
327  }
328 
329  // Execute the search
330  findNext(true, checkEnd, false);
331  if (mFind && newFind)
332  emit active(true);
333 }
334 
335 /******************************************************************************
336 * Perform the search.
337 * If 'fromCurrent' is true, the search starts with the current search item;
338 * otherwise, it starts from the next item.
339 */
340 void Find::findNext(bool forward, bool checkEnd, bool fromCurrent)
341 {
342  QModelIndex index;
343  if (!mNoCurrentItem)
344  index = mListView->selectionModel()->currentIndex();
345  if (!fromCurrent)
346  index = nextItem(index, forward);
347 
348  // Search successive alarms until a match is found or the end is reached
349  bool found = false;
350  bool last = false;
351  for ( ; index.isValid() && !last; index = nextItem(index, forward))
352  {
353 #ifdef USE_AKONADI
354  KAEvent viewEvent = mListView->event(index);
355  const KAEvent* event = &viewEvent;
356 #else
357  const KAEvent* event = mListView->event(index);
358 #endif
359  if (!fromCurrent && !mStartID.isNull() && mStartID == event->id())
360  last = true; // we've wrapped round and reached the starting alarm again
361  fromCurrent = false;
362  bool live = !event->expired();
363  if ((live && !(mOptions & FIND_LIVE))
364  || (!live && !(mOptions & FIND_ARCHIVED)))
365  continue; // we're not searching this type of alarm
366  switch (event->actionTypes())
367  {
368  case KAEvent::ACT_EMAIL:
369  if (!(mOptions & FIND_EMAIL))
370  break;
371  mFind->setData(event->emailAddresses(QLatin1String(", ")));
372  found = (mFind->find() == KFind::Match);
373  if (found)
374  break;
375  mFind->setData(event->emailSubject());
376  found = (mFind->find() == KFind::Match);
377  if (found)
378  break;
379  mFind->setData(event->emailAttachments().join(QLatin1String(", ")));
380  found = (mFind->find() == KFind::Match);
381  if (found)
382  break;
383  mFind->setData(event->cleanText());
384  found = (mFind->find() == KFind::Match);
385  break;
386 
387  case KAEvent::ACT_AUDIO:
388  if (!(mOptions & FIND_AUDIO))
389  break;
390  mFind->setData(event->audioFile());
391  found = (mFind->find() == KFind::Match);
392  break;
393 
394  case KAEvent::ACT_COMMAND:
395  if (!(mOptions & FIND_COMMAND))
396  break;
397  mFind->setData(event->cleanText());
398  found = (mFind->find() == KFind::Match);
399  break;
400 
401  case KAEvent::ACT_DISPLAY:
402  if (event->actionSubType() == KAEvent::FILE)
403  {
404  if (!(mOptions & FIND_FILE))
405  break;
406  mFind->setData(event->cleanText());
407  found = (mFind->find() == KFind::Match);
408  break;
409  }
410  // fall through to ACT_DISPLAY_COMMAND
411  case KAEvent::ACT_DISPLAY_COMMAND:
412  if (!(mOptions & FIND_MESSAGE))
413  break;
414  mFind->setData(event->cleanText());
415  found = (mFind->find() == KFind::Match);
416  break;
417  default:
418  break;
419  }
420  if (found)
421  break;
422  }
423 
424  // Process the search result
425  mNoCurrentItem = !index.isValid();
426  if (found)
427  {
428  // A matching alarm was found - highlight it and make it current
429  mFound = true;
430  QItemSelectionModel* sel = mListView->selectionModel();
431  sel->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
432  sel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
433  mListView->scrollTo(index);
434  }
435  else
436  {
437  // No match was found
438  if (mFound || checkEnd)
439  {
440  QString msg = forward ? i18nc("@info", "<para>End of alarm list reached.</para><para>Continue from the beginning?</para>")
441  : i18nc("@info", "<para>Beginning of alarm list reached.</para><para>Continue from the end?</para>");
442  if (KAMessageBox::questionYesNo(mListView, msg, QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::Yes)
443  {
444  mNoCurrentItem = true;
445  findNext(forward, false, false);
446  return;
447  }
448  }
449  else
450  mFind->displayFinalDialog(); // display "no match was found"
451  mNoCurrentItem = false; // restart from the currently highlighted alarm if Find Next etc selected
452  }
453 }
454 
455 /******************************************************************************
456 * Get the next alarm item to search.
457 */
458 QModelIndex Find::nextItem(const QModelIndex& index, bool forward) const
459 {
460  if (mOptions & KFind::FindBackwards)
461  forward = !forward;
462  if (!index.isValid())
463  {
464  QAbstractItemModel* model = mListView->model();
465  if (forward)
466  return model->index(0, 0);
467  else
468  return model->index(model->rowCount() - 1, 0);
469  }
470  if (forward)
471  return mListView->indexBelow(index);
472  else
473  return mListView->indexAbove(index);
474 }
475 #include "moc_find.cpp"
476 // vim: et sw=4:
QModelIndex
QWidget
QAbstractItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const =0
FIND_ARCHIVED
Definition: find.cpp:52
AlarmListFilterModel
Definition: alarmlistfiltermodel.h:31
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
QItemSelectionModel::currentIndex
QModelIndex currentIndex() const
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QAbstractItemView::selectionModel
QItemSelectionModel * selectionModel() const
text
virtual QByteArray text(quint32 serialNumber) const =0
EventListView
Definition: eventlistview.h:37
FIND_KALARM_OPTIONS
static long FIND_KALARM_OPTIONS
Definition: find.cpp:59
eventlistview.h
Find::~Find
~Find()
Definition: find.cpp:89
alarmlistfiltermodel.h
QCheckBox::sizeHint
virtual QSize sizeHint() const
AlarmListView
Definition: alarmlistview.h:31
FIND_FILE
Definition: find.cpp:54
QTreeView::indexBelow
QModelIndex indexBelow(const QModelIndex &index) const
QGridLayout
FIND_MESSAGE
Definition: find.cpp:53
QGridLayout::setSpacing
void setSpacing(int spacing)
QString::isNull
bool isNull() const
EventListView::event
KAEvent * event(int row) const
Definition: eventlistview.cpp:73
QObject::event
virtual bool event(QEvent *e)
QString::clear
void clear()
QRegExp
QModelIndex::isValid
bool isValid() const
FIND_COMMAND
Definition: find.cpp:55
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QGroupBox
QObject
find.h
QCheckBox
QItemSelectionModel::select
virtual void select(const QModelIndex &index, QFlags< QItemSelectionModel::SelectionFlag > command)
QItemSelectionModel::selectedRows
QModelIndexList selectedRows(int column) const
QVBoxLayout
messagebox.h
QString
QWidget::hide
void hide()
QLayout::setMargin
void setMargin(int margin)
QStringList
QWidget::setFixedSize
void setFixedSize(const QSize &s)
preferences.h
QTreeView::scrollTo
virtual void scrollTo(const QModelIndex &index, ScrollHint hint)
QAbstractButton::setChecked
void setChecked(bool)
QWidget::setWhatsThis
void setWhatsThis(const QString &)
QLatin1String
KAMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
QGridLayout::setColumnStretch
void setColumnStretch(int column, int stretch)
alarmlistview.h
kalarm.h
Find::Find
Find(EventListView *parent)
Definition: find.cpp:78
Find::active
void active(bool)
FIND_LIVE
Definition: find.cpp:51
QAbstractItemModel
FIND_AUDIO
Definition: find.cpp:57
QItemSelectionModel::setCurrentIndex
void setCurrentIndex(const QModelIndex &index, QFlags< QItemSelectionModel::SelectionFlag > command)
QWidget::show
void show()
Find::display
void display()
Definition: find.cpp:105
QAbstractItemView::model
QAbstractItemModel * model() const
QItemSelectionModel
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Find::findNext
void findNext(bool forward)
Definition: find.h:43
QTreeView::indexAbove
QModelIndex indexAbove(const QModelIndex &index) const
QObject::destroyed
void destroyed(QObject *obj)
QBoxLayout::setSpacing
void setSpacing(int spacing)
FIND_EMAIL
Definition: find.cpp:56
KAMessageBox::questionYesNo
static int questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|WindowModal))
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kalarm

Skip menu "kalarm"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal