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#include "kdatepicker.h"
22#include "kdatetable.h"
23#include "kdatetable_p.h"
24
25#include <QApplication>
26#include <QComboBox>
27#include <QFont>
28#include <QLayout>
29#include <QKeyEvent>
30#include <QMenu>
31#include <QPainter>
32#include <QStyle>
33#include <QToolButton>
34#include <QDoubleValidator>
35#include <QWidget>
36#include <QPushButton>
37
38#include <kcalendarsystem.h>
39#include <kdebug.h>
40#include <kdialog.h>
41#include <kglobal.h>
42#include <klineedit.h>
43#include <klocale.h>
44#include <knotification.h>
45#include <kdeversion.h>
46
47#include <KoIcon.h>
48#include "kptdebug.h"
49
50#include "kdatepicker.moc"
51
52namespace KPlato
53{
54
55// Week numbers are defined by ISO 8601
56// See http://www.merlyn.demon.co.uk/weekinfo.htm for details
57
58class KDatePicker::KDatePickerPrivate
59{
60public:
61 KDatePickerPrivate() : closeButton(0L), selectWeek(0L), todayButton(0), navigationLayout(0) {}
62
63 void fillWeeksCombo(const QDate &date);
64
65 QToolButton *closeButton;
66 QComboBox *selectWeek;
67 QPushButton *todayButton;
68 QBoxLayout *navigationLayout;
69
70 /// the year forward button
71 QPushButton *yearForward;
72 /// the year backward button
73 QPushButton *yearBackward;
74 /// the month forward button
75 QPushButton *monthForward;
76 /// the month backward button
77 QPushButton *monthBackward;
78 /// the button for selecting the month directly
79 QPushButton *selectMonth;
80 /// the button for selecting the year directly
81 QPushButton *selectYear;
82 /// the line edit to enter the date directly
83 QLineEdit *line;
84 /// the validator for the line edit:
85 KDateValidator *val;
86 /// the date table
87 KDateTable *table;
88 /// the widest month string in pixels:
89 QSize maxMonthRect;
90
91 /// the font size for the widget
92 int fontsize;
93};
94
95void KDatePicker::fillWeeksCombo(const QDate &date)
96{
97 // every year can have a different number of weeks
98 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
99
100 // it could be that we had 53,1..52 and now 1..53 which is the same number but different
101 // so always fill with new values
102
103 d->selectWeek->clear();
104
105 // We show all week numbers for all weeks between first day of year to last day of year
106 // This of course can be a list like 53,1,2..52
107
108 QDate day;
109 int year = calendar->year(date);
110 calendar->setDate(day, year, 1, 1);
111 int lastMonth = calendar->monthsInYear(day);
112 QDate lastDay, firstDayOfLastMonth;
113 calendar->setDate(firstDayOfLastMonth, year, lastMonth, 1);
114 calendar->setDate(lastDay, year, lastMonth, calendar->daysInMonth(firstDayOfLastMonth));
115
116 for (; day <= lastDay ; day = calendar->addDays(day, 7 /*calendar->daysOfWeek()*/) )
117 {
118#if KDE_IS_VERSION(4,7,0)
119 const int weekNumber = calendar->week(day, &year);
120#else
121 const int weekNumber = calendar->weekNumber(day, &year);
122#endif
123 QString week = i18n("Week %1", weekNumber);
124 if ( year != calendar->year(day) ) week += '*'; // show that this is a week from a different year
125 d->selectWeek->addItem(week);
126
127 // make sure that the week of the lastDay is always inserted: in Chinese calendar
128 // system, this is not always the case
129 if(day < lastDay && day.daysTo(lastDay) < 7 &&
130#if KDE_IS_VERSION(4,7,0)
131 calendar->week(day) != calendar->week(lastDay))
132#else
133 calendar->weekNumber(day) != calendar->weekNumber(lastDay))
134#endif
135 day = lastDay.addDays(-7);
136 }
137}
138
139KDatePicker::KDatePicker(QWidget* parent)
140 : QFrame(parent),d(new KDatePickerPrivate())
141{
142 init( QDate::currentDate() );
143}
144
145KDatePicker::KDatePicker(const QDate& dt, QWidget* parent)
146 : QFrame(parent),d(new KDatePickerPrivate())
147{
148 init( dt );
149}
150
151void KDatePicker::init( const QDate &dt )
152{
153 setFocusPolicy( Qt::StrongFocus );
154
155 QBoxLayout * topLayout = new QVBoxLayout(this);
156 topLayout->setSpacing(0);
157 topLayout->setMargin(0);
158
159 d->navigationLayout = new QHBoxLayout();
160 d->navigationLayout->setSpacing(0);
161 d->navigationLayout->setMargin(0);
162 topLayout->addLayout(d->navigationLayout);
163 d->navigationLayout->addStretch();
164
165 d->yearBackward = new QPushButton(this);
166 //d->yearBackward->setAutoRaise(true);
167 d->yearBackward->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
168 d->yearBackward->setMaximumSize( QSize( 30, 30 ) );
169 d->navigationLayout->addWidget(d->yearBackward);
170 d->yearBackward->installEventFilter( this );
171
172 d->monthBackward = new QPushButton(this);
173 //d->monthBackward ->setAutoRaise(true);
174 d->monthBackward->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
175 d->monthBackward->setMaximumSize( QSize( 30, 30 ) );
176 d->navigationLayout->addWidget(d->monthBackward);
177 d->navigationLayout->addSpacing(KDialog::spacingHint());
178 d->monthBackward->installEventFilter( this );
179
180 d->selectMonth = new QPushButton(this);
181 //d->selectMonth ->setAutoRaise(true);
182 d->selectMonth->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
183 d->selectMonth->setMaximumSize( QSize( 30, 30 ) );
184 d->navigationLayout->addWidget(d->selectMonth);
185 d->selectMonth->installEventFilter( this );
186
187 d->selectYear = new QPushButton(this);
188 d->selectYear->setCheckable(true);
189 //d->selectYear->setAutoRaise(true);
190 d->selectYear->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
191 d->selectYear->setMaximumSize( QSize( 30, 30 ) );
192 d->navigationLayout->addWidget(d->selectYear);
193 d->navigationLayout->addSpacing(KDialog::spacingHint());
194 d->selectYear->installEventFilter( this );
195
196 d->monthForward = new QPushButton(this);
197 //d->monthForward ->setAutoRaise(true);
198 d->monthForward->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
199 d->monthForward->setMaximumSize( QSize( 30, 30 ) );
200 d->navigationLayout->addWidget(d->monthForward);
201
202 d->yearForward = new QPushButton(this);
203 //d->yearForward ->setFlat(true);
204 d->yearForward->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed );
205 d->yearForward->setMaximumSize( QSize( 30, 30 ) );
206 d->navigationLayout->addWidget(d->yearForward);
207 d->yearForward->installEventFilter( this );
208
209 d->navigationLayout->addStretch();
210
211 d->line = new KLineEdit(this);
212 d->val = new KDateValidator(this);
213
214 Frame *f = new Frame( this );
215 topLayout->addWidget( f );
216 QVBoxLayout *l = new QVBoxLayout( f );
217
218 d->table = new KDateTable(f);
219 connect( d->table, SIGNAL( focusChanged( QFocusEvent* ) ), f, SLOT( updateFocus( QFocusEvent* ) ) );
220 l->addWidget( d->table );
221 f->setFocusProxy( d->table );
222 d->table->installEventFilter( this );
223
224 d->fontsize = KGlobalSettings::generalFont().pointSize();
225 if (d->fontsize == -1)
226 d->fontsize = QFontInfo(KGlobalSettings::generalFont()).pointSize();
227
228 d->fontsize++; // Make a little bigger
229
230 d->selectWeek = new QComboBox(this); // read only week selection
231 d->selectWeek->installEventFilter( this );
232
233 d->todayButton = new QPushButton(this);
234 d->todayButton->setIcon(koIcon("go-jump-today"));
235 d->todayButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
236 d->todayButton->setMaximumSize( QSize( 25, 25 ) );
237 d->todayButton->installEventFilter( this );
238
239 d->yearForward->setToolTip(i18n("Next year"));
240 d->yearBackward->setToolTip(i18n("Previous year"));
241 d->monthForward->setToolTip(i18n("Next month"));
242 d->monthBackward->setToolTip(i18n("Previous month"));
243 d->selectWeek->setToolTip(i18n("Select a week"));
244 d->selectMonth->setToolTip(i18n("Select a month"));
245 d->selectYear->setToolTip(i18n("Select a year"));
246 d->todayButton->setToolTip(i18n("Select the current day"));
247
248 // -----
249 setFontSize(d->fontsize);
250 d->line->setValidator(d->val);
251 d->line->installEventFilter( this );
252 if ( QApplication::isRightToLeft() )
253 {
254 d->yearForward->setIcon(koIcon("arrow-left-double"));
255 d->yearBackward->setIcon(koIcon("arrow-right-double"));
256 d->monthForward->setIcon(koIcon("arrow-left"));
257 d->monthBackward->setIcon(koIcon("arrow-right"));
258 }
259 else
260 {
261 d->yearForward->setIcon(koIcon("arrow-right-double"));
262 d->yearBackward->setIcon(koIcon("arrow-left-double"));
263 d->monthForward->setIcon(koIcon("arrow-right"));
264 d->monthBackward->setIcon(koIcon("arrow-left"));
265 }
266
267 connect(d->table, SIGNAL(dateChanged(const QDate&)), SLOT(dateChangedSlot(const QDate&)));
268 connect(d->table, SIGNAL(tableClicked()), SLOT(tableClickedSlot()));
269 connect(d->monthForward, SIGNAL(clicked()), SLOT(monthForwardClicked()));
270 connect(d->monthBackward, SIGNAL(clicked()), SLOT(monthBackwardClicked()));
271 connect(d->yearForward, SIGNAL(clicked()), SLOT(yearForwardClicked()));
272 connect(d->yearBackward, SIGNAL(clicked()), SLOT(yearBackwardClicked()));
273 connect(d->selectWeek, SIGNAL(activated(int)), SLOT(weekSelected(int)));
274 connect(d->todayButton, SIGNAL(clicked()), SLOT(todayButtonClicked()));
275 connect(d->selectMonth, SIGNAL(clicked()), SLOT(selectMonthClicked()));
276 connect(d->selectYear, SIGNAL(toggled(bool)), SLOT(selectYearClicked()));
277 connect(d->line, SIGNAL(returnPressed()), SLOT(lineEnterPressed()));
278 d->table->setFocus();
279
280
281 QBoxLayout * bottomLayout = new QHBoxLayout();
282 bottomLayout->setMargin(0);
283 bottomLayout->setSpacing(0);
284 topLayout->addLayout(bottomLayout);
285
286 bottomLayout->addWidget(d->todayButton);
287 bottomLayout->addWidget(d->line);
288 bottomLayout->addWidget(d->selectWeek);
289
290 d->table->setDate(dt);
291 dateChangedSlot(dt); // needed because table emits changed only when newDate != oldDate
292}
293
294KDatePicker::~KDatePicker()
295{
296 delete d;
297}
298
299bool
300KDatePicker::eventFilter(QObject *o, QEvent *e )
301{
302/* if ( e->type() == QEvent::KeyPress ) {
303 QKeyEvent *k = (QKeyEvent *)e;
304
305 if ( (k->key() == Qt::Key_PageUp) ||
306 (k->key() == Qt::Key_PageDown) ||
307 (k->key() == Qt::Key_Up) ||
308 (k->key() == Qt::Key_Down) )
309 {
310 QApplication::sendEvent( d->table, e );
311 d->table->setFocus();
312 return true; // eat event
313 }
314 }*/
315 if ( o != this && ( e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut ) ) {
316 update();
317 }
318 return QFrame::eventFilter( o, e );
319}
320
321void
322KDatePicker::resizeEvent(QResizeEvent* e)
323{
324 QWidget::resizeEvent(e);
325}
326
327void
328KDatePicker::paintEvent(QPaintEvent *e)
329{
330 Q_UNUSED(e);
331 //kDebug(planDbg())<<e;
332 QPainter paint(this);
333 drawFrame(&paint);
334}
335
336void
337KDatePicker::drawFrame(QPainter *p)
338{
339 QPoint p1, p2;
340 QStyleOptionFrame opt;
341 opt.init(this);
342 QList<QWidget*> lst = findChildren<QWidget*>();
343 foreach ( QWidget *w, lst ) {
344 if ( w->hasFocus() ) {
345 opt.state |= QStyle::State_HasFocus;
346 break;
347 }
348 }
349 int frameShape = frameStyle() & QFrame::Shape_Mask;
350 int frameShadow = frameStyle() & QFrame::Shadow_Mask;
351
352 int lw = 0;
353 int mlw = 0;
354 opt.rect = frameRect();
355 switch (frameShape) {
356 case QFrame::Box:
357 case QFrame::HLine:
358 case QFrame::VLine:
359 case QFrame::StyledPanel:
360 lw = lineWidth();
361 mlw = midLineWidth();
362 break;
363 default:
364 // most frame styles do not handle customized line and midline widths
365 // (see updateFrameWidth()).
366 lw = frameWidth();
367 break;
368 }
369 opt.lineWidth = lw;
370 opt.midLineWidth = mlw;
371 if (frameShadow == Sunken)
372 opt.state |= QStyle::State_Sunken;
373 else if (frameShadow == Raised)
374 opt.state |= QStyle::State_Raised;
375
376 switch (frameShape) {
377 case Box:
378 if (frameShadow == Plain)
379 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
380 else
381 qDrawShadeRect(p, opt.rect, opt.palette, frameShadow == Sunken, lw, mlw);
382 break;
383
384
385 case StyledPanel:
386 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
387 break;
388
389 case Panel:
390 if (frameShadow == Plain)
391 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
392 else
393 qDrawShadePanel(p, opt.rect, opt.palette, frameShadow == Sunken, lw);
394 break;
395
396 case WinPanel:
397 if (frameShadow == Plain)
398 qDrawPlainRect(p, opt.rect, opt.palette.foreground().color(), lw);
399 else
400 qDrawWinPanel(p, opt.rect, opt.palette, frameShadow == Sunken);
401 break;
402 case HLine:
403 case VLine:
404 if (frameShape == HLine) {
405 p1 = QPoint(opt.rect.x(), opt.rect.height() / 2);
406 p2 = QPoint(opt.rect.x() + opt.rect.width(), p1.y());
407 } else {
408 p1 = QPoint(opt.rect.x()+opt.rect.width() / 2, 0);
409 p2 = QPoint(p1.x(), opt.rect.height());
410 }
411 if (frameShadow == Plain) {
412 QPen oldPen = p->pen();
413 p->setPen(QPen(opt.palette.foreground().color(), lw));
414 p->drawLine(p1, p2);
415 p->setPen(oldPen);
416 } else {
417 qDrawShadeLine(p, p1, p2, opt.palette, frameShadow == Sunken, lw, mlw);
418 }
419 break;
420 }
421}
422
423void
424KDatePicker::dateChangedSlot(const QDate &date)
425{
426 kDebug(planDbg())<< "KDatePicker::dateChangedSlot: date changed (" << date.year() << "/" << date.month() << "/" << date.day() << ").";
427
428 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
429
430 d->line->setText(KGlobal::locale()->formatDate(date, KLocale::ShortDate));
431 d->selectMonth->setText(calendar->monthName(date, KCalendarSystem::ShortName));
432 fillWeeksCombo(date);
433
434 // calculate the item num in the week combo box; normalize selected day so as if 1.1. is the first day of the week
435 QDate firstDay;
436 calendar->setDate(firstDay, calendar->year(date), 1, 1);
437 d->selectWeek->setCurrentIndex((calendar->dayOfYear(date) + calendar->dayOfWeek(firstDay) - 2) / 7/*calendar->daysInWeek()*/);
438 d->selectYear->setText(calendar->formatDate(date, KLocale::Year, KLocale::ShortNumber));
439
440 emit(dateChanged(date));
441}
442
443void
444KDatePicker::tableClickedSlot()
445{
446 kDebug(planDbg())<< "KDatePicker::tableClickedSlot: table clicked.";
447 emit(dateSelected(d->table->date()));
448 emit(tableClicked());
449}
450
451const QDate &
452KDatePicker::date() const
453{
454 return d->table->date();
455}
456
457bool
458KDatePicker::setDate(const QDate& date)
459{
460 if(date.isValid())
461 {
462 d->table->setDate(date); // this also emits dateChanged() which then calls our dateChangedSlot()
463 return true;
464 }
465 else
466 {
467 kDebug(planDbg())<<"KDatePicker::setDate: refusing to set invalid date.";
468 return false;
469 }
470}
471
472void
473KDatePicker::monthForwardClicked()
474{
475 QDate temp;
476 temp = KGlobal::locale()->calendar()->addMonths( d->table->date(), 1 );
477
478 setDate( temp );
479}
480
481void
482KDatePicker::monthBackwardClicked()
483{
484 QDate temp;
485 temp = KGlobal::locale()->calendar()->addMonths( d->table->date(), -1 );
486
487 setDate( temp );
488}
489
490void
491KDatePicker::yearForwardClicked()
492{
493 QDate temp;
494 temp = KGlobal::locale()->calendar()->addYears( d->table->date(), 1 );
495
496 setDate( temp );
497}
498
499void
500KDatePicker::yearBackwardClicked()
501{
502 QDate temp;
503 temp = KGlobal::locale()->calendar()->addYears( d->table->date(), -1 );
504
505 setDate( temp );
506}
507
508void
509KDatePicker::weekSelected(int week)
510{
511 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
512
513 QDate date = d->table->date();
514 int year = calendar->year(date);
515
516 calendar->setDate(date, year, 1, 1); // first day of selected year
517
518 // calculate the first day in the selected week (day 1 is first day of week)
519 date = calendar->addDays(date, week * 7/*calendar->daysOfWeek()*/ -calendar->dayOfWeek(date) + 1);
520
521 setDate(date);
522}
523
524void
525KDatePicker::selectMonthClicked()
526{
527 // every year can have different month names (in some calendar systems)
528 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
529 QDate date = d->table->date();
530 const int months = calendar->monthsInYear(date);
531
532 QMenu popup(d->selectMonth);
533
534 for (int i = 1; i <= months; i++)
535 popup.addAction(calendar->monthName(i, calendar->year(date)))->setData(i);
536
537 //QMenuItem *item = popup.findItem (calendar->month(date) - 1);
538 QAction *item=popup.actions()[calendar->month(date)-1];
539 if (item) // if this happens the above should already given an assertion
540 popup.setActiveAction(item);
541
542 if ( (item = popup.exec(d->selectMonth->mapToGlobal(QPoint(0, 0)), item)) == 0 ) return; // canceled
543
544 int day = calendar->day(date);
545 // ----- construct a valid date in this month:
546 calendar->setDate(date, calendar->year(date), item->data().toInt(), 1);
547 date = date.addDays(qMin(day, calendar->daysInMonth(date)) - 1);
548 // ----- set this month
549 setDate(date);
550}
551
552void
553KDatePicker::selectYearClicked()
554{
555 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
556
557 if (!d->selectYear->isChecked ())
558 {
559 return;
560 }
561
562 int year;
563 KPopupFrame* popup = new KPopupFrame(this);
564 KDateInternalYearSelector* picker = new KDateInternalYearSelector(popup);
565 // -----
566 picker->resize(picker->sizeHint());
567 picker->setYear( d->table->date().year() );
568 picker->selectAll();
569 popup->setMainWidget(picker);
570 connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int)));
571 picker->setFocus();
572 if(popup->exec(d->selectYear->mapToGlobal(QPoint(0, d->selectMonth->height()))))
573 {
574 QDate date;
575 int day;
576 // -----
577 year=picker->getYear();
578 date=d->table->date();
579 day=calendar->day(date);
580 // ----- construct a valid date in this month:
581 //date.setDate(year, date.month(), 1);
582 //date.setDate(year, date.month(), qMin(day, date.daysInMonth()));
583 calendar->setDate(date, year, calendar->month(date),
584 qMin(day, calendar->daysInMonth(date)));
585 // ----- set this month
586 setDate(date);
587 } else {
588 //KNotification::beep();
589 }
590 d->selectYear->setChecked( false );
591 delete popup;
592}
593
594// ####### KDE4: setEnabled isn't virtual anymore, so this isn't polymorphic.
595// Better reimplement changeEvent() instead.
596void
597KDatePicker::setEnabled(bool enable)
598{
599 QWidget *widgets[]= {
600 d->yearForward, d->yearBackward, d->monthForward, d->monthBackward,
601 d->selectMonth, d->selectYear,
602 d->line, d->table, d->selectWeek, d->todayButton };
603 const int Size=sizeof(widgets)/sizeof(widgets[0]);
604 int count;
605 // -----
606 for(count=0; count<Size; ++count)
607 {
608 widgets[count]->setEnabled(enable);
609 }
610}
611
612KDateTable *KDatePicker::dateTable() const
613{
614 return d->table;
615}
616
617void
618KDatePicker::lineEnterPressed()
619{
620 QDate temp;
621 // -----
622 if(d->val->date(d->line->text(), temp)==QValidator::Acceptable)
623 {
624 kDebug(planDbg())<< "KDatePicker::lineEnterPressed: valid date entered.";
625 emit(dateEntered(temp));
626 setDate(temp);
627 } else {
628 KNotification::beep();
629 kDebug(planDbg())<< "KDatePicker::lineEnterPressed: invalid date entered.";
630 }
631}
632
633void
634KDatePicker::todayButtonClicked()
635{
636 setDate(QDate::currentDate());
637}
638
639QSize
640KDatePicker::sizeHint() const
641{
642 return QWidget::sizeHint();
643}
644
645void
646KDatePicker::setFontSize(int s)
647{
648 QWidget *buttons[]= {
649 // yearBackward,
650 // monthBackward,
651 d->selectMonth,
652 d->selectYear,
653 // monthForward,
654 // yearForward
655 };
656 const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]);
657 int count;
658 QFont font;
659 QRect r;
660 // -----
661 d->fontsize=s;
662 for(count=0; count<NoOfButtons; ++count)
663 {
664 font=buttons[count]->font();
665 font.setPointSize(s);
666 buttons[count]->setFont(font);
667 }
668 QFontMetrics metrics(d->selectMonth->fontMetrics());
669
670 for (int i = 1; ; ++i)
671 {
672 QString str = KGlobal::locale()->calendar()->monthName(i,
673 KGlobal::locale()->calendar()->year(d->table->date()), KCalendarSystem::ShortName);
674 if (str.isNull()) break;
675 r=metrics.boundingRect(str);
676 d->maxMonthRect.setWidth(qMax(r.width(), d->maxMonthRect.width()));
677 d->maxMonthRect.setHeight(qMax(r.height(), d->maxMonthRect.height()));
678 }
679
680 QStyleOptionToolButton opt;
681
682 // stolen from KToolBarButton
683 opt.init(this);
684 opt.font = d->selectMonth->font();
685 opt.icon = d->selectMonth->icon();
686 opt.text = d->selectMonth->text();
687 opt.features = d->selectMonth->menu() ? QStyleOptionToolButton::Menu : QStyleOptionToolButton::None; //### FIXME: delay?
688 opt.subControls = QStyle::SC_All;
689 opt.activeSubControls = 0; //### FIXME: !!
690
691 QSize metricBound = style()->sizeFromContents(QStyle::CT_ToolButton,
692 &opt,
693 d->maxMonthRect, d->selectMonth);
694 d->selectMonth->setMinimumSize(metricBound);
695
696 d->table->setFontSize(s);
697}
698
699int KDatePicker::fontSize() const
700{
701 return d->fontsize;
702}
703
704
705void
706KDatePicker::setCloseButton( bool enable )
707{
708 if ( enable == (d->closeButton != 0L) )
709 return;
710
711 if ( enable ) {
712 d->closeButton = new QToolButton( this );
713 d->closeButton->setAutoRaise(true);
714 d->navigationLayout->addSpacing(KDialog::spacingHint());
715 d->navigationLayout->addWidget(d->closeButton);
716 d->closeButton->setToolTip(i18n("Close"));
717 d->closeButton->setIcon(koIcon("list-remove"));
718 connect( d->closeButton, SIGNAL( clicked() ),
719 topLevelWidget(), SLOT( close() ) );
720 }
721 else {
722 delete d->closeButton;
723 d->closeButton = 0L;
724 }
725
726 updateGeometry();
727}
728
729bool KDatePicker::hasCloseButton() const
730{
731 return (d->closeButton);
732}
733
734} //namespace KPlato
735