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 }