00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qlayout.h>
00022
#include <qframe.h>
00023
#include <qpainter.h>
00024
#include <qdialog.h>
00025
#include <qstyle.h>
00026
#include <qtoolbutton.h>
00027
#include <qcombobox.h>
00028
#include <qtooltip.h>
00029
#include <qfont.h>
00030
#include <qvalidator.h>
00031
#include <qpopupmenu.h>
00032
00033
#include "kdatepicker.h"
00034
#include <kglobal.h>
00035
#include <kapplication.h>
00036
#include <kdialog.h>
00037
#include <klocale.h>
00038
#include <kiconloader.h>
00039
#include <ktoolbar.h>
00040
#include <klineedit.h>
00041
#include <kdebug.h>
00042
#include <knotifyclient.h>
00043
#include <kcalendarsystem.h>
00044
00045
#include "kdatetbl.h"
00046
#include "kdatepicker.moc"
00047
00048
00049
00050
00051
class KDatePicker::KDatePickerPrivate
00052 {
00053
public:
00054 KDatePickerPrivate() : closeButton(0L), selectWeek(0L), todayButton(0), navigationLayout(0) {}
00055
00056
void fillWeeksCombo(
const QDate &date);
00057
00058
QToolButton *closeButton;
00059
QComboBox *selectWeek;
00060
QToolButton *todayButton;
00061
QBoxLayout *navigationLayout;
00062 };
00063
00064
void KDatePicker::fillWeeksCombo(
const QDate &date)
00065 {
00066
00067
const KCalendarSystem * calendar =
KGlobal::locale()->
calendar();
00068
00069
00070
00071
00072 d->selectWeek->clear();
00073
00074
00075
00076
00077
QDate day(date.year(), 1, 1);
00078
int lastMonth = calendar->
monthsInYear(day);
00079
QDate lastDay(date.year(), lastMonth, calendar->
daysInMonth(
QDate(date.year(), lastMonth, 1)));
00080
00081
for (; day <= lastDay; day = calendar->
addDays(day, 7 ) )
00082 {
00083
int year = 0;
00084
QString week = i18n(
"Week %1").arg(calendar->
weekNumber(day, &year));
00085
if ( year != date.year() ) week +=
"*";
00086 d->selectWeek->insertItem(week);
00087 }
00088 }
00089
00090 KDatePicker::KDatePicker(
QWidget *parent,
QDate dt,
const char *name)
00091 :
QFrame(parent,name)
00092 {
00093 init( dt );
00094 }
00095
00096 KDatePicker::KDatePicker(
QWidget *parent,
QDate dt,
const char *name, WFlags f)
00097 :
QFrame(parent,name, f)
00098 {
00099 init( dt );
00100 }
00101
00102 KDatePicker::KDatePicker(
QWidget *parent,
const char *name )
00103 :
QFrame(parent,name)
00104 {
00105 init( QDate::currentDate() );
00106 }
00107
00108
void KDatePicker::init(
const QDate &dt )
00109 {
00110 d =
new KDatePickerPrivate();
00111
00112
QBoxLayout * topLayout =
new QVBoxLayout(
this);
00113
00114 d->navigationLayout =
new QHBoxLayout(topLayout);
00115 d->navigationLayout->addStretch();
00116 yearBackward =
new QToolButton(
this);
00117 yearBackward->setAutoRaise(
true);
00118 d->navigationLayout->addWidget(yearBackward);
00119 monthBackward =
new QToolButton(
this);
00120 monthBackward ->setAutoRaise(
true);
00121 d->navigationLayout->addWidget(monthBackward);
00122 d->navigationLayout->addSpacing(KDialog::spacingHint());
00123
00124 selectMonth =
new QToolButton(
this);
00125 selectMonth ->setAutoRaise(
true);
00126 d->navigationLayout->addWidget(selectMonth);
00127 selectYear =
new QToolButton(
this);
00128 selectYear->setToggleButton(
true);
00129 selectYear->setAutoRaise(
true);
00130 d->navigationLayout->addWidget(selectYear);
00131 d->navigationLayout->addSpacing(KDialog::spacingHint());
00132
00133 monthForward =
new QToolButton(
this);
00134 monthForward ->setAutoRaise(
true);
00135 d->navigationLayout->addWidget(monthForward);
00136 yearForward =
new QToolButton(
this);
00137 yearForward ->setAutoRaise(
true);
00138 d->navigationLayout->addWidget(yearForward);
00139 d->navigationLayout->addStretch();
00140
00141 line =
new KLineEdit(
this);
00142 val =
new KDateValidator(
this);
00143 table =
new KDateTable(
this);
00144 fontsize =
KGlobalSettings::generalFont().
pointSize();
00145
if (fontsize == -1)
00146 fontsize =
QFontInfo(KGlobalSettings::generalFont()).pointSize();
00147
00148 fontsize++;
00149
00150 d->selectWeek =
new QComboBox(
false,
this);
00151 d->todayButton =
new QToolButton(
this);
00152 d->todayButton->setIconSet(SmallIconSet(
"today"));
00153
00154 QToolTip::add(yearForward, i18n(
"Next year"));
00155 QToolTip::add(yearBackward, i18n(
"Previous year"));
00156 QToolTip::add(monthForward, i18n(
"Next month"));
00157 QToolTip::add(monthBackward, i18n(
"Previous month"));
00158 QToolTip::add(d->selectWeek, i18n(
"Select a week"));
00159 QToolTip::add(selectMonth, i18n(
"Select a month"));
00160 QToolTip::add(selectYear, i18n(
"Select a year"));
00161 QToolTip::add(d->todayButton, i18n(
"Select the current day"));
00162
00163
00164 setFontSize(fontsize);
00165 line->setValidator(val);
00166 line->installEventFilter(
this );
00167
if ( QApplication::reverseLayout() )
00168 {
00169 yearForward->setIconSet(BarIconSet(QString::fromLatin1(
"2leftarrow")));
00170 yearBackward->setIconSet(BarIconSet(QString::fromLatin1(
"2rightarrow")));
00171 monthForward->setIconSet(BarIconSet(QString::fromLatin1(
"1leftarrow")));
00172 monthBackward->setIconSet(BarIconSet(QString::fromLatin1(
"1rightarrow")));
00173 }
00174
else
00175 {
00176
yearForward->setIconSet(BarIconSet(QString::fromLatin1(
"2rightarrow")));
00177
yearBackward->setIconSet(BarIconSet(QString::fromLatin1(
"2leftarrow")));
00178
monthForward->setIconSet(BarIconSet(QString::fromLatin1(
"1rightarrow")));
00179
monthBackward->setIconSet(BarIconSet(QString::fromLatin1(
"1leftarrow")));
00180 }
00181 connect(table, SIGNAL(
dateChanged(
QDate)), SLOT(dateChangedSlot(
QDate)));
00182 connect(table, SIGNAL(
tableClicked()), SLOT(tableClickedSlot()));
00183 connect(monthForward, SIGNAL(clicked()), SLOT(monthForwardClicked()));
00184 connect(monthBackward, SIGNAL(clicked()), SLOT(monthBackwardClicked()));
00185 connect(yearForward, SIGNAL(clicked()), SLOT(yearForwardClicked()));
00186 connect(yearBackward, SIGNAL(clicked()), SLOT(yearBackwardClicked()));
00187 connect(d->selectWeek, SIGNAL(activated(
int)), SLOT(
weekSelected(
int)));
00188 connect(d->todayButton, SIGNAL(clicked()), SLOT(
todayButtonClicked()));
00189 connect(selectMonth, SIGNAL(clicked()), SLOT(
selectMonthClicked()));
00190 connect(selectYear, SIGNAL(toggled(
bool)), SLOT(
selectYearClicked()));
00191 connect(line, SIGNAL(returnPressed()), SLOT(
lineEnterPressed()));
00192
table->setFocus();
00193
00194
00195 topLayout->
addWidget(table);
00196
00197
QBoxLayout * bottomLayout =
new QHBoxLayout(topLayout);
00198 bottomLayout->
addWidget(d->todayButton);
00199 bottomLayout->
addWidget(line);
00200 bottomLayout->
addWidget(d->selectWeek);
00201
00202
table->
setDate(dt);
00203 dateChangedSlot(dt);
00204 }
00205
00206 KDatePicker::~KDatePicker()
00207 {
00208
delete d;
00209 }
00210
00211
bool
00212 KDatePicker::eventFilter(
QObject *o,
QEvent *e )
00213 {
00214
if ( e->type() == QEvent::KeyPress ) {
00215
QKeyEvent *k = (
QKeyEvent *)e;
00216
00217
if ( (k->key() == Qt::Key_Prior) ||
00218 (k->key() == Qt::Key_Next) ||
00219 (k->key() == Qt::Key_Up) ||
00220 (k->key() == Qt::Key_Down) )
00221 {
00222 QApplication::sendEvent(
table, e );
00223
table->setFocus();
00224
return true;
00225 }
00226 }
00227
return QFrame::eventFilter( o, e );
00228 }
00229
00230
void
00231 KDatePicker::resizeEvent(
QResizeEvent* e)
00232 {
00233 QWidget::resizeEvent(e);
00234 }
00235
00236
void
00237 KDatePicker::dateChangedSlot(
QDate date)
00238 {
00239
kdDebug(298) <<
"KDatePicker::dateChangedSlot: date changed (" << date.year() <<
"/" << date.month() <<
"/" << date.day() <<
")." <<
endl;
00240
00241
const KCalendarSystem * calendar =
KGlobal::locale()->
calendar();
00242
00243 line->setText(KGlobal::locale()->formatDate(date,
true));
00244 selectMonth->setText(calendar->
monthName(date,
false));
00245 fillWeeksCombo(date);
00246
00247
00248
QDate firstDay(date.year(), 1, 1);
00249 d->selectWeek->setCurrentItem((calendar->
dayOfYear(date) + calendar->
dayOfWeek(firstDay) - 2) / 7);
00250
00251 selectYear->setText(calendar->
yearString(date,
false));
00252
00253 emit(dateChanged(date));
00254 }
00255
00256
void
00257 KDatePicker::tableClickedSlot()
00258 {
00259
kdDebug(298) <<
"KDatePicker::tableClickedSlot: table clicked." <<
endl;
00260 emit(
dateSelected(
table->
getDate()));
00261 emit(
tableClicked());
00262 }
00263
00264
const QDate&
00265 KDatePicker::getDate()
const
00266
{
00267
return table->
getDate();
00268 }
00269
00270
const QDate &
00271
KDatePicker::date()
const
00272
{
00273
return table->
getDate();
00274 }
00275
00276
bool
00277 KDatePicker::setDate(
const QDate& date)
00278 {
00279
if(date.isValid())
00280 {
00281
table->
setDate(date);
00282
return true;
00283 }
00284
else
00285 {
00286
kdDebug(298) <<
"KDatePicker::setDate: refusing to set invalid date." <<
endl;
00287
return false;
00288 }
00289 }
00290
00291
void
00292 KDatePicker::monthForwardClicked()
00293 {
00294
QDate temp;
00295 temp =
KGlobal::locale()->
calendar()->
addMonths( table->
getDate(), 1 );
00296
00297 setDate( temp );
00298 }
00299
00300
void
00301 KDatePicker::monthBackwardClicked()
00302 {
00303
QDate temp;
00304 temp =
KGlobal::locale()->
calendar()->
addMonths(
table->
getDate(), -1 );
00305
00306
setDate( temp );
00307 }
00308
00309
void
00310 KDatePicker::yearForwardClicked()
00311 {
00312
QDate temp;
00313 temp =
KGlobal::locale()->
calendar()->
addYears(
table->
getDate(), 1 );
00314
00315
setDate( temp );
00316 }
00317
00318
void
00319 KDatePicker::yearBackwardClicked()
00320 {
00321
QDate temp;
00322 temp =
KGlobal::locale()->
calendar()->
addYears(
table->
getDate(), -1 );
00323
00324
setDate( temp );
00325 }
00326
00327 void KDatePicker::selectWeekClicked() {}
00328
00329
void
00330 KDatePicker::weekSelected(
int week)
00331 {
00332
const KCalendarSystem * calendar =
KGlobal::locale()->
calendar();
00333
00334
QDate date =
table->
getDate();
00335
int year = calendar->
year(date);
00336
00337 calendar->
setYMD(date, year, 1, 1);
00338
00339
00340 date = calendar->
addDays(date, week * 7 -calendar->
dayOfWeek(date) + 1);
00341
00342
setDate(date);
00343 }
00344
00345
void
00346 KDatePicker::selectMonthClicked()
00347 {
00348
00349
const KCalendarSystem * calendar =
KGlobal::locale()->
calendar();
00350
QDate date =
table->
getDate();
00351
int i, month, months = calendar->
monthsInYear(date);
00352
00353
QPopupMenu popup(
selectMonth);
00354
00355
for (i = 1; i <= months; i++)
00356 popup.insertItem(calendar->
monthName(i, calendar->
year(date)), i);
00357
00358 popup.setActiveItem(calendar->
month(date) - 1);
00359
00360
if ( (month = popup.exec(
selectMonth->mapToGlobal(
QPoint(0, 0)), calendar->
month(date) - 1)) == -1 )
return;
00361
00362
int day = calendar->
day(date);
00363
00364
00365
00366 calendar->
setYMD(date, calendar->
year(date), month,
00367 QMIN(day, calendar->
daysInMonth(date)));
00368
00369
setDate(date);
00370 }
00371
00372
void
00373 KDatePicker::selectYearClicked()
00374 {
00375
const KCalendarSystem * calendar =
KGlobal::locale()->
calendar();
00376
00377
if (
selectYear->state() == QButton::Off)
00378 {
00379
return;
00380 }
00381
00382
int year;
00383
KPopupFrame* popup =
new KPopupFrame(
this);
00384
KDateInternalYearSelector* picker =
new KDateInternalYearSelector(popup);
00385
00386 picker->resize(picker->sizeHint());
00387 picker->
setYear(
table->
getDate().year() );
00388 picker->selectAll();
00389 popup->
setMainWidget(picker);
00390 connect(picker, SIGNAL(closeMe(
int)), popup, SLOT(close(
int)));
00391 picker->setFocus();
00392
if(popup->
exec(
selectYear->mapToGlobal(
QPoint(0,
selectMonth->height()))))
00393 {
00394
QDate date;
00395
int day;
00396
00397 year=picker->
getYear();
00398 date=
table->
getDate();
00399 day=calendar->
day(date);
00400
00401
00402
00403 calendar->
setYMD(date, year, calendar->
month(date),
00404 QMIN(day, calendar->
daysInMonth(date)));
00405
00406
setDate(date);
00407 }
else {
00408
KNotifyClient::beep();
00409 }
00410
selectYear->setOn(
false );
00411
delete popup;
00412 }
00413
00414
void
00415 KDatePicker::setEnabled(
bool enable)
00416 {
00417
QWidget *widgets[]= {
00418
yearForward,
yearBackward,
monthForward,
monthBackward,
00419
selectMonth,
selectYear,
00420
line,
table, d->selectWeek, d->todayButton };
00421
const int Size=
sizeof(widgets)/
sizeof(widgets[0]);
00422
int count;
00423
00424
for(count=0; count<Size; ++count)
00425 {
00426 widgets[count]->setEnabled(enable);
00427 }
00428 }
00429
00430
void
00431 KDatePicker::lineEnterPressed()
00432 {
00433
QDate temp;
00434
00435
if(
val->
date(
line->text(), temp)==QValidator::Acceptable)
00436 {
00437
kdDebug(298) <<
"KDatePicker::lineEnterPressed: valid date entered." <<
endl;
00438 emit(
dateEntered(temp));
00439
setDate(temp);
00440 }
else {
00441
KNotifyClient::beep();
00442
kdDebug(298) <<
"KDatePicker::lineEnterPressed: invalid date entered." <<
endl;
00443 }
00444 }
00445
00446
void
00447 KDatePicker::todayButtonClicked()
00448 {
00449
setDate(QDate::currentDate());
00450 }
00451
00452
QSize
00453 KDatePicker::sizeHint()
const
00454
{
00455
return QWidget::sizeHint();
00456 }
00457
00458
void
00459 KDatePicker::setFontSize(
int s)
00460 {
00461
QWidget *buttons[]= {
00462
00463
00464
selectMonth,
00465
selectYear,
00466
00467
00468 };
00469
const int NoOfButtons=
sizeof(buttons)/
sizeof(buttons[0]);
00470
int count;
00471
QFont font;
00472
QRect r;
00473
00474 fontsize=s;
00475
for(count=0; count<NoOfButtons; ++count)
00476 {
00477 font=buttons[count]->font();
00478 font.setPointSize(s);
00479 buttons[count]->setFont(font);
00480 }
00481
QFontMetrics metrics(
selectMonth->fontMetrics());
00482
00483
for (
int i = 1; ; ++i)
00484 {
00485
QString str =
KGlobal::locale()->
calendar()->
monthName(i,
00486 KGlobal::locale()->calendar()->year(
table->
getDate()),
false);
00487
if (str.isNull())
break;
00488 r=metrics.boundingRect(str);
00489
maxMonthRect.setWidth(QMAX(r.width(),
maxMonthRect.width()));
00490
maxMonthRect.setHeight(QMAX(r.height(),
maxMonthRect.height()));
00491 }
00492
00493
QSize metricBound = style().sizeFromContents(QStyle::CT_ToolButton,
00494
selectMonth,
00495
maxMonthRect);
00496
selectMonth->setMinimumSize(metricBound);
00497
00498
table->
setFontSize(s);
00499 }
00500
00501
void
00502 KDatePicker::setCloseButton(
bool enable )
00503 {
00504
if ( enable == (d->closeButton != 0L) )
00505
return;
00506
00507
if ( enable ) {
00508 d->closeButton =
new QToolButton(
this );
00509 d->closeButton->setAutoRaise(
true);
00510 d->navigationLayout->addSpacing(KDialog::spacingHint());
00511 d->navigationLayout->addWidget(d->closeButton);
00512 QToolTip::add(d->closeButton, i18n(
"Close"));
00513 d->closeButton->setPixmap( SmallIcon(
"remove") );
00514 connect( d->closeButton, SIGNAL( clicked() ),
00515 topLevelWidget(), SLOT( close() ) );
00516 }
00517
else {
00518
delete d->closeButton;
00519 d->closeButton = 0L;
00520 }
00521
00522 updateGeometry();
00523 }
00524
00525 bool KDatePicker::hasCloseButton()
const
00526
{
00527
return (d->closeButton);
00528 }
00529
00530
void KDatePicker::virtual_hook(
int ,
void* )
00531 { }
00532