korganizer

searchdialog.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 1998 Preston Brown <pbrown@kde.org>
00005     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00006     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021 
00022     As a special exception, permission is given to link this program
00023     with any edition of Qt, and distribute the resulting executable,
00024     without including the source code for Qt in the source distribution.
00025 */
00026 
00027 #include <qlayout.h>
00028 #include <qcheckbox.h>
00029 #include <qgroupbox.h>
00030 #include <qhbuttongroup.h>
00031 #include <qlabel.h>
00032 #include <qlineedit.h>
00033 
00034 #include <klocale.h>
00035 #include <kmessagebox.h>
00036 
00037 #include <libkcal/calendar.h>
00038 
00039 #include <libkdepim/kdateedit.h>
00040 
00041 #include "koglobals.h"
00042 #include "koprefs.h"
00043 #include "kolistview.h"
00044 
00045 #include "searchdialog.h"
00046 #include "searchdialog.moc"
00047 
00048 SearchDialog::SearchDialog(Calendar *calendar,QWidget *parent)
00049   : KDialogBase(Plain,i18n("Find Events"),User1|Close,User1,parent,0,false,false,
00050                 KGuiItem( i18n("&Find"), "find") )
00051 {
00052   mCalendar = calendar;
00053 
00054   QFrame *topFrame = plainPage();
00055   QVBoxLayout *layout = new QVBoxLayout(topFrame,0,spacingHint());
00056 
00057   // Search expression
00058   QHBoxLayout *subLayout = new QHBoxLayout();
00059   layout->addLayout(subLayout);
00060 
00061   searchEdit = new QLineEdit( "*", topFrame ); // Find all events by default
00062   searchLabel = new QLabel( searchEdit, i18n("&Search for:"), topFrame );
00063   subLayout->addWidget( searchLabel );
00064   subLayout->addWidget( searchEdit );
00065   searchEdit->setFocus();
00066   connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
00067            this, SLOT( searchTextChanged( const QString & ) ) );
00068 
00069 
00070   QHButtonGroup *itemsGroup = new QHButtonGroup( i18n("Search For"), topFrame );
00071   layout->addWidget( itemsGroup );
00072   mEventsCheck = new QCheckBox( i18n("&Events"), itemsGroup );
00073   mTodosCheck = new QCheckBox( i18n("To-&dos"), itemsGroup );
00074   mJournalsCheck = new QCheckBox( i18n("&Journal entries"), itemsGroup );
00075   mEventsCheck->setChecked( true );
00076   mTodosCheck->setChecked( true );
00077 
00078   // Date range
00079   QGroupBox *rangeGroup = new QGroupBox( 1, Horizontal, i18n( "Date Range" ),
00080                                         topFrame );
00081   layout->addWidget( rangeGroup );
00082 
00083   QWidget *rangeWidget = new QWidget( rangeGroup );
00084   QHBoxLayout *rangeLayout = new QHBoxLayout( rangeWidget, 0, spacingHint() );
00085 
00086   mStartDate = new KDateEdit( rangeWidget );
00087   rangeLayout->addWidget( new QLabel( mStartDate, i18n("Fr&om:"), rangeWidget ) );
00088   rangeLayout->addWidget( mStartDate );
00089 
00090   mEndDate = new KDateEdit( rangeWidget );
00091   rangeLayout->addWidget( new QLabel( mEndDate, i18n("&To:"), rangeWidget ) );
00092   mEndDate->setDate( QDate::currentDate().addDays( 365 ) );
00093   rangeLayout->addWidget( mEndDate );
00094 
00095   mInclusiveCheck = new QCheckBox( i18n("E&vents have to be completely included"),
00096                                   rangeGroup );
00097   mInclusiveCheck->setChecked( false );
00098   mIncludeUndatedTodos = new QCheckBox( i18n("Include to-dos &without due date"), rangeGroup );
00099   mIncludeUndatedTodos->setChecked( true );
00100 
00101   // Subjects to search
00102   QHButtonGroup *subjectGroup = new QHButtonGroup( i18n("Search In"), topFrame );
00103   layout->addWidget(subjectGroup);
00104 
00105   mSummaryCheck = new QCheckBox( i18n("Su&mmaries"), subjectGroup );
00106   mSummaryCheck->setChecked( true );
00107   mDescriptionCheck = new QCheckBox( i18n("Desc&riptions"), subjectGroup );
00108   mCategoryCheck = new QCheckBox( i18n("Cate&gories"), subjectGroup );
00109 
00110 
00111   // Results list view
00112   listView = new KOListView( mCalendar, topFrame );
00113   listView->showDates();
00114   layout->addWidget( listView );
00115 
00116   if ( KOPrefs::instance()->mCompactDialogs ) {
00117     KOGlobals::fitDialogToScreen( this, true );
00118   }
00119 
00120   connect( this,SIGNAL(user1Clicked()),SLOT(doSearch()));
00121 
00122   // Propagate edit and delete event signals from event list view
00123   connect( listView, SIGNAL( showIncidenceSignal( Incidence * ) ),
00124           SIGNAL( showIncidenceSignal( Incidence *) ) );
00125   connect( listView, SIGNAL( editIncidenceSignal( Incidence * ) ),
00126           SIGNAL( editIncidenceSignal( Incidence * ) ) );
00127   connect( listView, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00128           SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00129 }
00130 
00131 SearchDialog::~SearchDialog()
00132 {
00133 }
00134 
00135 void SearchDialog::searchTextChanged( const QString &_text )
00136 {
00137   enableButton( KDialogBase::User1, !_text.isEmpty() );
00138 }
00139 
00140 void SearchDialog::doSearch()
00141 {
00142   QRegExp re;
00143 
00144   re.setWildcard( true ); // most people understand these better.
00145   re.setCaseSensitive( false );
00146   re.setPattern( searchEdit->text() );
00147   if ( !re.isValid() ) {
00148     KMessageBox::sorry( this,
00149                         i18n("Invalid search expression, cannot perform "
00150                             "the search. Please enter a search expression "
00151                             "using the wildcard characters '*' and '?' "
00152                             "where needed." ) );
00153     return;
00154   }
00155 
00156   search( re );
00157 
00158   listView->showIncidences( mMatchedEvents );
00159 
00160   if ( mMatchedEvents.count() == 0 ) {
00161     KMessageBox::information( this,
00162         i18n("No events were found matching your search expression."),
00163         "NoSearchResults" );
00164   }
00165 }
00166 
00167 void SearchDialog::updateView()
00168 {
00169   QRegExp re;
00170   re.setWildcard( true ); // most people understand these better.
00171   re.setCaseSensitive( false );
00172   re.setPattern( searchEdit->text() );
00173   if ( re.isValid() ) {
00174     search( re );
00175   } else {
00176     mMatchedEvents.clear();
00177   }
00178 
00179   listView->showIncidences( mMatchedEvents );
00180 }
00181 
00182 void SearchDialog::search( const QRegExp &re )
00183 {
00184   QDate startDt = mStartDate->date();
00185   QDate endDt = mEndDate->date();
00186 
00187   Event::List events;
00188   if (mEventsCheck->isChecked()) {
00189     events = mCalendar->events( startDt, endDt, mInclusiveCheck->isChecked() );
00190   }
00191   Todo::List todos;
00192   if (mTodosCheck->isChecked()) {
00193     if ( mIncludeUndatedTodos->isChecked() ) {
00194       Todo::List alltodos = mCalendar->todos();
00195       Todo::List::iterator it;
00196       Todo *todo;
00197       for (it=alltodos.begin(); it!=alltodos.end(); ++it) {
00198         todo = *it;
00199         if ( (!todo->hasStartDate() && !todo->hasDueDate() ) || // undated
00200              ( todo->hasStartDate() && (todo->dtStart()>=startDt) && (todo->dtStart()<=endDt) ) || // start dt in range
00201              ( todo->hasDueDate() && (todo->dtDue().date()>=startDt) && (todo->dtDue()<=endDt) ) || // due dt in range
00202              ( todo->hasCompletedDate() && (todo->completed().date()>=startDt) && (todo->completed()<=endDt) ) ) { // completed dt in range
00203           todos.append( todo );
00204         }
00205       }
00206     } else {
00207       QDate dt = startDt;
00208       while ( dt <= endDt ) {
00209         todos += mCalendar->todos( dt );
00210         dt = dt.addDays( 1 );
00211       }
00212     }
00213   }
00214 
00215   Journal::List journals;
00216   if (mJournalsCheck->isChecked()) {
00217     QDate dt = startDt;
00218     while ( dt <= endDt ) {
00219       journals += mCalendar->journals( dt );
00220       dt = dt.addDays( 1 );
00221     }
00222   }
00223 
00224   Incidence::List allIncidences = Calendar::mergeIncidenceList( events, todos, journals );
00225 
00226   mMatchedEvents.clear();
00227   Incidence::List::ConstIterator it;
00228   for( it = allIncidences.begin(); it != allIncidences.end(); ++it ) {
00229     Incidence *ev = *it;
00230     if ( mSummaryCheck->isChecked() ) {
00231 #if QT_VERSION >= 300
00232       if ( re.search( ev->summary() ) != -1 ) {
00233 #else
00234       if ( re.match( ev->summary() ) != -1 ) {
00235 #endif
00236         mMatchedEvents.append( ev );
00237         continue;
00238       }
00239     }
00240     if ( mDescriptionCheck->isChecked() ) {
00241 #if QT_VERSION >= 300
00242       if ( re.search( ev->description() ) != -1 ) {
00243 #else
00244       if ( re.match( ev->description() ) != -1 ) {
00245 #endif
00246         mMatchedEvents.append( ev );
00247         continue;
00248       }
00249     }
00250     if ( mCategoryCheck->isChecked() ) {
00251 #if QT_VERSION >= 300
00252       if ( re.search( ev->categoriesStr() ) != -1 ) {
00253 #else
00254       if ( re.match( ev->categoriesStr() ) != -1 ) {
00255 #endif
00256         mMatchedEvents.append( ev );
00257         continue;
00258       }
00259     }
00260   }
00261 }
KDE Home | KDE Accessibility Home | Description of Access Keys