summaryrefslogtreecommitdiff
path: root/core/pim/datebook/datebook.cpp
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/pim/datebook/datebook.cpp
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'core/pim/datebook/datebook.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/datebook/datebook.cpp854
1 files changed, 854 insertions, 0 deletions
diff --git a/core/pim/datebook/datebook.cpp b/core/pim/datebook/datebook.cpp
new file mode 100644
index 0000000..6ec6cc2
--- a/dev/null
+++ b/core/pim/datebook/datebook.cpp
@@ -0,0 +1,854 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19** $Id$
20**
21**********************************************************************/
22
23#include "datebook.h"
24#include "datebookday.h"
25#include "datebooksettings.h"
26#include "datebookweek.h"
27#include "dateentryimpl.h"
28
29#include <qpe/datebookmonth.h>
30#include <qpe/qpeapplication.h>
31#include <qpe/config.h>
32#include <qpe/qpedebug.h>
33#include <qpe/event.h>
34#include <qpe/finddialog.h>
35#include <qpe/ir.h>
36#include <qpe/qpemenubar.h>
37#include <qpe/qpemessagebox.h>
38#include <qpe/resource.h>
39#include <qpe/sound.h>
40#include <qpe/timestring.h>
41#include <qpe/qpetoolbar.h>
42#include <qpe/tzselect.h>
43#include <qpe/xmlreader.h>
44
45#include <qaction.h>
46#include <qcopchannel_qws.h>
47#include <qdatetime.h>
48#include <qdialog.h>
49#include <qfile.h>
50#include <qlabel.h>
51#include <qlayout.h>
52#include <qmessagebox.h>
53#include <qpopupmenu.h>
54#include <qpushbutton.h>
55#include <qtextcodec.h>
56#include <qtextstream.h>
57#include <qtl.h>
58#include <qwidgetstack.h>
59#include <qwindowsystem_qws.h>
60
61#include <sys/stat.h>
62#include <sys/types.h>
63#include <fcntl.h>
64#include <unistd.h>
65
66#include <stdlib.h>
67
68#define DAY 1
69#define WEEK 2
70#define MONTH 3
71
72
73DateBook::DateBook( QWidget *parent, const char *, WFlags f )
74 : QMainWindow( parent, "datebook", f ),
75 aPreset( FALSE ),
76 presetTime( -1 ),
77 startTime( 8 ), // an acceptable default
78 syncing(FALSE),
79 inSearch(FALSE)
80{
81 QTime t;
82 t.start();
83 db = new DateBookDB;
84 qDebug("loading db t=%d", t.elapsed() );
85 loadSettings();
86 setCaption( tr("Calendar") );
87 setIcon( Resource::loadPixmap( "datebook_icon" ) );
88
89 setToolBarsMovable( FALSE );
90
91 QPEToolBar *bar = new QPEToolBar( this );
92 bar->setHorizontalStretchable( TRUE );
93
94 QPEMenuBar *mb = new QPEMenuBar( bar );
95 mb->setMargin( 0 );
96
97 QPEToolBar *sub_bar = new QPEToolBar(this);
98
99 QPopupMenu *view = new QPopupMenu( this );
100 QPopupMenu *settings = new QPopupMenu( this );
101
102 mb->insertItem( tr( "View" ), view );
103 mb->insertItem( tr( "Settings" ), settings );
104
105 QActionGroup *g = new QActionGroup( this );
106 g->setExclusive( TRUE );
107
108 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ),
109 QString::null, 0, this, 0 );
110 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
111 a->addTo( sub_bar );
112
113 a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 );
114 connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) );
115 a->addTo( sub_bar );
116 a->addTo( view );
117 a->setToggleAction( TRUE );
118 a->setOn( TRUE );
119 dayAction = a;
120 a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 );
121 connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) );
122 a->addTo( sub_bar );
123 a->addTo( view );
124 a->setToggleAction( TRUE );
125 weekAction = a;
126 a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 );
127 connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) );
128 a->addTo( sub_bar );
129 a->addTo( view );
130 a->setToggleAction( TRUE );
131 monthAction = a;
132
133 a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 );
134 connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
135 a->addTo( sub_bar );
136
137 a = new QAction( tr( "Today" ), QString::null, 0, 0 );
138 connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) );
139 a->addTo( view );
140
141 a = new QAction( tr( "Alarm and Start Time..." ), QString::null, 0, 0 );
142 connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
143 a->addTo( settings );
144
145 views = new QWidgetStack( this );
146 setCentralWidget( views );
147
148 dayView = 0;
149 weekView = 0;
150 monthView = 0;
151
152 viewDay();
153 connect( qApp, SIGNAL(clockChanged(bool)),
154 this, SLOT(changeClock(bool)) );
155 connect( qApp, SIGNAL(weekChanged(bool)),
156 this, SLOT(changeWeek(bool)) );
157
158#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
159 connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
160 this, SLOT(appMessage(const QCString&, const QByteArray&)) );
161#endif
162
163 // listen on QPE/System
164#if defined(Q_WS_QWS)
165#if !defined(QT_NO_COP)
166 QCopChannel *channel = new QCopChannel( "QPE/System", this );
167 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
168 this, SLOT(receive(const QCString&, const QByteArray&)) );
169#endif
170#endif
171
172 qDebug("done t=%d", t.elapsed() );
173
174}
175
176void DateBook::receive( const QCString &msg, const QByteArray &data )
177{
178 QDataStream stream( data, IO_ReadOnly );
179 if ( msg == "timeChange(QString)" ) {
180 // update active view!
181 if ( dayAction->isOn() )
182 viewDay();
183 else if ( weekAction->isOn() )
184 viewWeek();
185 else if ( monthAction->isOn() )
186 viewMonth();
187 }
188}
189
190DateBook::~DateBook()
191{
192}
193
194void DateBook::slotSettings()
195{
196 DateBookSettings frmSettings( ampm, this );
197 frmSettings.setStartTime( startTime );
198 frmSettings.setAlarmPreset( aPreset, presetTime );
199#if defined (Q_WS_QWS) || defined(_WS_QWS_)
200 frmSettings.showMaximized();
201#endif
202
203 if ( frmSettings.exec() ) {
204 aPreset = frmSettings.alarmPreset();
205 presetTime = frmSettings.presetTime();
206 startTime = frmSettings.startTime();
207 if ( dayView )
208 dayView->setStartViewTime( startTime );
209 if ( weekView )
210 weekView->setStartViewTime( startTime );
211 saveSettings();
212
213 // make the change obvious
214 if ( views->visibleWidget() ) {
215 if ( views->visibleWidget() == dayView )
216 dayView->redraw();
217 else if ( views->visibleWidget() == weekView )
218 weekView->redraw();
219 }
220 }
221}
222
223void DateBook::fileNew()
224{
225 slotNewEventFromKey("");
226}
227
228QString DateBook::checkEvent(const Event &e)
229{
230 /* check if overlaps with itself */
231 bool checkFailed = FALSE;
232
233 /* check the next 12 repeats. should catch most problems */
234 QDate current_date = e.start().date();
235 Event previous = e;
236 for(int i = 0; i < 12; i++)
237 {
238 QDateTime next;
239 if (!nextOccurance(previous, current_date.addDays(1), next)) {
240 break; // no more repeats
241 }
242 if(next < previous.end()) {
243 checkFailed = TRUE;
244 break;
245 }
246 current_date = next.date();
247 }
248
249 if(checkFailed)
250 return tr("Event duration is potentially longer\n"
251 "than interval between repeats.");
252
253 return QString::null;
254}
255
256QDate DateBook::currentDate()
257{
258 QDate d = QDate::currentDate();
259
260 if ( dayView && views->visibleWidget() == dayView ) {
261 d = dayView->date();
262 } else if ( weekView && views->visibleWidget() == weekView ) {
263 d = weekView->date();
264 } else if ( monthView && views->visibleWidget() == monthView ) {
265 d = monthView->selectedDate();
266 }
267
268 return d;
269}
270
271void DateBook::viewDay()
272{
273 initDay();
274 dayAction->setOn( TRUE );
275 QDate d = currentDate();
276 dayView->setDate( d );
277 views->raiseWidget( dayView );
278 dayView->redraw();
279}
280
281void DateBook::viewWeek()
282{
283 initWeek();
284 weekAction->setOn( TRUE );
285 QDate d = currentDate();
286 weekView->setDate( d );
287 views->raiseWidget( weekView );
288 weekView->redraw();
289}
290
291void DateBook::viewMonth()
292{
293 initMonth();
294 monthAction->setOn( TRUE );
295 QDate d = currentDate();
296 monthView->setDate( d.year(), d.month(), d.day() );
297 views->raiseWidget( monthView );
298 monthView->redraw();
299}
300
301void DateBook::editEvent( const Event &e )
302{
303 if (syncing) {
304 QMessageBox::warning( this, tr("Calendar"),
305 tr( "Can not edit data, currently syncing") );
306 return;
307 }
308
309 // workaround added for text input.
310 QDialog editDlg( this, 0, TRUE );
311 DateEntry *entry;
312 editDlg.setCaption( tr("Edit Event") );
313 QVBoxLayout *vb = new QVBoxLayout( &editDlg );
314 QScrollView *sv = new QScrollView( &editDlg, "scrollview" );
315 sv->setResizePolicy( QScrollView::AutoOneFit );
316 // KLUDGE!!!
317 sv->setHScrollBarMode( QScrollView::AlwaysOff );
318 vb->addWidget( sv );
319 entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" );
320 entry->timezone->setEnabled( FALSE );
321 sv->addChild( entry );
322
323#if defined(Q_WS_QWS) || defined(_WS_QWS_)
324 editDlg.showMaximized();
325#endif
326 while (editDlg.exec() ) {
327 Event newEv = entry->event();
328 QString error = checkEvent(newEv);
329 if (!error.isNull()) {
330 if (QMessageBox::warning(this, "error box",
331 error, "Fix it", "Continue", 0, 0, 1) == 0)
332 continue;
333 }
334 db->editEvent(e, newEv);
335 emit newEvent();
336 break;
337 }
338}
339
340void DateBook::removeEvent( const Event &e )
341{
342 if (syncing) {
343 QMessageBox::warning( this, tr("Calendar"),
344 tr( "Can not edit data, currently syncing") );
345 return;
346 }
347
348 QString strName = e.description();
349
350 if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) )
351 return;
352
353 db->removeEvent( e );
354 if ( views->visibleWidget() == dayView && dayView )
355 dayView->redraw();
356}
357
358void DateBook::addEvent( const Event &e )
359{
360 QDate d = e.start().date();
361 initDay();
362 dayView->setDate( d );
363}
364
365void DateBook::showDay( int year, int month, int day )
366{
367 initDay();
368 dayView->setDate( year, month, day );
369 views->raiseWidget( dayView );
370 dayAction->setOn( TRUE );
371}
372
373void DateBook::initDay()
374{
375 if ( !dayView ) {
376 dayView = new DateBookDay( ampm, onMonday, db, views, "day view" );
377 views->addWidget( dayView, DAY );
378 dayView->setStartViewTime( startTime );
379 connect( this, SIGNAL( newEvent() ),
380 dayView, SLOT( redraw() ) );
381 connect( dayView, SIGNAL( newEvent() ),
382 this, SLOT( fileNew() ) );
383 connect( dayView, SIGNAL( removeEvent( const Event & ) ),
384 this, SLOT( removeEvent( const Event & ) ) );
385 connect( dayView, SIGNAL( editEvent( const Event & ) ),
386 this, SLOT( editEvent( const Event & ) ) );
387 connect( dayView, SIGNAL( beamEvent( const Event & ) ),
388 this, SLOT( beamEvent( const Event & ) ) );
389 connect( dayView, SIGNAL(sigNewEvent(const QString &)),
390 this, SLOT(slotNewEventFromKey(const QString &)) );
391 }
392}
393
394void DateBook::initWeek()
395{
396 if ( !weekView ) {
397 weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" );
398 weekView->setStartViewTime( startTime );
399 views->addWidget( weekView, WEEK );
400 connect( weekView, SIGNAL( showDate( int, int, int ) ),
401 this, SLOT( showDay( int, int, int ) ) );
402 connect( this, SIGNAL( newEvent() ),
403 weekView, SLOT( redraw() ) );
404 }
405 //But also get it right: the year that we display can be different
406 //from the year of the current date. So, first find the year
407 //number of the current week.
408
409 int yearNumber, totWeeks;
410 calcWeek( currentDate(), totWeeks, yearNumber, onMonday );
411
412 QDate d = QDate( yearNumber, 12, 31 );
413 calcWeek( d, totWeeks, yearNumber, onMonday );
414
415 while ( totWeeks == 1 ) {
416 d = d.addDays( -1 );
417 calcWeek( d, totWeeks, yearNumber, onMonday );
418 }
419 if ( totWeeks != weekView->totalWeeks() )
420 weekView->setTotalWeeks( totWeeks );
421}
422
423void DateBook::initMonth()
424{
425 if ( !monthView ) {
426 monthView = new DateBookMonth( views, "month view", FALSE, db );
427 views->addWidget( monthView, MONTH );
428 connect( monthView, SIGNAL( dateClicked( int, int, int ) ),
429 this, SLOT( showDay( int, int, int ) ) );
430 connect( this, SIGNAL( newEvent() ),
431 monthView, SLOT( redraw() ) );
432 qApp->processEvents();
433 }
434}
435
436void DateBook::loadSettings()
437{
438 {
439 Config config( "qpe" );
440 config.setGroup("Time");
441 ampm = config.readBoolEntry( "AMPM", TRUE );
442 onMonday = config.readBoolEntry( "MONDAY" );
443 }
444
445 {
446 Config config("DateBook");
447 config.setGroup("Main");
448 startTime = config.readNumEntry("startviewtime", 8);
449 aPreset = config.readBoolEntry("alarmpreset");
450 presetTime = config.readNumEntry("presettime");
451 }
452}
453
454void DateBook::saveSettings()
455{
456 Config config( "qpe" );
457 Config configDB( "DateBook" );
458 configDB.setGroup( "Main" );
459 configDB.writeEntry("startviewtime",startTime);
460 configDB.writeEntry("alarmpreset",aPreset);
461 configDB.writeEntry("presettime",presetTime);
462}
463
464void DateBook::appMessage(const QCString& msg, const QByteArray& data)
465{
466 bool needShow = FALSE;
467 if ( msg == "alarm(QDateTime,int)" ) {
468 QDataStream ds(data,IO_ReadOnly);
469 QDateTime when; int warn;
470 ds >> when >> warn;
471
472 // check to make it's okay to continue,
473 // this is the case that the time was set ahead, and
474 // we are forced given a stale alarm...
475 QDateTime current = QDateTime::currentDateTime();
476 if ( current.time().hour() != when.time().hour()
477 && current.time().minute() != when.time().minute() )
478 return;
479
480 QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60));
481 if ( list.count() > 0 ) {
482 QString msg;
483 bool bSound = FALSE;
484 int stopTimer = 0;
485 bool found = FALSE;
486 for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin();
487 it!=list.end(); ++it ) {
488 if ( (*it).event().hasAlarm() ) {
489 found = TRUE;
490 msg += "<CENTER><B>" + (*it).description() + "</B>"
491 + "<BR>" + (*it).location() + "<BR>"
492 + TimeString::dateString((*it).event().start(),ampm)
493 + (warn
494 ? tr(" (in " + QString::number(warn)
495 + tr(" minutes)"))
496 : QString(""))
497 + "<BR>"
498 + (*it).notes() + "</CENTER>";
499 if ( (*it).event().alarmSound() != Event::Silent ) {
500 bSound = TRUE;
501 }
502 }
503 }
504 if ( found ) {
505 if ( bSound ) {
506 Sound::soundAlarm();
507 stopTimer = startTimer( 5000 );
508 }
509
510 QDialog dlg( this, 0, TRUE );
511 QVBoxLayout *vb = new QVBoxLayout( &dlg );
512 QScrollView *view = new QScrollView( &dlg, "scrollView");
513 view->setResizePolicy( QScrollView::AutoOneFit );
514 vb->addWidget( view );
515 QLabel *lblMsg = new QLabel( msg, &dlg );
516 view->addChild( lblMsg );
517 QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg );
518 connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) );
519 vb->addWidget( cmdOk );
520
521#if defined(Q_WS_QWS) || defined(_WS_QWS_)
522 dlg.showMaximized();
523#endif
524 needShow = dlg.exec();
525
526 if ( bSound )
527 killTimer( stopTimer );
528 }
529 }
530 } else if ( msg == "nextView()" ) {
531 QWidget* cur = views->visibleWidget();
532 if ( cur ) {
533 if ( cur == dayView )
534 viewWeek();
535 else if ( cur == weekView )
536 viewMonth();
537 else if ( cur == monthView )
538 viewDay();
539 needShow = TRUE;
540 }
541 }
542 if ( needShow ) {
543#if defined(Q_WS_QWS) || defined(_WS_QWS_)
544 showMaximized();
545#else
546 show();
547#endif
548 raise();
549 QPEApplication::setKeepRunning();
550 setActiveWindow();
551 }
552}
553
554void DateBook::reload()
555{
556 db->reload();
557 if ( dayAction->isOn() )
558 viewDay();
559 else if ( weekAction->isOn() )
560 viewWeek();
561 else if ( monthAction->isOn() )
562 viewMonth();
563 syncing = FALSE;
564}
565
566void DateBook::flush()
567{
568 syncing = TRUE;
569 db->save();
570}
571
572void DateBook::timerEvent( QTimerEvent *e )
573{
574 static int stop = 0;
575 if ( stop < 10 ) {
576 Sound::soundAlarm();
577 stop++;
578 } else {
579 stop = 0;
580 killTimer( e->timerId() );
581 }
582}
583
584void DateBook::changeClock( bool newClock )
585{
586 ampm = newClock;
587 // repaint the affected objects...
588 if (dayView) dayView->redraw();
589 if (weekView) weekView->redraw();
590}
591
592void DateBook::changeWeek( bool m )
593{
594 /* no need to redraw, each widget catches. Do need to
595 store though for widgets we haven't made yet */
596 onMonday = m;
597}
598
599void DateBook::slotToday()
600{
601 // we need to view today
602 QDate dt = QDate::currentDate();
603 showDay( dt.year(), dt.month(), dt.day() );
604}
605
606void DateBook::closeEvent( QCloseEvent *e )
607{
608 if(syncing) {
609 /* no need to save, did that at flush */
610 e->accept();
611 return;
612 }
613
614 // save settings will generate it's own error messages, no
615 // need to do checking ourselves.
616 saveSettings();
617 if ( db->save() )
618 e->accept();
619 else {
620 if ( QMessageBox::critical( this, tr( "Out of space" ),
621 tr("Calendar was unable to save\n"
622 "your changes.\n"
623 "Free up some space and try again.\n"
624 "\nQuit anyway?"),
625 QMessageBox::Yes|QMessageBox::Escape,
626 QMessageBox::No|QMessageBox::Default )
627 != QMessageBox::No )
628 e->accept();
629 else
630 e->ignore();
631 }
632}
633
634// Entering directly from the "keyboard"
635void DateBook::slotNewEventFromKey( const QString &str )
636{
637 if (syncing) {
638 QMessageBox::warning( this, tr("Calendar"),
639 tr( "Can not edit data, currently syncing") );
640 return;
641 }
642
643 // We get to here from a key pressed in the Day View
644 // So we can assume some things. We want the string
645 // passed in to be part of the description.
646 QDateTime start, end;
647 if ( views->visibleWidget() == dayView ) {
648 dayView->selectedDates( start, end );
649 } else if ( views->visibleWidget() == monthView ) {
650 QDate d = monthView->selectedDate();
651 start = end = d;
652 start.setTime( QTime( 10, 0 ) );
653 end.setTime( QTime( 12, 0 ) );
654 } else if ( views->visibleWidget() == weekView ) {
655 QDate d = weekView->date();
656 start = end = d;
657 start.setTime( QTime( 10, 0 ) );
658 end.setTime( QTime( 12, 0 ) );
659 }
660
661 // argh! This really needs to be encapsulated in a class
662 // or function.
663 QDialog newDlg( this, 0, TRUE );
664 newDlg.setCaption( DateEntryBase::tr("New Event") );
665 DateEntry *e;
666 QVBoxLayout *vb = new QVBoxLayout( &newDlg );
667 QScrollView *sv = new QScrollView( &newDlg );
668 sv->setResizePolicy( QScrollView::AutoOneFit );
669 sv->setFrameStyle( QFrame::NoFrame );
670 sv->setHScrollBarMode( QScrollView::AlwaysOff );
671 vb->addWidget( sv );
672
673 Event ev;
674 ev.setDescription( str );
675 // When the new gui comes in, change this...
676 ev.setLocation( tr("(Unknown)") );
677 ev.setStart( start );
678 ev.setEnd( end );
679
680 e = new DateEntry( onMonday, ev, ampm, &newDlg );
681 e->setAlarmEnabled( aPreset, presetTime, Event::Loud );
682 sv->addChild( e );
683#if defined(Q_WS_QWS) || defined(_WS_QWS_)
684 newDlg.showMaximized();
685#endif
686 while (newDlg.exec()) {
687 ev = e->event();
688 ev.assignUid();
689 QString error = checkEvent( ev );
690 if ( !error.isNull() ) {
691 if ( QMessageBox::warning( this, tr("Error!"),
692 error, tr("Fix it"), tr("Continue"), 0, 0, 1 ) == 0 )
693 continue;
694 }
695 db->addEvent( ev );
696 emit newEvent();
697 break;
698 }
699}
700
701void DateBook::setDocument( const QString &filename )
702{
703 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
704
705 QValueList<Event> tl = Event::readVCalendar( filename );
706 for( QValueList<Event>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
707 db->addEvent( *it );
708 }
709}
710
711static const char * beamfile = "/tmp/obex/event.vcs";
712
713void DateBook::beamEvent( const Event &e )
714{
715 qDebug("trying to beamn");
716 unlink( beamfile ); // delete if exists
717 mkdir("/tmp/obex/", 0755);
718 Event::writeVCalendar( beamfile, e );
719 Ir *ir = new Ir( this );
720 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
721 QString description = e.description();
722 ir->send( beamfile, description, "text/x-vCalendar" );
723}
724
725void DateBook::beamDone( Ir *ir )
726{
727 delete ir;
728 unlink( beamfile );
729}
730
731void DateBook::slotFind()
732{
733 // move it to the day view...
734 viewDay();
735 FindDialog frmFind( "Calendar", this );
736 frmFind.setUseDate( true );
737 frmFind.setDate( currentDate() );
738 QObject::connect( &frmFind,
739 SIGNAL(signalFindClicked(const QString&, const QDate&,
740 bool, bool, int)),
741 this,
742 SLOT(slotDoFind(const QString&, const QDate&,
743 bool, bool, int)) );
744 QObject::connect( this,
745 SIGNAL(signalNotFound()),
746 &frmFind,
747 SLOT(slotNotFound()) );
748 QObject::connect( this,
749 SIGNAL(signalWrapAround()),
750 &frmFind,
751 SLOT(slotWrapAround()) );
752 frmFind.exec();
753 inSearch = false;
754}
755
756bool catComp( QArray<int> cats, int category )
757{
758 bool returnMe;
759 int i,
760 count;
761
762 count = int(cats.count());
763 returnMe = false;
764 if ( (category == -1 && count == 0) || category == -2 )
765 returnMe = true;
766 else {
767 for ( i = 0; i < count; i++ ) {
768 if ( category == cats[i] ) {
769 returnMe = true;
770 break;
771 }
772 }
773 }
774 return returnMe;
775}
776
777
778void DateBook::slotDoFind( const QString& txt, const QDate &dt,
779 bool caseSensitive, bool /*backwards*/,
780 int category )
781{
782 QDateTime dtEnd( QDate(3001, 1, 1), QTime(0, 0, 0) ),
783 next;
784
785 QRegExp r( txt );
786 r.setCaseSensitive( caseSensitive );
787
788
789 static Event rev,
790 nonrev;
791 if ( !inSearch ) {
792 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
793 nonrev.setStart( rev.start() );
794 inSearch = true;
795 }
796 static QDate searchDate = dt;
797 static bool wrapAround = true;
798 bool candidtate;
799 candidtate = false;
800
801 QValueList<Event> repeats = db->getRawRepeats();
802
803 // find the candidate for the first repeat that matches...
804 QValueListConstIterator<Event> it;
805 QDate start = dt;
806 for ( it = repeats.begin(); it != repeats.end(); ++it ) {
807 if ( catComp( (*it).categories(), category ) ) {
808 while ( nextOccurance( *it, start, next ) ) {
809 if ( next < dtEnd ) {
810 if ( (*it).match( r ) && !(next <= rev.start()) ) {
811 rev = *it;
812 dtEnd = next;
813 rev.setStart( next );
814 candidtate = true;
815 wrapAround = true;
816 start = dt;
817 break;
818 } else
819 start = next.date().addDays( 1 );
820 }
821 }
822 }
823 }
824
825 // now the for first non repeat...
826 QValueList<Event> nonRepeats = db->getNonRepeatingEvents( dt, dtEnd.date() );
827 qHeapSort( nonRepeats.begin(), nonRepeats.end() );
828 for ( it = nonRepeats.begin(); it != nonRepeats.end(); ++it ) {
829 if ( catComp( (*it).categories(), category ) ) {
830 if ( (*it).start() < dtEnd ) {
831 if ( (*it).match( r ) && !(*it <= nonrev) ) {
832 nonrev = *it;
833 dtEnd = nonrev.start();
834 candidtate = true;
835 wrapAround = true;
836 break;
837 }
838 }
839 }
840 }
841 if ( candidtate ) {
842 dayView->setStartViewTime( dtEnd.time().hour() );
843 dayView->setDate( dtEnd.date().year(), dtEnd.date().month(),
844 dtEnd.date().day() );
845 } else {
846 if ( wrapAround ) {
847 emit signalWrapAround();
848 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
849 nonrev.setStart( rev.start() );
850 } else
851 emit signalNotFound();
852 wrapAround = !wrapAround;
853 }
854}