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

kalarm

find.cpp

Go to the documentation of this file.
00001 /*
00002  *  find.cpp  -  search facility
00003  *  Program:  kalarm
00004  *  Copyright © 2005-2008 by David Jarvie <djarvie@kde.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kalarm.h"
00022 
00023 #include <QGroupBox>
00024 #include <QCheckBox>
00025 #include <QVBoxLayout>
00026 #include <QGridLayout>
00027 
00028 #include <kfinddialog.h>
00029 #include <kfind.h>
00030 #include <kseparator.h>
00031 #include <kwindowsystem.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kdebug.h>
00035 
00036 #include "alarmevent.h"
00037 #include "alarmlistfiltermodel.h"
00038 #include "alarmlistview.h"
00039 #include "eventlistview.h"
00040 #include "preferences.h"
00041 #include "find.moc"
00042 
00043 #ifdef __GNUC__
00044 #warning Search for text, then '29', then '2', reverts to text
00045 #endif
00046 // KAlarm-specific options for Find dialog
00047 enum {
00048     FIND_LIVE     = KFind::MinimumUserOption,
00049     FIND_ARCHIVED = KFind::MinimumUserOption << 1,
00050     FIND_MESSAGE  = KFind::MinimumUserOption << 2,
00051     FIND_FILE     = KFind::MinimumUserOption << 3,
00052     FIND_COMMAND  = KFind::MinimumUserOption << 4,
00053     FIND_EMAIL    = KFind::MinimumUserOption << 5
00054 };
00055 static long FIND_KALARM_OPTIONS = FIND_LIVE | FIND_ARCHIVED | FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL;
00056 
00057 
00058 class FindDlg : public KFindDialog
00059 {
00060     public:
00061         FindDlg(QWidget* parent, long options = 0, const QStringList& findStrings = QStringList(), bool hasSelection = false)
00062                : KFindDialog(parent, options, findStrings, hasSelection) {}
00063     protected slots:
00064         void slotButtonClicked(int button)
00065         {
00066             if (button == Ok)
00067                 emit okClicked();
00068             else
00069                 KFindDialog::slotButtonClicked(button);
00070         }
00071 };
00072 
00073 
00074 Find::Find(EventListView* parent)
00075     : QObject(parent),
00076       mListView(parent),
00077       mDialog(0),
00078       mFind(0),
00079       mOptions(0)
00080 {
00081     connect(mListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), SLOT(slotSelectionChanged()));
00082 }
00083 
00084 Find::~Find()
00085 {
00086     delete mDialog;    // automatically set to 0
00087     delete mFind;
00088     mFind = 0;
00089 }
00090 
00091 void Find::slotSelectionChanged()
00092 {
00093     if (mDialog)
00094         mDialog->setHasCursor(mListView->selectionModel()->currentIndex().isValid());
00095 }
00096 
00097 /******************************************************************************
00098 *  Display the Find dialog.
00099 */
00100 void Find::display()
00101 {
00102     if (!mOptions)
00103         // Set defaults the first time the Find dialog is activated
00104         mOptions = FIND_LIVE | FIND_ARCHIVED | FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL;
00105     bool noArchived = !Preferences::archivedKeepDays();
00106     bool showArchived = qobject_cast<AlarmListView*>(mListView)
00107                         && (static_cast<AlarmListFilterModel*>(mListView->model())->statusFilter() & KCalEvent::ARCHIVED);
00108     if (noArchived  ||  !showArchived)      // these settings could change between activations
00109         mOptions &= ~FIND_ARCHIVED;
00110 
00111     if (mDialog)
00112     {
00113 #ifdef Q_WS_X11
00114         KWindowSystem::activateWindow(mDialog->winId());
00115 #endif
00116     }
00117     else
00118     {
00119         mDialog = new FindDlg(mListView, mOptions, mHistory, (mListView->selectionModel()->selectedRows().count() > 1));
00120         mDialog->setModal(false);
00121         mDialog->setObjectName("FindDlg");
00122         mDialog->setHasSelection(false);
00123         QWidget* kalarmWidgets = mDialog->findExtension();
00124 
00125         // Alarm types
00126         QVBoxLayout* layout = new QVBoxLayout(kalarmWidgets);
00127         layout->setMargin(0);
00128         layout->setSpacing(KDialog::spacingHint());
00129         QGroupBox* group = new QGroupBox(i18nc("@title:group", "Alarm Type"), kalarmWidgets);
00130         layout->addWidget(group);
00131         QGridLayout* grid = new QGridLayout(group);
00132         grid->setMargin(KDialog::marginHint());
00133         grid->setSpacing(KDialog::spacingHint());
00134         grid->setColumnStretch(1, 1);
00135 
00136         // Live & archived alarm selection
00137         mLive = new QCheckBox(i18nc("@option:check Alarm type", "Active"), group);
00138         mLive->setFixedSize(mLive->sizeHint());
00139         mLive->setWhatsThis(i18nc("@info:whatsthis", "Check to include active alarms in the search."));
00140         grid->addWidget(mLive, 1, 0, Qt::AlignLeft);
00141 
00142         mArchived = new QCheckBox(i18nc("@option:check Alarm type", "Archived"), group);
00143         mArchived->setFixedSize(mArchived->sizeHint());
00144         mArchived->setWhatsThis(i18nc("@info:whatsthis", "Check to include archived alarms in the search. "
00145                                      "This option is only available if archived alarms are currently being displayed."));
00146         grid->addWidget(mArchived, 1, 2, Qt::AlignLeft);
00147 
00148         mActiveArchivedSep = new KSeparator(Qt::Horizontal, kalarmWidgets);
00149         grid->addWidget(mActiveArchivedSep, 2, 0, 1, 3);
00150 
00151         // Alarm actions
00152         mMessageType = new QCheckBox(i18nc("@option:check Alarm action = text display", "Text"), group);
00153         mMessageType->setFixedSize(mMessageType->sizeHint());
00154         mMessageType->setWhatsThis(i18nc("@info:whatsthis", "Check to include text message alarms in the search."));
00155         grid->addWidget(mMessageType, 3, 0);
00156 
00157         mFileType = new QCheckBox(i18nc("@option:check Alarm action = file display", "File"), group);
00158         mFileType->setFixedSize(mFileType->sizeHint());
00159         mFileType->setWhatsThis(i18nc("@info:whatsthis", "Check to include file alarms in the search."));
00160         grid->addWidget(mFileType, 3, 2);
00161 
00162         mCommandType = new QCheckBox(i18nc("@option:check Alarm action", "Command"), group);
00163         mCommandType->setFixedSize(mCommandType->sizeHint());
00164         mCommandType->setWhatsThis(i18nc("@info:whatsthis", "Check to include command alarms in the search."));
00165         grid->addWidget(mCommandType, 4, 0);
00166 
00167         mEmailType = new QCheckBox(i18nc("@option:check Alarm action", "Email"), group);
00168         mEmailType->setFixedSize(mEmailType->sizeHint());
00169         mEmailType->setWhatsThis(i18nc("@info:whatsthis", "Check to include email alarms in the search."));
00170         grid->addWidget(mEmailType, 4, 2);
00171 
00172         // Set defaults
00173         mLive->setChecked(mOptions & FIND_LIVE);
00174         mArchived->setChecked(mOptions & FIND_ARCHIVED);
00175         mMessageType->setChecked(mOptions & FIND_MESSAGE);
00176         mFileType->setChecked(mOptions & FIND_FILE);
00177         mCommandType->setChecked(mOptions & FIND_COMMAND);
00178         mEmailType->setChecked(mOptions & FIND_EMAIL);
00179 
00180         connect(mDialog, SIGNAL(okClicked()), this, SLOT(slotFind()));
00181     }
00182 
00183     // Only display active/archived options if archived alarms are being kept
00184     if (noArchived)
00185     {
00186         mLive->hide();
00187         mArchived->hide();
00188         mActiveArchivedSep->hide();
00189     }
00190     else
00191     {
00192         mLive->show();
00193         mArchived->show();
00194         mActiveArchivedSep->show();
00195     }
00196 
00197     // Disable options where no displayed alarms match them
00198     bool live     = false;
00199     bool archived = false;
00200     bool text     = false;
00201     bool file     = false;
00202     bool command  = false;
00203     bool email    = false;
00204     int rowCount = mListView->model()->rowCount();
00205     for (int row = 0;  row < rowCount;  ++row)
00206     {
00207         const KAEvent* event = mListView->event(row);
00208         if (event->expired())
00209             archived = true;
00210         else
00211             live = true;
00212         switch (event->action())
00213         {
00214             case KAEvent::MESSAGE:  text    = true;  break;
00215             case KAEvent::FILE:     file    = true;  break;
00216             case KAEvent::COMMAND:  command = true;  break;
00217             case KAEvent::EMAIL:    email   = true;  break;
00218         }
00219     }
00220     mLive->setEnabled(live);
00221     mArchived->setEnabled(archived);
00222     mMessageType->setEnabled(text);
00223     mFileType->setEnabled(file);
00224     mCommandType->setEnabled(command);
00225     mEmailType->setEnabled(email);
00226 
00227     mDialog->setHasCursor(mListView->selectionModel()->currentIndex().isValid());
00228     mDialog->show();
00229 }
00230 
00231 /******************************************************************************
00232 *  Called when the user requests a search by clicking the dialog OK button.
00233 */
00234 void Find::slotFind()
00235 {
00236     if (!mDialog)
00237         return;
00238     mHistory = mDialog->findHistory();    // save search history so that it can be displayed again
00239     mOptions = mDialog->options() & ~FIND_KALARM_OPTIONS;
00240     mOptions |= (mLive->isEnabled()        && mLive->isChecked()        ? FIND_LIVE : 0)
00241              |  (mArchived->isEnabled()    && mArchived->isChecked()    ? FIND_ARCHIVED : 0)
00242              |  (mMessageType->isEnabled() && mMessageType->isChecked() ? FIND_MESSAGE : 0)
00243              |  (mFileType->isEnabled()    && mFileType->isChecked()    ? FIND_FILE : 0)
00244              |  (mCommandType->isEnabled() && mCommandType->isChecked() ? FIND_COMMAND : 0)
00245              |  (mEmailType->isEnabled()   && mEmailType->isChecked()   ? FIND_EMAIL : 0);
00246     if (!(mOptions & (FIND_LIVE | FIND_ARCHIVED))
00247     ||  !(mOptions & (FIND_MESSAGE | FIND_FILE | FIND_COMMAND | FIND_EMAIL)))
00248     {
00249         KMessageBox::sorry(mDialog, i18nc("@info", "No alarm types are selected to search"));
00250         return;
00251     }
00252 
00253     // Supply KFind with only those options which relate to the text within alarms
00254     long options = mOptions & (KFind::WholeWordsOnly | KFind::CaseSensitive | KFind::RegularExpression);
00255     bool newFind = !mFind;
00256     bool newPattern = (mDialog->pattern() != mLastPattern);
00257     mLastPattern = mDialog->pattern();
00258     if (mFind)
00259     {
00260         mFind->resetCounts();
00261         mFind->setPattern(mLastPattern);
00262         mFind->setOptions(options);
00263     }
00264     else
00265     {
00266         mFind = new KFind(mLastPattern, options, mListView, mDialog);
00267         connect(mFind, SIGNAL(destroyed()), SLOT(slotKFindDestroyed()));
00268         mFind->closeFindNextDialog();    // prevent 'Find Next' dialog appearing
00269     }
00270 
00271     // Set the starting point for the search
00272     mStartID.clear();
00273     mNoCurrentItem = newPattern;
00274     bool checkEnd = false;
00275     if (newPattern)
00276     {
00277         mFound = false;
00278         if (mOptions & KFind::FromCursor)
00279         {
00280             QModelIndex index = mListView->selectionModel()->currentIndex();
00281             if (index.isValid())
00282             {
00283                 mStartID       = mListView->event(index)->id();
00284                 mNoCurrentItem = false;
00285                 checkEnd = true;
00286             }
00287         }
00288     }
00289 
00290     // Execute the search
00291     findNext(true, checkEnd, false);
00292     if (mFind  &&  newFind)
00293         emit active(true);
00294 }
00295 
00296 /******************************************************************************
00297 *  Perform the search.
00298 *  If 'fromCurrent' is true, the search starts with the current search item;
00299 *  otherwise, it starts from the next item.
00300 */
00301 void Find::findNext(bool forward, bool checkEnd, bool fromCurrent)
00302 {
00303     QModelIndex index;
00304     if (!mNoCurrentItem)
00305         index = mListView->selectionModel()->currentIndex();
00306     if (!fromCurrent)
00307         index = nextItem(index, forward);
00308 
00309     // Search successive alarms until a match is found or the end is reached
00310     bool found = false;
00311     bool last = false;
00312     for ( ;  index.isValid() && !last;  index = nextItem(index, forward))
00313     {
00314         const KAEvent* event = mListView->event(index);
00315         if (!fromCurrent  &&  !mStartID.isNull()  &&  mStartID == event->id())
00316             last = true;    // we've wrapped round and reached the starting alarm again
00317         fromCurrent = false;
00318         bool live = !event->expired();
00319         if ((live  &&  !(mOptions & FIND_LIVE))
00320         ||  (!live  &&  !(mOptions & FIND_ARCHIVED)))
00321             continue;     // we're not searching this type of alarm
00322         switch (event->action())
00323         {
00324             case KAEvent::MESSAGE:
00325                 if (!(mOptions & FIND_MESSAGE))
00326                     break;
00327                 mFind->setData(event->cleanText());
00328                 found = (mFind->find() == KFind::Match);
00329                 break;
00330 
00331             case KAEvent::FILE:
00332                 if (!(mOptions & FIND_FILE))
00333                     break;
00334                 mFind->setData(event->cleanText());
00335                 found = (mFind->find() == KFind::Match);
00336                 break;
00337 
00338             case KAEvent::COMMAND:
00339                 if (!(mOptions & FIND_COMMAND))
00340                     break;
00341                 mFind->setData(event->cleanText());
00342                 found = (mFind->find() == KFind::Match);
00343                 break;
00344 
00345             case KAEvent::EMAIL:
00346                 if (!(mOptions & FIND_EMAIL))
00347                     break;
00348                 mFind->setData(event->emailAddresses(", "));
00349                 found = (mFind->find() == KFind::Match);
00350                 if (found)
00351                     break;
00352                 mFind->setData(event->emailSubject());
00353                 found = (mFind->find() == KFind::Match);
00354                 if (found)
00355                     break;
00356                 mFind->setData(event->emailAttachments().join(", "));
00357                 found = (mFind->find() == KFind::Match);
00358                 if (found)
00359                     break;
00360                 mFind->setData(event->cleanText());
00361                 found = (mFind->find() == KFind::Match);
00362                 break;
00363         }
00364         if (found)
00365             break;
00366     }
00367 
00368     // Process the search result
00369     mNoCurrentItem = !index.isValid();
00370     if (found)
00371     {
00372         // A matching alarm was found - highlight it and make it current
00373         mFound = true;
00374         QItemSelectionModel* sel = mListView->selectionModel();
00375         sel->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00376         sel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
00377         mListView->scrollTo(index);
00378     }
00379     else
00380     {
00381         // No match was found
00382         if (mFound  ||  checkEnd)
00383         {
00384             QString msg = forward ? i18nc("@info", "<para>End of alarm list reached.</para><para>Continue from the beginning?</para>")
00385                                   : i18nc("@info", "<para>Beginning of alarm list reached.</para><para>Continue from the end?</para>");
00386             if (KMessageBox::questionYesNo(mListView, msg, QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::Yes)
00387             {
00388                 mNoCurrentItem = true;
00389                 findNext(forward, false, false);
00390                 return;
00391             }
00392         }
00393         else
00394             mFind->displayFinalDialog();     // display "no match was found"
00395         mNoCurrentItem = false;    // restart from the currently highlighted alarm if Find Next etc selected
00396     }
00397 }
00398 
00399 /******************************************************************************
00400 *  Get the next alarm item to search.
00401 */
00402 QModelIndex Find::nextItem(const QModelIndex& index, bool forward) const
00403 {
00404     if (mOptions & KFind::FindBackwards)
00405         forward = !forward;
00406     if (!index.isValid())
00407     {
00408         QAbstractItemModel* model = mListView->model();
00409         if (forward)
00410             return model->index(0, 0);
00411         else
00412             return model->index(model->rowCount() - 1, 0);
00413     }
00414     if (forward)
00415         return mListView->indexBelow(index);
00416     else
00417         return mListView->indexAbove(index);
00418 }

kalarm

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

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal