00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qhbox.h>
00025 #include <qvbox.h>
00026 #include <qlabel.h>
00027 #include <qframe.h>
00028 #include <qlayout.h>
00029 #ifndef KORG_NOSPLITTER
00030 #include <qsplitter.h>
00031 #endif
00032 #include <qfont.h>
00033 #include <qfontmetrics.h>
00034 #include <qpopupmenu.h>
00035 #include <qtooltip.h>
00036 #include <qpainter.h>
00037 #include <qpushbutton.h>
00038 #include <qcursor.h>
00039
00040 #include <kapplication.h>
00041 #include <kdebug.h>
00042 #include <kstandarddirs.h>
00043 #include <kiconloader.h>
00044 #include <klocale.h>
00045 #include <kconfig.h>
00046 #include <kglobal.h>
00047 #include <kglobalsettings.h>
00048
00049 #include <libkcal/calendar.h>
00050 #include <libkcal/icaldrag.h>
00051 #include <libkcal/dndfactory.h>
00052 #include <libkcal/calfilter.h>
00053
00054 #include <kcalendarsystem.h>
00055
00056 #include "koglobals.h"
00057 #ifndef KORG_NOPLUGINS
00058 #include "kocore.h"
00059 #endif
00060 #include "koprefs.h"
00061 #include "koagenda.h"
00062 #include "koagendaitem.h"
00063 #ifndef KORG_NOPRINTER
00064 #include "calprinter.h"
00065 #endif
00066
00067 #include "koincidencetooltip.h"
00068 #include "kogroupware.h"
00069 #include "kodialogmanager.h"
00070
00071 #include "koagendaview.h"
00072 #include "koagendaview.moc"
00073
00074 using namespace KOrg;
00075
00076 TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) :
00077 QScrollView(parent,name,f)
00078 {
00079 mRows = rows;
00080
00081 mCellHeight = KOPrefs::instance()->mHourSize*4;
00082
00083 enableClipper(true);
00084
00085 setHScrollBarMode(AlwaysOff);
00086 setVScrollBarMode(AlwaysOff);
00087
00088 resizeContents(50,mRows * mCellHeight);
00089
00090 viewport()->setBackgroundMode( PaletteBackground );
00091 }
00092
00093 void TimeLabels::setCellHeight(int height)
00094 {
00095 mCellHeight = height;
00096 }
00097
00098
00099
00100
00101
00102 void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch)
00103 {
00104
00105
00106
00107
00108
00109
00110 cx = contentsX() + 2;
00111 cw = contentsWidth() - 2;
00112 int visWidth = visibleWidth();
00113 double cellHeight=mCellHeight;
00114 if (mAgenda) cellHeight=(4*mAgenda->gridSpacingY());
00115
00116
00117 int cell = ((int)(cy/cellHeight));
00118 double y = (cell * cellHeight);
00119 QFontMetrics fm = fontMetrics();
00120 QString hour;
00121 QString suffix;
00122 QString fullTime;
00123
00124 while (y < cy + ch) {
00125 p->drawLine(cx,(int)y,cx+cw,(int)y);
00126 hour.setNum(cell);
00127 suffix = "am";
00128
00129
00130 if (KGlobal::locale()->use12Clock()) {
00131 if (cell > 11) suffix = "pm";
00132 if (cell == 0) hour.setNum(12);
00133 if (cell > 12) hour.setNum(cell - 12);
00134 } else {
00135 suffix = ":00";
00136 }
00137
00138
00139 fullTime = hour + suffix;
00140
00141
00142 QRect r( cx, (int)y+3, visWidth-4, (int)(y+cellHeight-3) );
00143 p->drawText ( r, Qt::AlignHCenter | Qt::AlignTop | Qt::SingleLine, fullTime );
00144
00145
00146 y += cellHeight;
00147 cell++;
00148 }
00149 }
00150
00154 int TimeLabels::minimumWidth() const
00155 {
00156 QFontMetrics fm = fontMetrics();
00157
00158
00159 int borderWidth = 4;
00160
00161
00162 int width = fm.width("88:88") + borderWidth;
00163
00164 return width;
00165 }
00166
00168 void TimeLabels::updateConfig()
00169 {
00170
00171
00172
00173 setFont(KOPrefs::instance()->mTimeBarFont);
00174
00175
00176 setFixedWidth(minimumWidth());
00177
00178
00179 mCellHeight = KOPrefs::instance()->mHourSize*4;
00180 if (mCellHeight>mAgenda->gridSpacingY())
00181 mCellHeight=(int)(4*mAgenda->gridSpacingY());
00182
00183 resizeContents(50,mRows * mCellHeight);
00184 }
00185
00187 void TimeLabels::positionChanged()
00188 {
00189 int adjustment = mAgenda->contentsY();
00190 setContentsPos(0, adjustment);
00191 }
00192
00194 void TimeLabels::setAgenda(KOAgenda* agenda)
00195 {
00196 mAgenda = agenda;
00197 }
00198
00199
00201 void TimeLabels::paintEvent(QPaintEvent*)
00202 {
00203
00204
00205
00206
00207 repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight());
00208 }
00209
00211
00212 EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name)
00213 : QFrame(parent,name)
00214 {
00215 mColumns = 1;
00216 mTopBox = 0;
00217 mLocation = loc;
00218 mTopLayout = 0;
00219
00220 if (mLocation == Top) mPixmap = KOGlobals::self()->smallIcon("1uparrow");
00221 else mPixmap = KOGlobals::self()->smallIcon("1downarrow");
00222
00223 setMinimumHeight(mPixmap.height());
00224 }
00225
00226 EventIndicator::~EventIndicator()
00227 {
00228 }
00229
00230 void EventIndicator::drawContents(QPainter *p)
00231 {
00232
00233
00234
00235
00236 int i;
00237 for(i=0;i<mColumns;++i) {
00238 if (mEnabled[i]) {
00239 int cellWidth = contentsRect().right()/mColumns;
00240 int xOffset = KOGlobals::self()->reverseLayout() ?
00241 (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 :
00242 i*cellWidth + cellWidth/2 -mPixmap.width()/2;
00243 p->drawPixmap(QPoint(xOffset,0),mPixmap);
00244 }
00245 }
00246 }
00247
00248 void EventIndicator::changeColumns(int columns)
00249 {
00250 mColumns = columns;
00251 mEnabled.resize(mColumns);
00252
00253 update();
00254 }
00255
00256 void EventIndicator::enableColumn(int column, bool enable)
00257 {
00258 mEnabled[column] = enable;
00259 }
00260
00261
00262 #include <libkcal/incidence.h>
00263
00267
00268
00269 KOAlternateLabel::KOAlternateLabel(QString shortlabel, QString longlabel,
00270 QString extensivelabel, QWidget *parent, const char *name )
00271 : QLabel(parent, name), mTextTypeFixed(false), mShortText(shortlabel),
00272 mLongText(longlabel), mExtensiveText(extensivelabel)
00273 {
00274 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
00275 if (mExtensiveText.isEmpty()) mExtensiveText = mLongText;
00276 squeezeTextToLabel();
00277 }
00278
00279 KOAlternateLabel::~KOAlternateLabel() {}
00280
00281 void KOAlternateLabel::useShortText()
00282 {
00283 mTextTypeFixed = true;
00284 QLabel::setText( mShortText );
00285 QToolTip::remove( this );
00286 QToolTip::add( this, mExtensiveText );
00287 }
00288
00289 void KOAlternateLabel::useLongText()
00290 {
00291 mTextTypeFixed = true;
00292 QLabel::setText( mLongText );
00293 QToolTip::remove( this );
00294 QToolTip::add( this, mExtensiveText );
00295 }
00296
00297 void KOAlternateLabel::useExtensiveText()
00298 {
00299 mTextTypeFixed = true;
00300 QLabel::setText( mExtensiveText );
00301 QToolTip::remove( this );
00302 QToolTip::hide();
00303 }
00304
00305 void KOAlternateLabel::useDefaultText()
00306 {
00307 mTextTypeFixed = false;
00308 squeezeTextToLabel();
00309 }
00310
00311 void KOAlternateLabel::squeezeTextToLabel() {
00312 if (mTextTypeFixed) return;
00313
00314 QFontMetrics fm(fontMetrics());
00315 int labelWidth = size().width();
00316 int textWidth = fm.width(mLongText);
00317 int longTextWidth = fm.width(mExtensiveText);
00318 if (longTextWidth <= labelWidth) {
00319 QLabel::setText( mExtensiveText );
00320 QToolTip::remove( this );
00321 QToolTip::hide();
00322 } else if (textWidth <= labelWidth) {
00323 QLabel::setText( mLongText );
00324 QToolTip::remove( this );
00325 QToolTip::add( this, mExtensiveText );
00326 } else {
00327 QLabel::setText( mShortText );
00328 QToolTip::remove( this );
00329 QToolTip::add( this, mExtensiveText );
00330 }
00331 }
00332
00333 void KOAlternateLabel::resizeEvent( QResizeEvent * ) {
00334 squeezeTextToLabel();
00335 }
00336
00337 QSize KOAlternateLabel::minimumSizeHint() const
00338 {
00339 QSize sh = QLabel::minimumSizeHint();
00340 sh.setWidth(-1);
00341 return sh;
00342 }
00343
00344 void KOAlternateLabel::setText( const QString &text ) {
00345 mLongText = text;
00346 squeezeTextToLabel();
00347 }
00348
00349
00353
00354 KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name) :
00355 KOEventView (cal,parent,name)
00356 {
00357 mSelectedDates.append(QDate::currentDate());
00358
00359 mLayoutDayLabels = 0;
00360 mDayLabelsFrame = 0;
00361 mDayLabels = 0;
00362
00363 bool isRTL = KOGlobals::self()->reverseLayout();
00364
00365 if ( KOPrefs::instance()->mVerticalScreen ) {
00366 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00367 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00368 } else {
00369 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00370 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00371 }
00372
00373 QBoxLayout *topLayout = new QVBoxLayout(this);
00374
00375
00376 mDayLabelsFrame = new QHBox(this);
00377 topLayout->addWidget(mDayLabelsFrame);
00378
00379
00380 #ifndef KORG_NOSPLITTER
00381 mSplitterAgenda = new QSplitter(Vertical,this);
00382 topLayout->addWidget(mSplitterAgenda);
00383 #
00384 #if KDE_IS_VERSION( 3, 1, 93 )
00385 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00386 #else
00387 mSplitterAgenda->setOpaqueResize();
00388 #endif
00389
00390 mAllDayFrame = new QHBox(mSplitterAgenda);
00391
00392 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00393 #else
00394 QVBox *mainBox = new QVBox( this );
00395 topLayout->addWidget( mainBox );
00396
00397 mAllDayFrame = new QHBox(mainBox);
00398
00399 QWidget *agendaFrame = new QWidget(mainBox);
00400 #endif
00401
00402
00403 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00404
00405 mExpandButton = new QPushButton(mDummyAllDayLeft);
00406 mExpandButton->setPixmap( mNotExpandedPixmap );
00407 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00408 QSizePolicy::Fixed ) );
00409 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00410
00411 mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
00412 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00413
00414
00415 mAllDayAgendaPopup = eventPopup();
00416 connect(mAllDayAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)),
00417 mAllDayAgendaPopup,SLOT(showIncidencePopup(Incidence *)));
00418
00419
00420 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00421
00422
00423
00424 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00425 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00426 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00427 agendaFrame);
00428 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00429 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00430 agendaLayout->addWidget(dummyAgendaRight,0,2);
00431
00432
00433 mTimeLabels = new TimeLabels(24,agendaFrame);
00434 agendaLayout->addWidget(mTimeLabels,1,0);
00435
00436
00437 mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
00438 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00439 agendaLayout->setColStretch(1,1);
00440
00441
00442 mAgendaPopup = eventPopup();
00443 mAgendaPopup->addAdditionalItem(QIconSet(KOGlobals::self()->smallIcon("bell")),
00444 i18n("Toggle Alarm"),mAgenda,
00445 SLOT(popupAlarm()),true);
00446 connect(mAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)),
00447 mAgendaPopup,SLOT(showIncidencePopup(Incidence *)));
00448
00449 connect(mAgenda,SIGNAL(showNewEventPopupSignal()),
00450 this, SLOT(showNewEventPopup()));
00451
00452
00453 mTimeLabels->setAgenda(mAgenda);
00454
00455
00456
00457
00458 createDayLabels();
00459
00460
00461 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00462 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00463 mDummyAllDayLeft->setFixedWidth(mTimeLabels->width());
00464
00465 mAllDayAgenda->setCalendar( calendar() );
00466 mAgenda->setCalendar( calendar() );
00467
00468
00469 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00470 mTimeLabels, SLOT(positionChanged()));
00471 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00472 SLOT(setContentsPos(int)));
00473
00474
00475 connect(mAgenda,SIGNAL(newEventSignal()),SIGNAL(newEventSignal()));
00476 connect(mAgenda,SIGNAL(newEventSignal(int,int)),
00477 SLOT(newEvent(int,int)));
00478 connect(mAgenda,SIGNAL(newEventSignal(int,int,int,int)),
00479 SLOT(newEvent(int,int,int,int)));
00480 connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int)),
00481 SLOT(newEventAllDay(int,int)));
00482 connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int,int,int)),
00483 SLOT(newEventAllDay(int,int)));
00484 connect(mAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)),
00485 SLOT(newTimeSpanSelected(int,int,int,int)));
00486 connect(mAllDayAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)),
00487 SLOT(newTimeSpanSelectedAllDay(int,int,int,int)));
00488
00489
00490
00491
00492
00493 connect(mAgenda,SIGNAL(editIncidenceSignal(Incidence *)),
00494 SIGNAL(editIncidenceSignal(Incidence *)));
00495 connect(mAllDayAgenda,SIGNAL(editIncidenceSignal(Incidence *)),
00496 SIGNAL(editIncidenceSignal(Incidence *)));
00497 connect(mAgenda,SIGNAL(showIncidenceSignal(Incidence *)),
00498 SIGNAL(showIncidenceSignal(Incidence *)));
00499 connect(mAllDayAgenda,SIGNAL(showIncidenceSignal(Incidence *)),
00500 SIGNAL(showIncidenceSignal(Incidence *)));
00501 connect(mAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)),
00502 SIGNAL(deleteIncidenceSignal(Incidence *)));
00503 connect(mAllDayAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)),
00504 SIGNAL(deleteIncidenceSignal(Incidence *)));
00505
00506 connect(mAgenda,SIGNAL(itemModified(KOAgendaItem *)),
00507 SLOT(updateEventDates(KOAgendaItem *)));
00508 connect(mAllDayAgenda,SIGNAL(itemModified(KOAgendaItem *)),
00509 SLOT(updateEventDates(KOAgendaItem *)));
00510
00511
00512 connect(mAgenda,SIGNAL(lowerYChanged(int)),
00513 SLOT(updateEventIndicatorTop(int)));
00514 connect(mAgenda,SIGNAL(upperYChanged(int)),
00515 SLOT(updateEventIndicatorBottom(int)));
00516
00517
00518 connect( mAgenda, SIGNAL( startDragSignal( Incidence * ) ),
00519 SLOT( startDrag( Incidence * ) ) );
00520 connect( mAllDayAgenda, SIGNAL( startDragSignal( Incidence * ) ),
00521 SLOT( startDrag( Incidence * ) ) );
00522
00523
00524 connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ),
00525 mAllDayAgenda, SLOT( deselectItem() ) );
00526 connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ),
00527 mAgenda, SLOT( deselectItem() ) );
00528 connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ),
00529 SIGNAL( incidenceSelected( Incidence * ) ) );
00530 connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ),
00531 SIGNAL( incidenceSelected( Incidence * ) ) );
00532
00533
00534 connect( mAgenda, SIGNAL( droppedToDo( Todo*, int, int, bool ) ),
00535 SLOT( slotTodoDropped( Todo *, int, int, bool ) ) );
00536 connect( mAllDayAgenda, SIGNAL( droppedToDo( Todo *, int, int, bool ) ),
00537 SLOT( slotTodoDropped( Todo *, int, int, bool ) ) );
00538 }
00539
00540
00541 KOAgendaView::~KOAgendaView()
00542 {
00543 delete mAgendaPopup;
00544 delete mAllDayAgendaPopup;
00545 }
00546
00547 void KOAgendaView::createDayLabels()
00548 {
00549
00550
00551
00552
00553
00554 delete mDayLabels;
00555
00556 mDayLabels = new QFrame (mDayLabelsFrame);
00557 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00558 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00559
00560 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00561
00562 DateList::ConstIterator dit;
00563 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00564 QDate date = *dit;
00565 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00566 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00567
00568
00569 int dW = calsys->dayOfWeek(date);
00570 QString veryLongStr = KGlobal::locale()->formatDate( date );
00571 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00572 .arg( calsys->weekDayName( dW, true ) )
00573 .arg( calsys->day(date) );
00574 QString shortstr = QString::number(calsys->day(date));
00575
00576 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00577 longstr, veryLongStr, mDayLabels);
00578 dayLabel->setMinimumWidth(1);
00579 dayLabel->setAlignment(QLabel::AlignHCenter);
00580 if (date == QDate::currentDate()) {
00581 QFont font = dayLabel->font();
00582 font.setBold(true);
00583 dayLabel->setFont(font);
00584 }
00585 dayLayout->addWidget(dayLabel);
00586
00587 #ifndef KORG_NOPLUGINS
00588 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00589 CalendarDecoration *it;
00590 for(it = cds.first(); it; it = cds.next()) {
00591 QString text = it->shortText( date );
00592 if ( !text.isEmpty() ) {
00593
00594 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00595 label->setMinimumWidth(1);
00596 label->setAlignment(AlignCenter);
00597 dayLayout->addWidget(label);
00598 }
00599 }
00600
00601 for(it = cds.first(); it; it = cds.next()) {
00602 QWidget *wid = it->smallWidget(mDayLabels,date);
00603 if ( wid ) {
00604
00605 dayLayout->addWidget(wid);
00606 }
00607 }
00608 #endif
00609 }
00610
00611 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00612 mDayLabels->show();
00613 }
00614
00615 int KOAgendaView::maxDatesHint()
00616 {
00617
00618 return 0;
00619 }
00620
00621 int KOAgendaView::currentDateCount()
00622 {
00623 return mSelectedDates.count();
00624 }
00625
00626 Incidence::List KOAgendaView::selectedIncidences()
00627 {
00628 Incidence::List selected;
00629 Incidence *incidence;
00630
00631 incidence = mAgenda->selectedIncidence();
00632 if (incidence) selected.append(incidence);
00633
00634 incidence = mAllDayAgenda->selectedIncidence();
00635 if (incidence) selected.append(incidence);
00636
00637 return selected;
00638 }
00639
00640 DateList KOAgendaView::selectedDates()
00641 {
00642 DateList selected;
00643 QDate qd;
00644
00645 qd = mAgenda->selectedIncidenceDate();
00646 if (qd.isValid()) selected.append(qd);
00647
00648 qd = mAllDayAgenda->selectedIncidenceDate();
00649 if (qd.isValid()) selected.append(qd);
00650
00651 return selected;
00652 }
00653
00655 bool KOAgendaView::selectedIsSingleCell()
00656 {
00657 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00658
00659 if (selectedIsAllDay()) {
00660 int days = selectionStart().daysTo(selectionEnd());
00661 return ( days < 1 );
00662 } else {
00663 int secs = selectionStart().secsTo(selectionEnd());
00664 return ( secs <= 24*60*60/mAgenda->rows() );
00665 }
00666 }
00667
00668
00669
00670 void KOAgendaView::updateView()
00671 {
00672
00673 fillAgenda();
00674 }
00675
00676
00677
00678
00679
00680
00681 void KOAgendaView::updateConfig()
00682 {
00683
00684
00685
00686 mTimeLabels->updateConfig();
00687 mAgenda->updateConfig();
00688 mAllDayAgenda->updateConfig();
00689
00690
00691
00692 mTimeLabels->positionChanged();
00693
00694
00695 mTimeLabels->repaint();
00696
00697 mDummyAllDayLeft->setFixedWidth(mTimeLabels->width());
00698
00699
00700 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00701 ->mEnableToolTips);
00702
00703 setHolidayMasks();
00704
00705 createDayLabels();
00706
00707 updateView();
00708 }
00709
00710
00711 void KOAgendaView::updateEventDates(KOAgendaItem *item)
00712 {
00713
00714
00715 QDateTime startDt,endDt;
00716 QDate startDate;
00717
00718 if (item->cellXLeft() < 0) {
00719 startDate = (mSelectedDates.first()).addDays(item->cellXLeft());
00720 } else {
00721 startDate = mSelectedDates[item->cellXLeft()];
00722 }
00723 startDt.setDate(startDate);
00724
00725 Incidence*incidence = item->incidence();
00726 if (!incidence) return;
00727 Incidence*oldIncidence = incidence->clone();
00728
00729 if (incidence->doesFloat()) {
00730 endDt.setDate(startDate.addDays(item->cellWidth() - 1));
00731 } else {
00732 startDt.setTime(mAgenda->gyToTime(item->cellYTop()));
00733 if (item->lastMultiItem()) {
00734 endDt.setTime(mAgenda->gyToTime(item->lastMultiItem()->cellYBottom()+1));
00735 endDt.setDate(startDate.
00736 addDays(item->lastMultiItem()->cellXLeft() - item->cellXLeft()));
00737 } else {
00738 endDt.setTime(mAgenda->gyToTime(item->cellYBottom()+1));
00739 endDt.setDate(startDate);
00740 }
00741 }
00742
00743
00744 Incidence *i = incidence->clone();
00745 if ( i->type() == "Event" ) {
00746 if( i->dtStart() == startDt && static_cast<Event*>(i)->dtEnd() == endDt ) {
00747
00748 delete i;
00749 return;
00750 }
00751 i->setDtStart(startDt);
00752 (static_cast<Event*>(i))->setDtEnd(endDt);
00753 } else if ( i->type() == "Todo" ) {
00754 if( static_cast<Todo*>(i)->dtDue() == endDt ) {
00755
00756 delete i;
00757 return;
00758 }
00759 (static_cast<Todo*>(i))->setDtDue(endDt);
00760 }
00761
00762 i->setRevision(i->revision()+1);
00763 if( !KOPrefs::instance()->mUseGroupwareCommunication ||
00764 KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Request, i ) ) {
00765 if ( i->type() == "Event" ) {
00766 incidence->setDtStart(startDt);
00767 (static_cast<Event*>(incidence))->setDtEnd(endDt);
00768 } else if ( i->type() == "Todo" ) {
00769 (static_cast<Todo*>(incidence))->setDtDue(endDt);
00770 }
00771 incidence->setRevision(i->revision());
00772 item->setItemDate(startDt.date());
00773
00774 KOIncidenceToolTip::remove(item);
00775 KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
00776
00777 emit incidenceChanged( oldIncidence, incidence );
00778 } else
00779 ;
00780
00781 delete i;
00782 delete oldIncidence;
00783
00784 }
00785
00786
00787 void KOAgendaView::showDates( const QDate &start, const QDate &end )
00788 {
00789
00790
00791 mSelectedDates.clear();
00792
00793 QDate d = start;
00794 while (d <= end) {
00795 mSelectedDates.append(d);
00796 d = d.addDays( 1 );
00797 }
00798
00799
00800 fillAgenda();
00801 }
00802
00803
00804 void KOAgendaView::showEvents( const Event::List & )
00805 {
00806 kdDebug(5850) << "KOAgendaView::showEvents() is not yet implemented" << endl;
00807 }
00808
00809 void KOAgendaView::insertEvent( Event *event, QDate curDate, int curCol )
00810 {
00811 if ( curCol<0 ) {
00812 curCol = mSelectedDates.findIndex( curDate );
00813 }
00814
00815 if ( curCol<0 || curCol>(int)mSelectedDates.size() )
00816 return;
00817
00818 int beginX = curDate.daysTo( event->dtStart().date() ) + curCol;
00819 int endX = curDate.daysTo( event->dtEnd().date() ) + curCol;
00820
00821 if ( event->doesFloat() ) {
00822 if ( event->recurrence()->doesRecur() ) {
00823 mAllDayAgenda->insertAllDayItem( event, curDate, curCol, curCol );
00824 } else {
00825 if ( beginX <= 0 && curCol == 0 ) {
00826 mAllDayAgenda->insertAllDayItem( event, curDate, beginX, endX);
00827 } else if (beginX == curCol) {
00828 mAllDayAgenda->insertAllDayItem( event, curDate, beginX, endX );
00829 }
00830 }
00831 } else if ( event->isMultiDay() ) {
00832 int startY = mAgenda->timeToY( event->dtStart().time() );
00833 int endY = mAgenda->timeToY( event->dtEnd().time() ) - 1;
00834 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
00835 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
00836 }
00837 if (beginX == curCol) {
00838 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
00839 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
00840 } else if (endX == curCol) {
00841 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
00842 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
00843 } else {
00844 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
00845 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
00846 }
00847 } else {
00848 int startY = mAgenda->timeToY( event->dtStart().time() );
00849 int endY = mAgenda->timeToY( event->dtEnd().time() ) - 1;
00850 if ( endY < startY ) endY = startY;
00851 mAgenda->insertItem( event, curDate, curCol, startY, endY );
00852 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
00853 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
00854 }
00855 }
00856
00857 void KOAgendaView::changeEventDisplayAdded( Event *event )
00858 {
00859 if ( !calendar()->filter()->filterEvent( event ) ) return;
00860
00861 if ( !event->doesRecur() ) {
00862
00863 QDate f = mSelectedDates.first();
00864 QDate l = mSelectedDates.last();
00865 QDate startDt = event->dtStart().date();
00866 QDate endDt = event->dtEnd().date();
00867 if ( startDt <= l ) {
00868 if ( startDt >= f ) {
00869 insertEvent( event, startDt );
00870 } else if ( endDt >= f ) {
00871 insertEvent( event, endDt );
00872 }
00873 }
00874 } else {
00875 DateList::ConstIterator dit;
00876 QDate curDate;
00877 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00878 curDate = *dit;
00879 if ( event->recursOn( curDate ) ) insertEvent( event, curDate );
00880 }
00881 }
00882
00883 }
00884
00885 void KOAgendaView::changeEventDisplay(Event *event, int mode)
00886 {
00887 kdDebug(5850) << "KOAgendaView::changeEventDisplay" << endl;
00888
00889 switch (mode) {
00890 case KOGlobals::EVENTADDED: {
00891
00892
00893
00894
00895 changeEventDisplayAdded( event );
00896 }
00897 break;
00898
00899 case KOGlobals::EVENTEDITED:
00900
00901
00902
00903
00904
00905
00906
00907
00908 updateView();
00909 break;
00910 case KOGlobals::EVENTDELETED:
00911
00912
00913
00914
00915
00916
00917
00918 updateView();
00919 break;
00920
00921 default:
00922 fillAgenda();
00923 }
00924 }
00925
00926 void KOAgendaView::fillAgenda(const QDate &)
00927 {
00928 fillAgenda();
00929 }
00930
00931 void KOAgendaView::fillAgenda()
00932 {
00933
00934
00935 mAllDayAgenda->changeColumns(mSelectedDates.count());
00936 mAgenda->changeColumns(mSelectedDates.count());
00937 mEventIndicatorTop->changeColumns(mSelectedDates.count());
00938 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
00939
00940 createDayLabels();
00941 setHolidayMasks();
00942
00943 mMinY.resize(mSelectedDates.count());
00944 mMaxY.resize(mSelectedDates.count());
00945
00946 Event::List dayEvents;
00947
00948
00949
00950 Todo::List todos = calendar()->todos();
00951
00952 mAgenda->setDateList(mSelectedDates);
00953
00954 QDate today = QDate::currentDate();
00955
00956 DateList::ConstIterator dit;
00957 int curCol = 0;
00958 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00959 QDate currentDate = *dit;
00960
00961
00962
00963 dayEvents = calendar()->events(currentDate,true);
00964
00965
00966 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
00967 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
00968
00969 unsigned int numEvent;
00970 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
00971 Event *event = *dayEvents.at(numEvent);
00972
00973 insertEvent( event, currentDate, curCol );
00974 }
00975
00976
00977
00978
00979 unsigned int numTodo;
00980 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
00981 Todo *todo = *todos.at(numTodo);
00982
00983 if ( ! todo->hasDueDate() ) continue;
00984
00985
00986
00987 bool overdue = (!todo->isCompleted()) && (todo->dtDue() < today);
00988
00989 if ( ((todo->dtDue().date() == currentDate) && !overdue) ||
00990 ((currentDate == today) && overdue) )
00991 if ( todo->doesFloat() || overdue ) {
00992
00993
00994 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
00995 }
00996 else {
00997
00998
00999 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01000 int startY = endY - 1;
01001
01002 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01003
01004 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01005 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01006 }
01007 }
01008
01009
01010 ++curCol;
01011 }
01012
01013 mAgenda->checkScrollBoundaries();
01014
01015
01016
01017
01018
01019 deleteSelectedDateTime();
01020
01021 emit incidenceSelected( 0 );
01022
01023
01024 }
01025
01026 void KOAgendaView::clearView()
01027 {
01028
01029 mAllDayAgenda->clear();
01030 mAgenda->clear();
01031 }
01032
01033 void KOAgendaView::printPreview(CalPrinter *calPrinter, const QDate &fd,
01034 const QDate &td)
01035 {
01036 #ifndef KORG_NOPRINTER
01037 if (fd == td)
01038 calPrinter->preview(CalPrinter::Day, fd, td);
01039 else
01040 calPrinter->preview(CalPrinter::Week, fd, td);
01041 #endif
01042 }
01043
01044 CalPrinter::PrintType KOAgendaView::printType()
01045 {
01046 if ( currentDateCount() == 1 ) return CalPrinter::Day;
01047 else return CalPrinter::Week;
01048 }
01049
01050 void KOAgendaView::newEvent(int gx, int gy)
01051 {
01052 if (!mSelectedDates.count()) return;
01053
01054 QDate day = mSelectedDates[gx];
01055
01056 QTime time = mAgenda->gyToTime(gy);
01057 QDateTime dt(day,time);
01058
01059 emit newEventSignal(dt);
01060 }
01061
01062 void KOAgendaView::newEvent(int gxStart, int gyStart, int gxEnd, int gyEnd)
01063 {
01064 if (!mSelectedDates.count()) return;
01065
01066 QDate dayStart = mSelectedDates[gxStart];
01067 QDate dayEnd = mSelectedDates[gxEnd];
01068
01069 QTime timeStart = mAgenda->gyToTime(gyStart);
01070 QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 );
01071
01072 QDateTime dtStart(dayStart,timeStart);
01073 QDateTime dtEnd(dayEnd,timeEnd);
01074
01075 emit newEventSignal(dtStart,dtEnd);
01076 }
01077
01078 void KOAgendaView::newEventAllDay(int gx, int )
01079 {
01080 if (!mSelectedDates.count()) return;
01081
01082 QDate day = mSelectedDates[gx];
01083
01084 emit newEventSignal(day);
01085 }
01086
01087 void KOAgendaView::updateEventIndicatorTop(int newY)
01088 {
01089 uint i;
01090 for(i=0;i<mMinY.size();++i) {
01091 if (newY >= mMinY[i]) mEventIndicatorTop->enableColumn(i,true);
01092 else mEventIndicatorTop->enableColumn(i,false);
01093 }
01094
01095 mEventIndicatorTop->update();
01096 }
01097
01098 void KOAgendaView::updateEventIndicatorBottom(int newY)
01099 {
01100 uint i;
01101 for(i=0;i<mMaxY.size();++i) {
01102 if (newY <= mMaxY[i]) mEventIndicatorBottom->enableColumn(i,true);
01103 else mEventIndicatorBottom->enableColumn(i,false);
01104 }
01105
01106 mEventIndicatorBottom->update();
01107 }
01108
01109 void KOAgendaView::slotTodoDropped( Todo *todo, int gx, int gy, bool allDay )
01110 {
01111 if (gx<0 || gy<0) return;
01112 QDate day = mSelectedDates[gx];
01113 QTime time = mAgenda->gyToTime(gy);
01114 QDateTime newTime(day, time);
01115
01116 if (todo) {
01117 Todo *existingTodo = calendar()->todo(todo->uid());
01118 if(existingTodo) {
01119 kdDebug(5850) << "Drop existing Todo" << endl;
01120 Todo *oldTodo = existingTodo->clone();
01121 existingTodo->setDtDue( newTime );
01122 existingTodo->setFloats( allDay );
01123 existingTodo->setHasDueDate( true );
01124 existingTodo->setRevision( existingTodo->revision() + 1 );
01125 emit todoChanged( oldTodo, existingTodo );
01126 delete oldTodo;
01127 } else {
01128 kdDebug(5850) << "Drop new Todo" << endl;
01129 todo->setDtDue( newTime );
01130 todo->setFloats( allDay );
01131 existingTodo->setHasDueDate( true );
01132 if ( calendar()->addTodo( todo ) ) {
01133 emit todoDropped(todo);
01134 } else {
01135 KODialogManager::errorSaveTodo( this );
01136 }
01137 }
01138 }
01139 }
01140
01141 void KOAgendaView::startDrag( Incidence *incidence )
01142 {
01143 #ifndef KORG_NODND
01144 DndFactory factory( calendar() );
01145 ICalDrag *vd = factory.createDrag( incidence, this );
01146 if ( vd->drag() ) {
01147 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01148 }
01149 #endif
01150 }
01151
01152 void KOAgendaView::readSettings()
01153 {
01154 readSettings(KOGlobals::self()->config());
01155 }
01156
01157 void KOAgendaView::readSettings(KConfig *config)
01158 {
01159
01160
01161 config->setGroup("Views");
01162
01163 #ifndef KORG_NOSPLITTER
01164 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01165 if (sizes.count() == 2) {
01166 mSplitterAgenda->setSizes(sizes);
01167 }
01168 #endif
01169
01170 updateConfig();
01171 }
01172
01173 void KOAgendaView::writeSettings(KConfig *config)
01174 {
01175
01176
01177 config->setGroup("Views");
01178
01179 #ifndef KORG_NOSPLITTER
01180 QValueList<int> list = mSplitterAgenda->sizes();
01181 config->writeEntry("Separator AgendaView",list);
01182 #endif
01183 }
01184
01185 void KOAgendaView::setHolidayMasks()
01186 {
01187 mHolidayMask.resize(mSelectedDates.count());
01188
01189 uint i;
01190 for(i=0;i<mSelectedDates.count();++i) {
01191 QDate date = mSelectedDates[i];
01192 bool showSaturday = KOPrefs::instance()->mExcludeSaturdays && (date.dayOfWeek() == 6);
01193 bool showSunday = KOPrefs::instance()->mExcludeHolidays && (date.dayOfWeek() == 7);
01194 #ifndef KORG_NOPLUGINS
01195 bool showHoliday = KOPrefs::instance()->mExcludeHolidays &&
01196 !KOCore::self()->holiday(date).isEmpty();
01197 bool showDay = showSaturday || showSunday || showHoliday;
01198 #else
01199 bool showDay = showSaturday || showSunday;
01200 #endif
01201 if (showDay) {
01202 mHolidayMask[i] = true;
01203 } else {
01204 mHolidayMask[i] = false;
01205 }
01206 }
01207
01208 mAgenda->setHolidayMask(&mHolidayMask);
01209 mAllDayAgenda->setHolidayMask(&mHolidayMask);
01210 }
01211
01212 void KOAgendaView::setContentsPos(int y)
01213 {
01214 mAgenda->setContentsPos(0,y);
01215 }
01216
01217 void KOAgendaView::setExpandedButton( bool expanded )
01218 {
01219 if ( expanded ) {
01220 mExpandButton->setPixmap( mExpandedPixmap );
01221 } else {
01222 mExpandButton->setPixmap( mNotExpandedPixmap );
01223 }
01224 }
01225
01226 void KOAgendaView::clearSelection()
01227 {
01228 mAgenda->deselectItem();
01229 mAllDayAgenda->deselectItem();
01230 }
01231
01232 void KOAgendaView::newTimeSpanSelectedAllDay(int gxStart, int gyStart,
01233 int gxEnd, int gyEnd)
01234 {
01235 mTimeSpanInAllDay = true;
01236 newTimeSpanSelected(gxStart,gyStart,gxEnd,gyEnd);
01237 }
01238
01239 void KOAgendaView::newTimeSpanSelected(int gxStart, int gyStart,
01240 int gxEnd, int gyEnd)
01241 {
01242 if (!mSelectedDates.count()) return;
01243
01244 QDate dayStart = mSelectedDates[gxStart];
01245 QDate dayEnd = mSelectedDates[gxEnd];
01246
01247 QTime timeStart = mAgenda->gyToTime(gyStart);
01248 QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 );
01249
01250 QDateTime dtStart(dayStart,timeStart);
01251 QDateTime dtEnd(dayEnd,timeEnd);
01252
01253 mTimeSpanBegin = dtStart;
01254 mTimeSpanEnd = dtEnd;
01255 }
01256
01257 void KOAgendaView::deleteSelectedDateTime()
01258 {
01259 mTimeSpanBegin.setDate(QDate());
01260 mTimeSpanEnd.setDate(QDate());
01261 mTimeSpanInAllDay = false;
01262 }
01263
01264 void KOAgendaView::showNewEventPopup()
01265 {
01266 QPopupMenu *popup = newEventPopup();
01267 if ( !popup ) {
01268 kdError() << "KOAgendaView::showNewEventPopup(): popup creation failed"
01269 << endl;
01270 return;
01271 }
01272
01273 popup->popup( QCursor::pos() );
01274 }
01275
01276 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01277 {
01278 mAgenda->setTypeAheadReceiver( o );
01279 }
01280
01281 void KOAgendaView::finishTypeAhead()
01282 {
01283 mAgenda->finishTypeAhead();
01284 }