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