00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <qpopupmenu.h>
00027 #include <qfont.h>
00028 #include <qfontmetrics.h>
00029 #include <qkeycode.h>
00030 #include <qhbox.h>
00031 #include <qvbox.h>
00032 #include <qpushbutton.h>
00033 #include <qtooltip.h>
00034 #include <qpainter.h>
00035 #include <qcursor.h>
00036 #include <qlistbox.h>
00037 #include <qlayout.h>
00038 #include <qlabel.h>
00039
00040 #include <kdebug.h>
00041 #include <klocale.h>
00042 #include <kglobal.h>
00043 #include <kconfig.h>
00044 #include <kiconloader.h>
00045 #include <kwordwrap.h>
00046
00047 #include <kcalendarsystem.h>
00048 #include <libkcal/calfilter.h>
00049 #include <libkcal/calendar.h>
00050 #include <libkcal/incidenceformatter.h>
00051 #include <libkcal/calendarresources.h>
00052
00053 #include "koprefs.h"
00054 #include "koglobals.h"
00055 #include "koincidencetooltip.h"
00056 #include "koeventpopupmenu.h"
00057 #include "kohelper.h"
00058
00059 #include "komonthview.h"
00060 #include "komonthview.moc"
00061
00062
00063
00064 KOMonthCellToolTip::KOMonthCellToolTip( QWidget *parent,
00065 KNoScrollListBox *lv )
00066 : QToolTip( parent )
00067 {
00068 eventlist = lv;
00069 }
00070
00071 void KOMonthCellToolTip::maybeTip( const QPoint & pos )
00072 {
00073 QRect r;
00074 QListBoxItem *it = eventlist->itemAt( pos );
00075 MonthViewItem *i = static_cast<MonthViewItem*>( it );
00076
00077 if( i && KOPrefs::instance()->mEnableToolTips ) {
00078
00079 r=eventlist->itemRect( it );
00080
00081 QString tipText( IncidenceFormatter::toolTipString( i->incidence() ) );
00082 if ( !tipText.isEmpty() ) {
00083 tip( r, tipText );
00084 }
00085 }
00086 }
00087
00088 KNoScrollListBox::KNoScrollListBox( QWidget *parent, const char *name )
00089 : QListBox( parent, name ),
00090 mSqueezing( false )
00091 {
00092 QPalette pal = palette();
00093 pal.setColor( QColorGroup::Foreground, KOPrefs::instance()->agendaBgColor().dark( 150 ) );
00094 pal.setColor( QColorGroup::Base, KOPrefs::instance()->agendaBgColor() );
00095 setPalette( pal );
00096 }
00097
00098 void KNoScrollListBox::setBackground( bool primary, bool workDay )
00099 {
00100 QColor color;
00101 if ( workDay ) {
00102 color = KOPrefs::instance()->workingHoursColor();
00103 } else {
00104 color = KOPrefs::instance()->agendaBgColor();
00105 }
00106
00107 QPalette pal = palette();
00108 if ( primary ) {
00109 pal.setColor( QColorGroup::Base, color );
00110 } else {
00111 pal.setColor( QColorGroup::Base, color.dark( 115 ) );
00112 }
00113 setPalette( pal );
00114 }
00115
00116 void KNoScrollListBox::keyPressEvent( QKeyEvent *e )
00117 {
00118 switch( e->key() ) {
00119 case Key_Right:
00120 scrollBy( 4, 0 );
00121 break;
00122 case Key_Left:
00123 scrollBy( -4, 0 );
00124 break;
00125 case Key_Up:
00126 if ( !count() ) break;
00127 setCurrentItem( ( currentItem() + count() - 1 ) % count() );
00128 if ( !itemVisible( currentItem() ) ) {
00129 if ( (unsigned int)currentItem() == ( count() - 1 ) ) {
00130 setTopItem( currentItem() - numItemsVisible() + 1 );
00131 } else {
00132 setTopItem( topItem() - 1 );
00133 }
00134 }
00135 break;
00136 case Key_Down:
00137 if ( !count() ) break;
00138 setCurrentItem( ( currentItem() + 1 ) % count() );
00139 if( !itemVisible( currentItem() ) ) {
00140 if( currentItem() == 0 ) {
00141 setTopItem( 0 );
00142 } else {
00143 setTopItem( topItem() + 1 );
00144 }
00145 }
00146 case Key_Shift:
00147 emit shiftDown();
00148 break;
00149 default:
00150 break;
00151 }
00152 }
00153
00154 void KNoScrollListBox::keyReleaseEvent( QKeyEvent *e )
00155 {
00156 switch( e->key() ) {
00157 case Key_Shift:
00158 emit shiftUp();
00159 break;
00160 default:
00161 break;
00162 }
00163 }
00164
00165 void KNoScrollListBox::mousePressEvent( QMouseEvent *e )
00166 {
00167 QListBox::mousePressEvent( e );
00168
00169 if ( e->button() == RightButton ) {
00170 emit rightClick();
00171 }
00172 }
00173
00174 void KNoScrollListBox::contentsMouseDoubleClickEvent ( QMouseEvent * e )
00175 {
00176 QListBox::contentsMouseDoubleClickEvent( e );
00177 QListBoxItem *item = itemAt( e->pos() );
00178 if ( !item ) {
00179 emit doubleClicked( item );
00180 }
00181 }
00182
00183 void KNoScrollListBox::resizeEvent( QResizeEvent *e )
00184 {
00185 bool s = count() && ( maxItemWidth() > e->size().width() );
00186 if ( mSqueezing || s )
00187 triggerUpdate( false );
00188
00189 mSqueezing = s;
00190 QListBox::resizeEvent( e );
00191 }
00192
00193 MonthViewItem::MonthViewItem( Incidence *incidence, const QDateTime &qd,
00194 const QString & s ) : QListBoxItem()
00195 {
00196 setText( s );
00197
00198 mIncidence = incidence;
00199 mDateTime = qd;
00200
00201 mTodoPixmap = KOGlobals::self()->smallIcon("todo");
00202 mTodoDonePixmap = KOGlobals::self()->smallIcon("checkedbox");
00203 mAlarmPixmap = KOGlobals::self()->smallIcon("bell");
00204 mRecurPixmap = KOGlobals::self()->smallIcon("recur");
00205 mReplyPixmap = KOGlobals::self()->smallIcon("mail_reply");
00206
00207 mResourceColor = QColor();
00208 mTodo = false;
00209 mTodoDone = false;
00210 mRecur = false;
00211 mAlarm = false;
00212 mReply = false;
00213 }
00214
00215 void MonthViewItem::paint( QPainter *p )
00216 {
00217 #if QT_VERSION >= 0x030000
00218 bool sel = isSelected();
00219 #else
00220 bool sel = selected();
00221 #endif
00222
00223 QColor bgColor = palette().color( QPalette::Normal,
00224 sel ? QColorGroup::Highlight : QColorGroup::Background );
00225 int offset=0;
00226 if ( KOPrefs::instance()->monthViewUsesResourceColor() &&
00227 mResourceColor.isValid() ) {
00228 p->setBackgroundColor( mResourceColor );
00229 p->eraseRect( 0, 0, listBox()->maxItemWidth(), height( listBox() ) );
00230 offset=2;
00231 }
00232 if ( KOPrefs::instance()->monthViewUsesCategoryColor() ) {
00233 p->setBackgroundColor( bgColor );
00234 p->eraseRect( offset, offset, listBox()->maxItemWidth()-2*offset, height( listBox() )-2*offset );
00235 }
00236 int x = 3;
00237 if ( mTodo ) {
00238 p->drawPixmap( x, 0, mTodoPixmap );
00239 x += mTodoPixmap.width() + 2;
00240 }
00241 if ( mTodoDone ) {
00242 p->drawPixmap( x, 0, mTodoDonePixmap );
00243 x += mTodoPixmap.width() + 2;
00244 }
00245 if ( mRecur ) {
00246 p->drawPixmap( x, 0, mRecurPixmap );
00247 x += mRecurPixmap.width() + 2;
00248 }
00249 if ( mAlarm ) {
00250 p->drawPixmap( x, 0, mAlarmPixmap );
00251 x += mAlarmPixmap.width() + 2;
00252 }
00253 if ( mReply ) {
00254 p->drawPixmap(x, 0, mReplyPixmap );
00255 x += mReplyPixmap.width() + 2;
00256 }
00257 QFontMetrics fm = p->fontMetrics();
00258 int yPos;
00259 int pmheight = QMAX( mRecurPixmap.height(),
00260 QMAX( mAlarmPixmap.height(), mReplyPixmap.height() ) );
00261 if( pmheight < fm.height() )
00262 yPos = fm.ascent() + fm.leading()/2;
00263 else
00264 yPos = pmheight/2 - fm.height()/2 + fm.ascent();
00265 QColor textColor = palette().color( QPalette::Normal, sel ? \
00266 QColorGroup::HighlightedText : QColorGroup::Text );
00267 p->setPen( textColor );
00268
00269 KWordWrap::drawFadeoutText( p, x, yPos, listBox()->width() - x, text() );
00270 }
00271
00272 int MonthViewItem::height( const QListBox *lb ) const
00273 {
00274 return QMAX( QMAX( mRecurPixmap.height(), mReplyPixmap.height() ),
00275 QMAX( mAlarmPixmap.height(), lb->fontMetrics().lineSpacing()+1) );
00276 }
00277
00278 int MonthViewItem::width( const QListBox *lb ) const
00279 {
00280 int x = 3;
00281 if( mRecur ) {
00282 x += mRecurPixmap.width()+2;
00283 }
00284 if( mAlarm ) {
00285 x += mAlarmPixmap.width()+2;
00286 }
00287 if( mReply ) {
00288 x += mReplyPixmap.width()+2;
00289 }
00290
00291 return( x + lb->fontMetrics().boundingRect( text() ).width() + 1 );
00292 }
00293
00294
00295 MonthViewCell::MonthViewCell( KOMonthView *parent)
00296 : QWidget( parent ),
00297 mMonthView( parent ), mPrimary( false ), mHoliday( false )
00298 {
00299 QVBoxLayout *topLayout = new QVBoxLayout( this );
00300
00301 mLabel = new QLabel( this );
00302 mLabel->setFrameStyle( QFrame::Panel | QFrame::Plain );
00303 mLabel->setLineWidth( 1 );
00304 mLabel->setAlignment( AlignCenter );
00305
00306 mItemList = new KNoScrollListBox( this );
00307 mItemList->setMinimumSize( 10, 10 );
00308 mItemList->setFrameStyle( QFrame::Panel | QFrame::Plain );
00309 mItemList->setLineWidth( 1 );
00310
00311 new KOMonthCellToolTip( mItemList->viewport(),
00312 static_cast<KNoScrollListBox *>( mItemList ) );
00313
00314 topLayout->addWidget( mItemList );
00315
00316 mLabel->raise();
00317
00318 mStandardPalette = palette();
00319
00320 enableScrollBars( false );
00321
00322 updateConfig();
00323
00324 connect( mItemList, SIGNAL( doubleClicked( QListBoxItem *) ),
00325 SLOT( defaultAction( QListBoxItem * ) ) );
00326 connect( mItemList, SIGNAL( rightButtonPressed( QListBoxItem *,
00327 const QPoint &) ),
00328 SLOT( contextMenu( QListBoxItem * ) ) );
00329 connect( mItemList, SIGNAL( clicked( QListBoxItem * ) ),
00330 SLOT( select() ) );
00331 }
00332
00333 void MonthViewCell::setDate( const QDate &date )
00334 {
00335
00336
00337 mDate = date;
00338
00339 setFrameWidth();
00340
00341 QString text;
00342 if ( KOGlobals::self()->calendarSystem()->day( date ) == 1 ) {
00343 text = i18n("'Month day' for month view cells", "%1 %2")
00344 .arg( KOGlobals::self()->calendarSystem()->monthName( date, true ) )
00345 .arg( KOGlobals::self()->calendarSystem()->day(mDate) );
00346 QFontMetrics fm( mLabel->font() );
00347 mLabel->resize( mLabelSize + QSize( fm.width( text ), 0 ) );
00348 } else {
00349 mLabel->resize( mLabelSize );
00350 text = QString::number( KOGlobals::self()->calendarSystem()->day(mDate) );
00351 }
00352 mLabel->setText( text );
00353
00354 resizeEvent( 0 );
00355 }
00356
00357 QDate MonthViewCell::date() const
00358 {
00359 return mDate;
00360 }
00361
00362 void MonthViewCell::setFrameWidth()
00363 {
00364
00365 if ( mDate == QDate::currentDate() )
00366 mItemList->setLineWidth( 3 );
00367 else
00368 mItemList->setLineWidth( 1 );
00369 }
00370
00371 void MonthViewCell::setPrimary( bool primary )
00372 {
00373 mPrimary = primary;
00374
00375 if ( mPrimary ) {
00376 mLabel->setBackgroundMode( PaletteBase );
00377 } else {
00378 mLabel->setBackgroundMode( PaletteBackground );
00379 }
00380
00381 mItemList->setBackground( mPrimary, KOGlobals::self()->isWorkDay( mDate ) );
00382 }
00383
00384 bool MonthViewCell::isPrimary() const
00385 {
00386 return mPrimary;
00387 }
00388
00389 void MonthViewCell::setHoliday( bool holiday )
00390 {
00391 mHoliday = holiday;
00392
00393 if ( holiday ) {
00394 setPalette( mHolidayPalette );
00395 } else {
00396 setPalette( mStandardPalette );
00397 }
00398 }
00399
00400 void MonthViewCell::setHolidayString( const QString &holiday )
00401 {
00402 mHolidayString = holiday;
00403 }
00404
00405 void MonthViewCell::updateCell()
00406 {
00407 setFrameWidth();
00408
00409 if ( mDate == QDate::currentDate() ) {
00410 setPalette( mTodayPalette );
00411
00412 QPalette pal = mItemList->palette();
00413 pal.setColor( QColorGroup::Foreground, KOPrefs::instance()->highlightColor() );
00414 mItemList->setPalette( pal );
00415 }
00416 else {
00417 if ( mHoliday )
00418 setPalette( mHolidayPalette );
00419 else
00420 setPalette( mStandardPalette );
00421
00422 QPalette pal = mItemList->palette();
00423 pal.setColor( QColorGroup::Foreground, KOPrefs::instance()->agendaBgColor().dark( 150 ) );
00424 mItemList->setPalette( pal );
00425 }
00426
00427 mItemList->clear();
00428
00429 if ( !mHolidayString.isEmpty() ) {
00430 MonthViewItem *item = new MonthViewItem( 0, QDateTime( mDate ), mHolidayString );
00431 item->setPalette( mHolidayPalette );
00432 mItemList->insertItem( item );
00433 }
00434 }
00435
00436 class MonthViewCell::CreateItemVisitor :
00437 public IncidenceBase::Visitor
00438 {
00439 public:
00440 CreateItemVisitor() : mItem(0) { emails = KOPrefs::instance()->allEmails(); }
00441
00442 bool act( IncidenceBase *incidence, QDate date, QPalette stdPal )
00443 {
00444 mItem = 0;
00445 mDate = date;
00446 mStandardPalette = stdPal;
00447 return incidence->accept( *this );
00448 }
00449 MonthViewItem *item() const { return mItem; }
00450 QStringList emails;
00451
00452 protected:
00453 bool visit( Event *event ) {
00454 QString text;
00455 QDateTime dt( mDate );
00456 if ( event->isMultiDay() ) {
00457 if (mDate == event->dtStart().date()) {
00458 text = "(-- " + event->summary();
00459 dt = event->dtStart();
00460 } else if (mDate == event->dtEnd().date()) {
00461 text = event->summary() + " --)";
00462 } else if (!(event->dtStart().date().daysTo(mDate) % 7)) {
00463 text = "-- " + event->summary() + " --";
00464 } else {
00465 text = "----------------";
00466 dt = QDateTime( mDate );
00467 }
00468 } else {
00469 if (event->doesFloat())
00470 text = event->summary();
00471 else {
00472 text = KGlobal::locale()->formatTime(event->dtStart().time());
00473 dt.setTime( event->dtStart().time() );
00474 text += " " + event->summary();
00475 }
00476 }
00477
00478 mItem = new MonthViewItem( event, dt, text );
00479 if (KOPrefs::instance()->monthViewUsesCategoryColor()) {
00480 QStringList categories = event->categories();
00481 QString cat = categories.first();
00482 if (cat.isEmpty()) {
00483 mItem->setPalette(QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor));
00484 } else {
00485 mItem->setPalette(QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))));
00486 }
00487 } else {
00488 mItem->setPalette( mStandardPalette );
00489 }
00490
00491 Attendee *me = event->attendeeByMails( emails );
00492 if ( me != 0 ) {
00493 mItem->setReply( me->status() == Attendee::NeedsAction && me->RSVP() );
00494 } else
00495 mItem->setReply(false);
00496 return true;
00497 }
00498 bool visit( Todo *todo ) {
00499 QString text;
00500 if ( !KOPrefs::instance()->showAllDayTodo() )
00501 return false;
00502 QDateTime dt( mDate );
00503 if ( todo->hasDueDate() && !todo->doesFloat() ) {
00504 text += KGlobal::locale()->formatTime( todo->dtDue().time() );
00505 text += " ";
00506 dt.setTime( todo->dtDue().time() );
00507 }
00508 text += todo->summary();
00509
00510 mItem = new MonthViewItem( todo, dt, text );
00511
00512 if ( todo->doesRecur() ) {
00513 mDate < todo->dtDue().date() ?
00514 mItem->setTodoDone( true ) : mItem->setTodo( true );
00515 }
00516 else
00517 todo->isCompleted() ? mItem->setTodoDone( true ) : mItem->setTodo( true );
00518 mItem->setPalette( mStandardPalette );
00519 return true;
00520 }
00521 protected:
00522 MonthViewItem *mItem;
00523 QDate mDate;
00524 QPalette mStandardPalette;
00525 };
00526
00527
00528 void MonthViewCell::addIncidence( Incidence *incidence, CreateItemVisitor& v)
00529 {
00530 if ( v.act( incidence, mDate, mStandardPalette ) ) {
00531 MonthViewItem *item = v.item();
00532 if ( item ) {
00533 item->setAlarm( incidence->isAlarmEnabled() );
00534 item->setRecur( incidence->recurrenceType() );
00535
00536 QColor resourceColor = KOHelper::resourceColor( mCalendar, incidence );
00537 if ( !resourceColor.isValid() )
00538 resourceColor = KOPrefs::instance()->mEventColor;
00539 item->setResourceColor( resourceColor );
00540
00541
00542
00543
00544 uint i = 0;
00545 int pos = -1;
00546 QDateTime dt( item->incidenceDateTime() );
00547
00548 while ( i < mItemList->count() && pos<0 ) {
00549 QListBoxItem *item = mItemList->item( i );
00550 MonthViewItem *mvitem = dynamic_cast<MonthViewItem*>( item );
00551 if ( mvitem && mvitem->incidenceDateTime()>dt ) {
00552 pos = i;
00553 }
00554 ++i;
00555 }
00556 mItemList->insertItem( item, pos );
00557 }
00558 }
00559 }
00560
00561 bool MonthViewCell::removeIncidence( Incidence *incidence )
00562 {
00563 for ( uint i = 0; i < mItemList->count(); i++ ) {
00564 MonthViewItem *item = static_cast<MonthViewItem *>(mItemList->item( i ) );
00565 if ( item && item->incidence() &&
00566 item->incidence()->uid() == incidence->uid() ) {
00567 mItemList->removeItem( i );
00568 return true;
00569 }
00570 }
00571
00572 return false;
00573 }
00574
00575 void MonthViewCell::updateConfig()
00576 {
00577 setFont( KOPrefs::instance()->mMonthViewFont );
00578
00579 QFontMetrics fm( font() );
00580 mLabelSize = fm.size( 0, "30" ) +
00581 QSize( mLabel->frameWidth() * 2, mLabel->frameWidth() * 2 ) +
00582 QSize( 2, 2 );
00583
00584 QColor bg = mStandardPalette.color( QPalette::Active, QColorGroup::Background );
00585 int h,s,v;
00586 bg.getHsv( &h, &s, &v );
00587 if ( date().month() %2 == 0 ) {
00588 if ( v < 128 ) {
00589 bg = bg.light( 125 );
00590 } else {
00591 bg = bg.dark( 125 );
00592 }
00593 }
00594 setPaletteBackgroundColor( bg );
00595
00596
00597 mHolidayPalette = mStandardPalette;
00598 mHolidayPalette.setColor( QColorGroup::Foreground,
00599 KOPrefs::instance()->holidayColor() );
00600 mHolidayPalette.setColor( QColorGroup::Text,
00601 KOPrefs::instance()->holidayColor() );
00602 mTodayPalette = mStandardPalette;
00603 mTodayPalette.setColor( QColorGroup::Foreground,
00604 KOPrefs::instance()->highlightColor() );
00605 mTodayPalette.setColor( QColorGroup::Text,
00606 KOPrefs::instance()->highlightColor() );
00607 updateCell();
00608
00609 mItemList->setBackground( mPrimary, KOGlobals::self()->isWorkDay( mDate ) );
00610 }
00611
00612 void MonthViewCell::enableScrollBars( bool enabled )
00613 {
00614 if ( enabled ) {
00615 mItemList->setVScrollBarMode( QScrollView::Auto );
00616 mItemList->setHScrollBarMode( QScrollView::Auto );
00617 } else {
00618 mItemList->setVScrollBarMode( QScrollView::AlwaysOff );
00619 mItemList->setHScrollBarMode( QScrollView::AlwaysOff );
00620 }
00621 }
00622
00623 Incidence *MonthViewCell::selectedIncidence()
00624 {
00625 int index = mItemList->currentItem();
00626 if ( index < 0 ) return 0;
00627
00628 MonthViewItem *item =
00629 static_cast<MonthViewItem *>( mItemList->item( index ) );
00630
00631 if ( !item ) return 0;
00632
00633 return item->incidence();
00634 }
00635
00636 QDate MonthViewCell::selectedIncidenceDate()
00637 {
00638 QDate qd;
00639 int index = mItemList->currentItem();
00640 if ( index < 0 ) return qd;
00641
00642 MonthViewItem *item =
00643 static_cast<MonthViewItem *>( mItemList->item( index ) );
00644
00645 if ( !item ) return qd;
00646
00647 return item->incidenceDateTime().date();
00648 }
00649
00650 void MonthViewCell::select()
00651 {
00652
00653 mMonthView->setSelectedCell( this );
00654
00655 if( KOPrefs::instance()->enableMonthScroll() )
00656 enableScrollBars( true );
00657
00658
00659 if( mDate != QDate::currentDate() ) {
00660 mItemList->setFrameStyle( QFrame::Sunken | QFrame::Panel );
00661 mItemList->setLineWidth( 3 );
00662 }
00663 }
00664
00665 void MonthViewCell::deselect()
00666 {
00667 mItemList->clearSelection();
00668 mItemList->setFrameStyle( QFrame::Plain | QFrame::Panel );
00669 setFrameWidth();
00670
00671 enableScrollBars( false );
00672 }
00673
00674 void MonthViewCell::resizeEvent ( QResizeEvent * )
00675 {
00676 mLabel->move( width() - mLabel->width(), height() - mLabel->height() );
00677 }
00678
00679 void MonthViewCell::defaultAction( QListBoxItem *item )
00680 {
00681 select();
00682
00683 if ( !item ) {
00684 emit newEventSignal( date() );
00685 } else {
00686 MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
00687 Incidence *incidence = eventItem->incidence();
00688 if ( incidence ) mMonthView->defaultAction( incidence );
00689 }
00690 }
00691
00692 void MonthViewCell::contextMenu( QListBoxItem *item )
00693 {
00694 select();
00695
00696 if ( item ) {
00697 MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
00698 Incidence *incidence = eventItem->incidence();
00699 if ( incidence ) mMonthView->showEventContextMenu( incidence, date() );
00700 }
00701 else {
00702 mMonthView->showGeneralContextMenu();
00703 }
00704 }
00705
00706
00707 KOMonthView::KOMonthView( Calendar *calendar, QWidget *parent, const char *name )
00708 : KOEventView( calendar, parent, name ),
00709 mDaysPerWeek( 7 ), mNumWeeks( 6 ), mNumCells( mDaysPerWeek * mNumWeeks ),
00710 mShortDayLabels( false ), mWidthLongDayLabel( 0 ), mSelectedCell( 0 )
00711 {
00712 mCells.setAutoDelete( true );
00713
00714 QGridLayout *dayLayout = new QGridLayout( this );
00715
00716 QFont bfont = font();
00717 bfont.setBold( true );
00718
00719 QFont mfont = bfont;
00720 mfont.setPointSize( 20 );
00721
00722
00723 mLabel = new QLabel( this );
00724 mLabel->setFont( mfont );
00725 mLabel->setAlignment( AlignCenter );
00726 mLabel->setLineWidth( 0 );
00727 mLabel->setFrameStyle( QFrame::Plain );
00728
00729 dayLayout->addMultiCellWidget( mLabel, 0, 0, 0, mDaysPerWeek );
00730
00731
00732
00733 mDayLabels.resize( mDaysPerWeek );
00734 int i;
00735 for( i = 0; i < mDaysPerWeek; i++ ) {
00736 QLabel *label = new QLabel( this );
00737 label->setFont( bfont );
00738 label->setFrameStyle( QFrame::Panel | QFrame::Raised );
00739 label->setLineWidth( 1 );
00740 label->setAlignment( AlignCenter );
00741
00742 mDayLabels.insert( i, label );
00743
00744 dayLayout->addWidget( label, 1, i );
00745 dayLayout->addColSpacing( i, 10 );
00746 dayLayout->setColStretch( i, 1 );
00747 }
00748
00749 int row, col;
00750
00751 mCells.resize( mNumCells );
00752 for( row = 0; row < mNumWeeks; ++row ) {
00753 for( col = 0; col < mDaysPerWeek; ++col ) {
00754 MonthViewCell *cell = new MonthViewCell( this );
00755 cell->setCalendar(calendar);
00756 mCells.insert( row * mDaysPerWeek + col, cell );
00757 dayLayout->addWidget( cell, row + 2, col );
00758
00759 connect( cell, SIGNAL( defaultAction( Incidence * ) ),
00760 SLOT( defaultAction( Incidence * ) ) );
00761 connect( cell, SIGNAL( newEventSignal( const QDate & ) ),
00762 SIGNAL( newEventSignal( const QDate & ) ) );
00763 }
00764 dayLayout->setRowStretch( row + 2, 1 );
00765 }
00766
00767 mEventContextMenu = eventPopup();
00768
00769 updateConfig();
00770
00771 emit incidenceSelected( 0 );
00772 }
00773
00774 KOMonthView::~KOMonthView()
00775 {
00776 delete mEventContextMenu;
00777 }
00778
00779 int KOMonthView::maxDatesHint()
00780 {
00781 return mNumCells;
00782 }
00783
00784 int KOMonthView::currentDateCount()
00785 {
00786 return mNumCells;
00787 }
00788
00789 Incidence::List KOMonthView::selectedIncidences()
00790 {
00791 Incidence::List selected;
00792
00793 if ( mSelectedCell ) {
00794 Incidence *incidence = mSelectedCell->selectedIncidence();
00795 if ( incidence ) selected.append( incidence );
00796 }
00797
00798 return selected;
00799 }
00800
00801 DateList KOMonthView::selectedDates()
00802 {
00803 DateList selected;
00804
00805 if ( mSelectedCell ) {
00806 QDate qd = mSelectedCell->selectedIncidenceDate();
00807 if ( qd.isValid() ) selected.append( qd );
00808 }
00809
00810 return selected;
00811 }
00812
00813 bool KOMonthView::eventDurationHint( QDateTime &startDt, QDateTime &endDt, bool &allDay )
00814 {
00815 if ( mSelectedCell ) {
00816 startDt.setDate( mSelectedCell->date() );
00817 endDt.setDate( mSelectedCell->date() );
00818 allDay = true;
00819 return true;
00820 }
00821 return false;
00822 }
00823
00824 void KOMonthView::updateConfig()
00825 {
00826 mWeekStartDay = KGlobal::locale()->weekStartDay();
00827
00828 QFontMetrics fontmetric( mDayLabels[0]->font() );
00829 mWidthLongDayLabel = 0;
00830
00831 for ( int i = 0; i < 7; ++i ) {
00832 int width =
00833 fontmetric.width( KOGlobals::self()->calendarSystem()->weekDayName( i + 1 ) );
00834 if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width;
00835 }
00836
00837 updateDayLabels();
00838
00839 for ( uint i = 0; i < mCells.count(); ++i ) {
00840 mCells[i]->updateConfig();
00841 }
00842 }
00843
00844 void KOMonthView::updateDayLabels()
00845 {
00846 kdDebug(5850) << "KOMonthView::updateDayLabels()" << endl;
00847
00848 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00849 int currDay;
00850 for ( int i = 0; i < 7; i++ ) {
00851 currDay = i+mWeekStartDay;
00852 if ( currDay > 7 ) currDay -= 7;
00853 mDayLabels[i]->setText( calsys->weekDayName( currDay, mShortDayLabels ) );
00854 }
00855 }
00856
00857 void KOMonthView::showDates( const QDate &start, const QDate & )
00858 {
00859
00860
00861 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
00862
00863
00864 mStartDate = start.addDays( -start.day() + 1 );
00865
00866 int weekdayCol=( mStartDate.dayOfWeek() + 7 - mWeekStartDay ) % 7;
00867 mStartDate = mStartDate.addDays( -weekdayCol );
00868
00869 mLabel->setText( i18n( "monthname year", "%1 %2" )
00870 .arg( calSys->monthName( start ) )
00871 .arg( calSys->year( start ) ) );
00872
00873 bool primary = false;
00874 uint i;
00875 for( i = 0; i < mCells.size(); ++i ) {
00876 QDate date = mStartDate.addDays( i );
00877 if ( calSys->day( date ) == 1 ) {
00878 primary = !primary;
00879 }
00880
00881 mCells[i]->setDate( date );
00882 if( date == start )
00883 mCells[i]->select();
00884
00885 mCells[i]->setPrimary( primary );
00886
00887 bool isHoliday = calSys->dayOfWeek( date ) == calSys->weekDayOfPray()
00888 || !KOGlobals::self()->isWorkDay( date );
00889 mCells[i]->setHoliday( isHoliday );
00890
00891
00892 QString hstring( KOGlobals::self()->holiday( date ) );
00893 mCells[i]->setHolidayString( hstring );
00894 }
00895
00896 updateView();
00897 }
00898
00899 void KOMonthView::showIncidences( const Incidence::List & )
00900 {
00901 kdDebug(5850) << "KOMonthView::showIncidences( const Incidence::List & ) is not implemented yet." << endl;
00902 }
00903
00904 class KOMonthView::GetDateVisitor : public IncidenceBase::Visitor
00905 {
00906 public:
00907 GetDateVisitor() {}
00908
00909 bool act( IncidenceBase *incidence )
00910 {
00911 return incidence->accept( *this );
00912 }
00913 QDate date() const { return mDate; }
00914
00915 protected:
00916 bool visit( Event *event ) {
00917 mDate = event->dtStart().date();
00918 return true;
00919 }
00920 bool visit( Todo *todo ) {
00921 if ( todo->hasDueDate() ) {
00922 mDate = todo->dtDue().date();
00923 return true;
00924 } else
00925 return false;
00926 }
00927 bool visit( Journal *journal ) {
00928 mDate = journal->dtStart().date();
00929 return true;
00930 }
00931 protected:
00932 QDate mDate;
00933 };
00934
00935 void KOMonthView::changeIncidenceDisplayAdded( Incidence *incidence, MonthViewCell::CreateItemVisitor& v)
00936 {
00937 MonthViewCell *mvc;
00938 Event *event = 0;
00939 Todo *todo = 0;
00940 QDate date;
00941
00942
00943 if ( incidence->type() == "Event" ) {
00944 event = static_cast<Event *>( incidence );
00945 date = event->dtStart().date();
00946 }
00947 if ( incidence->type() == "Todo" ) {
00948 todo = static_cast<Todo *>( incidence );
00949 if ( !todo->hasDueDate() ) return;
00950 date = todo->dtDue().date();
00951 }
00952
00953 if ( incidence->doesRecur() ) {
00954
00955 for ( uint i = 0; i < mCells.count(); i++ ) {
00956 if ( incidence->recursOn( mCells[i]->date() ) ) {
00957 mCells[i]->addIncidence( incidence, v );
00958 }
00959 }
00960 } else if ( event ) {
00961 for ( QDateTime _date = date;
00962 _date <= event->dtEnd(); _date = _date.addDays( 1 ) ) {
00963 mvc = lookupCellByDate( _date.date() );
00964 if ( mvc ) mvc->addIncidence( event, v );
00965 }
00966 } else if ( todo ) {
00967 mvc = lookupCellByDate( date );
00968 if ( mvc ) mvc->addIncidence( todo, v );
00969 }
00970 }
00971
00972 void KOMonthView::changeIncidenceDisplay( Incidence *incidence, int action )
00973 {
00974 MonthViewCell::CreateItemVisitor v;
00975 switch ( action ) {
00976 case KOGlobals::INCIDENCEADDED:
00977 changeIncidenceDisplayAdded( incidence, v );
00978 break;
00979 case KOGlobals::INCIDENCEEDITED:
00980 for( uint i = 0; i < mCells.count(); i++ )
00981 mCells[i]->removeIncidence( incidence );
00982 changeIncidenceDisplayAdded( incidence, v );
00983 break;
00984 case KOGlobals::INCIDENCEDELETED:
00985 for( uint i = 0; i < mCells.count(); i++ )
00986 mCells[i]->removeIncidence( incidence );
00987 break;
00988 default:
00989 return;
00990 }
00991 }
00992
00993 void KOMonthView::updateView()
00994 {
00995 for( uint i = 0; i < mCells.count(); ++i ) {
00996 mCells[i]->updateCell();
00997 }
00998
00999 Incidence::List incidences = calendar()->incidences();
01000 Incidence::List::ConstIterator it;
01001
01002 MonthViewCell::CreateItemVisitor v;
01003 for ( it = incidences.begin(); it != incidences.end(); ++it )
01004 changeIncidenceDisplayAdded( *it, v );
01005
01006 processSelectionChange();
01007 }
01008
01009 void KOMonthView::resizeEvent( QResizeEvent * )
01010 {
01011
01012
01013
01014
01015 if( mDayLabels[0]->width() < mWidthLongDayLabel ) {
01016 if ( !mShortDayLabels ) {
01017 mShortDayLabels = true;
01018 updateDayLabels();
01019 }
01020 } else {
01021 if ( mShortDayLabels ) {
01022 mShortDayLabels = false;
01023 updateDayLabels();
01024 }
01025 }
01026 }
01027
01028 void KOMonthView::showEventContextMenu( Incidence *incidence, const QDate &qd )
01029 {
01030 mEventContextMenu->showIncidencePopup( incidence, qd );
01031 }
01032
01033 void KOMonthView::showGeneralContextMenu()
01034 {
01035 showNewEventPopup();
01036 }
01037
01038 void KOMonthView::setSelectedCell( MonthViewCell *cell )
01039 {
01040 if ( cell == mSelectedCell ) return;
01041
01042 if ( mSelectedCell ) mSelectedCell->deselect();
01043
01044 mSelectedCell = cell;
01045
01046 if ( !mSelectedCell )
01047 emit incidenceSelected( 0 );
01048 else
01049 emit incidenceSelected( mSelectedCell->selectedIncidence() );
01050 }
01051
01052 void KOMonthView::processSelectionChange()
01053 {
01054 Incidence::List incidences = selectedIncidences();
01055 if (incidences.count() > 0) {
01056 emit incidenceSelected( incidences.first() );
01057 } else {
01058 emit incidenceSelected( 0 );
01059 }
01060 }
01061
01062 void KOMonthView::clearSelection()
01063 {
01064 if ( mSelectedCell ) {
01065 mSelectedCell->deselect();
01066 mSelectedCell = 0;
01067 }
01068 }
01069
01070 MonthViewCell *KOMonthView::lookupCellByDate ( const QDate &date )
01071 {
01072 for( uint i = 0; i < mCells.count(); i++ ) {
01073 if ( mCells[i]->date() == date )
01074 return mCells[i];
01075 }
01076 return 0;
01077 }