summaryrefslogtreecommitdiff
path: root/core/pim/datebook/datebookday.cpp
Unidiff
Diffstat (limited to 'core/pim/datebook/datebookday.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/datebook/datebookday.cpp553
1 files changed, 553 insertions, 0 deletions
diff --git a/core/pim/datebook/datebookday.cpp b/core/pim/datebook/datebookday.cpp
new file mode 100644
index 0000000..d5daab2
--- a/dev/null
+++ b/core/pim/datebook/datebookday.cpp
@@ -0,0 +1,553 @@
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**********************************************************************/
20
21#include "datebookday.h"
22#include "datebookdayheaderimpl.h"
23
24#include <qpe/datebookdb.h>
25#include <qpe/resource.h>
26#include <qpe/event.h>
27#include <qpe/qpeapplication.h>
28#include <qpe/timestring.h>
29#include <qpe/qpedebug.h>
30
31#include <qheader.h>
32#include <qdatetime.h>
33#include <qpainter.h>
34#include <qsimplerichtext.h>
35#include <qpopupmenu.h>
36#include <qtextcodec.h>
37#include <qpalette.h>
38
39DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent,
40 const char *name )
41 : QTable( 24, 1, parent, name ),
42 ampm( whichClock )
43{
44 enableClipper(TRUE);
45 setTopMargin( 0 );
46 horizontalHeader()->hide();
47 setLeftMargin(38);
48 setColumnStretchable( 0, TRUE );
49 setHScrollBarMode( QScrollView::AlwaysOff );
50 verticalHeader()->setPalette(white);
51 verticalHeader()->setResizeEnabled(FALSE);
52 setSelectionMode( Single );
53
54 // get rid of being able to edit things...
55 QTableItem *tmp;
56 int row;
57 for ( row = 0; row < numRows(); row++ ) {
58 tmp = new QTableItem( this, QTableItem::Never, QString::null);
59 setItem( row, 0, tmp );
60 }
61 initHeader();
62 QObject::connect( qApp, SIGNAL(clockChanged(bool)),
63 this, SLOT(slotChangeClock(bool)) );
64}
65
66void DateBookDayView::initHeader()
67{
68 QString strTmp;
69 for ( int i = 0; i < 24; ++i ) {
70 if ( ampm ) {
71 if ( i == 0 )
72 strTmp = QString::number(12) + ":00";
73 else if ( i == 12 )
74 strTmp = QString::number(12) + tr(":00p");
75 else if ( i > 12 )
76 strTmp = QString::number( i - 12 ) + tr(":00p");
77 else
78 strTmp = QString::number(i) + ":00";
79 } else {
80 if ( i < 10 )
81 strTmp = "0" + QString::number(i) + ":00";
82 else
83 strTmp = QString::number(i) + ":00";
84 }
85 strTmp = strTmp.rightJustify( 6, ' ' );
86 verticalHeader()->setLabel( i, strTmp );
87 setRowStretchable( i, FALSE );
88 }
89}
90
91void DateBookDayView::slotChangeClock( bool newClock )
92{
93 ampm = newClock;
94 initHeader();
95}
96
97bool DateBookDayView::whichClock() const
98{
99 return ampm;
100}
101
102void DateBookDayView::moveUp()
103{
104 scrollBy(0, -20);
105}
106
107void DateBookDayView::moveDown()
108{
109 scrollBy(0, 20);
110}
111
112void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
113{
114 int w = cr.width();
115 int h = cr.height();
116 p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
117 if ( showGrid() ) {
118 // Draw our lines
119 int x2 = w - 1;
120 int y2 = h - 1;
121 QPen pen( p->pen() );
122 p->setPen( colorGroup().mid() );
123 p->drawLine( x2, 0, x2, y2 );
124 p->drawLine( 0, y2, x2, y2 );
125 p->setPen( pen );
126 }
127}
128
129void DateBookDayView::paintFocus( QPainter *, const QRect & )
130{
131}
132
133
134void DateBookDayView::resizeEvent( QResizeEvent *e )
135{
136 QTable::resizeEvent( e );
137 columnWidthChanged( 0 );
138 emit sigColWidthChanged();
139}
140
141void DateBookDayView::keyPressEvent( QKeyEvent *e )
142{
143 QString txt = e->text();
144 if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
145 // we this is some sort of thing we know about...
146 e->accept();
147 emit sigCapturedKey( txt );
148 } else {
149 // I don't know what this key is, do you?
150 e->ignore();
151 }
152}
153
154
155//===========================================================================
156
157DateBookDay::DateBookDay( bool ampm, bool startOnMonday,
158 DateBookDB *newDb, QWidget *parent,
159 const char *name )
160 : QVBox( parent, name ),
161 currDate( QDate::currentDate() ),
162 db( newDb ),
163 startTime( 0 )
164{
165 widgetList.setAutoDelete( true );
166 header = new DateBookDayHeader( startOnMonday, this, "day header" );
167 header->setDate( currDate.year(), currDate.month(), currDate.day() );
168 view = new DateBookDayView( ampm, this, "day view" );
169 connect( header, SIGNAL( dateChanged( int, int, int ) ),
170 this, SLOT( dateChanged( int, int, int ) ) );
171 connect( view, SIGNAL( sigColWidthChanged() ),
172 this, SLOT( slotColWidthChanged() ) );
173 connect( qApp, SIGNAL(weekChanged(bool)),
174 this, SLOT(slotWeekChanged(bool)) );
175 connect( view, SIGNAL(sigCapturedKey(const QString &)),
176 this, SIGNAL(sigNewEvent(const QString&)) );
177}
178
179void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
180{
181 start.setDate( currDate );
182 end.setDate( currDate );
183
184 int sh=99,eh=-1;
185
186 int n = dayView()->numSelections();
187
188 for (int i=0; i<n; i++) {
189 QTableSelection sel = dayView()->selection( i );
190 sh = QMIN(sh,sel.topRow());
191 eh = QMAX(sh,sel.bottomRow()+1);
192 }
193 if (sh > 23 || eh < 1) {
194 sh=8;
195 eh=9;
196 }
197
198 start.setTime( QTime( sh, 0, 0 ) );
199 end.setTime( QTime( eh, 0, 0 ) );
200}
201
202void DateBookDay::setDate( int y, int m, int d )
203{
204 header->setDate( y, m, d );
205}
206
207void DateBookDay::setDate( QDate d)
208{
209 header->setDate( d.year(), d.month(), d.day() );
210}
211
212void DateBookDay::dateChanged( int y, int m, int d )
213{
214 QDate date( y, m, d );
215 if ( currDate == date )
216 return;
217 currDate.setYMD( y, m, d );
218 relayoutPage();
219 dayView()->clearSelection();
220 QTableSelection ts;
221 ts.init( startTime, 0 );
222 ts.expandTo( startTime, 0 );
223 dayView()->addSelection( ts );
224}
225
226void DateBookDay::redraw()
227{
228 if ( isUpdatesEnabled() )
229 relayoutPage();
230}
231
232void DateBookDay::getEvents()
233{
234 widgetList.clear();
235
236 QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate,
237 currDate );
238 QValueListIterator<EffectiveEvent> it;
239 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
240 DateBookDayWidget* w = new DateBookDayWidget( *it, this );
241 connect( w, SIGNAL( deleteMe( const Event & ) ),
242 this, SIGNAL( removeEvent( const Event & ) ) );
243 connect( w, SIGNAL( editMe( const Event & ) ),
244 this, SIGNAL( editEvent( const Event & ) ) );
245 connect( w, SIGNAL( beamMe( const Event & ) ),
246 this, SIGNAL( beamEvent( const Event & ) ) );
247 widgetList.append( w );
248 }
249}
250
251static int place( const DateBookDayWidget *item, bool *used, int maxn )
252{
253 int place = 0;
254 int start = item->event().start().hour();
255 QTime e = item->event().end();
256 int end = e.hour();
257 if ( e.minute() < 5 )
258 end--;
259 if ( end < start )
260 end = start;
261 while ( place < maxn ) {
262 bool free = TRUE;
263 int s = start;
264 while( s <= end ) {
265 if ( used[10*s+place] ) {
266 free = FALSE;
267 break;
268 }
269 s++;
270 }
271 if ( free ) break;
272 place++;
273 }
274 if ( place == maxn ) {
275 return -1;
276 }
277 while( start <= end ) {
278 used[10*start+place] = TRUE;
279 start++;
280 }
281 return place;
282}
283
284
285void DateBookDay::relayoutPage( bool fromResize )
286{
287 setUpdatesEnabled( FALSE );
288 if ( !fromResize )
289 getEvents(); // no need we already have them!
290
291 int wCount = widgetList.count();
292 int wid = view->columnWidth(0)-1;
293 int n = 1;
294
295 if ( wCount < 20 ) {
296 for ( int i = 0; i < wCount; ) {
297 DateBookDayWidget *w = widgetList.at(i);
298 int x = 0;
299 int xp = 0;
300 QRect geom = w->geometry();
301 geom.setX( x );
302 geom.setWidth( wid );
303 while ( xp < n && intersects( w, geom ) ) {
304 x += wid;
305 xp++;
306 geom.moveBy( wid, 0 );
307 }
308 if ( xp >= n ) {
309 n++;
310 wid = ( view->columnWidth(0)-1 ) / n;
311 i = 0;
312 } else {
313 w->setGeometry( geom );
314 i++;
315 }
316 }
317 view->setContentsPos( 0, startTime * view->rowHeight(0) );
318 } else {
319
320
321 int hours[24];
322 memset( hours, 0, 24*sizeof( int ) );
323 bool overFlow = FALSE;
324 for ( int i = 0; i < wCount; i++ ) {
325 DateBookDayWidget *w = widgetList.at(i);
326 int start = w->event().start().hour();
327 QTime e = w->event().end();
328 int end = e.hour();
329 if ( e.minute() < 5 )
330 end--;
331 if ( end < start )
332 end = start;
333 while( start <= end ) {
334 hours[start]++;
335 if ( hours[start] >= 10 )
336 overFlow = TRUE;
337 ++start;
338 }
339 if ( overFlow )
340 break;
341 }
342 for ( int i = 0; i < 24; i++ ) {
343 n = QMAX( n, hours[i] );
344 }
345 wid = ( view->columnWidth(0)-1 ) / n;
346
347 bool used[24*10];
348 memset( used, FALSE, 24*10*sizeof( bool ) );
349
350 for ( int i = 0; i < wCount; i++ ) {
351 DateBookDayWidget *w = widgetList.at(i);
352 int xp = place( w, used, n );
353 if ( xp != -1 ) {
354 QRect geom = w->geometry();
355 geom.setX( xp*wid );
356 geom.setWidth( wid );
357 w->setGeometry( geom );
358 }
359 }
360 view->setContentsPos( 0, startTime * view->rowHeight(0) );
361 }
362 setUpdatesEnabled( TRUE );
363 return;
364}
365
366DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
367{
368 int i = 0;
369 DateBookDayWidget *w = widgetList.at(i);
370 int wCount = widgetList.count();
371 while ( i < wCount && w != item ) {
372 if ( w->geometry().intersects( geom ) ) {
373 return w;
374 }
375 w = widgetList.at(++i);
376 }
377
378 return 0;
379}
380
381
382QDate DateBookDay::date() const
383{
384 return currDate;
385}
386
387void DateBookDay::setStartViewTime( int startHere )
388{
389 startTime = startHere;
390 dayView()->clearSelection();
391 QTableSelection ts;
392 ts.init( startTime, 0 );
393 ts.expandTo( startTime, 0 );
394 dayView()->addSelection( ts );
395}
396
397int DateBookDay::startViewTime() const
398{
399 return startTime;
400}
401
402void DateBookDay::slotWeekChanged( bool bStartOnMonday )
403{
404 header->setStartOfWeek( bStartOnMonday );
405 // redraw();
406}
407
408void DateBookDay::keyPressEvent(QKeyEvent *e)
409{
410 switch(e->key()) {
411 case Key_Up:
412 view->moveUp();
413 break;
414 case Key_Down:
415 view->moveDown();
416 break;
417 case Key_Left:
418 setDate(QDate(currDate).addDays(-1));
419 break;
420 case Key_Right:
421 setDate(QDate(currDate).addDays(1));
422 break;
423 default:
424 e->ignore();
425 }
426}
427
428//===========================================================================
429
430DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e,
431 DateBookDay *db )
432 : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
433{
434 bool whichClock = db->dayView()->whichClock();
435
436 // why would someone use "<"? Oh well, fix it up...
437 // I wonder what other things may be messed up...
438 QString strDesc = ev.description();
439 int where = strDesc.find( "<" );
440 while ( where != -1 ) {
441 strDesc.remove( where, 1 );
442 strDesc.insert( where, "&#60;" );
443 where = strDesc.find( "<", where );
444 }
445
446 QString strCat;
447 // ### Fix later...
448// QString strCat = ev.category();
449// where = strCat.find( "<" );
450// while ( where != -1 ) {
451 // strCat.remove( where, 1 );
452 // strCat.insert( where, "&#60;" );
453 // where = strCat.find( "<", where );
454// }
455
456 QString strNote = ev.notes();
457 where = strNote.find( "<" );
458 while ( where != -1 ) {
459 strNote.remove( where, 1 );
460 strNote.insert( where, "&#60;" );
461 where = strNote.find( "<", where );
462 }
463
464 text = "<b>" + strDesc + "</b><br>" + "<i>"
465 + strCat + "</i>"
466 + "<br><b>" + tr("Start") + "</b>: ";
467
468
469 if ( e.startDate() != ev.date() ) {
470 // multi-day event. Show start date
471 text += TimeString::longDateString( e.startDate() );
472 } else {
473 // Show start time.
474 text += TimeString::timeString( ev.start(), whichClock, FALSE );
475 }
476
477 text += "<br><b>" + tr("End") + "</b>: ";
478 if ( e.endDate() != ev.date() ) {
479 // multi-day event. Show end date
480 text += TimeString::longDateString( e.endDate() );
481 } else {
482 // Show end time.
483 text += TimeString::timeString( ev.end(), whichClock, FALSE );
484 }
485 text += "<br><br>" + strNote;
486 setBackgroundMode( PaletteBase );
487
488 QTime s = ev.start();
489 QTime e = ev.end();
490 int y = s.hour()*60+s.minute();
491 int h = e.hour()*60+e.minute()-y;
492 int rh = dateBook->dayView()->rowHeight(0);
493 y = y*rh/60;
494 h = h*rh/60;
495 if ( h < 3 )
496 h = 3;
497 geom.setY( y );
498 geom.setHeight( h );
499}
500
501DateBookDayWidget::~DateBookDayWidget()
502{
503}
504
505void DateBookDayWidget::paintEvent( QPaintEvent *e )
506{
507 QPainter p( this );
508 p.setPen( QColor(100, 100, 100) );
509 p.setBrush( QColor( 255, 240, 230 ) ); // based on priority?
510 p.drawRect(rect());
511
512 int y = 0;
513 int d = 0;
514
515 if ( ev.event().hasAlarm() ) {
516 p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) );
517 y = 20;
518 d = 20;
519 }
520
521 if ( ev.event().hasRepeat() ) {
522 p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) );
523 d = 20;
524 }
525
526 QSimpleRichText rt( text, font() );
527 rt.setWidth( geom.width() - d - 6 );
528 rt.draw( &p, 3, 0, e->region(), colorGroup() );
529}
530
531void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
532{
533 QPopupMenu m;
534 m.insertItem( tr( "Edit" ), 1 );
535 m.insertItem( tr( "Delete" ), 2 );
536 m.insertItem( tr( "Beam" ), 3 );
537 int r = m.exec( e->globalPos() );
538 if ( r == 1 ) {
539 emit editMe( ev.event() );
540 } else if ( r == 2 ) {
541 emit deleteMe( ev.event() );
542 } else if ( r == 3 ) {
543 emit beamMe( ev.event() );
544 }
545}
546
547void DateBookDayWidget::setGeometry( const QRect &r )
548{
549 geom = r;
550 setFixedSize( r.width()+1, r.height()+1 );
551 dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
552 show();
553}