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

KDEUI

kdatetable.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               (C) 2007 John Layt <john@layt.net>
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kdatetable.h"
00023 
00024 #include <kconfig.h>
00025 #include <kcolorscheme.h>
00026 #include <kglobal.h>
00027 #include <kglobalsettings.h>
00028 #include <klocale.h>
00029 #include <kdebug.h>
00030 #include <knotification.h>
00031 #include <kcalendarsystem.h>
00032 #include <kshortcut.h>
00033 #include <kstandardshortcut.h>
00034 #include "kdatepicker.h"
00035 #include "kmenu.h"
00036 #include "kactioncollection.h"
00037 #include "kaction.h"
00038 #include <kdeversion.h>
00039 
00040 #include <QtCore/QDate>
00041 #include <QtCore/QCharRef>
00042 #include <QtGui/QPen>
00043 #include <QtGui/QPainter>
00044 #include <QtGui/QDialog>
00045 #include <QtGui/QActionEvent>
00046 #include <QtCore/QHash>
00047 #include <QtGui/QApplication>
00048 #include <assert.h>
00049 
00050 #include <cmath>
00051 
00052 class KDateTable::KDateTablePrivate
00053 {
00054 public:
00055     KDateTablePrivate( KDateTable *q ): q( q )
00056     {
00057         popupMenuEnabled = false;
00058         useCustomColors = false;
00059         m_calendar = 0;
00060     }
00061 
00062     ~KDateTablePrivate()
00063     {
00064     }
00065 
00066     void nextMonth();
00067     void previousMonth();
00068     void beginningOfMonth();
00069     void endOfMonth();
00070     void beginningOfWeek();
00071     void endOfWeek();
00072 
00073     KDateTable *q;
00074 
00078     int fontsize;
00079 
00083     QDate mDate;
00084 
00088     int weekDayFirstOfMonth;
00089 
00093     int numDaysThisMonth;
00094 
00098     QRectF maxCell;
00099 
00103     int numWeekRows;
00104 
00108     int numDayColumns;
00109 
00110     bool popupMenuEnabled : 1;
00111     bool useCustomColors : 1;
00112 
00113     struct DatePaintingMode
00114     {
00115         QColor fgColor;
00116         QColor bgColor;
00117         BackgroundMode bgMode;
00118     };
00119     QHash <QString, DatePaintingMode*> customPaintingModes;
00120 
00121     KCalendarSystem *m_calendar;
00122 
00123 };
00124 
00125 
00126 class KPopupFrame::KPopupFramePrivate
00127 {
00128 public:
00129     KPopupFramePrivate( KPopupFrame *q ):
00130             q( q ),
00131             result( 0 ), // rejected
00132             main( 0 )
00133     {
00134     }
00135 
00136     KPopupFrame *q;
00137 
00141     int result;
00142 
00146     QWidget *main;
00147 };
00148 
00149 
00150 class KDateValidator::KDateValidatorPrivate
00151 {
00152 public:
00153     KDateValidatorPrivate( KDateValidator *q ): q( q )
00154     {
00155     }
00156 
00157     ~KDateValidatorPrivate()
00158     {
00159     }
00160 
00161     KDateValidator *q;
00162 };
00163 
00164 KDateValidator::KDateValidator( QWidget *parent ) : QValidator( parent ), d( 0 )
00165 {
00166 }
00167 
00168 QValidator::State KDateValidator::validate( QString &text, int &unused ) const
00169 {
00170     Q_UNUSED( unused );
00171 
00172     QDate temp;
00173     // ----- everything is tested in date():
00174     return date( text, temp );
00175 }
00176 
00177 QValidator::State KDateValidator::date( const QString &text, QDate &d ) const
00178 {
00179     QDate tmp = KGlobal::locale()->readDate( text );
00180     if ( !tmp.isNull() ) {
00181         d = tmp;
00182         return Acceptable;
00183     } else {
00184         return QValidator::Intermediate;
00185     }
00186 }
00187 
00188 void KDateValidator::fixup( QString& ) const
00189 {
00190 }
00191 
00192 KDateTable::KDateTable( const QDate& date_, QWidget* parent )
00193            : QWidget( parent ), d( new KDateTablePrivate( this ) )
00194 {
00195     d->numWeekRows = 7;
00196     d->numDayColumns = calendar()->daysInWeek( date_ );
00197     setFontSize( 10 );
00198     setFocusPolicy( Qt::StrongFocus );
00199     QPalette palette;
00200     palette.setColor( backgroundRole(), KColorScheme(QPalette::Active, KColorScheme::View).background().color() );
00201     setPalette( palette );
00202 
00203     if( !setDate( date_ ) ) {
00204         // this initializes weekDayFirstOfMonth, numDaysThisMonth
00205         setDate( QDate::currentDate() );
00206     }
00207     initAccels();
00208 }
00209 
00210 KDateTable::KDateTable( QWidget *parent )
00211            : QWidget( parent ), d( new KDateTablePrivate( this ) )
00212 {
00213     // JPL should we just call KDateTable( QDate::currentDate(), parent ) here to save duplication?
00214     // Or if that is a problem with base class instantiation move all to a private init()
00215     d->numWeekRows = 7;
00216     d->numDayColumns = calendar()->daysInWeek( QDate::currentDate() );
00217     setFontSize( 10 );
00218     setFocusPolicy( Qt::StrongFocus );
00219     QPalette palette;
00220     palette.setColor( backgroundRole(), KColorScheme(QPalette::Active, KColorScheme::View).background().color() );
00221     setPalette( palette );
00222     // this initializes weekDayFirstOfMonth, numDaysThisMonth
00223     setDate( QDate::currentDate() );
00224     initAccels();
00225 }
00226 
00227 KDateTable::~KDateTable()
00228 {
00229     delete d;
00230 }
00231 
00232 void KDateTable::initAccels()
00233 {
00234     KActionCollection * localCollection = new KActionCollection( this );
00235 
00236     KAction* next = localCollection->addAction( QLatin1String( "next" ) );
00237     next->setShortcuts( KStandardShortcut::next() );
00238     connect( next, SIGNAL( triggered( bool ) ), SLOT( nextMonth() ) );
00239 
00240     KAction* prior = localCollection->addAction( QLatin1String( "prior" ) );
00241     prior->setShortcuts( KStandardShortcut::prior() );
00242     connect( prior, SIGNAL( triggered( bool ) ), SLOT( previousMonth() ) );
00243 
00244     KAction* beginMonth = localCollection->addAction( QLatin1String( "beginMonth" ) );
00245     beginMonth->setShortcuts( KStandardShortcut::begin() );
00246     connect( beginMonth, SIGNAL( triggered( bool ) ), SLOT( beginningOfMonth() ) );
00247 
00248     KAction* endMonth = localCollection->addAction( QLatin1String( "endMonth" ) );
00249     endMonth->setShortcuts( KStandardShortcut::end() );
00250     connect( endMonth, SIGNAL( triggered( bool ) ), SLOT( endOfMonth() ) );
00251 
00252     KAction* beginWeek = localCollection->addAction( QLatin1String( "beginWeek" ) );
00253     beginWeek->setShortcuts( KStandardShortcut::beginningOfLine() );
00254     connect( beginWeek, SIGNAL( triggered( bool ) ), SLOT( beginningOfWeek() ) );
00255 
00256     KAction* endWeek = localCollection->addAction( "endWeek" );
00257     endWeek->setShortcuts( KStandardShortcut::endOfLine() );
00258     connect( endWeek, SIGNAL( triggered( bool ) ), SLOT( endOfWeek() ) );
00259 
00260     localCollection->readSettings();
00261     localCollection->addAssociatedWidget( this );
00262     foreach (QAction* action, localCollection->actions())
00263         action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
00264 }
00265 
00266 int KDateTable::posFromDate( const QDate &date_ )
00267 {
00268     int initialPosition = calendar()->day( date_ );
00269     int offset = ( d->weekDayFirstOfMonth - calendar()->weekStartDay() + d->numDayColumns ) % d->numDayColumns;
00270 
00271     // make sure at least one day of the previous month is visible.
00272     // adjust this < 1 if more days should be forced visible:
00273     if ( offset < 1 ) {
00274         offset += d->numDayColumns;
00275     }
00276 
00277     return initialPosition + offset;
00278 }
00279 
00280 QDate KDateTable::dateFromPos( int position )
00281 {
00282     QDate cellDate;
00283 
00284     int offset = ( d->weekDayFirstOfMonth - calendar()->weekStartDay() + d->numDayColumns ) % d->numDayColumns;
00285 
00286     // make sure at least one day of the previous month is visible.
00287     // adjust this < 1 if more days should be forced visible:
00288     if ( offset < 1 ) {
00289         offset += d->numDayColumns;
00290     }
00291 
00292     if ( calendar()->setYMD( cellDate, calendar()->year( d->mDate ), calendar()->month( d->mDate ), 1 ) ) {
00293         cellDate = calendar()->addDays( cellDate, position - offset );
00294     } else {
00295         //If first of month is not valid, then that must be before earliestValid Date, so safe to assume next month ok
00296         if ( calendar()->setYMD( cellDate, calendar()->year( d->mDate ), calendar()->month( d->mDate ) + 1, 1 ) ) {
00297             cellDate = calendar()->addDays( cellDate, position - offset - calendar()->daysInMonth( d->mDate ) );
00298         }
00299     }
00300     return cellDate;
00301 }
00302 
00303 void KDateTable::paintEvent( QPaintEvent *e )
00304 {
00305     QPainter p( this );
00306     const QRect &rectToUpdate = e->rect();
00307     double cellWidth = width() / ( double ) d->numDayColumns;
00308     double cellHeight = height() / ( double ) d->numWeekRows;
00309     int leftCol = ( int )std::floor( rectToUpdate.left() / cellWidth );
00310     int topRow = ( int )std::floor( rectToUpdate.top() / cellHeight );
00311     int rightCol = ( int )std::ceil( rectToUpdate.right() / cellWidth );
00312     int bottomRow = ( int )std::ceil( rectToUpdate.bottom() / cellHeight );
00313     bottomRow = qMin( bottomRow, d->numWeekRows - 1 );
00314     rightCol = qMin( rightCol, d->numDayColumns - 1 );
00315     p.translate( leftCol * cellWidth, topRow * cellHeight );
00316     for ( int i = leftCol; i <= rightCol; ++i ) {
00317         for ( int j = topRow; j <= bottomRow; ++j ) {
00318             paintCell( &p, j, i );
00319             p.translate( 0, cellHeight );
00320         }
00321         p.translate( cellWidth, 0 );
00322         p.translate( 0, -cellHeight * ( bottomRow - topRow + 1 ) );
00323     }
00324 }
00325 
00326 void KDateTable::paintCell( QPainter *painter, int row, int col )
00327 {
00328     QRectF rect;
00329     QString text;
00330     QPen pen;
00331     double w = width() / ( double ) d->numDayColumns;
00332     double h = height() / ( double ) d->numWeekRows;
00333     w -= 1;
00334     h -= 1;
00335     QFont font = KGlobalSettings::generalFont();
00336 
00337     if( row == 0 ) { // we are drawing the headline
00338         font.setBold( true );
00339         painter->setFont( font );
00340         bool normalday = true;
00341         int daynum = ( col + calendar()->weekStartDay() <= d->numDayColumns ) ?
00342                            col + calendar()->weekStartDay() :
00343                            col + calendar()->weekStartDay() - d->numDayColumns;
00344         //JPL talk to KDEPIM guys about common way to define/set days off in all calendar systems
00345         if ( daynum == calendar()->weekDayOfPray() ||
00346            ( daynum == 6 && calendar()->calendarType() == "gregorian" ) ) {
00347             normalday = false;
00348         }
00349 
00350         QBrush brushInvertTitle( palette().base() );
00351         QColor titleColor( isEnabled() ? ( KGlobalSettings::activeTitleColor() )
00352                                        : ( KGlobalSettings::inactiveTitleColor() ) );
00353         QColor textColor( isEnabled() ? ( KGlobalSettings::activeTextColor() )
00354                                       : ( KGlobalSettings::inactiveTextColor() ) );
00355 
00356         if ( !normalday ) {
00357             painter->setPen( textColor );
00358             painter->setBrush( textColor );
00359             painter->drawRect( QRectF( 0, 0, w, h ) );
00360             painter->setPen( titleColor );
00361         } else {
00362             painter->setPen( titleColor );
00363             painter->setBrush( titleColor );
00364             painter->drawRect( QRectF( 0, 0, w, h ) );
00365             painter->setPen( textColor );
00366         }
00367         painter->drawText( QRectF( 0, 0, w, h ), Qt::AlignCenter,
00368                            calendar()->weekDayName( daynum, KCalendarSystem::ShortDayName ), &rect );
00369         painter->setPen( palette().color( QPalette::Text ) );
00370         painter->drawLine( QPointF( 0, h ), QPointF( w, h ) );
00371         // ----- draw the weekday:
00372     } else {
00373         bool paintRect = true;
00374         painter->setFont( font );
00375         int pos = d->numDayColumns * ( row - 1 ) + col;
00376 
00377         QDate cellDate = dateFromPos( pos );
00378 
00379         // Draw the day number in the cell, if the date is not valid then we don't want to show it
00380         if ( calendar()->isValid( cellDate ) ) {
00381             text = calendar()->dayString( cellDate, KCalendarSystem::ShortFormat );
00382         } else {
00383             text = "";
00384         }
00385 
00386         if( ! calendar()->isValid( cellDate ) ||
00387             calendar()->month( cellDate ) != calendar()->month( d->mDate ) ) {
00388             // we are either
00389             // ° painting a day of the previous month or
00390             // ° painting a day of the following month or
00391             // ° painting an invalid day
00392             // TODO: Use a color with less contrast to the background than normal text.
00393             // JPL talk to accessability guys about this
00394             painter->setPen( palette().color( QPalette::Mid ) );
00395         } else {
00396             // paint a day of the current month
00397             if ( d->useCustomColors ) {
00398                 KDateTablePrivate::DatePaintingMode * mode = d->customPaintingModes[calendar()->formatDate(cellDate)];
00399                 if ( mode ) {
00400                     if ( mode->bgMode != NoBgMode ) {
00401                         QBrush oldbrush = painter->brush();
00402                         painter->setBrush( mode->bgColor );
00403                         switch( mode->bgMode ) {
00404                         case( CircleMode ) : painter->drawEllipse( QRectF( 0, 0, w, h ) );break;
00405                         case( RectangleMode ) : painter->drawRect( QRectF( 0, 0, w, h ) );break;
00406                         case( NoBgMode ) : // Should never be here, but just to get one
00407                                            // less warning when compiling
00408                         default: break;
00409                         }
00410                         painter->setBrush( oldbrush );
00411                         paintRect = false;
00412                     }
00413                     painter->setPen( mode->fgColor );
00414                 } else {
00415                     painter->setPen( palette().color( QPalette::Text ) );
00416                 }
00417             } else {
00418                 painter->setPen( palette().color( QPalette::Text ) );
00419             }
00420         }
00421 
00422         pen = painter->pen();
00423 
00424         int offset = d->weekDayFirstOfMonth - calendar()->weekStartDay();
00425         if( offset < 1 ) {
00426             offset += d->numDayColumns;
00427         }
00428 
00429         int day = calendar()->day( d->mDate );
00430 
00431         if( ( offset + day ) == ( pos + 1 ) ) {
00432             // draw the currently selected date
00433             if ( isEnabled() ) {
00434                 painter->setPen( palette().color( QPalette::Highlight ) );
00435                 painter->setBrush( palette().color( QPalette::Highlight ) );
00436             } else {
00437                 painter->setPen( palette().color( QPalette::Text ) );
00438                 painter->setBrush( palette().color( QPalette::Text ) );
00439             }
00440             pen = palette().color( QPalette::HighlightedText );
00441         } else {
00442             painter->setBrush( palette().color( QPalette::Background ) );
00443             painter->setPen( palette().color( QPalette::Background ) );
00444         }
00445 
00446         if ( cellDate == QDate::currentDate() ) {
00447             painter->setPen( palette().color( QPalette::Text ) );
00448         }
00449 
00450         if ( paintRect ) painter->drawRect( QRectF( 0, 0, w, h ) );
00451         painter->setPen( pen );
00452         painter->drawText( QRectF( 0, 0, w, h ), Qt::AlignCenter, text, &rect );
00453     }
00454 
00455     if( rect.width() > d->maxCell.width() ) d->maxCell.setWidth( rect.width() );
00456     if( rect.height() > d->maxCell.height() ) d->maxCell.setHeight( rect.height() );
00457 }
00458 
00459 void KDateTable::KDateTablePrivate::nextMonth()
00460 {
00461     // setDate does validity checking for us
00462     q->setDate( q->calendar()->addMonths( mDate, 1 ) );
00463 }
00464 
00465 void KDateTable::KDateTablePrivate::previousMonth()
00466 {
00467     // setDate does validity checking for us
00468     q->setDate( q->calendar()->addMonths( mDate, -1 ) );
00469 }
00470 
00471 void KDateTable::KDateTablePrivate::beginningOfMonth()
00472 {
00473     // setDate does validity checking for us
00474     q->setDate( q->calendar()->addDays( mDate, 1 - q->calendar()->day( mDate ) ) );
00475 }
00476 
00477 void KDateTable::KDateTablePrivate::endOfMonth()
00478 {
00479     // setDate does validity checking for us
00480     q->setDate( q->calendar()->addDays( mDate,
00481                 q->calendar()->daysInMonth( mDate ) - q->calendar()->day( mDate ) ) );
00482 }
00483 
00484 // JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
00485 void KDateTable::KDateTablePrivate::beginningOfWeek()
00486 {
00487     // setDate does validity checking for us
00488     q->setDate( q->calendar()->addDays( mDate, 1 - q->calendar()->dayOfWeek( mDate ) ) );
00489 }
00490 
00491 // JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
00492 void KDateTable::KDateTablePrivate::endOfWeek()
00493 {
00494     // setDate does validity checking for us
00495     q->setDate( q->calendar()->addDays( mDate,
00496                 q->calendar()->daysInWeek( mDate ) - q->calendar()->dayOfWeek( mDate ) ) );
00497 }
00498 
00499 void KDateTable::keyPressEvent( QKeyEvent *e )
00500 {
00501     switch( e->key() ) {
00502     case Qt::Key_Up:
00503         // setDate does validity checking for us
00504         setDate( calendar()->addDays( d->mDate, - d->numDayColumns ) );
00505         break;
00506     case Qt::Key_Down:
00507         // setDate does validity checking for us
00508         setDate( calendar()->addDays( d->mDate, d->numDayColumns ) );
00509         break;
00510     case Qt::Key_Left:
00511         // setDate does validity checking for us
00512         setDate( calendar()->addDays( d->mDate, -1 ) );
00513         break;
00514     case Qt::Key_Right:
00515         // setDate does validity checking for us
00516         setDate( calendar()->addDays( d->mDate, 1 ) );
00517         break;
00518     case Qt::Key_Minus:
00519         // setDate does validity checking for us
00520         setDate( calendar()->addDays( d->mDate, -1 ) );
00521         break;
00522     case Qt::Key_Plus:
00523         // setDate does validity checking for us
00524         setDate( calendar()->addDays( d->mDate, 1 ) );
00525         break;
00526     case Qt::Key_N:
00527         // setDate does validity checking for us
00528         setDate( QDate::currentDate() );
00529         break;
00530     case Qt::Key_Return:
00531     case Qt::Key_Enter:
00532         emit tableClicked();
00533         break;
00534     case Qt::Key_Control:
00535     case Qt::Key_Alt:
00536     case Qt::Key_Meta:
00537     case Qt::Key_Shift:
00538         // Don't beep for modifiers
00539         break;
00540     default:
00541         if ( !e->modifiers() ) { // hm
00542             KNotification::beep();
00543         }
00544     }
00545 }
00546 
00547 void KDateTable::setFontSize( int size )
00548 {
00549     int count;
00550     QFontMetricsF metrics( fontMetrics() );
00551     QRectF rect;
00552     // ----- store rectangles:
00553     d->fontsize = size;
00554     // ----- find largest day name:
00555     d->maxCell.setWidth( 0 );
00556     d->maxCell.setHeight( 0 );
00557     for( count = 0; count < calendar()->daysInWeek( d->mDate ); ++count ) {
00558         rect = metrics.boundingRect( calendar()->weekDayName( count + 1, KCalendarSystem::ShortDayName ) );
00559         d->maxCell.setWidth( qMax( d->maxCell.width(), rect.width() ) );
00560         d->maxCell.setHeight( qMax( d->maxCell.height(), rect.height() ) );
00561     }
00562     // ----- compare with a real wide number and add some space:
00563     rect = metrics.boundingRect( QLatin1String( "88" ) );
00564     d->maxCell.setWidth( qMax( d->maxCell.width() + 2, rect.width() ) );
00565     d->maxCell.setHeight( qMax( d->maxCell.height() + 4, rect.height() ) );
00566 }
00567 
00568 void KDateTable::wheelEvent ( QWheelEvent * e )
00569 {
00570     setDate( calendar()->addMonths( d->mDate, -( int )( e->delta() / 120 ) ) );
00571     e->accept();
00572 }
00573 
00574 void KDateTable::mousePressEvent( QMouseEvent *e )
00575 {
00576     if( e->type() != QEvent::MouseButtonPress ) { // the KDatePicker only reacts on mouse press events:
00577         return;
00578     }
00579 
00580     if( !isEnabled() ) {
00581         KNotification::beep();
00582         return;
00583     }
00584 
00585     int row, col, pos, temp;
00586 
00587     QPoint mouseCoord = e->pos();
00588     row = mouseCoord.y() / ( height() / d->numWeekRows );
00589     col = mouseCoord.x() / ( width() / d->numDayColumns );
00590 
00591     if( row < 1 || col < 0 ) { // the user clicked on the frame of the table
00592         return;
00593     }
00594 
00595     // Rows and columns are zero indexed.  The (row - 1) below is to avoid counting
00596     // the row with the days of the week in the calculation.
00597 
00598     // old selected date:
00599     temp = posFromDate( d->mDate );
00600 
00601     // new position and date
00602     pos = ( d->numDayColumns * ( row - 1 ) ) + col;
00603     QDate clickedDate = dateFromPos( pos );
00604 
00605     // set the new date. If it is in the previous or next month, the month will
00606     // automatically be changed, no need to do that manually...
00607     // validity checking done inside setDate
00608     setDate( clickedDate );
00609 
00610     // This could be optimized to only call update over the regions
00611     // of old and new cell, but 99% of times there is also a call to
00612     // setDate that already calls update() so no need to optimize that
00613     // much here
00614     update();
00615 
00616     emit tableClicked();
00617 
00618     if (  e->button() == Qt::RightButton && d->popupMenuEnabled ) {
00619         KMenu * menu = new KMenu();
00620         menu->addTitle( calendar()->formatDate( clickedDate ) );
00621         emit aboutToShowContextMenu( menu, clickedDate );
00622         menu->popup( e->globalPos() );
00623     }
00624 }
00625 
00626 bool KDateTable::setDate( const QDate& date_ )
00627 {
00628     if( date_.isNull() || ! calendar()->isValid( date_ ) ) {
00629         return false;
00630     }
00631 
00632     bool changed = false;
00633 
00634     if( d->mDate != date_ ) {
00635         emit( dateChanged( d->mDate, date_ ) );
00636         d->mDate = date_;
00637         emit( dateChanged( d->mDate ) );
00638         changed = true;
00639     }
00640 
00641     // set weekday number of first day of this month, but this may not be a valid date so fake
00642     // it if needed e.g. in QDate Mon 1 Jan -4713 is not valid when it should be, so fake as day 1
00643     QDate firstDayOfMonth;
00644     if ( calendar()->setYMD( firstDayOfMonth,
00645                              calendar()->year( d->mDate ), calendar()->month( d->mDate ), 1 ) ) {
00646         d->weekDayFirstOfMonth = calendar()->dayOfWeek( firstDayOfMonth );
00647     } else {
00648         d->weekDayFirstOfMonth = calendar()->dayOfWeek( d->mDate ) -
00649                                  ( ( calendar()->day( d->mDate ) - 1 ) % d->numDayColumns );
00650         if ( d->weekDayFirstOfMonth <= 0 ) {
00651             d->weekDayFirstOfMonth = d->weekDayFirstOfMonth + d->numDayColumns;
00652         }
00653     }
00654 
00655     d->numDaysThisMonth = calendar()->daysInMonth( d->mDate );
00656 
00657     if( changed ) {
00658         update();
00659     }
00660 
00661     return true;
00662 }
00663 
00664 const QDate &KDateTable::date() const
00665 {
00666     return d->mDate;
00667 }
00668 
00669 const KCalendarSystem *KDateTable::calendar() const
00670 {
00671     if ( d->m_calendar ) {
00672         return d->m_calendar;
00673     }
00674 
00675     return  KGlobal::locale()->calendar();
00676 }
00677 
00678 bool KDateTable::setCalendar( KCalendarSystem *calendar_ )
00679 {
00680     // Delete the old calendar first, provided it's not the global (better to be safe...)
00681     if ( d->m_calendar && d->m_calendar != KGlobal::locale()->calendar() ) {
00682         delete d->m_calendar;
00683     }
00684 
00685     d->m_calendar = 0;
00686 
00687     // Don't actually set calendar if it's the global, setting to 0 will cause global to be returned
00688     if ( calendar_ != KGlobal::locale()->calendar() ) {
00689         d->m_calendar = calendar_;
00690 
00691         // Need to redraw to display correct calendar
00692         d->numDayColumns = calendar()->daysInWeek( d->mDate );
00693         setDate( d->mDate );
00694         // JPL not 100% sure we need to emit
00695         emit( dateChanged( d->mDate, d->mDate ) );
00696         emit( dateChanged( d->mDate ) );
00697         update();
00698     }
00699 
00700     return true;
00701 }
00702 
00703 bool KDateTable::setCalendar( const QString &calendarType )
00704 {
00705     // If type passed in is the same as the global, then use the global instead
00706     if ( calendarType != KGlobal::locale()->calendarType() ) {
00707         return( setCalendar( KCalendarSystem::create( calendarType ) ) );
00708     } else {
00709         // Delete the old calendar first, provided it's not the global (better to be safe...)
00710         if ( d->m_calendar && d->m_calendar != KGlobal::locale()->calendar() ) {
00711             delete d->m_calendar;
00712         }
00713         d->m_calendar = 0;
00714         return true;
00715     }
00716 }
00717 
00718 void KDateTable::focusInEvent( QFocusEvent *e )
00719 {
00720     QWidget::focusInEvent( e );
00721 }
00722 
00723 void KDateTable::focusOutEvent( QFocusEvent *e )
00724 {
00725     QWidget::focusOutEvent( e );
00726 }
00727 
00728 QSize KDateTable::sizeHint() const
00729 {
00730     if( d->maxCell.height() > 0 && d->maxCell.width() > 0 ) {
00731         return QSize( qRound( d->maxCell.width() * d->numDayColumns ),
00732                       ( qRound( d->maxCell.height() + 2 ) * d->numWeekRows ) );
00733     } else {
00734         kDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
00735         return QSize( -1, -1 );
00736     }
00737 }
00738 
00739 void KDateTable::setPopupMenuEnabled( bool enable )
00740 {
00741     d->popupMenuEnabled = enable;
00742 }
00743 
00744 bool KDateTable::popupMenuEnabled() const
00745 {
00746     return d->popupMenuEnabled;
00747 }
00748 
00749 void KDateTable::setCustomDatePainting( const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor )
00750 {
00751     if ( !fgColor.isValid() ) {
00752         unsetCustomDatePainting( date );
00753         return;
00754     }
00755 
00756     KDateTablePrivate::DatePaintingMode *mode = new KDateTablePrivate::DatePaintingMode;
00757     mode->bgMode = bgMode;
00758     mode->fgColor = fgColor;
00759     mode->bgColor = bgColor;
00760 
00761     d->customPaintingModes.insert( calendar()->formatDate( date ), mode );
00762     d->useCustomColors = true;
00763     update();
00764 }
00765 
00766 void KDateTable::unsetCustomDatePainting( const QDate &date )
00767 {
00768     d->customPaintingModes.remove( calendar()->formatDate( date ) );
00769 }
00770 
00771 
00772 // JPL Shouldn't this be in own file as is used in a couple of places?  Or moved to private in KDE5?
00773 
00774 KPopupFrame::KPopupFrame( QWidget* parent )
00775             : QFrame( parent, Qt::Popup ), d( new KPopupFramePrivate( this ) )
00776 {
00777     setFrameStyle( QFrame::Box | QFrame::Raised );
00778     setMidLineWidth( 2 );
00779 }
00780 
00781 KPopupFrame::~KPopupFrame()
00782 {
00783     delete d;
00784 }
00785 
00786 void KPopupFrame::keyPressEvent( QKeyEvent* e )
00787 {
00788     if( e->key() == Qt::Key_Escape ) {
00789         d->result = 0; // rejected
00790         emit leaveModality();
00791         //qApp->exit_loop();
00792     }
00793 }
00794 
00795 void KPopupFrame::close( int r )
00796 {
00797     d->result = r;
00798     emit leaveModality();
00799     //qApp->exit_loop();
00800 }
00801 
00802 void KPopupFrame::setMainWidget( QWidget *m )
00803 {
00804     d->main = m;
00805     if( d->main ) {
00806         resize( d->main->width() + 2 * frameWidth(), d->main->height() + 2 * frameWidth() );
00807     }
00808 }
00809 
00810 void KPopupFrame::resizeEvent( QResizeEvent *e )
00811 {
00812     Q_UNUSED( e );
00813 
00814     if( d->main ) {
00815         d->main->setGeometry( frameWidth(), frameWidth(),
00816                               width() - 2 * frameWidth(), height() - 2 * frameWidth() );
00817     }
00818 }
00819 
00820 void KPopupFrame::popup( const QPoint &pos )
00821 {
00822     // Make sure the whole popup is visible.
00823     QRect desktopGeometry = KGlobalSettings::desktopGeometry( pos );
00824 
00825     int x = pos.x();
00826     int y = pos.y();
00827     int w = width();
00828     int h = height();
00829     if ( x + w > desktopGeometry.x() + desktopGeometry.width() ) {
00830         x = desktopGeometry.width() - w;
00831     }
00832     if ( y + h > desktopGeometry.y() + desktopGeometry.height() ) {
00833         y = desktopGeometry.height() - h;
00834     }
00835     if ( x < desktopGeometry.x() ) {
00836         x = 0;
00837     }
00838     if ( y < desktopGeometry.y() ) {
00839         y = 0;
00840     }
00841 
00842     // Pop the thingy up.
00843     move( x, y );
00844     show();
00845     d->main->setFocus();
00846 }
00847 
00848 int KPopupFrame::exec( const QPoint &pos )
00849 {
00850     popup( pos );
00851     repaint();
00852     QEventLoop eventLoop;
00853     connect( this, SIGNAL( leaveModality() ),
00854              &eventLoop, SLOT( quit() ) );
00855     eventLoop.exec();
00856 
00857     hide();
00858     return d->result;
00859 }
00860 
00861 int KPopupFrame::exec( int x, int y )
00862 {
00863     return exec( QPoint( x, y ) );
00864 }
00865 
00866 #include "kdatetable.moc"

KDEUI

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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