00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include "datebookmonth.h"
00022 #include "datebookdb.h"
00023 #include "resource.h"
00024 #include <qpe/qpeapplication.h>
00025
00026 #include <qtoolbutton.h>
00027 #include <qspinbox.h>
00028 #include <qcombobox.h>
00029 #include <qvaluestack.h>
00030 #include <qwhatsthis.h>
00031
00032 static const QColor s_colorNormalLight = QColor(255, 150, 150);
00033 static const QColor s_colorRepeatLight = QColor(150, 150, 255);
00034 static const QColor s_colorHolidayLight= QColor(150, 255, 150);
00035
00036 DateBookMonthHeader::DateBookMonthHeader( QWidget *parent, const char *name )
00037 : QHBox( parent, name )
00038 {
00039 setBackgroundMode( PaletteButton );
00040
00041 begin = new QToolButton( this );
00042 begin->setFocusPolicy(NoFocus);
00043 begin->setPixmap( Resource::loadPixmap( "start" ) );
00044 begin->setAutoRaise( TRUE );
00045 begin->setFixedSize( begin->sizeHint() );
00046 QWhatsThis::add( begin, tr("Show January in the selected year") );
00047
00048 back = new QToolButton( this );
00049 back->setFocusPolicy(NoFocus);
00050 back->setPixmap( Resource::loadPixmap( "back" ) );
00051 back->setAutoRaise( TRUE );
00052 back->setFixedSize( back->sizeHint() );
00053 QWhatsThis::add( back, tr("Show the previous month") );
00054
00055 month = new QComboBox( FALSE, this );
00056 for ( int i = 0; i < 12; ++i )
00057 month->insertItem( Calendar::nameOfMonth( i + 1 ) );
00058
00059 year = new QSpinBox( 1752, 8000, 1, this );
00060
00061 next = new QToolButton( this );
00062 next->setFocusPolicy(NoFocus);
00063 next->setPixmap( Resource::loadPixmap( "forward" ) );
00064 next->setAutoRaise( TRUE );
00065 next->setFixedSize( next->sizeHint() );
00066 QWhatsThis::add( next, tr("Show the next month") );
00067
00068 end = new QToolButton( this );
00069 end->setFocusPolicy(NoFocus);
00070 end->setPixmap( Resource::loadPixmap( "finish" ) );
00071 end->setAutoRaise( TRUE );
00072 end->setFixedSize( end->sizeHint() );
00073 QWhatsThis::add( end, tr("Show December in the selected year") );
00074
00075 connect( month, SIGNAL( activated(int) ),
00076 this, SLOT( updateDate() ) );
00077 connect( year, SIGNAL( valueChanged(int) ),
00078 this, SLOT( updateDate() ) );
00079 connect( begin, SIGNAL( clicked() ),
00080 this, SLOT( firstMonth() ) );
00081 connect( end, SIGNAL( clicked() ),
00082 this, SLOT( lastMonth() ) );
00083 connect( back, SIGNAL( clicked() ),
00084 this, SLOT( monthBack() ) );
00085 connect( next, SIGNAL( clicked() ),
00086 this, SLOT( monthForward() ) );
00087 back->setAutoRepeat( TRUE );
00088 next->setAutoRepeat( TRUE );
00089 }
00090
00091
00092 DateBookMonthHeader::~DateBookMonthHeader()
00093 {
00094
00095 }
00096
00097 void DateBookMonthHeader::updateDate()
00098 {
00099 emit dateChanged( year->value(), month->currentItem() + 1 );
00100 }
00101
00102 void DateBookMonthHeader::firstMonth()
00103 {
00104 emit dateChanged( year->value(), 1 );
00105 month->setCurrentItem( 0 );
00106 }
00107
00108 void DateBookMonthHeader::lastMonth()
00109 {
00110 emit dateChanged( year->value(), 12 );
00111 month->setCurrentItem( 11 );
00112 }
00113
00114 void DateBookMonthHeader::monthBack()
00115 {
00116 if ( month->currentItem() > 0 ) {
00117 emit dateChanged( year->value(), month->currentItem() );
00118 month->setCurrentItem( month->currentItem() - 1 );
00119 } else {
00120 emit dateChanged( year->value() - 1, 12 );
00121
00122
00123 month->setCurrentItem( 11 );
00124 year->setValue( year->value() - 1 );
00125 }
00126 }
00127
00128 void DateBookMonthHeader::monthForward()
00129 {
00130 if ( month->currentItem() < 11 ) {
00131 emit dateChanged( year->value(), month->currentItem() + 2 );
00132 month->setCurrentItem( month->currentItem() + 1 );
00133 } else {
00134
00135
00136 month->setCurrentItem( 0 );
00137 year->setValue( year->value() + 1 );
00138 }
00139 }
00140
00141 void DateBookMonthHeader::setDate( int y, int m )
00142 {
00143 year->setValue( y );
00144 month->setCurrentItem( m - 1 );
00145 }
00146
00147
00148
00149 class DateBookMonthTablePrivate
00150 {
00151 public:
00152 DateBookMonthTablePrivate() {};
00153 ~DateBookMonthTablePrivate() { mMonthEvents.clear(); };
00154
00155 QValueList<EffectiveEvent> mMonthEvents;
00156 bool onMonday;
00157 };
00158
00159 DateBookMonthTable::DateBookMonthTable( QWidget *parent, const char *name,
00160 DateBookDB *newDb )
00161 : QTable( 6, 7, parent, name ),
00162 db( newDb )
00163 {
00164 d = new DateBookMonthTablePrivate();
00165 selYear = -1;
00166 selMonth = -1;
00167 selDay = -1;
00168
00169
00170 year = -1;
00171 month = -1;
00172 day = -1;
00173
00174 Config cfg( "qpe" );
00175 cfg.setGroup( "Time" );
00176 d->onMonday = cfg.readBoolEntry( "MONDAY" );
00177
00178 horizontalHeader()->setResizeEnabled( FALSE );
00179
00180 for ( int i = 0; i < 7; i++ ){
00181 horizontalHeader()->resizeSection( i, 30 );
00182 setColumnStretchable( i, TRUE );
00183 }
00184 setupLabels();
00185
00186 verticalHeader()->hide();
00187 setLeftMargin( 0 );
00188 for ( int i = 0; i < 6; ++i )
00189 setRowStretchable( i, TRUE );
00190
00191 setSelectionMode( NoSelection );
00192
00193 connect( this, SIGNAL( clicked(int,int,int,const QPoint&) ),
00194 this, SLOT( dayClicked(int,int) ) );
00195 connect( this, SIGNAL( currentChanged(int,int) ),
00196 this, SLOT( dragDay(int,int) ) );
00197 setVScrollBarMode( AlwaysOff );
00198 setHScrollBarMode( AlwaysOff );
00199 }
00200
00201 DateBookMonthTable::~DateBookMonthTable()
00202 {
00203 monthsEvents.clear();
00204 delete d;
00205 }
00206
00207 void DateBookMonthTable::setDate(int y, int m, int d)
00208 {
00209 if (month == m && year == y) {
00210 if ( selYear == -1 )
00211 year = selYear;
00212 if ( selMonth == -1 )
00213 month = selMonth;
00214 int r1, c1, r2, c2;
00215 findDay(selDay, r1, c1);
00216 selDay = day = d;
00217 findDay(selDay, r2, c2);
00218 setCurrentCell( r2, c2 );
00219
00220
00221 } else {
00222 selYear = year = y;
00223 selMonth = month = m;
00224 selDay = day = d;
00225 setupTable();
00226 }
00227 }
00228
00229 void DateBookMonthTable::redraw()
00230 {
00231 setupLabels();
00232 setupTable();
00233 }
00234
00235 void DateBookMonthTable::setWeekStart( bool onMonday )
00236 {
00237 d->onMonday = onMonday;
00238 setupLabels();
00239 setupTable();
00240 }
00241
00242 void DateBookMonthTable::setupTable()
00243 {
00244 QValueList<Calendar::Day> days = Calendar::daysOfMonth( year, month, d->onMonday );
00245 QValueList<Calendar::Day>::Iterator it = days.begin();
00246 int row = 0, col = 0;
00247 int crow = 0;
00248 int ccol = 0;
00249 for ( ; it != days.end(); ++it ) {
00250 DayItemMonth *i = (DayItemMonth *)item( row, col );
00251 if ( !i ) {
00252 i = new DayItemMonth( this, QTableItem::Never, "" );
00253 setItem( row, col, i );
00254 }
00255 Calendar::Day calDay = *it;
00256 i->clearEffEvents();
00257 i->setDay( calDay.date );
00258 i->setType( calDay.type );
00259 if ( i->day() == day && calDay.type == Calendar::Day::ThisMonth ) {
00260 crow = row;
00261 ccol = col;
00262 }
00263
00264 updateCell( row, col );
00265
00266 if ( col == 6 ) {
00267 ++row;
00268 col = 0;
00269 } else {
00270 ++col;
00271 }
00272 }
00273 setCurrentCell( crow, ccol );
00274 getEvents();
00275 }
00276
00277 void DateBookMonthTable::findDay( int day, int &row, int &col )
00278 {
00279 QDate dtBegin( year, month, 1 );
00280 int skips = dtBegin.dayOfWeek();
00281 int effective_day = day + skips - 1;
00282
00283 if ( d->onMonday )
00284 effective_day--;
00285 row = effective_day / 7;
00286 col = effective_day % 7;
00287 }
00288
00289 void DateBookMonthTable::dayClicked( int row, int col )
00290 {
00291 changeDaySelection( row, col );
00292 emit dateClicked( selYear, selMonth, selDay );
00293 }
00294
00295 void DateBookMonthTable::dragDay( int row, int col )
00296 {
00297 changeDaySelection( row, col );
00298 }
00299
00300 void DateBookMonthTable::changeDaySelection( int row, int col )
00301 {
00302 DayItemMonth *i = (DayItemMonth*)item( row, col );
00303 if ( !i )
00304 return;
00305 switch ( i->type() ) {
00306 case Calendar::Day::ThisMonth:
00307 selMonth = month;
00308 break;
00309 case Calendar::Day::PrevMonth:
00310 selMonth = month-1;
00311 break;
00312 default:
00313 selMonth = month+1;
00314 }
00315
00316 selYear = year;
00317 if ( selMonth <= 0 ) {
00318 selMonth = 12;
00319 selYear--;
00320 } else if ( selMonth > 12 ) {
00321 selMonth = 1;
00322 selYear++;
00323 }
00324 selDay = i->day();
00325 }
00326
00327
00328 void DateBookMonthTable::viewportMouseReleaseEvent( QMouseEvent * )
00329 {
00330 dayClicked( currentRow(), currentColumn() );
00331 }
00332
00333 void DateBookMonthTable::getEvents()
00334 {
00335 if ( !db )
00336 return;
00337
00338 QDate dtStart( year, month, 1 );
00339 d->mMonthEvents = db->getEffectiveEvents( dtStart,
00340 QDate( year, month,
00341 dtStart.daysInMonth() ) );
00342 QValueListIterator<EffectiveEvent> it = d->mMonthEvents.begin();
00343
00344
00345
00346 while ( it != d->mMonthEvents.end() ) {
00347 QValueList<EffectiveEvent> dayEvent;
00348 EffectiveEvent e = *it;
00349 ++it;
00350 dayEvent.append( e );
00351 while ( it != d->mMonthEvents.end()
00352 && e.date() == (*it).date() ) {
00353 dayEvent.append( *it );
00354 ++it;
00355 }
00356 int row, col;
00357 findDay( e.date().day(), row, col );
00358 DayItemMonth* w = static_cast<DayItemMonth*>( item( row, col ) );
00359 w->setEvents( dayEvent );
00360 updateCell( row, col );
00361 dayEvent.clear();
00362 }
00363 }
00364
00365
00366 void DateBookMonthTable::setupLabels()
00367 {
00368 for ( int i = 0; i < 7; ++i ) {
00369
00370
00371 if ( d->onMonday )
00372 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i + 1 ) );
00373 else {
00374 if ( i == 0 )
00375 horizontalHeader()->setLabel( i, Calendar::nameOfDay( 7 ) );
00376 else
00377 horizontalHeader()->setLabel( i, Calendar::nameOfDay( i ) );
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385 DateBookMonth::DateBookMonth( QWidget *parent, const char *name, bool ac,
00386 DateBookDB *data )
00387 : QVBox( parent, name ),
00388 autoClose( ac )
00389 {
00390 setFocusPolicy(StrongFocus);
00391 year = QDate::currentDate().year();
00392 month = QDate::currentDate().month();
00393 day = QDate::currentDate().day();
00394 header = new DateBookMonthHeader( this, "DateBookMonthHeader" );
00395 table = new DateBookMonthTable( this, "DateBookMonthTable", data );
00396 header->setDate( year, month );
00397 table->setDate( year, month, QDate::currentDate().day() );
00398 header->setFocusPolicy(NoFocus);
00399 table->setFocusPolicy(NoFocus);
00400 connect( header, SIGNAL( dateChanged(int,int) ),
00401 this, SLOT( setDate(int,int) ) );
00402 connect( table, SIGNAL( dateClicked(int,int,int) ),
00403 this, SLOT( finalDate(int,int,int) ) );
00404 connect( qApp, SIGNAL(weekChanged(bool)), this,
00405 SLOT(slotWeekChange(bool)) );
00406 table->setFocus();
00407 }
00408
00409 DateBookMonth::~DateBookMonth()
00410 {
00411
00412 }
00413
00414 void DateBookMonth::setDate( int y, int m )
00415 {
00416
00417
00418 if ( (y != year) || (m != month) ) {
00419 year = y;
00420 month = m;
00421 QDate nd( y, m, 1 );
00422 if ( nd.daysInMonth() < day )
00423 day = nd.daysInMonth();
00424 table->setDate( year, month, day );
00425 }
00426 }
00427
00428 void DateBookMonth::setDate( int y, int m, int d )
00429 {
00430 header->setDate( y, m);
00431 table->setDate( y, m, d);
00432 year = y;
00433 month = m;
00434 day = d;
00435 }
00436
00437
00438 void DateBookMonth::finalDate(int y, int m, int d)
00439 {
00440 setDate( y, m, d );
00441
00442 emit dateClicked(y, m, d);
00443
00444
00445 if ( autoClose && parentWidget() )
00446 parentWidget()->close();
00447 }
00448
00449 void DateBookMonth::setDate( QDate d)
00450 {
00451 setDate(d.year(), d.month(), d.day());
00452 }
00453
00454 void DateBookMonth::redraw()
00455 {
00456 table->setDate( year, month, day );
00457 table->redraw();
00458 }
00459
00460 QDate DateBookMonth::selectedDate() const
00461 {
00462 if ( !table )
00463 return QDate::currentDate();
00464 int y, m, d;
00465 table->getDate( y, m, d );
00466 return QDate( y, m, d );
00467 }
00468
00469 void DateBookMonth::slotWeekChange( bool startOnMonday )
00470 {
00471 table->setWeekStart( startOnMonday );
00472 }
00473
00474 void DateBookMonth::keyPressEvent( QKeyEvent *e )
00475 {
00476 switch(e->key()) {
00477 case Key_Up:
00478 setDate(QDate(year, month, day).addDays(-7));
00479 break;
00480 case Key_Down:
00481 setDate(QDate(year, month, day).addDays(7));
00482 break;
00483 case Key_Left:
00484 setDate(QDate(year, month, day).addDays(-1));
00485 break;
00486 case Key_Right:
00487 setDate(QDate(year, month, day).addDays(1));
00488 break;
00489 case Key_Space:
00490 qWarning("space");
00491 emit dateClicked(year, month, day);
00492 if ( autoClose && parentWidget() )
00493 parentWidget()->close();
00494 break;
00495 default:
00496 qWarning("ignore");
00497 e->ignore();
00498 break;
00499 }
00500 }
00501
00502
00503 class DayItemMonthPrivate
00504 {
00505 public:
00506 DayItemMonthPrivate() {};
00507 ~DayItemMonthPrivate() { mDayEvents.clear(); };
00508 QValueList<EffectiveEvent> mDayEvents;
00509 };
00510
00511 DayItemMonth::DayItemMonth( QTable *table, EditType et, const QString &t )
00512 : QTableItem( table, et, t )
00513 {
00514 d = new DayItemMonthPrivate();
00515 }
00516
00517 DayItemMonth::~DayItemMonth()
00518 {
00519 daysEvents.clear();
00520 delete d;
00521 }
00522
00523 void DayItemMonth::setEvents( const QValueList<EffectiveEvent> &effEv )
00524 {
00525 d->mDayEvents = effEv;
00526 }
00527
00528 void DayItemMonth::clearEffEvents()
00529 {
00530 d->mDayEvents.clear();
00531 }
00532
00533 void DayItemMonth::paint( QPainter *p, const QColorGroup &cg,
00534 const QRect &cr, bool selected )
00535 {
00536 p->save();
00537
00538 QColorGroup g( cg );
00539 g.setBrush( QColorGroup::Base, back );
00540 g.setColor( QColorGroup::Text, forg );
00541 if ( selected )
00542 p->setPen( g.highlightedText() );
00543 else
00544 p->setPen( g.text() );
00545
00546 QValueStack<int> normalLine;
00547 QValueStack<int> repeatLine;
00548 QValueStack<int> travelLine;
00549
00550 bool normalAllDay = FALSE;
00551 bool repeatAllDay = FALSE;
00552 bool travelAllDay = FALSE;
00553 bool holidayAllDay = FALSE;
00554
00555 QValueListIterator<EffectiveEvent> itDays = d->mDayEvents.begin();
00556
00557 for ( ; itDays != d->mDayEvents.end(); ++itDays ) {
00558 int w = cr.width();
00559 Event ev = (*itDays).event();
00560
00561 int f = (*itDays).start().hour();
00562 int t = (*itDays).end().hour();
00563
00564 if (ev.isAllDay()) {
00565 if (!ev.hasRepeat()) {
00566 normalAllDay = TRUE;
00567 if (!ev.isValidUid()) {
00568 holidayAllDay = TRUE;
00569 }
00570 } else {
00571 repeatAllDay = TRUE;
00572 }
00573 } else {
00574 int sLine, eLine;
00575 if (f == 0)
00576 sLine = 0;
00577 else if (f < 8 )
00578 sLine = 1;
00579 else if (f >= 17)
00580 sLine = w - 4;
00581 else {
00582 sLine = (f - 8) * (w - 8);
00583 if (sLine)
00584 sLine /= 8;
00585 sLine += 4;
00586 }
00587 if (t == 23)
00588 eLine = w;
00589 else if (t < 8)
00590 eLine = 4;
00591 else if (t >= 17)
00592 eLine = w - 1;
00593 else {
00594 eLine = (t - 8) * (w - 8);
00595 if (eLine)
00596 eLine /= 8;
00597 eLine += 4;
00598 }
00599 if (!ev.hasRepeat()) {
00600 normalLine.push(sLine);
00601 normalLine.push(eLine);
00602 } else {
00603 repeatLine.push(sLine);
00604 repeatLine.push(eLine);
00605 }
00606 }
00607 }
00608
00609
00610 if (normalAllDay || repeatAllDay || travelAllDay || holidayAllDay) {
00611 p->save();
00612
00613 if (normalAllDay)
00614 if (repeatAllDay) {
00615 p->fillRect( 0, 0, cr.width(), cr.height() / 2,
00616 s_colorNormalLight );
00617 p->fillRect( 0, cr.height() / 2, cr.width(), cr.height() / 2,
00618 colorRepeatLight );
00619 } else {
00620 if (!holidayAllDay) {
00621 p->fillRect( 0, 0, cr.width(), cr.height(),
00622 s_colorNormalLight );
00623 } else {
00624 p->fillRect( 0, 0, cr.width(), cr.height(),
00625 s_colorHolidayLight );
00626 }
00627 } else if (repeatAllDay) {
00628 p->fillRect( 0, 0, cr.width(), cr.height(),
00629 s_colorRepeatLight );
00630 }
00631 } else {
00632 p->fillRect( 0, 0, cr.width(),
00633 cr.height(), selected
00634 ? g.brush( QColorGroup::Highlight )
00635 : g.brush( QColorGroup::Base ) );
00636 }
00637
00638
00639
00640 int h = 5;
00641 int y = cr.height() / 2 - h;
00642
00643 while(normalLine.count() >= 2) {
00644 int x2 = normalLine.pop();
00645 int x1 = normalLine.pop();
00646 if (x2 < x1 + 2)
00647 x2 = x1 + 2;
00648 p->fillRect(x1, y, x2 - x1, h, colorNormal);
00649 }
00650
00651 y += h;
00652
00653 while(repeatLine.count() >= 2) {
00654 int x2 = repeatLine.pop();
00655 int x1 = repeatLine.pop();
00656 if (x2 < x1 + 2)
00657 x2 = x1 + 2;
00658 p->fillRect(x1, y, x2 - x1, h, colorRepeat);
00659 }
00660
00661
00662
00663 QFont f = p->font();
00664 if(qApp->desktop()->width() >= 480)
00665 {
00666 f.setPointSize( f.pointSize() - 2 );
00667 }
00668 else
00669 {
00670 f.setPointSize( ( f.pointSize() / 3 ) * 2 );
00671 }
00672 p->setFont( f );
00673 QFontMetrics fm( f );
00674 p->drawText( 1, 1 + fm.ascent(), QString::number( day() ) );
00675
00676 p->restore();
00677 }
00678
00679
00680
00681 void DayItemMonth::setType( Calendar::Day::Type t )
00682 {
00683 switch ( t ) {
00684 case Calendar::Day::PrevMonth:
00685 case Calendar::Day::NextMonth:
00686 back = QBrush( QColor( 224, 224, 224 ) );
00687 forg = black;
00688 break;
00689 case Calendar::Day::ThisMonth:
00690 back = QBrush( white );
00691 forg = black;
00692 break;
00693 }
00694 typ = t;
00695 }
00696
00697
00698
00699 DateButton::DateButton( bool longDate, QWidget *parent, const char * name )
00700 :QPushButton( parent, name )
00701 {
00702 longFormat = longDate;
00703 df = DateFormat('/', DateFormat::MonthDayYear, DateFormat::MonthDayYear);
00704 setDate( QDate::currentDate() );
00705
00706 connect(this,SIGNAL(pressed()),this,SLOT(pickDate()));
00707
00708
00709 }
00710
00711
00712 void DateButton::pickDate()
00713 {
00714 static QPopupMenu *m1 = 0;
00715 static DateBookMonth *picker = 0;
00716 if ( !m1 ) {
00717 m1 = new QPopupMenu( this );
00718 picker = new DateBookMonth( m1, 0, TRUE );
00719 m1->insertItem( picker );
00720 connect( picker, SIGNAL( dateClicked(int,int,int) ),
00721 this, SLOT( setDate(int,int,int) ) );
00722 connect( picker, SIGNAL( dateClicked(int,int,int) ),
00723 this, SIGNAL( dateSelected(int,int,int) ) );
00724 connect( m1, SIGNAL( aboutToHide() ),
00725 this, SLOT( gotHide() ) );
00726 }
00727 picker->slotWeekChange( weekStartsMonday );
00728 picker->setDate( currDate.year(), currDate.month(), currDate.day() );
00729 m1->popup(mapToGlobal(QPoint(0,height())));
00730 picker->setFocus();
00731 }
00732
00733
00734 void DateButton::gotHide()
00735 {
00736
00737 setDown( false );
00738 }
00739
00740
00741
00742
00743 void DateButton::setWeekStartsMonday( int b )
00744 {
00745 weekStartsMonday = b;
00746 }
00747
00748 void DateButton::setDate( int y, int m, int d )
00749 {
00750 setDate( QDate( y,m,d) );
00751 }
00752
00753 void DateButton::setDate( QDate d )
00754 {
00755 currDate = d;
00756 setText( longFormat ? TimeString::longDateString( d, df ) :
00757 TimeString::shortDate( d, df ) );
00758
00759 }
00760
00761 void DateButton::setDateFormat( DateFormat f )
00762 {
00763 df = f;
00764 setDate( currDate );
00765 }
00766
00767 bool DateButton::customWhatsThis() const
00768 {
00769 return TRUE;
00770 }
00771
00772
00773
00774
00775
00776
00777
00778 DateBookMonthPopup::DateBookMonthPopup ( QWidget *w )
00779 : QPopupMenu ( w )
00780 {
00781 m_dbm = new DateBookMonth( this, 0, TRUE );
00782 insertItem( m_dbm );
00783 }