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 TQt, and distribute the resulting executable, 00024 without including the source code for TQt in the source distribution. 00025 */ 00026 00027 #include <tqlayout.h> 00028 #include <tqcheckbox.h> 00029 #include <tqgroupbox.h> 00030 #include <tqhbuttongroup.h> 00031 #include <tqlabel.h> 00032 #include <tqlineedit.h> 00033 00034 #include <tdelocale.h> 00035 #include <tdemessagebox.h> 00036 00037 #include <libkcal/calendar.h> 00038 00039 #include <libtdepim/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,TQWidget *parent) 00049 : KDialogBase(Plain,i18n("Find Events"),User1|Close,User1,parent,0,false,false, 00050 KGuiItem( i18n("&Find"), "edit-find") ) 00051 { 00052 mCalendar = calendar; 00053 00054 TQFrame *topFrame = plainPage(); 00055 TQVBoxLayout *layout = new TQVBoxLayout(topFrame,0,spacingHint()); 00056 00057 // Search expression 00058 TQHBoxLayout *subLayout = new TQHBoxLayout(); 00059 layout->addLayout(subLayout); 00060 00061 searchEdit = new TQLineEdit( "*", topFrame ); // Find all events by default 00062 searchLabel = new TQLabel( searchEdit, i18n("&Search for:"), topFrame ); 00063 subLayout->addWidget( searchLabel ); 00064 subLayout->addWidget( searchEdit ); 00065 searchEdit->setFocus(); 00066 connect( searchEdit, TQT_SIGNAL( textChanged( const TQString & ) ), 00067 this, TQT_SLOT( searchTextChanged( const TQString & ) ) ); 00068 00069 00070 TQHButtonGroup *itemsGroup = new TQHButtonGroup( i18n("Search For"), topFrame ); 00071 layout->addWidget( itemsGroup ); 00072 mEventsCheck = new TQCheckBox( i18n("&Events"), itemsGroup ); 00073 mTodosCheck = new TQCheckBox( i18n("To-&dos"), itemsGroup ); 00074 mJournalsCheck = new TQCheckBox( i18n("&Journal entries"), itemsGroup ); 00075 mEventsCheck->setChecked( true ); 00076 mTodosCheck->setChecked( true ); 00077 00078 // Date range 00079 TQGroupBox *rangeGroup = new TQGroupBox( 1, Qt::Horizontal, i18n( "Date Range" ), 00080 topFrame ); 00081 layout->addWidget( rangeGroup ); 00082 00083 TQWidget *rangeWidget = new TQWidget( rangeGroup ); 00084 TQHBoxLayout *rangeLayout = new TQHBoxLayout( rangeWidget, 0, spacingHint() ); 00085 00086 mStartDate = new KDateEdit( rangeWidget ); 00087 rangeLayout->addWidget( new TQLabel( mStartDate, i18n("Fr&om:"), rangeWidget ) ); 00088 rangeLayout->addWidget( mStartDate ); 00089 00090 mEndDate = new KDateEdit( rangeWidget ); 00091 rangeLayout->addWidget( new TQLabel( mEndDate, i18n("&To:"), rangeWidget ) ); 00092 mEndDate->setDate( TQDate::currentDate().addDays( 365 ) ); 00093 rangeLayout->addWidget( mEndDate ); 00094 00095 mInclusiveCheck = new TQCheckBox( i18n("E&vents have to be completely included"), 00096 rangeGroup ); 00097 mInclusiveCheck->setChecked( false ); 00098 mIncludeUndatedTodos = new TQCheckBox( i18n("Include to-dos &without due date"), rangeGroup ); 00099 mIncludeUndatedTodos->setChecked( true ); 00100 00101 // Subjects to search 00102 TQHButtonGroup *subjectGroup = new TQHButtonGroup( i18n("Search In"), topFrame ); 00103 layout->addWidget(subjectGroup); 00104 00105 mSummaryCheck = new TQCheckBox( i18n("Su&mmaries"), subjectGroup ); 00106 mSummaryCheck->setChecked( true ); 00107 mDescriptionCheck = new TQCheckBox( i18n("Desc&riptions"), subjectGroup ); 00108 mCategoryCheck = new TQCheckBox( 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,TQT_SIGNAL(user1Clicked()),TQT_SLOT(doSearch())); 00121 00122 // Propagate edit and delete event signals from event list view 00123 connect( listView, TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)), 00124 TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)) ); 00125 connect( listView, TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)), 00126 TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)) ); 00127 connect( listView, TQT_SIGNAL(deleteIncidenceSignal(Incidence *)), 00128 TQT_SIGNAL(deleteIncidenceSignal(Incidence *)) ); 00129 } 00130 00131 SearchDialog::~SearchDialog() 00132 { 00133 } 00134 00135 void SearchDialog::searchTextChanged( const TQString &_text ) 00136 { 00137 enableButton( KDialogBase::User1, !_text.isEmpty() ); 00138 } 00139 00140 void SearchDialog::doSearch() 00141 { 00142 TQRegExp 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, TQDate() ); 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 TQRegExp 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, TQDate() ); 00180 } 00181 00182 void SearchDialog::search( const TQRegExp &re ) 00183 { 00184 TQDate startDt = mStartDate->date(); 00185 TQDate 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()>=TQDateTime(startDt)) && (todo->dtStart()<=TQDateTime(endDt)) ) || // start dt in range 00201 ( todo->hasDueDate() && (todo->dtDue().date()>=startDt) && (todo->dtDue()<=TQDateTime(endDt)) ) || // due dt in range 00202 ( todo->hasCompletedDate() && (todo->completed().date()>=startDt) && (todo->completed()<=TQDateTime(endDt)) ) ) { // completed dt in range 00203 todos.append( todo ); 00204 } 00205 } 00206 } else { 00207 TQDate 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 TQDate 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 ( re.search( ev->summary() ) != -1 ) { 00232 mMatchedEvents.append( ev ); 00233 continue; 00234 } 00235 } 00236 if ( mDescriptionCheck->isChecked() ) { 00237 if ( re.search( ev->description() ) != -1 ) { 00238 mMatchedEvents.append( ev ); 00239 continue; 00240 } 00241 } 00242 if ( mCategoryCheck->isChecked() ) { 00243 if ( re.search( ev->categoriesStr() ) != -1 ) { 00244 mMatchedEvents.append( ev ); 00245 continue; 00246 } 00247 } 00248 } 00249 }