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 #include <qevent.h>
00026 #include <qpainter.h>
00027 #include <qptrlist.h>
00028
00029 #include <kglobal.h>
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032
00033 #include <libkcal/vcaldrag.h>
00034 #include <libkcal/icaldrag.h>
00035 #include <libkcal/dndfactory.h>
00036
00037 #include "koprefs.h"
00038 #include "kodaymatrix.h"
00039 #include "kodaymatrix.moc"
00040
00041 #ifndef KORG_NOPLUGINS
00042 #include "kocore.h"
00043 #endif
00044
00045
00046
00047
00048
00049
00050 DynamicTip::DynamicTip( QWidget * parent )
00051 : QToolTip( parent )
00052 {
00053 matrix = (KODayMatrix*)parent;
00054 }
00055
00056
00057 void DynamicTip::maybeTip( const QPoint &pos )
00058 {
00059
00060 QRect sz = matrix->frameRect();
00061 int dheight = sz.height()*7 / 42;
00062 int dwidth = sz.width() / 7;
00063 int row = pos.y()/dheight;
00064 int col = pos.x()/dwidth;
00065
00066 QRect rct(col*dwidth, row*dheight, dwidth, dheight);
00067
00068
00069
00070
00071
00072 QString str = matrix->getHolidayLabel(col+row*7);
00073 if (str.isEmpty()) return;
00074 tip(rct, str);
00075 }
00076
00077
00078
00079
00080
00081
00082 const int KODayMatrix::NOSELECTION = -1000;
00083 const int KODayMatrix::NUMDAYS = 42;
00084
00085 KODayMatrix::KODayMatrix(QWidget *parent, Calendar* calendar, QDate date, const char *name) :
00086 QFrame(parent, name)
00087 {
00088 mCalendar = calendar;
00089
00090
00091 days = new QDate[NUMDAYS];
00092 daylbls = new QString[NUMDAYS];
00093 events = new int[NUMDAYS];
00094 mToolTip = new DynamicTip(this);
00095
00096
00097 mDefaultBackColor = palette().active().base();
00098 mDefaultTextColor = palette().active().foreground();
00099 mDefaultTextColorShaded = getShadedColor(mDefaultTextColor);
00100 mHolidayColorShaded = getShadedColor(KOPrefs::instance()->mHolidayColor);
00101 mSelectedDaysColor = QColor("white");
00102 mTodayMarginWidth = 2;
00103 mSelEnd = mSelStart = NOSELECTION;
00104
00105 setAcceptDrops(true);
00106
00107 updateView(date);
00108 }
00109
00110 QColor KODayMatrix::getShadedColor(QColor color)
00111 {
00112 QColor shaded;
00113 int h=0;
00114 int s=0;
00115 int v=0;
00116 color.hsv(&h,&s,&v);
00117 s = s/4;
00118 v = 192+v/4;
00119 shaded.setHsv(h,s,v);
00120
00121 return shaded;
00122 }
00123
00124 KODayMatrix::~KODayMatrix()
00125 {
00126 delete [] days;
00127 delete [] daylbls;
00128 delete [] events;
00129 delete mToolTip;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 void KODayMatrix::addSelectedDaysTo(DateList& selDays)
00140 {
00141 kdDebug() << "KODayMatrix::addSelectedDaysTo() - " << "mSelStart:" << mSelStart << endl;
00142
00143 if (mSelStart == NOSELECTION) {
00144 return;
00145 }
00146
00147
00148 int i0 = mSelStart;
00149 if (i0 < 0) {
00150 for (int i = i0; i < 0; i++) {
00151 selDays.append(days[0].addDays(i));
00152 }
00153 i0 = 0;
00154 }
00155
00156
00157 if (mSelEnd > NUMDAYS-1) {
00158 for (int i = i0; i <= NUMDAYS-1; i++) {
00159 selDays.append(days[i]);
00160 }
00161 for (int i = NUMDAYS; i < mSelEnd; i++) {
00162 selDays.append(days[0].addDays(i));
00163 }
00164
00165
00166 } else {
00167 for (int i = i0; i <= mSelEnd; i++) {
00168 selDays.append(days[i]);
00169 }
00170 }
00171 }
00172
00173 void KODayMatrix::setSelectedDaysFrom(const QDate& start, const QDate& end)
00174 {
00175 mSelStart = startdate.daysTo(start);
00176 mSelEnd = startdate.daysTo(end);
00177 }
00178
00179
00180 void KODayMatrix::recalculateToday()
00181 {
00182 today = -1;
00183 for (int i=0; i<NUMDAYS; i++) {
00184 days[i] = startdate.addDays(i);
00185 daylbls[i] = QString::number( KOCore::self()->calendarSystem()->day( days[i] ));
00186
00187
00188 if (days[i].year() == QDate::currentDate().year() &&
00189 days[i].month() == QDate::currentDate().month() &&
00190 days[i].day() == QDate::currentDate().day()) {
00191 today = i;
00192 }
00193 }
00194
00195 }
00196
00197 void KODayMatrix::updateView()
00198 {
00199 updateView(startdate);
00200 }
00201
00202 void KODayMatrix::updateView(QDate actdate)
00203 {
00204
00205
00206
00207 bool daychanged = false;
00208
00209
00210
00211 if (actdate != startdate) {
00212
00213 if (mSelStart != NOSELECTION) {
00214 int tmp = actdate.daysTo(startdate);
00215
00216
00217
00218 if (mSelStart+tmp < NUMDAYS && mSelEnd+tmp >= 0) {
00219
00220
00221 if( mSelStart > NUMDAYS || mSelStart < 0 )
00222 mSelStart = mSelStart + tmp;
00223 if( mSelEnd > NUMDAYS || mSelEnd < 0 )
00224 mSelEnd = mSelEnd + tmp;
00225 }
00226 }
00227
00228 startdate = actdate;
00229 daychanged = true;
00230 }
00231
00232 if (daychanged) {
00233 recalculateToday();
00234 }
00235
00236 for(int i = 0; i < NUMDAYS; i++) {
00237
00238
00239 QPtrList<Event> eventlist = mCalendar->events(days[i]);
00240 Event *event;
00241 int numEvents = eventlist.count();
00242
00243 for(event=eventlist.first();event != 0;event=eventlist.next()) {
00244 ushort recurType = event->recurrence()->doesRecur();
00245
00246 if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) ||
00247 (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) {
00248 numEvents--;
00249 }
00250 }
00251 events[i] = numEvents;
00252
00253
00254 #ifndef KORG_NOPLUGINS
00255 QString holiStr = KOCore::self()->holiday(days[i]);
00256 #else
00257 QString holiStr = QString::null;
00258 #endif
00259 if ( (KOCore::self()->calendarSystem()->dayOfTheWeek(days[i]) == KOCore::self()->calendarSystem()->weekDayOfPray()) ||
00260 !holiStr.isEmpty()) {
00261 if (holiStr.isNull()) holiStr = "";
00262 mHolidays[i] = holiStr;
00263
00264 } else {
00265 mHolidays[i] = QString::null;
00266 }
00267 }
00268 }
00269
00270 const QDate& KODayMatrix::getDate(int offset)
00271 {
00272 if (offset < 0 || offset > NUMDAYS-1) {
00273 kdDebug() << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl;
00274 return days[0];
00275 }
00276 return days[offset];
00277 }
00278
00279 QString KODayMatrix::getHolidayLabel(int offset)
00280 {
00281 if (offset < 0 || offset > NUMDAYS-1) {
00282 kdDebug() << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl;
00283 return 0;
00284 }
00285 return mHolidays[offset];
00286 }
00287
00288 int KODayMatrix::getDayIndexFrom(int x, int y)
00289 {
00290 return 7*(y/daysize.height()) + (QApplication::reverseLayout() ?
00291 6 - x/daysize.width() : x/daysize.width());
00292 }
00293
00294
00295
00296
00297
00298 void KODayMatrix::mousePressEvent (QMouseEvent* e)
00299 {
00300 mSelStart = getDayIndexFrom(e->x(), e->y());
00301 if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
00302 mSelInit = mSelStart;
00303 }
00304
00305 void KODayMatrix::mouseReleaseEvent (QMouseEvent* e)
00306 {
00307 int tmp = getDayIndexFrom(e->x(), e->y());
00308 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00309
00310 if (mSelInit > tmp) {
00311 mSelEnd = mSelInit;
00312 if (tmp != mSelStart) {
00313 mSelStart = tmp;
00314 repaint();
00315 }
00316 } else {
00317 mSelStart = mSelInit;
00318
00319
00320 if (tmp != mSelEnd) {
00321 mSelEnd = tmp;
00322 repaint();
00323 }
00324 }
00325
00326 DateList daylist;
00327 for (int i = mSelStart; i <= mSelEnd; i++) {
00328 daylist.append(days[i]);
00329 }
00330 emit selected((const DateList)daylist);
00331 }
00332
00333 void KODayMatrix::mouseMoveEvent (QMouseEvent* e)
00334 {
00335 int tmp = getDayIndexFrom(e->x(), e->y());
00336 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
00337
00338 if (mSelInit > tmp) {
00339 mSelEnd = mSelInit;
00340 if (tmp != mSelStart) {
00341 mSelStart = tmp;
00342 repaint();
00343 }
00344 } else {
00345 mSelStart = mSelInit;
00346
00347
00348 if (tmp != mSelEnd) {
00349 mSelEnd = tmp;
00350 repaint();
00351 }
00352 }
00353 }
00354
00355
00356
00357
00358
00359 void KODayMatrix::dragEnterEvent(QDragEnterEvent *e)
00360 {
00361 #ifndef KORG_NODND
00362 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00363 e->ignore();
00364 return;
00365 }
00366
00367
00368
00369
00370
00371 #endif
00372 }
00373
00374 void KODayMatrix::dragMoveEvent(QDragMoveEvent *e)
00375 {
00376 #ifndef KORG_NODND
00377 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00378 e->ignore();
00379 return;
00380 }
00381
00382 e->accept();
00383 #endif
00384 }
00385
00386 void KODayMatrix::dragLeaveEvent(QDragLeaveEvent *)
00387 {
00388 #ifndef KORG_NODND
00389
00390
00391 #endif
00392 }
00393
00394 void KODayMatrix::dropEvent(QDropEvent *e)
00395 {
00396 #ifndef KORG_NODND
00397
00398
00399 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
00400 e->ignore();
00401 return;
00402 }
00403
00404 DndFactory factory( mCalendar );
00405 Event *event = factory.createDrop(e);
00406
00407 if (event) {
00408 e->acceptAction();
00409
00410 Event *existingEvent = mCalendar->event(event->uid());
00411
00412 if(existingEvent) {
00413
00414 event->recreate();
00415
00416
00417
00418
00419
00420
00421
00422 }
00423
00424
00425 QDateTime start = event->dtStart();
00426 QDateTime end = event->dtEnd();
00427 int duration = start.daysTo(end);
00428 int idx = getDayIndexFrom(e->pos().x(), e->pos().y());
00429
00430 start.setDate(days[idx]);
00431 end.setDate(days[idx].addDays(duration));
00432
00433 event->setDtStart(start);
00434 event->setDtEnd(end);
00435 mCalendar->addEvent(event);
00436
00437 emit eventDropped(event);
00438 } else {
00439
00440 e->ignore();
00441 }
00442 #endif
00443 }
00444
00445
00446
00447
00448
00449 void KODayMatrix::paintEvent(QPaintEvent * pevent)
00450 {
00451
00452
00453 QPainter p(this);
00454
00455 QRect sz = frameRect();
00456 int dheight = daysize.height();
00457 int dwidth = daysize.width();
00458 int row,col;
00459 int selw, selh;
00460 bool isRTL = QApplication::reverseLayout();
00461
00462
00463 p.fillRect(pevent->rect(), mDefaultBackColor);
00464 p.setPen(mDefaultTextColor);
00465 p.drawRect(0, 0, sz.width()+1, sz.height()+1);
00466
00467
00468 if (mSelStart != NOSELECTION) {
00469
00470 row = mSelStart/7;
00471 col = mSelStart -row*7;
00472 QColor selcol = KOPrefs::instance()->mHighlightColor;
00473
00474 if (row == mSelEnd/7) {
00475
00476 p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
00477 row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
00478 } else {
00479
00480 p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
00481 dheight, selcol);
00482
00483 selh = mSelEnd/7-row;
00484 if (selh > 1) {
00485 p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
00486 }
00487
00488 selw = mSelEnd-7*(mSelEnd/7)+1;
00489 p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight,
00490 selw*dwidth, dheight, selcol);
00491 }
00492 }
00493
00494
00495 QColor actcol = mDefaultTextColorShaded;
00496 p.setPen(actcol);
00497 QPen tmppen;
00498 for(int i = 0; i < NUMDAYS; i++) {
00499 row = i/7;
00500 col = isRTL ? 6-(i-row*7) : i-row*7;
00501
00502
00503 if ( KOCore::self()->calendarSystem()->day( days[i] ) == 1) {
00504 if (actcol == mDefaultTextColorShaded) {
00505 actcol = mDefaultTextColor;
00506 } else {
00507 actcol = mDefaultTextColorShaded;
00508 }
00509 p.setPen(actcol);
00510 }
00511
00512
00513 if (i == mSelEnd+1) {
00514 p.setPen(actcol);
00515 }
00516
00517
00518 if (today == i) {
00519 tmppen = p.pen();
00520 QPen mTodayPen(p.pen());
00521
00522 mTodayPen.setWidth(mTodayMarginWidth);
00523
00524 if (!mHolidays[i].isNull()) {
00525 if (actcol == mDefaultTextColor) {
00526 mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
00527 } else {
00528 mTodayPen.setColor(mHolidayColorShaded);
00529 }
00530 }
00531
00532 if (i >= mSelStart && i <= mSelEnd) {
00533 QColor grey("grey");
00534 mTodayPen.setColor(grey);
00535 }
00536 p.setPen(mTodayPen);
00537 p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
00538 p.setPen(tmppen);
00539 }
00540
00541
00542 if (events[i] > 0) {
00543 QFont myFont = font();
00544 myFont.setBold(true);
00545 p.setFont(myFont);
00546 }
00547
00548
00549 if (!mHolidays[i].isNull()) {
00550 if (actcol == mDefaultTextColor) {
00551 p.setPen(KOPrefs::instance()->mHolidayColor);
00552 } else {
00553 p.setPen(mHolidayColorShaded);
00554 }
00555 }
00556
00557
00558
00559 if (i >= mSelStart && i <= mSelEnd) {
00560 p.setPen(mSelectedDaysColor);
00561 }
00562
00563 p.drawText(col*dwidth, row*dheight, dwidth, dheight,
00564 Qt::AlignHCenter | Qt::AlignVCenter, daylbls[i]);
00565
00566
00567 if (!mHolidays[i].isNull()) {
00568 p.setPen(actcol);
00569 }
00570
00571 if (events[i] > 0) {
00572 QFont myFont = font();
00573 myFont.setBold(false);
00574 p.setFont(myFont);
00575 }
00576 }
00577 }
00578
00579
00580
00581
00582
00583 void KODayMatrix::resizeEvent(QResizeEvent *)
00584 {
00585 QRect sz = frameRect();
00586 daysize.setHeight(sz.height()*7 / NUMDAYS);
00587 daysize.setWidth(sz.width() / 7);
00588 }