korganizer

searchdialog.cpp
1/*
2 This file is part of KOrganizer.
3
4 Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
6 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
22 As a special exception, permission is given to link this program
23 with any edition of TQt, and distribute the resulting executable,
24 without including the source code for TQt in the source distribution.
25*/
26
27#include <tqlayout.h>
28#include <tqcheckbox.h>
29#include <tqgroupbox.h>
30#include <tqhbuttongroup.h>
31#include <tqlabel.h>
32#include <tqlineedit.h>
33
34#include <tdelocale.h>
35#include <tdemessagebox.h>
36
37#include <libkcal/calendar.h>
38
39#include <libtdepim/kdateedit.h>
40
41#include "koglobals.h"
42#include "koprefs.h"
43#include "kolistview.h"
44
45#include "searchdialog.h"
46#include "searchdialog.moc"
47
48SearchDialog::SearchDialog(Calendar *calendar,TQWidget *parent)
49 : KDialogBase(Plain,i18n("Find Events"),User1|Close,User1,parent,0,false,false,
50 KGuiItem( i18n("&Find"), "edit-find") )
51{
52 mCalendar = calendar;
53
54 TQFrame *topFrame = plainPage();
55 TQVBoxLayout *layout = new TQVBoxLayout(topFrame,0,spacingHint());
56
57 // Search expression
58 TQHBoxLayout *subLayout = new TQHBoxLayout();
59 layout->addLayout(subLayout);
60
61 searchEdit = new TQLineEdit( "*", topFrame ); // Find all events by default
62 searchLabel = new TQLabel( searchEdit, i18n("&Search for:"), topFrame );
63 subLayout->addWidget( searchLabel );
64 subLayout->addWidget( searchEdit );
65 searchEdit->setFocus();
66 connect( searchEdit, TQ_SIGNAL( textChanged( const TQString & ) ),
67 this, TQ_SLOT( searchTextChanged( const TQString & ) ) );
68
69
70 TQHButtonGroup *itemsGroup = new TQHButtonGroup( i18n("Search For"), topFrame );
71 layout->addWidget( itemsGroup );
72 mEventsCheck = new TQCheckBox( i18n("&Events"), itemsGroup );
73 mTodosCheck = new TQCheckBox( i18n("To-&dos"), itemsGroup );
74 mJournalsCheck = new TQCheckBox( i18n("&Journal entries"), itemsGroup );
75 mEventsCheck->setChecked( true );
76 mTodosCheck->setChecked( true );
77
78 // Date range
79 TQGroupBox *rangeGroup = new TQGroupBox( 1, TQt::Horizontal, i18n( "Date Range" ),
80 topFrame );
81 layout->addWidget( rangeGroup );
82
83 TQWidget *rangeWidget = new TQWidget( rangeGroup );
84 TQHBoxLayout *rangeLayout = new TQHBoxLayout( rangeWidget, 0, spacingHint() );
85
86 mStartDate = new KDateEdit( rangeWidget );
87 rangeLayout->addWidget( new TQLabel( mStartDate, i18n("Fr&om:"), rangeWidget ) );
88 rangeLayout->addWidget( mStartDate );
89
90 mEndDate = new KDateEdit( rangeWidget );
91 rangeLayout->addWidget( new TQLabel( mEndDate, i18n("&To:"), rangeWidget ) );
92 mEndDate->setDate( TQDate::currentDate().addDays( 365 ) );
93 rangeLayout->addWidget( mEndDate );
94
95 mInclusiveCheck = new TQCheckBox( i18n("E&vents have to be completely included"),
96 rangeGroup );
97 mInclusiveCheck->setChecked( false );
98 mIncludeUndatedTodos = new TQCheckBox( i18n("Include to-dos &without due date"), rangeGroup );
99 mIncludeUndatedTodos->setChecked( true );
100
101 // Subjects to search
102 TQHButtonGroup *subjectGroup = new TQHButtonGroup( i18n("Search In"), topFrame );
103 layout->addWidget(subjectGroup);
104
105 mSummaryCheck = new TQCheckBox( i18n("Su&mmaries"), subjectGroup );
106 mSummaryCheck->setChecked( true );
107 mDescriptionCheck = new TQCheckBox( i18n("Desc&riptions"), subjectGroup );
108 mCategoryCheck = new TQCheckBox( i18n("Cate&gories"), subjectGroup );
109
110
111 // Results list view
112 listView = new KOListView( mCalendar, topFrame );
113 listView->showDates();
114 layout->addWidget( listView );
115
116 if ( KOPrefs::instance()->mCompactDialogs ) {
117 KOGlobals::fitDialogToScreen( this, true );
118 }
119
120 connect( this,TQ_SIGNAL(user1Clicked()),TQ_SLOT(doSearch()));
121
122 // Propagate edit and delete event signals from event list view
123 connect( listView, TQ_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)),
124 TQ_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)) );
125 connect( listView, TQ_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)),
126 TQ_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)) );
127 connect( listView, TQ_SIGNAL(deleteIncidenceSignal(Incidence *)),
128 TQ_SIGNAL(deleteIncidenceSignal(Incidence *)) );
129}
130
131SearchDialog::~SearchDialog()
132{
133}
134
135void SearchDialog::searchTextChanged( const TQString &_text )
136{
137 enableButton( KDialogBase::User1, !_text.isEmpty() );
138}
139
140void SearchDialog::doSearch()
141{
142 TQRegExp re;
143
144 re.setWildcard( true ); // most people understand these better.
145 re.setCaseSensitive( false );
146 re.setPattern( searchEdit->text() );
147 if ( !re.isValid() ) {
148 KMessageBox::sorry( this,
149 i18n("Invalid search expression, cannot perform "
150 "the search. Please enter a search expression "
151 "using the wildcard characters '*' and '?' "
152 "where needed." ) );
153 return;
154 }
155
156 search( re );
157
158 listView->showIncidences( mMatchedEvents, TQDate() );
159
160 if ( mMatchedEvents.count() == 0 ) {
161 KMessageBox::information( this,
162 i18n("No events were found matching your search expression."),
163 "NoSearchResults" );
164 }
165}
166
167void SearchDialog::updateView()
168{
169 TQRegExp re;
170 re.setWildcard( true ); // most people understand these better.
171 re.setCaseSensitive( false );
172 re.setPattern( searchEdit->text() );
173 if ( re.isValid() ) {
174 search( re );
175 } else {
176 mMatchedEvents.clear();
177 }
178
179 listView->showIncidences( mMatchedEvents, TQDate() );
180}
181
182void SearchDialog::search( const TQRegExp &re )
183{
184 TQDate startDt = mStartDate->date();
185 TQDate endDt = mEndDate->date();
186
187 Event::List events;
188 if (mEventsCheck->isChecked()) {
189 events = mCalendar->events( startDt, endDt, mInclusiveCheck->isChecked() );
190 }
191 Todo::List todos;
192 if (mTodosCheck->isChecked()) {
193 if ( mIncludeUndatedTodos->isChecked() ) {
194 Todo::List alltodos = mCalendar->todos();
195 Todo::List::iterator it;
196 Todo *todo;
197 for (it=alltodos.begin(); it!=alltodos.end(); ++it) {
198 todo = *it;
199 if ( (!todo->hasStartDate() && !todo->hasDueDate() ) || // undated
200 ( todo->hasStartDate() && (todo->dtStart()>=TQDateTime(startDt)) && (todo->dtStart()<=TQDateTime(endDt)) ) || // start dt in range
201 ( todo->hasDueDate() && (todo->dtDue().date()>=startDt) && (todo->dtDue()<=TQDateTime(endDt)) ) || // due dt in range
202 ( todo->hasCompletedDate() && (todo->completed().date()>=startDt) && (todo->completed()<=TQDateTime(endDt)) ) ) { // completed dt in range
203 todos.append( todo );
204 }
205 }
206 } else {
207 TQDate dt = startDt;
208 while ( dt <= endDt ) {
209 todos += mCalendar->todos( dt );
210 dt = dt.addDays( 1 );
211 }
212 }
213 }
214
215 Journal::List journals;
216 if (mJournalsCheck->isChecked()) {
217 TQDate dt = startDt;
218 while ( dt <= endDt ) {
219 journals += mCalendar->journals( dt );
220 dt = dt.addDays( 1 );
221 }
222 }
223
224 Incidence::List allIncidences = Calendar::mergeIncidenceList( events, todos, journals );
225
226 mMatchedEvents.clear();
227 Incidence::List::ConstIterator it;
228 for( it = allIncidences.begin(); it != allIncidences.end(); ++it ) {
229 Incidence *ev = *it;
230 if ( mSummaryCheck->isChecked() ) {
231 if ( re.search( ev->summary() ) != -1 ) {
232 mMatchedEvents.append( ev );
233 continue;
234 }
235 }
236 if ( mDescriptionCheck->isChecked() ) {
237 if ( re.search( ev->description() ) != -1 ) {
238 mMatchedEvents.append( ev );
239 continue;
240 }
241 }
242 if ( mCategoryCheck->isChecked() ) {
243 if ( re.search( ev->categoriesStr() ) != -1 ) {
244 mMatchedEvents.append( ev );
245 continue;
246 }
247 }
248 }
249}
TQString description() const
TQString categoriesStr() const
TQString summary() const
bool hasDueDate() const
bool hasStartDate() const
TQDateTime dtStart(bool first=false) const
TQDateTime completed() const
bool hasCompletedDate() const
TQDateTime dtDue(bool first=false) const
This class provides a multi-column list view of events.
Definition: kolistview.h:69