00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <kglobal.h>
00036 #include <kglobalsettings.h>
00037 #include <kapplication.h>
00038 #include <klocale.h>
00039 #include <kdebug.h>
00040 #include <knotifyclient.h>
00041 #include "kdatepicker.h"
00042 #include "kdatetbl.h"
00043 #include <qdatetime.h>
00044 #include <qstring.h>
00045 #include <qpen.h>
00046 #include <qpainter.h>
00047 #include <qdialog.h>
00048 #include <assert.h>
00049
00050 KDateValidator::KDateValidator(QWidget* parent, const char* name)
00051 : QValidator(parent, name)
00052 {
00053 }
00054
00055 QValidator::State
00056 KDateValidator::validate(QString& text, int&) const
00057 {
00058 QDate temp;
00059
00060 return date(text, temp);
00061 }
00062
00063 QValidator::State
00064 KDateValidator::date(const QString& text, QDate& d) const
00065 {
00066 QDate tmp = KGlobal::locale()->readDate(text);
00067 if (!tmp.isNull())
00068 {
00069 d = tmp;
00070 return Acceptable;
00071 } else
00072 return Valid;
00073 }
00074
00075 void
00076 KDateValidator::fixup( QString& ) const
00077 {
00078
00079 }
00080
00081 KDateTable::KDateTable(QWidget *parent, QDate date_, const char* name, WFlags f)
00082 : QGridView(parent, name, f)
00083 {
00084 setFontSize(10);
00085 if(!date_.isValid())
00086 {
00087 kdDebug() << "KDateTable ctor: WARNING: Given date is invalid, using current date." << endl;
00088 date_=QDate::currentDate();
00089 }
00090 setFocusPolicy( QWidget::StrongFocus );
00091 setNumRows(7);
00092 setNumCols(7);
00093 setHScrollBarMode(AlwaysOff);
00094 setVScrollBarMode(AlwaysOff);
00095 viewport()->setEraseColor(KGlobalSettings::baseColor());
00096 setDate(date_);
00097 }
00098
00099 void
00100 KDateTable::paintCell(QPainter *painter, int row, int col)
00101 {
00102 QRect rect;
00103 QString text;
00104 QPen pen;
00105 int w=cellWidth();
00106 int h=cellHeight();
00107 int pos;
00108 QBrush brushBlue(KGlobalSettings::activeTitleColor());
00109 QBrush brushLightblue(KGlobalSettings::baseColor());
00110 QFont font=KGlobalSettings::generalFont();
00111
00112 font.setPointSize(fontsize);
00113 int firstWeekDay = KGlobal::locale()->weekStartDay();
00114 if(row==0)
00115 {
00116 font.setBold(true);
00117 painter->setFont(font);
00118 bool normalday = true;
00119 QString daystr;
00120 if ( col+firstWeekDay < 8 )
00121 daystr = KGlobal::locale()->weekDayName(col+firstWeekDay, true);
00122 else
00123 daystr = KGlobal::locale()->weekDayName(col+firstWeekDay-7, true);
00124 if ( daystr==i18n("Sunday", "Sun") || daystr==i18n("Saturday", "Sat") )
00125 normalday=false;
00126
00127 if (!normalday)
00128 {
00129 painter->setPen(KGlobalSettings::baseColor());
00130 painter->setBrush(brushLightblue);
00131 painter->drawRect(0, 0, w, h);
00132 painter->setPen(KGlobalSettings::activeTitleColor());
00133 } else {
00134 painter->setPen(KGlobalSettings::activeTitleColor());
00135 painter->setBrush(brushBlue);
00136 painter->drawRect(0, 0, w, h);
00137 painter->setPen(KGlobalSettings::activeTextColor());
00138 }
00139 painter->drawText(0, 0, w, h-1, AlignCenter,
00140 daystr, -1, &rect);
00141 painter->setPen(KGlobalSettings::textColor());
00142 painter->moveTo(0, h-1);
00143 painter->lineTo(w-1, h-1);
00144
00145 } else {
00146 painter->setFont(font);
00147 pos=7*(row-1)+col;
00148 if ( firstWeekDay < 4 )
00149 pos += firstWeekDay;
00150 else
00151 pos += firstWeekDay - 7;
00152 if(pos<firstday || (firstday+numdays<=pos))
00153 {
00154
00155
00156 if(pos<firstday)
00157 {
00158 text.setNum(numDaysPrevMonth+pos-firstday+1);
00159 } else {
00160 text.setNum(pos-firstday-numdays+1);
00161 }
00162 painter->setPen(gray);
00163 } else {
00164 text.setNum(pos-firstday+1);
00165 painter->setPen(KGlobalSettings::textColor());
00166 }
00167
00168 pen=painter->pen();
00169 if(firstday+date.day()-1==pos)
00170 {
00171 if(hasFocus())
00172 {
00173 painter->setPen(KGlobalSettings::highlightColor());
00174 painter->setBrush(KGlobalSettings::highlightColor());
00175 pen=white;
00176 } else {
00177 painter->setPen(KGlobalSettings::calculateAlternateBackgroundColor(KGlobalSettings::highlightColor()));
00178 painter->setBrush(KGlobalSettings::calculateAlternateBackgroundColor(KGlobalSettings::highlightColor()));
00179 pen=white;
00180 }
00181 } else {
00182 painter->setBrush(KGlobalSettings::baseColor());
00183 painter->setPen(KGlobalSettings::baseColor());
00184 }
00185
00186 QDate cur_date = QDate::currentDate();
00187 if ( (date.year() == cur_date.year()) &&
00188 (date.month() == cur_date.month()) &&
00189 (firstday+cur_date.day()-1 == pos) )
00190 {
00191 painter->setPen(KGlobalSettings::textColor());
00192 }
00193
00194 painter->drawRect(0, 0, w, h);
00195 painter->setPen(pen);
00196 painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
00197 }
00198 if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
00199 if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
00200 }
00201
00202 void
00203 KDateTable::keyPressEvent( QKeyEvent *e )
00204 {
00205 if ( e->key() == Qt::Key_Prior ) {
00206 setDate(date.addMonths(-1));
00207 return;
00208 }
00209 if ( e->key() == Qt::Key_Next ) {
00210 setDate(date.addMonths(1));
00211 return;
00212 }
00213
00214 if ( e->key() == Qt::Key_Up ) {
00215 if ( date.day() > 7 ) {
00216 setDate(date.addDays(-7));
00217 return;
00218 }
00219 }
00220 if ( e->key() == Qt::Key_Down ) {
00221 if ( date.day() <= date.daysInMonth()-7 ) {
00222 setDate(date.addDays(7));
00223 return;
00224 }
00225 }
00226 if ( e->key() == Qt::Key_Left ) {
00227 if ( date.day() > 1 ) {
00228 setDate(date.addDays(-1));
00229 return;
00230 }
00231 }
00232 if ( e->key() == Qt::Key_Right ) {
00233 if ( date.day() < date.daysInMonth() ) {
00234 setDate(date.addDays(1));
00235 return;
00236 }
00237 }
00238
00239 if ( e->key() == Qt::Key_Minus ) {
00240 setDate(date.addDays(-1));
00241 return;
00242 }
00243 if ( e->key() == Qt::Key_Plus ) {
00244 setDate(date.addDays(1));
00245 return;
00246 }
00247 if ( e->key() == Qt::Key_N ) {
00248 setDate(QDate::currentDate());
00249 return;
00250 }
00251
00252 KNotifyClient::beep();
00253 }
00254
00255 void
00256 KDateTable::viewportResizeEvent(QResizeEvent * e)
00257 {
00258 QGridView::viewportResizeEvent(e);
00259
00260 setCellWidth(viewport()->width()/7);
00261 setCellHeight(viewport()->height()/7);
00262 }
00263
00264 void
00265 KDateTable::setFontSize(int size)
00266 {
00267 int count;
00268 QFontMetrics metrics(fontMetrics());
00269 QRect rect;
00270
00271 fontsize=size;
00272
00273 maxCell.setWidth(0);
00274 maxCell.setHeight(0);
00275 for(count=0; count<7; ++count)
00276 {
00277 rect=metrics.boundingRect(KGlobal::locale()->weekDayName(count+1, true));
00278 maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
00279 maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
00280 }
00281
00282 rect=metrics.boundingRect(QString::fromLatin1("88"));
00283 maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
00284 maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
00285 }
00286
00287 void
00288 KDateTable::wheelEvent ( QWheelEvent * e )
00289 {
00290 setDate(date.addMonths( -(int)(e->delta()/120)) );
00291 e->accept();
00292 }
00293
00294 void
00295 KDateTable::contentsMousePressEvent(QMouseEvent *e)
00296 {
00297 if(e->type()!=QEvent::MouseButtonPress)
00298 {
00299 return;
00300 }
00301 if(!isEnabled())
00302 {
00303 KNotifyClient::beep();
00304 return;
00305 }
00306
00307
00308 int dayoff = KGlobal::locale()->weekStartDay();
00309
00310 int row, col, pos, temp;
00311 QPoint mouseCoord;
00312
00313 mouseCoord = e->pos();
00314 row=rowAt(mouseCoord.y());
00315 col=columnAt(mouseCoord.x());
00316 if(row<1 || col<0)
00317 {
00318 return;
00319 }
00320
00321
00322
00323
00324
00325 pos = (7 * (row - 1)) + col + 1;
00326
00327
00328
00329
00330
00331
00332
00333 if(pos + dayoff % 7 <= firstday)
00334 {
00335 setDate(date.addDays(-1 * (date.day() + firstday - pos - dayoff % 7)));
00336 return;
00337 }
00338 if(firstday + numdays < pos + dayoff % 7)
00339 {
00340 setDate(date.addDays(pos - firstday - date.day() + dayoff % 7));
00341 return;
00342 }
00343 temp = firstday + date.day() - dayoff % 7 - 1;
00344
00345 setDate(QDate(date.year(), date.month(), pos - firstday + dayoff % 7));
00346
00347 updateCell(temp/7+1, temp%7);
00348 updateCell(row, col);
00349
00350 emit(tableClicked());
00351 }
00352
00353 bool
00354 KDateTable::setDate(const QDate& date_)
00355 {
00356 bool changed=false;
00357 QDate temp;
00358
00359 if(!date_.isValid())
00360 {
00361 kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
00362 return false;
00363 }
00364 if(date!=date_)
00365 {
00366 date=date_;
00367 changed=true;
00368 }
00369 temp.setYMD(date.year(), date.month(), 1);
00370 firstday=temp.dayOfWeek();
00371 if(firstday==1) firstday=8;
00372 numdays=date.daysInMonth();
00373 if(date.month()==1)
00374 {
00375 temp.setYMD(date.year()-1, 12, 1);
00376 } else {
00377 temp.setYMD(date.year(), date.month()-1, 1);
00378 }
00379 numDaysPrevMonth=temp.daysInMonth();
00380 if(changed)
00381 {
00382 repaintContents(false);
00383 }
00384 emit(dateChanged(date));
00385 return true;
00386 }
00387
00388 const QDate&
00389 KDateTable::getDate() const
00390 {
00391 return date;
00392 }
00393
00394
00395 void KDateTable::focusInEvent( QFocusEvent *e )
00396 {
00397
00398 QGridView::focusInEvent( e );
00399 }
00400
00401 void KDateTable::focusOutEvent( QFocusEvent *e )
00402 {
00403
00404 QGridView::focusOutEvent( e );
00405 }
00406
00407 QSize
00408 KDateTable::sizeHint() const
00409 {
00410 if(maxCell.height()>0 && maxCell.width()>0)
00411 {
00412 return QSize(maxCell.width()*numCols()+2*frameWidth(),
00413 (maxCell.height()+2)*numRows()+2*frameWidth());
00414 } else {
00415 kdDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
00416 return QSize(-1, -1);
00417 }
00418 }
00419
00420 KDateInternalWeekSelector::KDateInternalWeekSelector
00421 (int fontsize, QWidget* parent, const char* name)
00422 : QLineEdit(parent, name),
00423 val(new QIntValidator(this)),
00424 result(0)
00425 {
00426 QFont font;
00427
00428 font=KGlobalSettings::generalFont();
00429 font.setPointSize(fontsize);
00430 setFont(font);
00431 setFrameStyle(QFrame::NoFrame);
00432 val->setRange(1, 53);
00433 setValidator(val);
00434 connect(this, SIGNAL(returnPressed()), SLOT(weekEnteredSlot()));
00435 }
00436
00437 void
00438 KDateInternalWeekSelector::weekEnteredSlot()
00439 {
00440 bool ok;
00441 int week;
00442
00443 week=text().toInt(&ok);
00444 if(!ok)
00445 {
00446 KNotifyClient::beep();
00447 return;
00448 }
00449 result=week;
00450 emit(closeMe(1));
00451 }
00452
00453 int
00454 KDateInternalWeekSelector::getWeek()
00455 {
00456 return result;
00457 }
00458
00459 void
00460 KDateInternalWeekSelector::setWeek(int week)
00461 {
00462 QString temp;
00463
00464 temp.setNum(week);
00465 setText(temp);
00466 }
00467
00468 KDateInternalMonthPicker::KDateInternalMonthPicker
00469 (int fontsize, QWidget* parent, const char* name)
00470 : QGridView(parent, name),
00471 result(0)
00472 {
00473 QRect rect;
00474 QFont font;
00475
00476 activeCol = -1;
00477 activeRow = -1;
00478 font=KGlobalSettings::generalFont();
00479 font.setPointSize(fontsize);
00480 setFont(font);
00481 setHScrollBarMode(AlwaysOff);
00482 setVScrollBarMode(AlwaysOff);
00483 setFrameStyle(QFrame::NoFrame);
00484 setNumRows(4);
00485 setNumCols(3);
00486
00487
00488 viewport()->setEraseColor(KGlobalSettings::baseColor());
00489
00490
00491 QFontMetrics metrics(font);
00492 for(int i=1; i <= 12; ++i)
00493 {
00494 rect=metrics.boundingRect(KGlobal::locale()->monthName(i, false));
00495 if(max.width()<rect.width()) max.setWidth(rect.width());
00496 if(max.height()<rect.height()) max.setHeight(rect.height());
00497 }
00498
00499 }
00500
00501 QSize
00502 KDateInternalMonthPicker::sizeHint() const
00503 {
00504 return QSize((max.width()+6)*numCols()+2*frameWidth(),
00505 (max.height()+6)*numRows()+2*frameWidth());
00506 }
00507
00508 int
00509 KDateInternalMonthPicker::getResult() const
00510 {
00511 return result;
00512 }
00513
00514 void
00515 KDateInternalMonthPicker::setupPainter(QPainter *p)
00516 {
00517 p->setPen(KGlobalSettings::textColor());
00518 }
00519
00520 void
00521 KDateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
00522 {
00523 setCellWidth(width()/3);
00524 setCellHeight(height()/4);
00525 }
00526
00527 void
00528 KDateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
00529 {
00530 int index;
00531 QString text;
00532
00533 index=3*row+col+1;
00534 text=KGlobal::locale()->monthName(index, false);
00535 painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
00536 if ( activeCol == col && activeRow == row )
00537 painter->drawRect( 0, 0, cellWidth(), cellHeight() );
00538 }
00539
00540 void
00541 KDateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
00542 {
00543 if(!isEnabled() || e->button() != LeftButton)
00544 {
00545 KNotifyClient::beep();
00546 return;
00547 }
00548
00549 int row, col;
00550 QPoint mouseCoord;
00551
00552 mouseCoord = e->pos();
00553 row=rowAt(mouseCoord.y());
00554 col=columnAt(mouseCoord.x());
00555
00556 if(row<0 || col<0)
00557 {
00558 activeCol = -1;
00559 activeRow = -1;
00560 } else {
00561 activeCol = col;
00562 activeRow = row;
00563 updateCell( row, col );
00564 }
00565 }
00566
00567 void
00568 KDateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
00569 {
00570 if (e->state() & LeftButton)
00571 {
00572 int row, col;
00573 QPoint mouseCoord;
00574
00575 mouseCoord = e->pos();
00576 row=rowAt(mouseCoord.y());
00577 col=columnAt(mouseCoord.x());
00578 int tmpRow = -1, tmpCol = -1;
00579 if(row<0 || col<0)
00580 {
00581 if ( activeCol > -1 )
00582 {
00583 tmpRow = activeRow;
00584 tmpCol = activeCol;
00585 }
00586 activeCol = -1;
00587 activeRow = -1;
00588 } else {
00589 bool differentCell = (activeRow != row || activeCol != col);
00590 if ( activeCol > -1 && differentCell)
00591 {
00592 tmpRow = activeRow;
00593 tmpCol = activeCol;
00594 }
00595 if ( differentCell)
00596 {
00597 activeRow = row;
00598 activeCol = col;
00599 updateCell( row, col );
00600 }
00601 }
00602 if ( tmpRow > -1 )
00603 updateCell( tmpRow, tmpCol );
00604 }
00605 }
00606
00607 void
00608 KDateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
00609 {
00610 if(!isEnabled())
00611 {
00612 return;
00613 }
00614
00615 int row, col, pos;
00616 QPoint mouseCoord;
00617
00618 mouseCoord = e->pos();
00619 row=rowAt(mouseCoord.y());
00620 col=columnAt(mouseCoord.x());
00621 if(row<0 || col<0)
00622 {
00623 emit(closeMe(0));
00624 }
00625 pos=3*row+col+1;
00626 result=pos;
00627 emit(closeMe(1));
00628 }
00629
00630
00631
00632 KDateInternalYearSelector::KDateInternalYearSelector
00633 (int fontsize, QWidget* parent, const char* name)
00634 : QLineEdit(parent, name),
00635 val(new QIntValidator(this)),
00636 result(0)
00637 {
00638 QFont font;
00639
00640 font=KGlobalSettings::generalFont();
00641 font.setPointSize(fontsize);
00642 setFont(font);
00643 setFrameStyle(QFrame::NoFrame);
00644
00645 val->setRange(0, 8000);
00646 setValidator(val);
00647 connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
00648 }
00649
00650 void
00651 KDateInternalYearSelector::yearEnteredSlot()
00652 {
00653 bool ok;
00654 int year;
00655 QDate date;
00656
00657 year=text().toInt(&ok);
00658 if(!ok)
00659 {
00660 KNotifyClient::beep();
00661 return;
00662 }
00663 date.setYMD(year, 1, 1);
00664 if(!date.isValid())
00665 {
00666 KNotifyClient::beep();
00667 return;
00668 }
00669 result=year;
00670 emit(closeMe(1));
00671 }
00672
00673 int
00674 KDateInternalYearSelector::getYear()
00675 {
00676 return result;
00677 }
00678
00679 void
00680 KDateInternalYearSelector::setYear(int year)
00681 {
00682 QString temp;
00683
00684 temp.setNum(year);
00685 setText(temp);
00686 }
00687
00688 KPopupFrame::KPopupFrame(QWidget* parent, const char* name)
00689 : QFrame(parent, name, WType_Popup),
00690 result(0),
00691 main(0)
00692 {
00693 setFrameStyle(QFrame::Box|QFrame::Raised);
00694 setMidLineWidth(2);
00695 }
00696
00697 void
00698 KPopupFrame::keyPressEvent(QKeyEvent* e)
00699 {
00700 if(e->key()==Key_Escape)
00701 {
00702 result=0;
00703 qApp->exit_loop();
00704 }
00705 }
00706
00707 void
00708 KPopupFrame::close(int r)
00709 {
00710 result=r;
00711 qApp->exit_loop();
00712 }
00713
00714 void
00715 KPopupFrame::setMainWidget(QWidget* m)
00716 {
00717 main=m;
00718 if(main!=0)
00719 {
00720 resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
00721 }
00722 }
00723
00724 void
00725 KPopupFrame::resizeEvent(QResizeEvent*)
00726 {
00727 if(main!=0)
00728 {
00729 main->setGeometry(frameWidth(), frameWidth(),
00730 width()-2*frameWidth(), height()-2*frameWidth());
00731 }
00732 }
00733
00734 void
00735 KPopupFrame::popup(const QPoint &pos)
00736 {
00737
00738 QRect d = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(pos));
00739 int x = pos.x();
00740 int y = pos.y();
00741 int w = width();
00742 int h = height();
00743 if (x+w > d.x()+d.width())
00744 x = d.width() - w;
00745 if (y+h > d.y()+d.height())
00746 y = d.height() - h;
00747 if (x < d.x())
00748 x = 0;
00749 if (y < d.y())
00750 y = 0;
00751
00752
00753 move(x, y);
00754 show();
00755 }
00756
00757 int
00758 KPopupFrame::exec(QPoint pos)
00759 {
00760 popup(pos);
00761 repaint();
00762 qApp->enter_loop();
00763 hide();
00764 return result;
00765 }
00766
00767 int
00768 KPopupFrame::exec(int x, int y)
00769 {
00770 return exec(QPoint(x, y));
00771 }
00772
00773 void KPopupFrame::virtual_hook( int, void* )
00774 { }
00775
00776 void KDateTable::virtual_hook( int, void* )
00777 { }
00778
00779 #include "kdatetbl.moc"