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