• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kdatetbl.cpp

Go to the documentation of this file.
00001 /*  -*- C++ -*-
00002     This file is part of the KDE libraries
00003     Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
00004               (C) 1998-2001 Mirko Boehm (mirko@kde.org)
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00022 //
00023 // Copyright (C) 1997 Tim D. Gilman
00024 //           (C) 1998-2001 Mirko Boehm
00025 // Written using Qt (http://www.troll.no) for the
00026 // KDE project (http://www.kde.org)
00027 //
00028 // This is a support class for the KDatePicker class.  It just
00029 // draws the calender table without titles, but could theoretically
00030 // be used as a standalone.
00031 //
00032 // When a date is selected by the user, it emits a signal:
00033 //      dateSelected(QDate)
00034 
00035 #include <kconfig.h>
00036 #include <kglobal.h>
00037 #include <kglobalsettings.h>
00038 #include <kapplication.h>
00039 #include <kaccel.h>
00040 #include <klocale.h>
00041 #include <kdebug.h>
00042 #include <knotifyclient.h>
00043 #include <kcalendarsystem.h>
00044 #include <kshortcut.h>
00045 #include <kstdaccel.h>
00046 #include "kdatepicker.h"
00047 #include "kdatetbl.h"
00048 #include "kpopupmenu.h"
00049 #include <qdatetime.h>
00050 #include <qguardedptr.h>
00051 #include <qstring.h>
00052 #include <qpen.h>
00053 #include <qpainter.h>
00054 #include <qdialog.h>
00055 #include <qdict.h>
00056 #include <assert.h>
00057 
00058 
00059 class KDateTable::KDateTablePrivate
00060 {
00061 public:
00062    KDateTablePrivate()
00063    {
00064       popupMenuEnabled=false;
00065       useCustomColors=false;
00066    }
00067 
00068    ~KDateTablePrivate()
00069    {
00070    }
00071 
00072    bool popupMenuEnabled;
00073    bool useCustomColors;
00074 
00075    struct DatePaintingMode
00076    {
00077      QColor fgColor;
00078      QColor bgColor;
00079      BackgroundMode bgMode;
00080    };
00081    QDict <DatePaintingMode> customPaintingModes;
00082 
00083 };
00084 
00085 
00086 KDateValidator::KDateValidator(QWidget* parent, const char* name)
00087     : QValidator(parent, name)
00088 {
00089 }
00090 
00091 QValidator::State
00092 KDateValidator::validate(QString& text, int&) const
00093 {
00094   QDate temp;
00095   // ----- everything is tested in date():
00096   return date(text, temp);
00097 }
00098 
00099 QValidator::State
00100 KDateValidator::date(const QString& text, QDate& d) const
00101 {
00102   QDate tmp = KGlobal::locale()->readDate(text);
00103   if (!tmp.isNull())
00104     {
00105       d = tmp;
00106       return Acceptable;
00107     } else
00108       return Valid;
00109 }
00110 
00111 void
00112 KDateValidator::fixup( QString& ) const
00113 {
00114 
00115 }
00116 
00117 KDateTable::KDateTable(QWidget *parent, QDate date_, const char* name, WFlags f)
00118   : QGridView(parent, name, (f | WNoAutoErase))
00119 {
00120   d = new KDateTablePrivate;
00121   setFontSize(10);
00122   if(!date_.isValid())
00123     {
00124       kdDebug() << "KDateTable ctor: WARNING: Given date is invalid, using current date." << endl;
00125       date_=QDate::currentDate();
00126     }
00127   setFocusPolicy( QWidget::StrongFocus );
00128   setNumRows(7); // 6 weeks max + headline
00129   setNumCols(7); // 7 days a week
00130   setHScrollBarMode(AlwaysOff);
00131   setVScrollBarMode(AlwaysOff);
00132   viewport()->setEraseColor(KGlobalSettings::baseColor());
00133   setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
00134 
00135   initAccels();
00136 }
00137 
00138 KDateTable::KDateTable(QWidget *parent, const char* name, WFlags f)
00139   : QGridView(parent, name, (f | WNoAutoErase))
00140 {
00141   d = new KDateTablePrivate;
00142   setFontSize(10);
00143   setFocusPolicy( QWidget::StrongFocus );
00144   setNumRows(7); // 6 weeks max + headline
00145   setNumCols(7); // 7 days a week
00146   setHScrollBarMode(AlwaysOff);
00147   setVScrollBarMode(AlwaysOff);
00148   viewport()->setEraseColor(KGlobalSettings::baseColor());
00149   setDate(QDate::currentDate()); // this initializes firstday, numdays, numDaysPrevMonth
00150   initAccels();
00151 }
00152 
00153 KDateTable::~KDateTable()
00154 {
00155   delete d;
00156 }
00157 
00158 void KDateTable::initAccels()
00159 {
00160   KAccel* accel = new KAccel(this, "date table accel");
00161   accel->insert(KStdAccel::Next, this, SLOT(nextMonth()));
00162   accel->insert(KStdAccel::Prior, this, SLOT(previousMonth()));
00163   accel->insert(KStdAccel::Home, this, SLOT(beginningOfMonth()));
00164   accel->insert(KStdAccel::End, this, SLOT(endOfMonth()));
00165   accel->insert(KStdAccel::BeginningOfLine, this, SLOT(beginningOfWeek()));
00166   accel->insert(KStdAccel::EndOfLine, this, SLOT(endOfWeek()));
00167   accel->readSettings();
00168 }
00169 
00170 int KDateTable::posFromDate( const QDate &dt )
00171 {
00172   const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00173   const int firstWeekDay = KGlobal::locale()->weekStartDay();
00174   int pos = calendar->day( dt );
00175   int offset = (firstday - firstWeekDay + 7) % 7;
00176   // make sure at least one day of the previous month is visible.
00177   // adjust this <1 if more days should be forced visible:
00178   if ( offset < 1 ) offset += 7;
00179   return pos + offset;
00180 }
00181 
00182 QDate KDateTable::dateFromPos( int pos )
00183 {
00184   QDate pCellDate;
00185   const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00186   calendar->setYMD(pCellDate, calendar->year(date), calendar->month(date), 1);
00187 
00188   int firstWeekDay = KGlobal::locale()->weekStartDay();
00189   int offset = (firstday - firstWeekDay + 7) % 7;
00190   // make sure at least one day of the previous month is visible.
00191   // adjust this <1 if more days should be forced visible:
00192   if ( offset < 1 ) offset += 7;
00193   pCellDate = calendar->addDays( pCellDate, pos - offset );
00194   return pCellDate;
00195 }
00196 
00197 void
00198 KDateTable::paintEmptyArea(QPainter *paint, int, int, int, int)
00199 {
00200   // Erase the unused areas on the right and bottom.
00201   QRect unusedRight = frameRect();
00202   unusedRight.setLeft(gridSize().width());
00203 
00204   QRect unusedBottom = frameRect();
00205   unusedBottom.setTop(gridSize().height());
00206 
00207   paint->eraseRect(unusedRight);
00208   paint->eraseRect(unusedBottom);
00209 }
00210 
00211 void
00212 KDateTable::paintCell(QPainter *painter, int row, int col)
00213 {
00214   const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00215 
00216   QRect rect;
00217   QString text;
00218   QPen pen;
00219   int w=cellWidth();
00220   int h=cellHeight();
00221   QFont font=KGlobalSettings::generalFont();
00222   // -----
00223 
00224   if(row == 0)
00225     { // we are drawing the headline
00226       font.setBold(true);
00227       painter->setFont(font);
00228       bool normalday = true;
00229       int firstWeekDay = KGlobal::locale()->weekStartDay();
00230       int daynum = ( col+firstWeekDay < 8 ) ? col+firstWeekDay :
00231                                               col+firstWeekDay-7;
00232       if ( daynum == calendar->weekDayOfPray() ||
00233          ( daynum == 6 && calendar->calendarName() == "gregorian" ) )
00234           normalday=false;
00235 
00236             QBrush brushInvertTitle(colorGroup().base());
00237             QColor titleColor(isEnabled()?( KGlobalSettings::activeTitleColor() ):( KGlobalSettings::inactiveTitleColor() ) );
00238             QColor textColor(isEnabled()?( KGlobalSettings::activeTextColor() ):( KGlobalSettings::inactiveTextColor() ) );
00239       if (!normalday)
00240         {
00241           painter->setPen(textColor);
00242           painter->setBrush(textColor);
00243           painter->drawRect(0, 0, w, h);
00244           painter->setPen(titleColor);
00245         } else {
00246           painter->setPen(titleColor);
00247           painter->setBrush(titleColor);
00248           painter->drawRect(0, 0, w, h);
00249           painter->setPen(textColor);
00250         }
00251       painter->drawText(0, 0, w, h-1, AlignCenter,
00252                         calendar->weekDayName(daynum, true), -1, &rect);
00253       painter->setPen(colorGroup().text());
00254       painter->moveTo(0, h-1);
00255       painter->lineTo(w-1, h-1);
00256       // ----- draw the weekday:
00257     } else {
00258       bool paintRect=true;
00259       painter->setFont(font);
00260       int pos=7*(row-1)+col;
00261 
00262       QDate pCellDate = dateFromPos( pos );
00263       // First day of month
00264       text = calendar->dayString(pCellDate, true);
00265       if( calendar->month(pCellDate) != calendar->month(date) )
00266         { // we are either
00267           // ° painting a day of the previous month or
00268           // ° painting a day of the following month
00269           // TODO: don't hardcode gray here! Use a color with less contrast to the background than normal text.
00270           painter->setPen( colorGroup().mid() );
00271 //          painter->setPen(gray);
00272         } else { // paint a day of the current month
00273           if ( d->useCustomColors )
00274           {
00275             KDateTablePrivate::DatePaintingMode *mode=d->customPaintingModes[pCellDate.toString()];
00276             if (mode)
00277             {
00278               if (mode->bgMode != NoBgMode)
00279               {
00280                 QBrush oldbrush=painter->brush();
00281                 painter->setBrush( mode->bgColor );
00282                 switch(mode->bgMode)
00283                 {
00284                   case(CircleMode) : painter->drawEllipse(0,0,w,h);break;
00285                   case(RectangleMode) : painter->drawRect(0,0,w,h);break;
00286                   case(NoBgMode) : // Should never be here, but just to get one
00287                                    // less warning when compiling
00288                   default: break;
00289                 }
00290                 painter->setBrush( oldbrush );
00291                 paintRect=false;
00292               }
00293               painter->setPen( mode->fgColor );
00294             } else
00295               painter->setPen(colorGroup().text());
00296           } else //if ( firstWeekDay < 4 ) // <- this doesn' make sense at all!
00297           painter->setPen(colorGroup().text());
00298         }
00299 
00300       pen=painter->pen();
00301       int firstWeekDay=KGlobal::locale()->weekStartDay();
00302       int offset=firstday-firstWeekDay;
00303       if(offset<1)
00304         offset+=7;
00305       int d = calendar->day(date);
00306            if( (offset+d) == (pos+1))
00307         {
00308            // draw the currently selected date
00309        if (isEnabled())
00310        {
00311            painter->setPen(colorGroup().highlight());
00312            painter->setBrush(colorGroup().highlight());
00313        }
00314        else
00315        {
00316        painter->setPen(colorGroup().text());
00317            painter->setBrush(colorGroup().text());
00318        }
00319            pen=colorGroup().highlightedText();
00320         } else {
00321           painter->setBrush(paletteBackgroundColor());
00322           painter->setPen(paletteBackgroundColor());
00323 //          painter->setBrush(colorGroup().base());
00324 //          painter->setPen(colorGroup().base());
00325         }
00326 
00327       if ( pCellDate == QDate::currentDate() )
00328       {
00329          painter->setPen(colorGroup().text());
00330       }
00331 
00332       if ( paintRect ) painter->drawRect(0, 0, w, h);
00333       painter->setPen(pen);
00334       painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
00335     }
00336   if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
00337   if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
00338 }
00339 
00340 void KDateTable::nextMonth()
00341 {
00342     const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00343   setDate(calendar->addMonths( date, 1 ));
00344 }
00345 
00346 void KDateTable::previousMonth()
00347 {
00348   const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00349   setDate(calendar->addMonths( date, -1 ));
00350 }
00351 
00352 void KDateTable::beginningOfMonth()
00353 {
00354   setDate(date.addDays(1 - date.day()));
00355 }
00356 
00357 void KDateTable::endOfMonth()
00358 {
00359   setDate(date.addDays(date.daysInMonth() - date.day()));
00360 }
00361 
00362 void KDateTable::beginningOfWeek()
00363 {
00364   setDate(date.addDays(1 - date.dayOfWeek()));
00365 }
00366 
00367 void KDateTable::endOfWeek()
00368 {
00369   setDate(date.addDays(7 - date.dayOfWeek()));
00370 }
00371 
00372 void
00373 KDateTable::keyPressEvent( QKeyEvent *e )
00374 {
00375     switch( e->key() ) {
00376     case Key_Up:
00377             setDate(date.addDays(-7));
00378         break;
00379     case Key_Down:
00380             setDate(date.addDays(7));
00381         break;
00382     case Key_Left:
00383             setDate(date.addDays(-1));
00384         break;
00385     case Key_Right:
00386             setDate(date.addDays(1));
00387         break;
00388     case Key_Minus:
00389         setDate(date.addDays(-1));
00390     break;
00391     case Key_Plus:
00392         setDate(date.addDays(1));
00393     break;
00394     case Key_N:
00395         setDate(QDate::currentDate());
00396     break;
00397     case Key_Return:
00398     case Key_Enter:
00399         emit tableClicked();
00400         break;
00401     case Key_Control:
00402     case Key_Alt:
00403     case Key_Meta:
00404     case Key_Shift:
00405       // Don't beep for modifiers
00406       break;
00407     default:
00408       if (!e->state()) { // hm
00409     KNotifyClient::beep();
00410 }
00411     }
00412 }
00413 
00414 void
00415 KDateTable::viewportResizeEvent(QResizeEvent * e)
00416 {
00417   QGridView::viewportResizeEvent(e);
00418 
00419   setCellWidth(viewport()->width()/7);
00420   setCellHeight(viewport()->height()/7);
00421 }
00422 
00423 void
00424 KDateTable::setFontSize(int size)
00425 {
00426   int count;
00427   QFontMetrics metrics(fontMetrics());
00428   QRect rect;
00429   // ----- store rectangles:
00430   fontsize=size;
00431   // ----- find largest day name:
00432   maxCell.setWidth(0);
00433   maxCell.setHeight(0);
00434   for(count=0; count<7; ++count)
00435     {
00436       rect=metrics.boundingRect(KGlobal::locale()->calendar()
00437                                 ->weekDayName(count+1, true));
00438       maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
00439       maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
00440     }
00441   // ----- compare with a real wide number and add some space:
00442   rect=metrics.boundingRect(QString::fromLatin1("88"));
00443   maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
00444   maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
00445 }
00446 
00447 void
00448 KDateTable::wheelEvent ( QWheelEvent * e )
00449 {
00450     setDate(date.addMonths( -(int)(e->delta()/120)) );
00451     e->accept();
00452 }
00453 
00454 void
00455 KDateTable::contentsMousePressEvent(QMouseEvent *e)
00456 {
00457 
00458   if(e->type()!=QEvent::MouseButtonPress)
00459     { // the KDatePicker only reacts on mouse press events:
00460       return;
00461     }
00462   if(!isEnabled())
00463     {
00464       KNotifyClient::beep();
00465       return;
00466     }
00467 
00468   // -----
00469   int row, col, pos, temp;
00470   QPoint mouseCoord;
00471   // -----
00472   mouseCoord = e->pos();
00473   row=rowAt(mouseCoord.y());
00474   col=columnAt(mouseCoord.x());
00475   if(row<1 || col<0)
00476     { // the user clicked on the frame of the table
00477       return;
00478     }
00479 
00480   // Rows and columns are zero indexed.  The (row - 1) below is to avoid counting
00481   // the row with the days of the week in the calculation.
00482 
00483   // old selected date:
00484   temp = posFromDate( date );
00485   // new position and date
00486   pos = (7 * (row - 1)) + col;
00487   QDate clickedDate = dateFromPos( pos );
00488 
00489   // set the new date. If it is in the previous or next month, the month will
00490   // automatically be changed, no need to do that manually...
00491   setDate( clickedDate );
00492 
00493   // call updateCell on the old and new selection. If setDate switched to a different
00494   // month, these cells will be painted twice, but that's no problem.
00495   updateCell( temp/7+1, temp%7 );
00496   updateCell( row, col );
00497 
00498   emit tableClicked();
00499 
00500   if (  e->button() == Qt::RightButton && d->popupMenuEnabled )
00501   {
00502         KPopupMenu *menu = new KPopupMenu();
00503         menu->insertTitle( KGlobal::locale()->formatDate(clickedDate) );
00504         emit aboutToShowContextMenu( menu, clickedDate );
00505         menu->popup(e->globalPos());
00506   }
00507 }
00508 
00509 bool
00510 KDateTable::setDate(const QDate& date_)
00511 {
00512   bool changed=false;
00513   QDate temp;
00514   // -----
00515   if(!date_.isValid())
00516     {
00517       kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
00518       return false;
00519     }
00520   if(date!=date_)
00521     {
00522       emit(dateChanged(date, date_));
00523       date=date_;
00524       emit(dateChanged(date));
00525       changed=true;
00526     }
00527   const KCalendarSystem * calendar = KGlobal::locale()->calendar();
00528 
00529   calendar->setYMD(temp, calendar->year(date), calendar->month(date), 1);
00530   //temp.setYMD(date.year(), date.month(), 1);
00531   //kdDebug() << "firstDayInWeek: " << temp.toString() << endl;
00532   firstday=temp.dayOfWeek();
00533   numdays=calendar->daysInMonth(date);
00534 
00535   temp = calendar->addMonths(temp, -1);
00536   numDaysPrevMonth=calendar->daysInMonth(temp);
00537   if(changed)
00538     {
00539       repaintContents(false);
00540     }
00541   return true;
00542 }
00543 
00544 const QDate&
00545 KDateTable::getDate() const
00546 {
00547   return date;
00548 }
00549 
00550 // what are those repaintContents() good for? (pfeiffer)
00551 void KDateTable::focusInEvent( QFocusEvent *e )
00552 {
00553 //    repaintContents(false);
00554     QGridView::focusInEvent( e );
00555 }
00556 
00557 void KDateTable::focusOutEvent( QFocusEvent *e )
00558 {
00559 //    repaintContents(false);
00560     QGridView::focusOutEvent( e );
00561 }
00562 
00563 QSize
00564 KDateTable::sizeHint() const
00565 {
00566   if(maxCell.height()>0 && maxCell.width()>0)
00567     {
00568       return QSize(maxCell.width()*numCols()+2*frameWidth(),
00569              (maxCell.height()+2)*numRows()+2*frameWidth());
00570     } else {
00571       kdDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
00572       return QSize(-1, -1);
00573     }
00574 }
00575 
00576 void KDateTable::setPopupMenuEnabled( bool enable )
00577 {
00578    d->popupMenuEnabled=enable;
00579 }
00580 
00581 bool KDateTable::popupMenuEnabled() const
00582 {
00583    return d->popupMenuEnabled;
00584 }
00585 
00586 void KDateTable::setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor)
00587 {
00588     if (!fgColor.isValid())
00589     {
00590         unsetCustomDatePainting( date );
00591         return;
00592     }
00593 
00594     KDateTablePrivate::DatePaintingMode *mode=new KDateTablePrivate::DatePaintingMode;
00595     mode->bgMode=bgMode;
00596     mode->fgColor=fgColor;
00597     mode->bgColor=bgColor;
00598 
00599     d->customPaintingModes.replace( date.toString(), mode );
00600     d->useCustomColors=true;
00601     update();
00602 }
00603 
00604 void KDateTable::unsetCustomDatePainting( const QDate &date )
00605 {
00606     d->customPaintingModes.remove( date.toString() );
00607 }
00608 
00609 KDateInternalWeekSelector::KDateInternalWeekSelector
00610 (QWidget* parent, const char* name)
00611   : QLineEdit(parent, name),
00612     val(new QIntValidator(this)),
00613     result(0)
00614 {
00615   QFont font;
00616   // -----
00617   font=KGlobalSettings::generalFont();
00618   setFont(font);
00619   setFrameStyle(QFrame::NoFrame);
00620   setValidator(val);
00621   connect(this, SIGNAL(returnPressed()), SLOT(weekEnteredSlot()));
00622 }
00623 
00624 void
00625 KDateInternalWeekSelector::weekEnteredSlot()
00626 {
00627   bool ok;
00628   int week;
00629   // ----- check if this is a valid week:
00630   week=text().toInt(&ok);
00631   if(!ok)
00632     {
00633       KNotifyClient::beep();
00634       emit(closeMe(0));
00635       return;
00636     }
00637   result=week;
00638   emit(closeMe(1));
00639 }
00640 
00641 int
00642 KDateInternalWeekSelector::getWeek()
00643 {
00644   return result;
00645 }
00646 
00647 void
00648 KDateInternalWeekSelector::setWeek(int week)
00649 {
00650   QString temp;
00651   // -----
00652   temp.setNum(week);
00653   setText(temp);
00654 }
00655 
00656 void
00657 KDateInternalWeekSelector::setMaxWeek(int max)
00658 {
00659   val->setRange(1, max);
00660 }
00661 
00662 // ### CFM To avoid binary incompatibility.
00663 //     In future releases, remove this and replace by  a QDate
00664 //     private member, needed in KDateInternalMonthPicker::paintCell
00665 class KDateInternalMonthPicker::KDateInternalMonthPrivate {
00666 public:
00667         KDateInternalMonthPrivate (int y, int m, int d)
00668         : year(y), month(m), day(d)
00669         {}
00670         int year;
00671         int month;
00672         int day;
00673 };
00674 
00675 KDateInternalMonthPicker::~KDateInternalMonthPicker() {
00676    delete d;
00677 }
00678 
00679 KDateInternalMonthPicker::KDateInternalMonthPicker
00680 (const QDate & date, QWidget* parent, const char* name)
00681   : QGridView(parent, name),
00682     result(0) // invalid
00683 {
00684   QRect rect;
00685   QFont font;
00686   // -----
00687   activeCol = -1;
00688   activeRow = -1;
00689   font=KGlobalSettings::generalFont();
00690   setFont(font);
00691   setHScrollBarMode(AlwaysOff);
00692   setVScrollBarMode(AlwaysOff);
00693   setFrameStyle(QFrame::NoFrame);
00694   setNumCols(3);
00695   d = new KDateInternalMonthPrivate(date.year(), date.month(), date.day());
00696   // For monthsInYear != 12
00697   setNumRows( (KGlobal::locale()->calendar()->monthsInYear(date) + 2) / 3);
00698   // enable to find drawing failures:
00699   // setTableFlags(Tbl_clipCellPainting);
00700   viewport()->setEraseColor(KGlobalSettings::baseColor()); // for consistency with the datepicker
00701   // ----- find the preferred size
00702   //       (this is slow, possibly, but unfortunately it is needed here):
00703   QFontMetrics metrics(font);
00704   for(int i = 1; ; ++i)
00705     {
00706       QString str = KGlobal::locale()->calendar()->monthName(i,
00707          KGlobal::locale()->calendar()->year(date), false);
00708       if (str.isNull()) break;
00709       rect=metrics.boundingRect(str);
00710       if(max.width()<rect.width()) max.setWidth(rect.width());
00711       if(max.height()<rect.height()) max.setHeight(rect.height());
00712     }
00713 }
00714 
00715 QSize
00716 KDateInternalMonthPicker::sizeHint() const
00717 {
00718   return QSize((max.width()+6)*numCols()+2*frameWidth(),
00719          (max.height()+6)*numRows()+2*frameWidth());
00720 }
00721 
00722 int
00723 KDateInternalMonthPicker::getResult() const
00724 {
00725   return result;
00726 }
00727 
00728 void
00729 KDateInternalMonthPicker::setupPainter(QPainter *p)
00730 {
00731   p->setPen(KGlobalSettings::textColor());
00732 }
00733 
00734 void
00735 KDateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
00736 {
00737   setCellWidth(width() / numCols());
00738   setCellHeight(height() / numRows());
00739 }
00740 
00741 void
00742 KDateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
00743 {
00744   int index;
00745   QString text;
00746   // ----- find the number of the cell:
00747   index=3*row+col+1;
00748   text=KGlobal::locale()->calendar()->monthName(index,
00749     KGlobal::locale()->calendar()->year(QDate(d->year, d->month,
00750     d->day)), false);
00751   painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
00752   if ( activeCol == col && activeRow == row )
00753       painter->drawRect( 0, 0, cellWidth(), cellHeight() );
00754 }
00755 
00756 void
00757 KDateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
00758 {
00759   if(!isEnabled() || e->button() != LeftButton)
00760     {
00761       KNotifyClient::beep();
00762       return;
00763     }
00764   // -----
00765   int row, col;
00766   QPoint mouseCoord;
00767   // -----
00768   mouseCoord = e->pos();
00769   row=rowAt(mouseCoord.y());
00770   col=columnAt(mouseCoord.x());
00771 
00772   if(row<0 || col<0)
00773     { // the user clicked on the frame of the table
00774       activeCol = -1;
00775       activeRow = -1;
00776     } else {
00777       activeCol = col;
00778       activeRow = row;
00779       updateCell( row, col /*, false */ );
00780   }
00781 }
00782 
00783 void
00784 KDateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
00785 {
00786   if (e->state() & LeftButton)
00787     {
00788       int row, col;
00789       QPoint mouseCoord;
00790       // -----
00791       mouseCoord = e->pos();
00792       row=rowAt(mouseCoord.y());
00793       col=columnAt(mouseCoord.x());
00794       int tmpRow = -1, tmpCol = -1;
00795       if(row<0 || col<0)
00796         { // the user clicked on the frame of the table
00797           if ( activeCol > -1 )
00798             {
00799               tmpRow = activeRow;
00800               tmpCol = activeCol;
00801             }
00802           activeCol = -1;
00803           activeRow = -1;
00804         } else {
00805           bool differentCell = (activeRow != row || activeCol != col);
00806           if ( activeCol > -1 && differentCell)
00807             {
00808               tmpRow = activeRow;
00809               tmpCol = activeCol;
00810             }
00811           if ( differentCell)
00812             {
00813               activeRow = row;
00814               activeCol = col;
00815               updateCell( row, col /*, false */ ); // mark the new active cell
00816             }
00817         }
00818       if ( tmpRow > -1 ) // repaint the former active cell
00819           updateCell( tmpRow, tmpCol /*, true */ );
00820     }
00821 }
00822 
00823 void
00824 KDateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
00825 {
00826   if(!isEnabled())
00827     {
00828       return;
00829     }
00830   // -----
00831   int row, col, pos;
00832   QPoint mouseCoord;
00833   // -----
00834   mouseCoord = e->pos();
00835   row=rowAt(mouseCoord.y());
00836   col=columnAt(mouseCoord.x());
00837   if(row<0 || col<0)
00838     { // the user clicked on the frame of the table
00839       emit(closeMe(0));
00840       return;
00841     }
00842 
00843   pos=3*row+col+1;
00844   result=pos;
00845   emit(closeMe(1));
00846 }
00847 
00848 
00849 
00850 KDateInternalYearSelector::KDateInternalYearSelector
00851 (QWidget* parent, const char* name)
00852   : QLineEdit(parent, name),
00853     val(new QIntValidator(this)),
00854     result(0)
00855 {
00856   QFont font;
00857   // -----
00858   font=KGlobalSettings::generalFont();
00859   setFont(font);
00860   setFrameStyle(QFrame::NoFrame);
00861   // we have to respect the limits of QDate here, I fear:
00862   val->setRange(0, 8000);
00863   setValidator(val);
00864   connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
00865 }
00866 
00867 void
00868 KDateInternalYearSelector::yearEnteredSlot()
00869 {
00870   bool ok;
00871   int year;
00872   QDate date;
00873   // ----- check if this is a valid year:
00874   year=text().toInt(&ok);
00875   if(!ok)
00876     {
00877       KNotifyClient::beep();
00878       emit(closeMe(0));
00879       return;
00880     }
00881   //date.setYMD(year, 1, 1);
00882   KGlobal::locale()->calendar()->setYMD(date, year, 1, 1);
00883   if(!date.isValid())
00884     {
00885       KNotifyClient::beep();
00886       emit(closeMe(0));
00887       return;
00888     }
00889   result=year;
00890   emit(closeMe(1));
00891 }
00892 
00893 int
00894 KDateInternalYearSelector::getYear()
00895 {
00896   return result;
00897 }
00898 
00899 void
00900 KDateInternalYearSelector::setYear(int year)
00901 {
00902   QString temp;
00903   // -----
00904   temp.setNum(year);
00905   setText(temp);
00906 }
00907 
00908 class KPopupFrame::KPopupFramePrivate
00909 {
00910     public:
00911         KPopupFramePrivate() : exec(false) {}
00912 
00913         bool exec;
00914 };
00915 
00916 KPopupFrame::KPopupFrame(QWidget* parent, const char*  name)
00917   : QFrame(parent, name, WType_Popup),
00918     result(0), // rejected
00919     main(0),
00920     d(new KPopupFramePrivate)
00921 {
00922   setFrameStyle(QFrame::Box|QFrame::Raised);
00923   setMidLineWidth(2);
00924 }
00925 
00926 KPopupFrame::~KPopupFrame()
00927 {
00928     delete d;
00929 }
00930 
00931 void
00932 KPopupFrame::keyPressEvent(QKeyEvent* e)
00933 {
00934   if(e->key()==Key_Escape)
00935     {
00936       result=0; // rejected
00937       d->exec = false;
00938       qApp->exit_loop();
00939     }
00940 }
00941 
00942 void
00943 KPopupFrame::close(int r)
00944 {
00945   result=r;
00946   d->exec = false;
00947   qApp->exit_loop();
00948 }
00949 
00950 void
00951 KPopupFrame::hide()
00952 {
00953     QFrame::hide();
00954     if (d->exec)
00955     {
00956         d->exec = false;
00957         qApp->exit_loop();
00958     }
00959 }
00960 
00961 void
00962 KPopupFrame::setMainWidget(QWidget* m)
00963 {
00964   main=m;
00965   if(main)
00966     {
00967       resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
00968     }
00969 }
00970 
00971 void
00972 KPopupFrame::resizeEvent(QResizeEvent*)
00973 {
00974   if(main)
00975     {
00976       main->setGeometry(frameWidth(), frameWidth(),
00977           width()-2*frameWidth(), height()-2*frameWidth());
00978     }
00979 }
00980 
00981 void
00982 KPopupFrame::popup(const QPoint &pos)
00983 {
00984   // Make sure the whole popup is visible.
00985   QRect d = KGlobalSettings::desktopGeometry(pos);
00986 
00987   int x = pos.x();
00988   int y = pos.y();
00989   int w = width();
00990   int h = height();
00991   if (x+w > d.x()+d.width())
00992     x = d.width() - w;
00993   if (y+h > d.y()+d.height())
00994     y = d.height() - h;
00995   if (x < d.x())
00996     x = 0;
00997   if (y < d.y())
00998     y = 0;
00999 
01000   // Pop the thingy up.
01001   move(x, y);
01002   show();
01003 }
01004 
01005 int
01006 KPopupFrame::exec(QPoint pos)
01007 {
01008   popup(pos);
01009   repaint();
01010   d->exec = true;
01011   const QGuardedPtr<QObject> that = this;
01012   qApp->enter_loop();
01013   if ( !that )
01014     return QDialog::Rejected;
01015   hide();
01016   return result;
01017 }
01018 
01019 int
01020 KPopupFrame::exec(int x, int y)
01021 {
01022   return exec(QPoint(x, y));
01023 }
01024 
01025 void KPopupFrame::virtual_hook( int, void* )
01026 { /*BASE::virtual_hook( id, data );*/ }
01027 
01028 void KDateTable::virtual_hook( int, void* )
01029 { /*BASE::virtual_hook( id, data );*/ }
01030 
01031 #include "kdatetbl.moc"

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal