1/* -*- C++ -*-
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
4 (C) 1998-2001 Mirko Boehm (mirko@kde.org)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/////////////////// KDateTable widget class //////////////////////
22//
23// Copyright (C) 1997 Tim D. Gilman
24// (C) 1998-2001 Mirko Boehm
25// Written using Qt (http://www.troll.no) for the
26// KDE project (http://www.kde.org)
27//
28// This is a support class for the KDatePicker class. It just
29// draws the calendar table without titles, but could theoretically
30// be used as a standalone.
31//
32// When a date is selected by the user, it emits a signal:
33// dateSelected(QDate)
34
35#include "kdatetable.h"
36#include "kdatetable_p.h"
37
38#include <kdeversion.h>
39#include <kconfig.h>
40#include <kcolorscheme.h>
41#include <kglobal.h>
42#include <kglobalsettings.h>
43#include <klocale.h>
44#include <kdebug.h>
45#include <knotification.h>
46#include <kcalendarsystem.h>
47#include <kshortcut.h>
48#include <kstandardshortcut.h>
49#include "kdatepicker.h"
50#include "kmenu.h"
51#include "kactioncollection.h"
52#include "kaction.h"
53
54#include <QDate>
55#include <QCharRef>
56#include <QPen>
57#include <QPainter>
58#include <QDialog>
59#include <QActionEvent>
60#include <QHash>
61#include <QApplication>
62#include <QToolTip>
63
64#include <assert.h>
65
66#include <cmath>
67
68#include "kptdebug.h"
69
70namespace KPlato
71{
72
73Frame::Frame( QWidget *parent )
74 : QFrame( parent )
75{
76 setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
77 setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
78 setLineWidth(1);
79}
80
81void Frame::updateFocus(QFocusEvent *e)
82{
83 if ( e->type() == QEvent::FocusIn ) {
84 setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
85 } else {
86 setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
87 }
88 update();
89}
90
91void Frame::paintEvent(QPaintEvent *e)
92{
93 Q_UNUSED(e);
94 //kDebug(planDbg())<<e;
95 QPainter paint(this);
96 drawFrame(&paint);
97}
98
99void Frame::drawFrame(QPainter *p)
100{
101 QPoint p1, p2;
102 QStyleOptionFrame opt;
103 opt.init(this);
104 if ( hasFocus() ) {
105 opt.state |= QStyle::State_HasFocus;
106 }
107 int frameShape = frameStyle() & QFrame::Shape_Mask;
108 int frameShadow = frameStyle() & QFrame::Shadow_Mask;
109
110 int lw = 0;
111 int mlw = 0;
112 opt.rect = frameRect();
113 switch (frameShape) {
114 case QFrame::Box:
115 case QFrame::HLine:
116 case QFrame::VLine:
117 case QFrame::StyledPanel:
118 lw = lineWidth();
119 mlw = midLineWidth();
120 break;
121 default:
122 // most frame styles do not handle customized line and midline widths
123 // (see updateFrameWidth()).
124 lw = frameWidth();
125 break;
126 }
127 opt.lineWidth = lw;
128 opt.midLineWidth = mlw;
129 if (frameShadow == Sunken)
130 opt.state |= QStyle::State_Sunken;
131 else if (frameShadow == Raised)
132 opt.state |= QStyle::State_Raised;
133
134 switch (frameShape) {
135 case Box:
136 if (frameShadow == Plain)
137 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
138 else
139 qDrawShadeRect(p, opt.rect, opt.palette, frameShadow == Sunken, lw, mlw);
140 break;
141
142
143 case StyledPanel:
144 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
145 break;
146
147 case Panel:
148 if (frameShadow == Plain)
149 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
150 else
151 qDrawShadePanel(p, opt.rect, opt.palette, frameShadow == Sunken, lw);
152 break;
153
154 case WinPanel:
155 if (frameShadow == Plain)
156 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
157 else
158 qDrawWinPanel(p, opt.rect, opt.palette, frameShadow == Sunken);
159 break;
160 case HLine:
161 case VLine:
162 if (frameShape == HLine) {
163 p1 = QPoint(opt.rect.x(), opt.rect.height() / 2);
164 p2 = QPoint(opt.rect.x() + opt.rect.width(), p1.y());
165 } else {
166 p1 = QPoint(opt.rect.x()+opt.rect.width() / 2, 0);
167 p2 = QPoint(p1.x(), opt.rect.height());
168 }
169 if (frameShadow == Plain) {
170 QPen oldPen = p->pen();
171 p->setPen(QPen(opt.palette.foreground().color(), lw));
172 p->drawLine(p1, p2);
173 p->setPen(oldPen);
174 } else {
175 qDrawShadeLine(p, p1, p2, opt.palette, frameShadow == Sunken, lw, mlw);
176 }
177 break;
178 }
179}
180
181
182class KDateTable::KDateTablePrivate
183{
184public:
185 KDateTablePrivate(KDateTable *q): q(q)
186 {
187 popupMenuEnabled=false;
188 m_selectionmode = KDateTable::SingleSelection;
189 m_paintweeknumbers = false;
190 m_model = 0;
191 m_grid = false;
192 }
193
194 ~KDateTablePrivate()
195 {
196 foreach( KDateTableDateDelegate *delegate, customPaintingModes ) {
197 delete delegate;
198 }
199 }
200
201 void nextMonth();
202 void previousMonth();
203 void beginningOfMonth();
204 void endOfMonth();
205 void beginningOfWeek();
206 void endOfWeek();
207
208 KDateTable *q;
209
210 /**
211 * The font size of the displayed text.
212 */
213 int fontsize;
214 /**
215 * The currently selected date.
216 */
217 QDate mDate;
218 /**
219 * The day of the first day in the month [1..7].
220 */
221 int firstday;
222 /**
223 * The number of days in the current month.
224 */
225 int numdays;
226 /**
227 * The number of days in the previous month.
228 */
229 int numDaysPrevMonth;
230 /**
231 * Save the size of the largest used cell content.
232 */
233 QRectF maxCell;
234
235 bool popupMenuEnabled;
236
237 //----->
238 QHash <QString, KDateTableDateDelegate*> customPaintingModes;
239
240 KDateTableDataModel *m_model;
241
242 KDateTableDateDelegate *m_dateDelegate;
243 KDateTableWeekDayDelegate *m_weekDayDelegate;
244 KDateTableWeekNumberDelegate *m_weekNumberDelegate;
245
246 StyleOptionViewItem m_styleOptionDate;
247 StyleOptionHeader m_styleOptionWeekDay;
248 StyleOptionHeader m_styleOptionWeekNumber;
249
250 QList<QDate> m_selectedDates;
251 SelectionMode m_selectionmode;
252
253 bool m_paintweeknumbers;
254 bool m_grid;
255};
256
257class KPopupFrame::KPopupFramePrivate
258{
259public:
260 KPopupFramePrivate(KPopupFrame *q):
261 q(q),
262 result(0), // rejected
263 main(0) {}
264
265 KPopupFrame *q;
266
267 /**
268 * The result. It is returned from exec() when the popup window closes.
269 */
270 int result;
271 /**
272 * The only subwidget that uses the whole dialog window.
273 */
274 QWidget *main;
275};
276
277
278KDateValidator::KDateValidator(QWidget* parent)
279 : QValidator(parent)
280{
281}
282
283QValidator::State
284KDateValidator::validate(QString& text, int&) const
285{
286 QDate temp;
287 // ----- everything is tested in date():
288 return date(text, temp);
289}
290
291QValidator::State
292KDateValidator::date(const QString& text, QDate& d) const
293{
294 QDate tmp = KGlobal::locale()->readDate(text);
295 if (!tmp.isNull())
296 {
297 d = tmp;
298 return Acceptable;
299 } else
300 return QValidator::Intermediate;
301}
302
303void
304KDateValidator::fixup( QString& ) const
305{
306
307}
308
309KDateTable::KDateTable(const QDate& date_, QWidget* parent)
310 : QWidget(parent), d(new KDateTablePrivate(this))
311{
312 setFontSize(10);
313 setFocusPolicy(Qt::StrongFocus);
314 QPalette palette;
315 palette.setColor(backgroundRole(), KColorScheme(QPalette::Active, KColorScheme::View).background().color() );
316
317 setPalette(palette);
318
319 if(!date_.isValid())
320 {
321 kDebug(planDbg()) << "KDateTable ctor: WARNING: Given date is invalid, using current date.";
322 setDate(QDate::currentDate()); // this initializes firstday, numdays, numDaysPrevMonth
323 }
324 else
325 setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
326 initAccels();
327
328 init();
329}
330
331KDateTable::KDateTable(QWidget *parent)
332 : QWidget(parent), d(new KDateTablePrivate(this))
333{
334 setFontSize(10);
335 setFocusPolicy(Qt::StrongFocus);
336 QPalette palette;
337 palette.setColor(backgroundRole(), KColorScheme(QPalette::Active, KColorScheme::View).background().color() );
338 setPalette(palette);
339 setDate(QDate::currentDate()); // this initializes firstday, numdays, numDaysPrevMonth
340 initAccels();
341
342 init();
343}
344
345KDateTable::~KDateTable()
346{
347 delete d;
348}
349
350void KDateTable::init()
351{
352 d->m_dateDelegate = new KDateTableDateDelegate( this );
353 d->m_weekDayDelegate = new KDateTableWeekDayDelegate( this );
354 d->m_weekNumberDelegate = new KDateTableWeekNumberDelegate( this );
355
356 d->m_styleOptionDate.initFrom( this );
357 d->m_styleOptionDate.displayAlignment = Qt::AlignCenter;
358
359 d->m_styleOptionWeekDay.initFrom( this );
360 d->m_styleOptionWeekDay.textAlignment = Qt::AlignCenter;
361
362 d->m_styleOptionWeekNumber.initFrom( this );
363 d->m_styleOptionWeekNumber.textAlignment = Qt::AlignCenter;
364
365 //setModel( new KDateTableDataModel( this ) );
366}
367
368void KDateTable::setStyleOptionDate( const StyleOptionViewItem &so )
369{
370 d->m_styleOptionDate = so;
371}
372
373void KDateTable::setStyleOptionWeekDay( const StyleOptionHeader &so )
374{
375 d->m_styleOptionWeekDay = so;
376}
377
378void KDateTable::setStyleOptionWeekNumber( const StyleOptionHeader &so )
379{
380 d->m_styleOptionWeekNumber = so;
381}
382
383void KDateTable::slotReset()
384{
385 update();
386}
387
388void KDateTable::slotDataChanged( const QDate &start, const QDate &end )
389{
390 Q_UNUSED(start);
391 Q_UNUSED(end);
392 update();
393}
394
395void KDateTable::setModel( KDateTableDataModel *model )
396{
397 if ( d->m_model )
398 {
399 disconnect( d->m_model, SIGNAL( reset() ), this, SLOT( slotReset() ) );
400 }
401 d->m_model = model;
402 if ( d->m_model )
403 {
404 connect( d->m_model, SIGNAL( reset() ), this, SLOT( slotReset() ) );
405 }
406 update();
407}
408
409KDateTableDataModel *KDateTable::model() const
410{
411 return d->m_model;
412}
413
414void KDateTable::setDateDelegate( KDateTableDateDelegate *delegate )
415{
416 delete d->m_dateDelegate;
417 d->m_dateDelegate = delegate;
418}
419
420void KDateTable::setDateDelegate( const QDate &date, KDateTableDateDelegate *delegate )
421{
422 delete d->customPaintingModes.take( date.toString() );
423 d->customPaintingModes[ date.toString() ] = delegate;
424}
425
426void KDateTable::setWeekDayDelegate( KDateTableWeekDayDelegate *delegate )
427{
428 delete d->m_weekDayDelegate;
429 d->m_weekDayDelegate = delegate;
430}
431
432void KDateTable::setWeekNumberDelegate( KDateTableWeekNumberDelegate *delegate )
433{
434 delete d->m_weekNumberDelegate;
435 d->m_weekNumberDelegate = delegate;
436}
437
438void KDateTable::setWeekNumbersEnabled( bool enable )
439{
440 d->m_paintweeknumbers = enable;
441}
442
443void KDateTable::setGridEnabled( bool enable )
444{
445 d->m_grid = enable;
446}
447
448void KDateTable::initAccels()
449{
450 KActionCollection* localCollection = new KActionCollection(this);
451 localCollection->addAssociatedWidget(this);
452
453 QAction* next = localCollection->addAction(QLatin1String("next"));
454 next->setShortcuts(KStandardShortcut::next());
455 connect(next, SIGNAL(triggered(bool)), SLOT(nextMonth()));
456
457 QAction* prior = localCollection->addAction(QLatin1String("prior"));
458 prior->setShortcuts(KStandardShortcut::prior());
459 connect(prior, SIGNAL(triggered(bool)), SLOT(previousMonth()));
460
461 QAction* beginMonth = localCollection->addAction(QLatin1String("beginMonth"));
462 beginMonth->setShortcuts(KStandardShortcut::home());
463 connect(beginMonth, SIGNAL(triggered(bool)), SLOT(beginningOfMonth()));
464
465 QAction* endMonth = localCollection->addAction(QLatin1String("endMonth"));
466 endMonth->setShortcuts(KStandardShortcut::end());
467 connect(endMonth, SIGNAL(triggered(bool)), SLOT(endOfMonth()));
468
469 QAction* beginWeek = localCollection->addAction(QLatin1String("beginWeek"));
470 beginWeek->setShortcuts(KStandardShortcut::beginningOfLine());
471 connect(beginWeek, SIGNAL(triggered(bool)), SLOT(beginningOfWeek()));
472
473 QAction* endWeek = localCollection->addAction("endWeek");
474 endWeek->setShortcuts(KStandardShortcut::endOfLine());
475 connect(endWeek, SIGNAL(triggered(bool)), SLOT(endOfWeek()));
476
477 localCollection->readSettings();
478}
479
480int KDateTable::posFromDate( const QDate &dt )
481{
482 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
483
484 // ISO Week numbering always uses Monday as first day of week
485 const int firstWeekDay = (KGlobal::locale()->weekNumberSystem() == KLocale::IsoWeekNumber)
486 ? Qt::Monday
487 : KGlobal::locale()->weekStartDay();
488
489 int pos = calendar->day( dt );
490 int offset = (d->firstday - firstWeekDay + 7) % 7;
491 // make sure at least one day of the previous month is visible.
492 // adjust this <1 if more days should be forced visible:
493 if ( offset < 1 ) offset += 7;
494 return pos + offset;
495}
496
497QDate KDateTable::dateFromPos( int pos )
498{
499 QDate pCellDate;
500 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
501 calendar->setDate(pCellDate, calendar->year(d->mDate), calendar->month(d->mDate), 1);
502
503 // ISO Week numbering always uses Monday as first day of week
504 const int firstWeekDay = (KGlobal::locale()->weekNumberSystem() == KLocale::IsoWeekNumber)
505 ? Qt::Monday
506 : KGlobal::locale()->weekStartDay();
507
508 int offset = (d->firstday - firstWeekDay + 7) % 7;
509 // make sure at least one day of the previous month is visible.
510 // adjust this <1 if more days should be forced visible:
511 if ( offset < 1 ) offset += 7;
512 pCellDate = calendar->addDays( pCellDate, pos - offset );
513 return pCellDate;
514}
515
516bool KDateTable::event( QEvent *event )
517{
518 if ( event->type() == QEvent::ToolTip ) {
519 //kDebug(planDbg())<<"Tooltip";
520 QHelpEvent *e = static_cast<QHelpEvent*>( event );
521
522 double cellWidth = width() / ( d->m_paintweeknumbers ? 8.0 : 7.0 );
523 double cellHeight = height() / 7.0;
524 int column = (int)floor(e->pos().x() / cellWidth);
525 int row = (int)floor(e->pos().y() / cellHeight);
526 QString text;
527 if ( row == 0 && column == 0 && d->m_paintweeknumbers ) {
528 // corner
529 } else if ( row == 0 ) { // we are drawing the headline (weekdays)
530 int col = d->m_paintweeknumbers ? column - 1 : column;
531
532 // ISO Week numbering always uses Monday as first day of week
533 const int firstWeekDay = (KGlobal::locale()->weekNumberSystem() == KLocale::IsoWeekNumber)
534 ? Qt::Monday
535 : KGlobal::locale()->weekStartDay();
536
537 int day = ( col+firstWeekDay < 8 ) ? col+firstWeekDay : col+firstWeekDay-7;
538 if ( d->m_weekDayDelegate )
539 {
540 text = d->m_weekDayDelegate->data( day, Qt::ToolTipRole, d->m_model ).toString();
541 }
542 }
543 else if ( d->m_paintweeknumbers && column == 0 )
544 {
545 int pos=7*(row-1);
546 QDate pCellDate = dateFromPos( pos );
547 if ( d->m_weekNumberDelegate )
548 {
549 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
550#if KDE_IS_VERSION(4,7,0)
551 const int weekNumber = calendar->week( pCellDate );
552#else
553 const int weekNumber = calendar->weekNumber( pCellDate );
554#endif
555 text = d->m_weekNumberDelegate->data( weekNumber, Qt::ToolTipRole, d->m_model ).toString();
556 }
557 }
558 else
559 {
560 // draw the dates
561 int col = d->m_paintweeknumbers ? column - 1 : column;
562 int pos=7*(row-1)+col;
563 QDate pCellDate = dateFromPos( pos );
564 if ( d->m_dateDelegate ) {
565 text = d->m_dateDelegate->data( pCellDate, Qt::ToolTipRole, d->m_model ).toString();
566 }
567 }
568 //kDebug(planDbg())<<row<<column<<text;
569 if ( text.isEmpty() ) {
570 QToolTip::hideText();
571 } else {
572 QToolTip::showText( e->globalPos(), text );
573 }
574 e->accept();
575 return true;
576 }
577 return QWidget::event( event );
578}
579
580void KDateTable::paintEvent(QPaintEvent *e)
581{
582 QPainter p(this);
583 const QRect &rectToUpdate = e->rect();
584 double cellWidth = width() / ( d->m_paintweeknumbers ? 8.0 : 7.0 );
585 double cellHeight = height() / 7.0;
586 int leftCol = (int)floor(rectToUpdate.left() / cellWidth);
587 int topRow = (int)floor(rectToUpdate.top() / cellHeight);
588 int rightCol = (int)ceil(rectToUpdate.right() / cellWidth);
589 int bottomRow = (int)ceil(rectToUpdate.bottom() / cellHeight);
590 bottomRow = qMin(bottomRow, 6);
591 rightCol = qMin(rightCol, ( d->m_paintweeknumbers ? 7 : 6 ) );
592 p.translate(leftCol * cellWidth, topRow * cellHeight);
593 for (int i = leftCol; i <= rightCol; ++i) {
594 for (int j = topRow; j <= bottomRow; ++j) {
595 paintCell(&p, j, i);
596 p.translate(0, cellHeight);
597 }
598
599 p.translate(cellWidth, 0);
600 p.translate(0, -cellHeight * (bottomRow - topRow + 1));
601 }
602}
603
604void
605KDateTable::paintCell(QPainter *painter, int row, int column)
606{
607 //kDebug(planDbg());
608
609 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
610
611 QSizeF size;
612 QString text;
613 QPen pen;
614 double w = width() / ( d->m_paintweeknumbers ? 8.0 : 7.0 );
615 double h = height() / 7.0;
616 w -= 1;
617 h -= 1;
618 QRectF rect( 0, 0, w, h );
619 if ( row == 0 && column == 0 && d->m_paintweeknumbers )
620 {
621 // paint something in the corner??
622/* painter->setPen(palette().color(QPalette::Text));
623 painter->drawRect( rect );*/
624 return;
625 }
626 if ( row == 0 )
627 { // we are drawing the headline (weekdays)
628 d->m_styleOptionWeekDay.rectF = rect;
629 d->m_styleOptionWeekDay.state = QStyle::State_None;
630
631 int col = d->m_paintweeknumbers ? column - 1 : column;
632
633 // ISO Week numbering always uses Monday as first day of week
634 const int firstWeekDay = (KGlobal::locale()->weekNumberSystem() == KLocale::IsoWeekNumber)
635 ? Qt::Monday
636 : KGlobal::locale()->weekStartDay();
637
638 int day = ( col+firstWeekDay < 8 ) ? col+firstWeekDay : col+firstWeekDay-7;
639 if ( d->m_weekDayDelegate )
640 {
641 size = d->m_weekDayDelegate->paint( painter, d->m_styleOptionWeekDay, day, d->m_model ).size();
642 }
643 }
644 else if ( d->m_paintweeknumbers && column == 0 )
645 {
646 d->m_styleOptionWeekNumber.rectF = rect;
647 d->m_styleOptionWeekNumber.state = QStyle::State_None;
648
649 int pos=7*(row-1);
650 QDate pCellDate = dateFromPos( pos );
651 if ( d->m_weekNumberDelegate )
652 {
653#if KDE_IS_VERSION(4,7,0)
654 const int weekNumber = calendar->week( pCellDate );
655#else
656 const int weekNumber = calendar->weekNumber( pCellDate );
657#endif
658 size = d->m_weekNumberDelegate->paint( painter, d->m_styleOptionWeekNumber, weekNumber, d->m_model ).size();
659 }
660 }
661 else
662 {
663 // draw the dates
664 int col = d->m_paintweeknumbers ? column - 1 : column;
665 int pos=7*(row-1)+col;
666
667 if ( d->m_grid )
668 {
669 painter->save();
670 QPen pen( "lightgrey" );
671 pen.setWidthF( 0.5 );
672 painter->setPen( pen );
673 double pw = painter->pen().width();
674 if ( col > 0 )
675 {
676 painter->drawLine( rect.topLeft(), rect.bottomLeft() );
677 }
678 if ( row > 1 )
679 {
680 painter->drawLine( rect.topLeft(), rect.topRight() );
681 }
682 rect = rect.adjusted(pw, pw, 0, 0 );
683 painter->restore();
684 //kDebug(planDbg())<<d->m_grid<<" "<<pw<<" "<<rect;
685 }
686
687 d->m_styleOptionDate.rectF = rect;
688 d->m_styleOptionDate.state = QStyle::State_None;
689
690
691 QDate pCellDate = dateFromPos( pos );
692 if( calendar->month(pCellDate) == calendar->month(d->mDate) )
693 {
694 d->m_styleOptionDate.state |= QStyle::State_Active;
695 }
696 if ( d->m_selectedDates.contains( pCellDate ) )
697 {
698 d->m_styleOptionDate.state |= QStyle::State_Selected;
699 }
700 if ( isEnabled() )
701 {
702 d->m_styleOptionDate.state |= QStyle::State_Enabled;
703 }
704 if ( pCellDate == d->mDate )
705 {
706 d->m_styleOptionDate.state |= QStyle::State_Active;
707 if ( d->m_selectionmode != SingleSelection && hasFocus() )
708 {
709 d->m_styleOptionDate.state |= QStyle::State_HasFocus;
710 }
711 }
712 KDateTableDateDelegate *del = d->customPaintingModes.value( pCellDate.toString() );
713 if ( del == 0 ) {
714 del = d->m_dateDelegate;
715 }
716 if ( del ) {
717 //kDebug(planDbg())<<del;
718 size = del->paint( painter, d->m_styleOptionDate, pCellDate, d->m_model ).size();
719 } else kWarning()<<"No delegate!";
720 }
721 if(size.width() > d->maxCell.width()) d->maxCell.setWidth(size.width());
722 if(size.height() > d->maxCell.height()) d->maxCell.setHeight(size.height());
723}
724
725void KDateTable::KDateTablePrivate::nextMonth()
726{
727 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
728 q->setDate(calendar->addMonths( mDate, 1 ));
729}
730
731void KDateTable::KDateTablePrivate::previousMonth()
732{
733 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
734 q->setDate(calendar->addMonths( mDate, -1 ));
735}
736
737void KDateTable::KDateTablePrivate::beginningOfMonth()
738{
739 q->setDate(mDate.addDays(1 - mDate.day()));
740}
741
742void KDateTable::KDateTablePrivate::endOfMonth()
743{
744 q->setDate(mDate.addDays(mDate.daysInMonth() - mDate.day()));
745}
746
747void KDateTable::KDateTablePrivate::beginningOfWeek()
748{
749 q->setDate(mDate.addDays(1 - mDate.dayOfWeek()));
750}
751
752void KDateTable::KDateTablePrivate::endOfWeek()
753{
754 q->setDate(mDate.addDays(7 - mDate.dayOfWeek()));
755}
756
757void
758KDateTable::keyPressEvent( QKeyEvent *e )
759{
760 QDate cd = d->mDate;
761 switch( e->key() ) {
762 case Qt::Key_Up:
763 setDate(d->mDate.addDays(-7));
764 break;
765 case Qt::Key_Down:
766 setDate(d->mDate.addDays(7));
767 break;
768 case Qt::Key_Left:
769 setDate(d->mDate.addDays(-1));
770 break;
771 case Qt::Key_Right:
772 setDate(d->mDate.addDays(1));
773 break;
774 case Qt::Key_Minus:
775 setDate(d->mDate.addDays(-1));
776 break;
777 case Qt::Key_Plus:
778 setDate(d->mDate.addDays(1));
779 break;
780 case Qt::Key_N:
781 setDate(QDate::currentDate());
782 break;
783 case Qt::Key_Return:
784 case Qt::Key_Enter:
785 emit tableClicked();
786 break;
787 }
788
789 switch( e->key() ) {
790 case Qt::Key_Down:
791 case Qt::Key_Up:
792 case Qt::Key_Left:
793 case Qt::Key_Right:
794 case Qt::Key_Minus:
795 case Qt::Key_Plus: {
796 if ( d->m_selectionmode == ExtendedSelection ) {
797 if ( e->modifiers() & Qt::ShiftModifier ) {
798 int inc = cd > d->mDate ? 1 : -1;
799 for ( QDate dd = d->mDate; dd != cd; dd = dd.addDays( inc ) ) {
800 if ( ! d->m_selectedDates.contains( dd ) ) {
801 d->m_selectedDates << dd;
802 }
803 }
804 } else if ( e->modifiers() & Qt::ControlModifier ) {
805 // keep selection, just move on
806 } else {
807 d->m_selectedDates.clear();
808 }
809 }
810 break;}
811 case Qt::Key_Space:
812 case Qt::Key_Select:
813 if ( d->m_selectionmode == ExtendedSelection ) {
814 if ( e->modifiers() & Qt::ControlModifier ) {
815 if ( d->m_selectedDates.contains( d->mDate ) ) {
816 d->m_selectedDates.removeAt( d->m_selectedDates.indexOf( d->mDate ) );
817 } else {
818 d->m_selectedDates << d->mDate;
819 }
820 } else if ( ! d->m_selectedDates.contains( d->mDate ) ) {
821 d->m_selectedDates << d->mDate;
822 }
823 update();
824 }
825 break;
826 case Qt::Key_Menu:
827 if ( d->popupMenuEnabled )
828 {
829 KMenu *menu = new KMenu();
830 if ( d->m_selectionmode == ExtendedSelection ) {
831 emit aboutToShowContextMenu( menu, d->m_selectedDates );
832 } else {
833 menu->addTitle( KGlobal::locale()->formatDate(d->mDate) );
834 emit aboutToShowContextMenu( menu, d->mDate );
835 }
836 if ( menu->isEmpty() ) {
837 delete menu;
838 } else {
839 int p = posFromDate( d->mDate ) - 1;
840 int col = p % 7;
841 int row = p / 7;
842 QPoint pos = geometry().topLeft();
843 QSize size = geometry().size();
844 int sx = size.width() / 8;
845 int sy = size.height() / 7;
846 pos = QPoint( pos.x() + sx + sx / 2 + sx * col, pos.y() + sy + sy * row );
847 kDebug(planDbg())<<pos<<p<<col<<row;
848 menu->popup(mapToGlobal(pos));
849 }
850 }
851 break;
852 case Qt::Key_Control:
853 case Qt::Key_Alt:
854 case Qt::Key_Meta:
855 case Qt::Key_Shift:
856 // Don't beep for modifiers
857 break;
858 default:
859 if (!e->modifiers()) { // hm
860 KNotification::beep();
861 }
862 }
863}
864
865void
866KDateTable::setFontSize(int size)
867{
868 int count;
869 QFontMetricsF metrics(fontMetrics());
870 QRectF rect;
871 // ----- store rectangles:
872 d->fontsize=size;
873 // ----- find largest day name:
874 d->maxCell.setWidth(0);
875 d->maxCell.setHeight(0);
876 for(count=0; count<7; ++count)
877 {
878 rect=metrics.boundingRect(KGlobal::locale()->calendar()
879 ->weekDayName(count+1, KCalendarSystem::ShortDayName));
880 d->maxCell.setWidth(qMax(d->maxCell.width(), rect.width()));
881 d->maxCell.setHeight(qMax(d->maxCell.height(), rect.height()));
882 }
883 // ----- compare with a real wide number and add some space:
884 rect=metrics.boundingRect(QLatin1String("88"));
885 d->maxCell.setWidth(qMax(d->maxCell.width()+2, rect.width()));
886 d->maxCell.setHeight(qMax(d->maxCell.height()+4, rect.height()));
887}
888
889void
890KDateTable::wheelEvent ( QWheelEvent * e )
891{
892 setDate(d->mDate.addMonths( -(int)(e->delta()/120)) );
893 e->accept();
894}
895
896void
897KDateTable::mousePressEvent(QMouseEvent *e)
898{
899 if(e->type()!=QEvent::MouseButtonPress)
900 { // the KDatePicker only reacts on mouse press events:
901 return;
902 }
903 if(!isEnabled())
904 {
905 KNotification::beep();
906 return;
907 }
908
909 // -----
910 int row, col, pos;
911 QPoint mouseCoord;
912 // -----
913 mouseCoord = e->pos();
914 row=mouseCoord.y() / ( height() / 7 );
915 col=mouseCoord.x() / ( width() / ( d->m_paintweeknumbers ? 8 : 7 ) );
916 //kDebug(planDbg())<<d->maxCell<<", "<<size()<<row<<", "<<col<<", "<<mouseCoord;
917 if(row<1 )
918 { // the user clicked on the frame of the table
919 //kDebug(planDbg())<<"weekday "<<col;
920 return;
921 }
922 if ( col < ( d->m_paintweeknumbers ? 1 : 0 ) )
923 {
924 //kDebug(planDbg())<<"weeknumber "<<row;
925 return;
926 }
927 if ( d->m_paintweeknumbers ) {
928 --col;
929 }
930
931 // Rows and columns are zero indexed. The (row - 1) below is to avoid counting
932 // the row with the days of the week in the calculation.
933
934 // old selected date:
935 // new position and date
936 pos = (7 * (row - 1)) + col;
937 QDate clickedDate = dateFromPos( pos );
938
939 if ( d->m_selectionmode != ExtendedSelection || e->button() != Qt::RightButton || ! d->m_selectedDates.contains( clickedDate ) )
940 {
941 switch ( d->m_selectionmode )
942 {
943 case SingleSelection:
944 break;
945 case ExtendedSelection:
946 //kDebug(planDbg())<<"extended "<<e->modifiers()<<", "<<clickedDate;
947 if ( e->modifiers() & Qt::ShiftModifier )
948 {
949 if ( d->m_selectedDates.isEmpty() )
950 {
951 d->m_selectedDates << clickedDate;
952 }
953 else if ( d->mDate != clickedDate )
954 {
955 QDate dt = d->mDate;
956 int nxt = dt < clickedDate ? 1 : -1;
957 if ( d->m_selectedDates.contains( clickedDate ) )
958 {
959 d->m_selectedDates.removeAt( d->m_selectedDates.indexOf( clickedDate ) );
960 }
961 while ( dt != clickedDate )
962 {
963 if ( ! d->m_selectedDates.contains( dt ) )
964 {
965 d->m_selectedDates << dt;
966 }
967 dt = dt.addDays( nxt );
968 }
969 d->m_selectedDates << clickedDate;
970 }
971 else
972 {
973 break; // selection not changed
974 }
975 }
976 else if ( e->modifiers() & Qt::ControlModifier )
977 {
978 if ( d->m_selectedDates.contains( clickedDate ) )
979 {
980 d->m_selectedDates.removeAt( d->m_selectedDates.indexOf( clickedDate ) );
981 }
982 else
983 {
984 d->m_selectedDates << clickedDate;
985 }
986 }
987 else
988 {
989 d->m_selectedDates.clear();
990 d->m_selectedDates << clickedDate;
991 }
992 emit selectionChanged( d->m_selectedDates );
993 break;
994 default: break;
995 }
996 // set the new date. If it is in the previous or next month, the month will
997 // automatically be changed, no need to do that manually...
998 setDate( clickedDate );
999
1000 // This could be optimized to only call update over the regions
1001 // of old and new cell, but 99% of times there is also a call to
1002 // setDate that already calls update() so no need to optimize that
1003 // much here
1004 update();
1005 }
1006 emit tableClicked();
1007
1008 if ( e->button() == Qt::RightButton && d->popupMenuEnabled )
1009 {
1010 KMenu *menu = new KMenu();
1011 if ( d->m_selectionmode == ExtendedSelection ) {
1012 emit aboutToShowContextMenu( menu, d->m_selectedDates );
1013 } else {
1014 menu->addTitle( KGlobal::locale()->formatDate(clickedDate) );
1015 emit aboutToShowContextMenu( menu, clickedDate );
1016 }
1017 menu->popup(e->globalPos());
1018 }
1019}
1020
1021bool
1022KDateTable::setDate(const QDate& date_)
1023{
1024 bool changed=false;
1025 QDate temp;
1026 // -----
1027 if(!date_.isValid())
1028 {
1029 kDebug(planDbg()) << "KDateTable::setDate: refusing to set invalid date.";
1030 return false;
1031 }
1032 if(d->mDate!=date_)
1033 {
1034 emit(dateChanged(d->mDate, date_));
1035 d->mDate=date_;
1036 emit(dateChanged(d->mDate));
1037 changed=true;
1038 }
1039 if ( d->m_selectionmode == KDateTable::SingleSelection )
1040 {
1041 d->m_selectedDates.clear();
1042 d->m_selectedDates << date_;
1043 emit selectionChanged( d->m_selectedDates );
1044 }
1045 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
1046
1047 calendar->setDate(temp, calendar->year(d->mDate), calendar->month(d->mDate), 1);
1048 //temp.setDate(d->mDate.year(), d->mDate.month(), 1);
1049 //kDebug(planDbg()) << "firstDayInWeek: " << temp.toString();
1050 d->firstday=temp.dayOfWeek();
1051 d->numdays=calendar->daysInMonth(d->mDate);
1052
1053 temp = calendar->addMonths(temp, -1);
1054 d->numDaysPrevMonth=calendar->daysInMonth(temp);
1055 if(changed)
1056 {
1057 update();
1058 }
1059 return true;
1060}
1061
1062const QDate&
1063KDateTable::date() const
1064{
1065 return d->mDate;
1066}
1067
1068// what are those repaintContents() good for? (pfeiffer)
1069void KDateTable::focusInEvent( QFocusEvent *e )
1070{
1071// repaintContents(false);
1072 QWidget::focusInEvent( e );
1073 emit focusChanged( e );
1074}
1075
1076void KDateTable::focusOutEvent( QFocusEvent *e )
1077{
1078// repaintContents(false);
1079 QWidget::focusOutEvent( e );
1080 emit focusChanged( e );
1081}
1082
1083QSize
1084KDateTable::sizeHint() const
1085{
1086 if(d->maxCell.height()>0 && d->maxCell.width()>0)
1087 {
1088 int s = d->m_paintweeknumbers ? 8 : 7;
1089 return QSize(qRound(d->maxCell.width()*s),
1090 (qRound(d->maxCell.height()+2)*7));
1091 } else {
1092 kDebug(planDbg()) << "KDateTable::sizeHint: obscure failure - ";
1093 return QSize(-1, -1);
1094 }
1095}
1096
1097void KDateTable::setPopupMenuEnabled( bool enable )
1098{
1099 d->popupMenuEnabled=enable;
1100}
1101
1102bool KDateTable::popupMenuEnabled() const
1103{
1104 return d->popupMenuEnabled;
1105}
1106
1107void KDateTable::setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor)
1108{
1109 KDateTableCustomDateDelegate *del = new KDateTableCustomDateDelegate();
1110 del->fgColor = fgColor;
1111 del->bgMode = bgMode;
1112 del->bgColor = bgColor;
1113 setDateDelegate( date, del );
1114 update();
1115}
1116
1117void KDateTable::unsetCustomDatePainting( const QDate &date )
1118{
1119 d->customPaintingModes.remove( date.toString() );
1120}
1121
1122void KDateTable::setSelectionMode( SelectionMode mode )
1123{
1124 d->m_selectionmode = mode;
1125}
1126
1127KDateInternalYearSelector::KDateInternalYearSelector
1128(QWidget* parent)
1129 : QLineEdit(parent),
1130 val(new QIntValidator(this)),
1131 result(0)
1132{
1133 QFont font;
1134 // -----
1135 font=KGlobalSettings::generalFont();
1136 setFont(font);
1137 setFrame(false);
1138 // we have to respect the limits of QDate here, I fear:
1139 val->setRange(0, 8000);
1140 setValidator(val);
1141 connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
1142}
1143
1144void KDateInternalYearSelector::focusOutEvent(QFocusEvent*)
1145{
1146 emit(closeMe(1));
1147}
1148
1149void
1150KDateInternalYearSelector::yearEnteredSlot()
1151{
1152 bool ok;
1153 int year;
1154 QDate date;
1155 // ----- check if this is a valid year:
1156 year=text().toInt(&ok);
1157 if(!ok)
1158 {
1159 KNotification::beep();
1160 return;
1161 }
1162 //date.setDate(year, 1, 1);
1163 KGlobal::locale()->calendar()->setDate(date, year, 1, 1);
1164 if(!date.isValid())
1165 {
1166 KNotification::beep();
1167 return;
1168 }
1169 result=year;
1170 emit(closeMe(1));
1171}
1172
1173int
1174KDateInternalYearSelector::getYear()
1175{
1176 return result;
1177}
1178
1179void
1180KDateInternalYearSelector::setYear(int year)
1181{
1182 QString temp;
1183 // -----
1184 temp.setNum(year);
1185 setText(temp);
1186}
1187
1188KPopupFrame::KPopupFrame(QWidget* parent)
1189 : QFrame(parent, Qt::Popup), d(new KPopupFramePrivate(this))
1190{
1191 setFrameStyle(QFrame::Box|QFrame::Raised);
1192 setMidLineWidth(2);
1193}
1194
1195KPopupFrame::~KPopupFrame()
1196{
1197 delete d;
1198}
1199
1200void
1201KPopupFrame::keyPressEvent(QKeyEvent* e)
1202{
1203 if(e->key()==Qt::Key_Escape)
1204 {
1205 d->result=0; // rejected
1206 emit leaveModality();
1207 //qApp->exit_loop();
1208 }
1209}
1210
1211void
1212KPopupFrame::close(int r)
1213{
1214 d->result=r;
1215 emit leaveModality();
1216 //qApp->exit_loop();
1217}
1218
1219void
1220KPopupFrame::setMainWidget(QWidget* m)
1221{
1222 d->main=m;
1223 if(d->main)
1224 {
1225 resize(d->main->width()+2*frameWidth(), d->main->height()+2*frameWidth());
1226 }
1227}
1228
1229void
1230KPopupFrame::resizeEvent(QResizeEvent*)
1231{
1232 if(d->main)
1233 {
1234 d->main->setGeometry(frameWidth(), frameWidth(),
1235 width()-2*frameWidth(), height()-2*frameWidth());
1236 }
1237}
1238
1239void
1240KPopupFrame::popup(const QPoint &pos)
1241{
1242 // Make sure the whole popup is visible.
1243 QRect d = KGlobalSettings::desktopGeometry(pos);
1244
1245 int x = pos.x();
1246 int y = pos.y();
1247 int w = width();
1248 int h = height();
1249 if (x+w > d.x()+d.width())
1250 x = d.width() - w;
1251 if (y+h > d.y()+d.height())
1252 y = d.height() - h;
1253 if (x < d.x())
1254 x = 0;
1255 if (y < d.y())
1256 y = 0;
1257
1258 // Pop the thingy up.
1259 move(x, y);
1260 show();
1261}
1262
1263int
1264KPopupFrame::exec(const QPoint &pos)
1265{
1266 popup(pos);
1267 repaint();
1268 QEventLoop eventLoop;
1269 connect(this, SIGNAL(leaveModality()),
1270 &eventLoop, SLOT(quit()));
1271 eventLoop.exec();
1272
1273 hide();
1274 kDebug(planDbg())<<d->result;
1275 return d->result;
1276}
1277
1278int
1279KPopupFrame::exec(int x, int y)
1280{
1281 return exec(QPoint(x, y));
1282}
1283
1284//-----------------------
1285KDateTableDataModel::KDateTableDataModel( QObject *parent )
1286 : QObject( parent )
1287{
1288}
1289
1290KDateTableDataModel::~KDateTableDataModel()
1291{
1292}
1293
1294QVariant KDateTableDataModel::data( const QDate &date, int role, int dataType ) const
1295{
1296 Q_UNUSED(date);
1297 Q_UNUSED(role);
1298 Q_UNUSED(dataType);
1299 return QVariant();
1300}
1301
1302QVariant KDateTableDataModel::weekDayData( int day, int role ) const
1303{
1304 Q_UNUSED(day);
1305 Q_UNUSED(role);
1306 return QVariant();
1307}
1308
1309QVariant KDateTableDataModel::weekNumberData( int week, int role ) const
1310{
1311 Q_UNUSED(week);
1312 Q_UNUSED(role);
1313 return QVariant();
1314}
1315
1316//-------------
1317KDateTableDateDelegate::KDateTableDateDelegate( QObject *parent )
1318 : QObject( parent )
1319{
1320}
1321
1322QVariant KDateTableDateDelegate::data( const QDate &date, int role, KDateTableDataModel *model )
1323{
1324 //kDebug(planDbg())<<date<<role<<model;
1325 if ( model == 0 ) {
1326 return QVariant();
1327 }
1328 return model->data( date, role );
1329}
1330
1331QRectF KDateTableDateDelegate::paint( QPainter *painter, const StyleOptionViewItem &option, const QDate &date, KDateTableDataModel *model )
1332{
1333 //kDebug(planDbg())<<date;
1334 painter->save();
1335 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
1336 QRectF r;
1337
1338 QPalette palette = option.palette;
1339 if ( option.state & QStyle::State_Enabled && option.state & QStyle::State_Active ) {
1340 palette.setCurrentColorGroup( QPalette::Active );
1341 } else {
1342 palette.setCurrentColorGroup( QPalette::Inactive );
1343 }
1344
1345 QFont font = option.font;
1346 QColor textColor = palette.text().color();
1347 QBrush bg( palette.base() );
1348 Qt::Alignment align = option.displayAlignment;
1349 QString text = calendar->formatDate(date, KLocale::Day, KLocale::ShortNumber);
1350
1351 if ( model )
1352 {
1353 QVariant v = model->data( date, Qt::ForegroundRole );
1354 if ( v.isValid() )
1355 {
1356 textColor = v.value<QColor>();
1357 }
1358 v = model->data( date, Qt::BackgroundRole );
1359 if ( v.isValid() )
1360 {
1361 bg.setColor( v.value<QColor>() );
1362 }
1363 v = model->data( date );
1364 if ( v.isValid() )
1365 {
1366 text = v.toString();
1367 }
1368 v = model->data( date, Qt::TextAlignmentRole );
1369 if ( v.isValid() )
1370 {
1371 align = (Qt::Alignment)v.toInt();
1372 }
1373 v = model->data( date, Qt::FontRole );
1374 if ( v.isValid() )
1375 {
1376 font = v.value<QFont>();
1377 }
1378 }
1379
1380 QPen pen = painter->pen();
1381 pen.setColor( textColor );
1382
1383 if ( option.state & QStyle::State_Selected ) {
1384 bg = palette.highlight();
1385 }
1386 painter->fillRect( option.rectF, bg );
1387 painter->setBrush( bg );
1388
1389
1390 if ( option.state & QStyle::State_HasFocus ) {
1391 painter->setPen( palette.text().color() );
1392 painter->setPen( Qt::DotLine );
1393 painter->drawRect( option.rectF );
1394 } else if ( date == QDate::currentDate() ) {
1395 painter->setPen( palette.text().color() );
1396 painter->drawRect( option.rectF );
1397 }
1398
1399 if ( option.state & QStyle::State_Selected ) {
1400 pen.setColor( palette.highlightedText().color() );
1401 }
1402 painter->setFont( font );
1403 painter->setPen( pen );
1404 painter->drawText( option.rectF, align, text, &r );
1405
1406 painter->restore();
1407 return r;
1408}
1409
1410//---------
1411
1412KDateTableCustomDateDelegate::KDateTableCustomDateDelegate( QObject *parent )
1413 : KDateTableDateDelegate( parent )
1414{
1415}
1416
1417QRectF KDateTableCustomDateDelegate::paint( QPainter *painter, const StyleOptionViewItem &option, const QDate &date, KDateTableDataModel *model )
1418{
1419 //kDebug(planDbg())<<date;
1420 painter->save();
1421 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
1422 QRectF r;
1423 bool paintRect=true;
1424 QBrush bg(option.palette.base());
1425
1426 if( (option.state & QStyle::State_Active) == 0 )
1427 { // we are either
1428 // ° painting a day of the previous month or
1429 // ° painting a day of the following month
1430 // TODO: don't hardcode gray here! Use a color with less contrast to the background than normal text.
1431 painter->setPen( option.palette.color(QPalette::Mid) );
1432// painter->setPen(gray);
1433 }
1434 else
1435 { // paint a day of the current month
1436 if (bgMode != KDateTable::NoBgMode)
1437 {
1438 QBrush oldbrush=painter->brush();
1439 painter->setBrush( bgColor );
1440 switch(bgMode)
1441 {
1442 case(KDateTable::CircleMode) : painter->drawEllipse(option.rectF);break;
1443 case(KDateTable::RectangleMode) : painter->drawRect(option.rectF);break;
1444 case(KDateTable::NoBgMode) : // Should never be here, but just to get one
1445 // less warning when compiling
1446 default: break;
1447 }
1448 painter->setBrush( oldbrush );
1449 paintRect=false;
1450 }
1451 painter->setPen( fgColor );
1452
1453 QPen pen=painter->pen();
1454 if ( option.state & QStyle::State_Selected )
1455 {
1456 // draw the currently selected date
1457 //kDebug(planDbg())<<"selected: "<<date;
1458 if ( option.state & QStyle::State_Enabled )
1459 {
1460 //kDebug(planDbg())<<"enabled & selected: "<<date;
1461 painter->setPen(option.palette.color(QPalette::Highlight));
1462 painter->setBrush(option.palette.color(QPalette::Highlight));
1463 }
1464 else
1465 {
1466 //kDebug(planDbg())<<"disabled & selected: "<<date;
1467 painter->setPen(option.palette.color(QPalette::Text));
1468 painter->setBrush(option.palette.color(QPalette::Text));
1469 }
1470 pen=option.palette.color(QPalette::HighlightedText);
1471 }
1472 else
1473 {
1474 painter->setBrush(option.palette.color(QPalette::Background));
1475 painter->setPen(option.palette.color(QPalette::Background));
1476 }
1477
1478 if ( date == QDate::currentDate() )
1479 {
1480 painter->setPen(option.palette.color(QPalette::Text));
1481 }
1482
1483 if ( paintRect )
1484 {
1485 painter->drawRect(option.rectF);
1486 }
1487 painter->setPen(pen);
1488 QString text = calendar->formatDate(date, KLocale::Day, KLocale::ShortNumber);
1489 if ( model )
1490 {
1491 QVariant v = model->data( date );
1492 if ( v.isValid() )
1493 {
1494 text = v.toString();
1495 }
1496 }
1497 painter->drawText(option.rectF, Qt::AlignCenter, text, &r);
1498 }
1499 painter->restore();
1500 return r;
1501}
1502
1503//---------
1504KDateTableWeekDayDelegate::KDateTableWeekDayDelegate( QObject *parent )
1505 : QObject( parent )
1506{
1507}
1508
1509QVariant KDateTableWeekDayDelegate::data( int day, int role, KDateTableDataModel *model )
1510{
1511 //kDebug(planDbg())<<day<<role<<model;
1512 if ( model == 0 ) {
1513 return QVariant();
1514 }
1515 return model->weekDayData( day, role );
1516}
1517
1518QRectF KDateTableWeekDayDelegate::paint( QPainter *painter, const StyleOptionHeader &option, int daynum, KDateTableDataModel *model )
1519{
1520 //kDebug(planDbg())<<daynum;
1521 painter->save();
1522 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
1523
1524 QPalette palette = option.palette;
1525 if ( option.state & QStyle::State_Active ) {
1526 palette.setCurrentColorGroup( QPalette::Active );
1527 } else {
1528 palette.setCurrentColorGroup( QPalette::Inactive );
1529 }
1530 QRectF rect;
1531 QFont font = KGlobalSettings::generalFont();
1532// font.setBold(true);
1533 painter->setFont(font);
1534
1535 QColor titleColor( palette.button().color() );
1536 QColor textColor( palette.buttonText().color() );
1537
1538 painter->setPen(titleColor);
1539 painter->setBrush(titleColor);
1540 painter->drawRect(option.rectF);
1541
1542 QString value = calendar->weekDayName( daynum, KCalendarSystem::ShortDayName );
1543 //kDebug(planDbg())<<daynum<<": "<<value;
1544 if ( model ) {
1545 QVariant v = model->weekDayData( daynum, Qt::DisplayRole );
1546 if ( v.isValid() ) {
1547 value = v.toString();
1548 }
1549 }
1550 painter->setPen( textColor );
1551 painter->drawText(option.rectF, option.textAlignment, value, &rect);
1552
1553// painter->setPen( palette.color(QPalette::Text) );
1554// painter->drawLine(QPointF(0, option.rectF.height()), QPointF(option.rectF.width(), option.rectF.height()));
1555
1556 painter->restore();
1557 return rect;
1558}
1559
1560//---------
1561KDateTableWeekNumberDelegate::KDateTableWeekNumberDelegate( QObject *parent )
1562 : QObject( parent )
1563{
1564}
1565
1566QVariant KDateTableWeekNumberDelegate::data( int week, int role, KDateTableDataModel *model )
1567{
1568 //kDebug(planDbg())<<week<<role<<model;
1569 if ( model == 0 ) {
1570 return QVariant();
1571 }
1572 return model->weekNumberData( week, role );
1573}
1574
1575QRectF KDateTableWeekNumberDelegate::paint( QPainter *painter, const StyleOptionHeader &option, int week, KDateTableDataModel *model )
1576{
1577 //kDebug(planDbg());
1578 painter->save();
1579 QRectF result;
1580 QFont font = KGlobalSettings::generalFont();
1581 painter->setFont(font);
1582
1583 QColor titleColor( option.palette.button().color() );
1584 QColor textColor( option.palette.buttonText().color() );
1585
1586 painter->setPen(titleColor);
1587 painter->setBrush(titleColor);
1588 painter->drawRect(option.rectF);
1589 painter->setPen(textColor);
1590
1591 QString value = QString("%1").arg( week );
1592 if ( model ) {
1593 QVariant v = model->weekNumberData( week, Qt::DisplayRole );
1594 if ( v.isValid() ) {
1595 value = v.toString();
1596 }
1597 }
1598 painter->drawText(option.rectF, option.textAlignment, value, &result);
1599
1600// painter->setPen(option.palette.color(QPalette::Text));
1601// painter->drawLine(QPointF(option.rectF.width(), 0), QPointF(option.rectF.width(), option.rectF.height()));
1602
1603 painter->restore();
1604 return result;
1605}
1606
1607} //namespace KPlato
1608
1609#include "kdatetable.moc"
1610#include "kdatetable_p.moc"
1611