F:/KPlato/koffice/kplato/kptdatetable.cc

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002     Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
00003               (C) 1998-2001 Mirko Boehm (mirko@kde.org)
00004               (C) 2004-2006 Dag Andersen <danders@get2net.dk>
00005 
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 "kptdatetable.h"
00023 #include "kptmap.h"
00024 
00025 #include <kapplication.h>
00026 #include <knotification.h>
00027 #include <kcalendarsystem.h>
00028 
00029 #include <QDateTime>
00030 #include <QString>
00031 #include <QPen>
00032 #include <QPainter>
00033 
00034 #include <QWheelEvent>
00035 #include <QFocusEvent>
00036 #include <QKeyEvent>
00037 #include <QEvent>
00038 #include <Q3Frame>
00039 #include <QResizeEvent>
00040 #include <QMouseEvent>
00041 #include <assert.h>
00042 #include <QLayout>
00043 #include <QDesktopWidget>
00044 
00045 #include <kglobalsettings.h>
00046 #include <kdebug.h>
00047 
00048 namespace KPlato
00049 {
00050 
00051 DateValidator::DateValidator(QWidget* parent, const char* name)
00052     : QValidator(parent, name)
00053 {
00054 }
00055 
00056 QValidator::State
00057 DateValidator::validate(QString& text, int&) const
00058 {
00059   QDate temp;
00060   // ----- everything is tested in date():
00061   return date(text, temp);
00062 }
00063 
00064 QValidator::State
00065 DateValidator::date(const QString& text, QDate& d) const
00066 {
00067   QDate tmp = KGlobal::locale()->readDate(text);
00068   if (!tmp.isNull())
00069     {
00070       d = tmp;
00071       return Acceptable;
00072     } else
00073       return QValidator::Intermediate;
00074 }
00075 
00076 void
00077 DateValidator::fixup( QString& ) const
00078 {
00079 
00080 }
00081 
00082 
00083 DateTable::DateTable(QWidget *parent, QDate date_, const char* name, Qt::WFlags f)
00084     : Q3GridView(parent, name, f),
00085       m_enabled(true)
00086 {
00087     //kDebug()<<k_funcinfo<<endl;
00088     m_dateStartCol = 1;
00089     m_selectedDates.clear();
00090     m_selectedWeekdays.clear();
00091 
00092     QPair<int, int> p(0,0);
00093     m_weeks.fill(p, 7);
00094 
00095     setFontSize(10);
00096     if(!date_.isValid()) {
00097         kError() <<k_funcinfo<<"Given date is invalid, using current date." << endl;
00098         date_=QDate::currentDate();
00099     }
00100     setFocusPolicy( Qt::StrongFocus );
00101     setNumCols(7+m_dateStartCol); // 7 days a week + maybe 1 for weeknumbers
00102     setNumRows(7); // 6 weeks max + headline
00103 
00104     setHScrollBarMode(AlwaysOff);
00105     setVScrollBarMode(AlwaysOff);
00106     viewport()->setEraseColor(KGlobalSettings::baseColor());
00107     setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
00108 
00109     colorBackgroundHoliday = QColor(0, 245, 255, QColor::Hsv);
00110     //colorBackgroundHoliday = colorBackgroundHoliday.light();
00111     colorBackgroundWorkday = QColor(208, 230, 240, QColor::Hsv);;
00112     //colorBackgroundWorkday = colorBackgroundWorkday.light();
00113     colorTextHoliday = Qt::black;
00114     colorTextWorkday = Qt::black;
00115     colorLine = Qt::black;
00116     backgroundSelectColor = KGlobalSettings::highlightColor();
00117     penSelectColor=KGlobalSettings::baseColor();
00118 
00119 }
00120 
00121 void DateTable::paintWeekday(QPainter *painter, int col) {
00122     QRect rect;
00123     int w=cellWidth();
00124     int h=cellHeight();
00125 
00126     QFont font = KGlobalSettings::generalFont();
00127     font.setBold(true);
00128     if (!m_enabled)
00129         font.setItalic(true);
00130     painter->setFont(font);
00131 
00132     int day = weekday(col);
00133 
00134     //kDebug()<<k_funcinfo<<" col="<<col<<" day="<<day<<" name="<<daystr<<endl;
00135 
00136     painter->setBrush(KGlobalSettings::baseColor());
00137     painter->setPen(KGlobalSettings::baseColor());
00138     painter->drawRect(0, 0, w, h);
00139     painter->setPen(KGlobalSettings::textColor());
00140 
00141     if (m_markedWeekdays.state(day) == Map::Working) {
00142         painter->setPen(colorBackgroundWorkday);
00143         painter->setBrush(colorBackgroundWorkday);
00144         painter->drawRect(0, 0, w, h);
00145         painter->setPen(colorTextWorkday);
00146     } else if (m_markedWeekdays.state(day) == Map::NonWorking) {
00147         painter->setPen(colorBackgroundHoliday);
00148         painter->setBrush(colorBackgroundHoliday);
00149         painter->drawRect(0, 0, w, h);
00150         painter->setPen(colorTextHoliday);
00151     }
00152     if (m_selectedWeekdays.contains(day)) {
00153         painter->setPen(backgroundSelectColor);
00154         painter->setBrush(backgroundSelectColor);
00155         painter->drawRect(2, 2, w-4, h-4);
00156         painter->setPen(penSelectColor);
00157     }
00158     painter->drawText(0, 0, w, h-1, Qt::AlignCenter, KGlobal::locale()->calendar()->weekDayName(day, true), -1, &rect);
00159     painter->setPen(colorLine);
00160     painter->drawLine(0, h-1, w-1, h-1);
00161 
00162     if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
00163     if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
00164 
00165     //kDebug()<<k_funcinfo<<"headline: row,col=("<<row<<","<<col<<")"<<" day="<<daystr<<endl;
00166 }
00167 
00168 void DateTable::paintWeekNumber(QPainter *painter, int row) {
00169     QRect rect;
00170     int w=cellWidth();
00171     int h=cellHeight();
00172 
00173     QFont font=KGlobalSettings::generalFont();
00174     font.setBold(true);
00175     if (!m_enabled)
00176         font.setItalic(true);
00177     painter->setFont(font);
00178 
00179     painter->setBrush(KGlobalSettings::baseColor());
00180     painter->setPen(KGlobalSettings::baseColor());
00181     painter->drawRect(0, 0, w, h);
00182     painter->setPen(KGlobalSettings::textColor());
00183 
00184     painter->drawText(0, 0, w, h-1, Qt::AlignCenter, QString("%1").arg(m_weeks[row].first), -1, &rect);
00185     painter->setPen(colorLine);
00186     painter->drawLine(w-1, 0, w-1, h-1);
00187 
00188     if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
00189     if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
00190 }
00191 
00192 void DateTable::paintDay(QPainter *painter, int row, int col) {
00193     //kDebug()<<k_funcinfo<<"row,col=("<<row<<","<<col<<")"<<" num col="<<numCols()<<endl;
00194     QRect rect;
00195     int w=cellWidth();
00196     int h=cellHeight();
00197 
00198     QFont font=KGlobalSettings::generalFont();
00199     font.setPointSize(fontsize);
00200     if (!m_enabled)
00201         font.setItalic(true);
00202     painter->setFont(font);
00203 
00204     QDate d = getDate(position(row, col));
00205 
00206     painter->setBrush(KGlobalSettings::baseColor());
00207     painter->setPen(KGlobalSettings::baseColor());
00208     painter->drawRect(0, 0, w, h);
00209 
00210     // First paint the dates background
00211     if (m_markedDates.state(d) == Map::NonWorking) {
00212         //kDebug()<<k_funcinfo<<"Marked date: "<<d<<"  row,col=("<<row<<","<<col<<")=NonWorking"<<endl;
00213         painter->setPen(colorBackgroundHoliday);
00214         painter->setBrush(colorBackgroundHoliday);
00215         painter->drawRect(0, 0, w, h);
00216     } else if (m_markedDates.state(d) == Map::Working) {
00217         //kDebug()<<k_funcinfo<<"Marked date: "<<d<<"  row,col=("<<row<<","<<col<<")=Working"<<endl;
00218         painter->setPen(colorBackgroundWorkday);
00219         painter->setBrush(colorBackgroundWorkday);
00220         painter->drawRect(0, 0, w, h);
00221     }
00222     if(m_selectedDates.contains(d)) {
00223         //kDebug()<<k_funcinfo<<"Selected: "<<d<<" row,col=("<<row<<","<<col<<")"<<endl;
00224         painter->setPen(backgroundSelectColor);
00225         painter->setBrush(backgroundSelectColor);
00226         painter->drawRect(2, 2, w-4, h-4);
00227     }
00228     // If weeks or weekdays are selected/marked we draw lines around the date
00229     QPen pen = painter->pen();
00230     if (m_markedWeekdays.state(weekday(col)) == Map::Working) {
00231         //kDebug()<<k_funcinfo<<"Marked weekday: row,dayCol=("<<row<<","<<dayCol<<")=Working"<<endl;
00232         pen.setColor(colorBackgroundWorkday);
00233         painter->setPen(pen);
00234         painter->drawLine(0, 0, 0, h-1);
00235         painter->drawLine(w-1, 0, w-1, h-1);
00236     }
00237     // then paint square if current date
00238     if (d  == QDate::currentDate()) {
00239         painter->setPen(colorLine);
00240         painter->drawRect(1, 1, w-2, h-2);
00241     }
00242 
00243     // and now the day number
00244     d.month() == date.month() ? painter->setPen(KGlobalSettings::textColor()) : painter->setPen(Qt::gray);
00245     painter->drawText(0, 0, w, h, Qt::AlignCenter, QString().setNum(d.day()), -1, &rect);
00246 
00247     if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
00248     if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
00249 }
00250 
00251 void DateTable::paintCell(QPainter *painter, int row, int col) {
00252     //kDebug()<<k_funcinfo<<"row,col=("<<row<<","<<col<<")"<<"enabled="<<m_enabled<<endl;
00253     if (row == 0 && col == 0) {
00254         painter->save();
00255         int w=cellWidth();
00256         int h=cellHeight();
00257         painter->setPen(colorLine);
00258         painter->setBrush(KGlobalSettings::baseColor());
00259         painter->drawLine(w-1, 0, w-1, h-1);
00260         painter->drawLine(w-1, h-1, 0, h-1);
00261         painter->restore();
00262         return;
00263     }
00264     painter->save();
00265     if(row==0) { // we are drawing the weekdays
00266         paintWeekday(painter, col);
00267     } else if (col == 0) { // draw week numbers
00268         paintWeekNumber(painter, row);
00269     } else { // draw the day
00270         paintDay(painter, row, col);
00271     }
00272     painter->restore();
00273 }
00274 
00275 //FIXME
00276 void DateTable::keyPressEvent( QKeyEvent *e ) {
00277     if (!m_enabled)
00278         return;
00279     if ( e->key() == Qt::Key_PageUp ) {
00280         setDate(date.addMonths(-1));
00281         return;
00282     }
00283     if ( e->key() == Qt::Key_PageDown ) {
00284         setDate(date.addMonths(1));
00285         return;
00286     }
00287 
00288     if ( e->key() == Qt::Key_Up ) {
00289         if ( date.day() > 7 ) {
00290             setDate(date.addDays(-7));
00291             return;
00292         }
00293     }
00294     if ( e->key() == Qt::Key_Down ) {
00295         if ( date.day() <= date.daysInMonth()-7 ) {
00296             setDate(date.addDays(7));
00297             return;
00298         }
00299     }
00300     if ( e->key() == Qt::Key_Left ) {
00301         if ( date.day() > 1 ) {
00302             setDate(date.addDays(-1));
00303             return;
00304         }
00305     }
00306     if ( e->key() == Qt::Key_Right ) {
00307         if ( date.day() < date.daysInMonth() ) {
00308             setDate(date.addDays(1));
00309             return;
00310         }
00311     }
00312 
00313     if ( e->key() == Qt::Key_Minus ) {
00314         setDate(date.addDays(-1));
00315         return;
00316     }
00317     if ( e->key() == Qt::Key_Plus ) {
00318         setDate(date.addDays(1));
00319         return;
00320     }
00321     if ( e->key() == Qt::Key_N ) {
00322         setDate(QDate::currentDate());
00323         return;
00324     }
00325     if ( e->key() == Qt::Key_Control ) {
00326         return;
00327     }
00328     if ( e->key() == Qt::Key_Shift ) {
00329         return;
00330     }
00331 
00332     KNotification::beep();
00333 }
00334 
00335 void DateTable::viewportResizeEvent(QResizeEvent * e) {
00336   Q3GridView::viewportResizeEvent(e);
00337 
00338   setCellWidth(viewport()->width()/numCols());
00339   setCellHeight(viewport()->height()/numRows());
00340 }
00341 
00342 void DateTable::setFontSize(int size) {
00343   int count;
00344   QFontMetrics metrics(fontMetrics());
00345   QRect rect;
00346   // ----- store rectangles:
00347   fontsize=size;
00348   // ----- find largest day name:
00349   maxCell.setWidth(0);
00350   maxCell.setHeight(0);
00351   for(count=0; count<7; ++count)
00352     {
00353       rect=metrics.boundingRect(KGlobal::locale()->calendar()->weekDayName(count+1, true));
00354       maxCell.setWidth(qMax(maxCell.width(), rect.width()));
00355       maxCell.setHeight(qMax(maxCell.height(), rect.height()));
00356     }
00357   // ----- compare with a real wide number and add some space:
00358   rect=metrics.boundingRect(QString::fromLatin1("88"));
00359   maxCell.setWidth(qMax(maxCell.width()+2, rect.width()));
00360   maxCell.setHeight(qMax(maxCell.height()+4, rect.height()));
00361 }
00362 
00363 //FIXME
00364 void DateTable::wheelEvent ( QWheelEvent * e ) {
00365     setDate(date.addMonths( -(int)(e->delta()/120)) );
00366     e->accept();
00367 }
00368 
00369 
00370 void DateTable::contentsMousePressEvent(QMouseEvent *e) {
00371     if (!m_enabled)
00372         return;
00373     //kDebug()<<k_funcinfo<<endl;
00374     if(e->type()!=QEvent::MouseButtonPress) {
00375         return;
00376     }
00377     QPoint mouseCoord = e->pos();
00378     int row=rowAt(mouseCoord.y());
00379     int col=columnAt(mouseCoord.x());
00380     if (row == 0 && col == 0) { // user clicked on (unused) upper left square
00381         updateSelectedCells();
00382         m_selectedWeekdays.clear();
00383         m_selectedDates.clear();
00384         repaintContents(false);
00385         emit selectionCleared();
00386         return;
00387     }
00388     if (col == 0) { // user clicked on week numbers
00389         updateSelectedCells();
00390         m_selectedWeekdays.clear();
00391         m_selectedDates.clear();
00392         updateSelectedCells();
00393         repaintContents(false);
00394         return;
00395     }
00396     if (row==0 && col>0) { // the user clicked on weekdays
00397         updateSelectedCells();
00398         m_selectedDates.clear();
00399         int day = weekday(col);
00400         if (e->state() & Qt::ShiftModifier) {
00401             // select all days between this and the furthest away selected day,
00402             // check first downside - then upside, clear all others
00403             bool select = false;
00404             for(int i=m_dateStartCol; i < col; ++i) {
00405                 //kDebug()<<"Down["<<i<<"]: col="<<col<<" day="<<day<<" column(i)="<<column(i)<<endl;
00406                 if (m_selectedWeekdays.contains(weekday(i))) {
00407                     select = true; // we have hit a selected day; select the rest
00408                 } else if (select) {
00409                     m_selectedWeekdays.toggle(weekday(i)); // select
00410                 }
00411             }
00412             bool selected = select;
00413             select = false;
00414             for(int i=7; i > col; --i) {
00415                 //kDebug()<<"Up["<<i<<"]: col="<<col<<" day="<<day<<" column(i)="<<column(i)<<endl;
00416                 if (m_selectedWeekdays.contains(weekday(i))) {
00417                     if (selected) m_selectedWeekdays.toggle(weekday(i)); // deselect
00418                     else select = true;
00419                 } else if (select) {
00420                     m_selectedWeekdays.toggle(weekday(i)); // select
00421                 }
00422             }
00423             if (!m_selectedWeekdays.contains(day)) {
00424                 m_selectedWeekdays.toggle(day); // always select
00425             }
00426         } else if (e->state() & Qt::ControlModifier) {
00427             // toggle select this date
00428             m_selectedWeekdays.toggle(day);
00429         } else {
00430             // toggle select this, clear all others
00431             m_selectedWeekdays.toggleClear(day);
00432         }
00433         updateSelectedCells();
00434         repaintContents(false);
00435         if (m_enabled) {
00436             //kDebug()<<k_funcinfo<<"emit weekdaySelected("<<day<<")"<<endl;
00437             emit weekdaySelected(day); // day= 1..7
00438         }
00439         return;
00440     }
00441 
00442     if (contentsMousePressEvent_internal(e)) {
00443         // Date hit,
00444         m_selectedWeekdays.clear();
00445         if (e->state() & Qt::ShiftModifier) {
00446             // find first&last date
00447             QDate first;
00448             QDate last;
00449             DateMap::ConstIterator it;
00450             for (it = m_selectedDates.constBegin(); it != m_selectedDates.constEnd(); ++it) {
00451                 //kDebug()<<k_funcinfo<<it.key()<<endl;
00452                 QDate d = QDate::fromString(it.key(), Qt::ISODate);
00453                 if (!d.isValid())
00454                     continue;
00455                 if (!first.isValid() || first > d)
00456                     first = d;
00457                 if (!last.isValid() || last < d)
00458                     last = d;
00459             }
00460             // select between anchor and pressed date inclusive
00461             m_selectedDates.clear();
00462             if (first.isValid() && last.isValid()) {
00463                 QDate anchor = first < date ? first : last;
00464                 int i = anchor > date ? -1 : 1;
00465                 while (anchor != date) {
00466                     //kDebug()<<k_funcinfo<<anchor.toString(Qt::ISODate)<<endl;
00467                     m_selectedDates.toggle(anchor);
00468                     anchor = anchor.addDays(i);
00469                 }
00470             }
00471             m_selectedDates.toggle(date);
00472         } else if (e->state() & Qt::ControlModifier) {
00473             // toggle select this date
00474             m_selectedDates.toggle(date);
00475             //kDebug()<<k_funcinfo<<"toggle date: "<<date.toString()<<" state="<<m_selectedDates.state(date)<<endl;
00476         } else {
00477             // Select this, clear all others
00478             m_selectedDates.clear();
00479             m_selectedDates.toggleClear(date);
00480             //kDebug()<<k_funcinfo<<"toggleClear date: "<<date.toString()<<" state="<<m_selectedDates.state(date)<<endl;
00481         }
00482     }
00483     repaintContents(false);
00484 }
00485 
00486 bool DateTable::contentsMousePressEvent_internal(QMouseEvent *e) {
00487     QPoint mouseCoord = e->pos();
00488     int row=rowAt(mouseCoord.y());
00489     int col=columnAt(mouseCoord.x());
00490     if(row<1 || col<0) { // the user clicked on the frame of the table
00491         return false;
00492     }
00493     //kDebug()<<k_funcinfo<<"pos["<<row<<","<<col<<"]="<<position(row,col)<<" firstday="<<firstday<<endl;
00494     selectDate(getDate(position(row, col)));
00495     return true;
00496 }
00497 
00498 bool DateTable::selectDate(const QDate& date_) {
00499     //kDebug()<<k_funcinfo<<"date="<<date_.toString()<<endl;
00500     bool changed=false;
00501     QDate temp;
00502     // -----
00503     if(!date_.isValid()) {
00504         return false;
00505     }
00506     if(date!=date_) {
00507         date=date_;
00508         changed=true;
00509     }
00510 
00511     temp.setYMD(date.year(), date.month(), 1);
00512     firstday=column(KGlobal::locale()->calendar()->dayOfWeek(temp));
00513     if(firstday==1) firstday=8; // Reserve row 1 for previous month
00514     numdays=date.daysInMonth();
00515     if(date.month()==1) { // set to december of previous year
00516         temp.setYMD(date.year()-1, 12, 1);
00517         setWeekNumbers(QDate(date.year()-1, 12, 31));
00518     } else { // set to previous month
00519         temp.setYMD(date.year(), date.month()-1, 1);
00520         QDate d(date.year(), date.month()-1,1);
00521         setWeekNumbers(d.addDays(d.daysInMonth()-1));
00522     }
00523     numDaysPrevMonth=temp.daysInMonth();
00524     if(changed) {
00525         repaintContents(false);
00526     }
00527     if (m_enabled)
00528         emit(dateChanged(date));
00529     return true;
00530 }
00531 
00532 bool DateTable::setDate(const QDate& date_, bool repaint) {
00533     //kDebug()<<k_funcinfo<<"date="<<date_.toString()<<endl;
00534     bool changed=false;
00535     QDate temp;
00536     // -----
00537     if(!date_.isValid()) {
00538         //kDebug() << "DateTable::setDate: refusing to set invalid date." << endl;
00539         return false;
00540         }
00541     if(date!=date_) {
00542         date=date_;
00543         changed=true;
00544     }
00545     //m_selectedDates.clear();
00546 
00547     temp.setYMD(date.year(), date.month(), 1);
00548     firstday=column(KGlobal::locale()->calendar()->dayOfWeek(temp));
00549     if(firstday==1) firstday=8;
00550     //kDebug()<<k_funcinfo<<"date="<<temp<<"day="<<(KGlobal::locale()->calendar()->dayOfWeek(temp))<<" firstday="<<firstday<<endl;
00551     numdays=date.daysInMonth();
00552     if(date.month()==1) { // set to december of previous year
00553         temp.setYMD(date.year()-1, 12, 1);
00554         setWeekNumbers(QDate(date.year()-1, 12, 31));
00555     } else { // set to previous month
00556         temp.setYMD(date.year(), date.month()-1, 1);
00557         QDate d(date.year(), date.month()-1,1);
00558         setWeekNumbers(d.addDays(d.daysInMonth()-1));
00559     }
00560 /*    if (m_selectedWeekdays.isEmpty() &&
00561         !m_selectedDates.isEmpty() && !m_selectedDates.contains(date))
00562     {
00563         //kDebug()<<k_funcinfo<<"date inserted"<<endl;
00564         m_selectedDates.insert(date);
00565     }*/
00566     numDaysPrevMonth=temp.daysInMonth();
00567     if(changed && repaint) {
00568         repaintContents(false);
00569     }
00570     if (m_enabled)
00571       emit(dateChanged(date));
00572     return true;
00573 }
00574 
00575 const QDate& DateTable::getDate() const {
00576   return date;
00577 }
00578 
00579 void DateTable::focusInEvent( QFocusEvent *e ) {
00580     Q3GridView::focusInEvent( e );
00581 }
00582 
00583 void DateTable::focusOutEvent( QFocusEvent *e ) {
00584     Q3GridView::focusOutEvent( e );
00585 }
00586 
00587 QSize DateTable::sizeHint() const {
00588     if(maxCell.height()>0 && maxCell.width()>0) {
00589       return QSize(maxCell.width()*numCols()+2*frameWidth(),
00590              (maxCell.height()+2)*numRows()+2*frameWidth());
00591     } else {
00592       //kDebug() << "DateTable::sizeHint: obscure failure - " << endl;
00593       return QSize(-1, -1);
00594     }
00595 }
00596 
00597 void DateTable::setWeekNumbers(QDate date) {
00598     if (!date.isValid()) {
00599         kError()<<k_funcinfo<<"Invalid date"<<endl;
00600     }
00601     QDate d(date);
00602     for (int i = 1; i < 7; ++i) {
00603         m_weeks[i].first = d.weekNumber(&(m_weeks[i].second));
00604         //kDebug()<<k_funcinfo<<"date="<<d.toString()<<" week=("<<m_weeks[i].first<<","<<m_weeks[i].second<<")"<<endl;
00605         d = d.addDays(7);
00606     }
00607 }
00608 
00609 void DateTable::updateCells() {
00610     //kDebug()<<k_funcinfo<<endl;
00611     for (int row=0; row < numRows(); ++row) {
00612         for (int col=0; col < numCols(); ++col) {
00613             updateCell(row, col);
00614         }
00615     }
00616 }
00617 
00618 void DateTable::updateSelectedCells() {
00619     //kDebug()<<k_funcinfo<<endl;
00620     QDate dt(date.year(), date.month(), 1);
00621     dt = dt.addDays(-firstday);
00622     for (int pos=0; pos < 42; ++pos) {
00623         if (m_selectedDates.contains(dt.addDays(pos)) ||
00624             m_selectedWeekdays.contains(pos%7+1))
00625         {
00626             updateCell(pos/7+1, pos%7+1);
00627             //kDebug()<<k_funcinfo<<" update cell ("<<pos/7+1<<","<<pos%7+1<<") date="<<dt.addDays(pos).toString()<<endl;
00628         }
00629     }
00630 }
00631 
00632 void DateTable::updateMarkedCells() {
00633     QDate dt(date.year(), date.month(), 1);
00634     dt = dt.addDays(-firstday);
00635     for (int pos=0; pos < 42; ++pos) {
00636         if (m_markedDates.contains(dt.addDays(pos)) ||
00637             m_markedWeekdays.contains(pos%7+1))
00638         {
00639             updateCell(pos/7+1, pos%7+1);
00640             //kDebug()<<k_funcinfo<<" update cell ("<<pos/7+1<<","<<pos%7+1<<") date="<<dt.addDays(pos).toString()<<endl;
00641         }
00642     }
00643 }
00644 
00645 void DateTable::setMarkedWeekdays(const IntMap days) {
00646     updateMarkedCells();
00647     m_markedWeekdays.clear();
00648     m_markedWeekdays = days;
00649     updateMarkedCells();
00650     repaintContents(false);
00651 }
00652 
00653 bool DateTable::weekdayMarked(int day) {
00654     return m_markedWeekdays.contains(day);
00655 }
00656 
00657 bool DateTable::dateMarked(QDate date) {
00658     return m_markedDates[date.toString()];
00659 }
00660 
00661 QDate DateTable::getDate(int pos) const {
00662     return QDate(date.year(), date.month(), 1).addDays(pos-firstday); 
00663 }
00664 
00665 int DateTable::weekday(int col) const {
00666     int day = col - m_dateStartCol + KGlobal::locale()->weekStartDay();
00667     if (day > 7) day %= 7;
00668     //kDebug()<<k_funcinfo<<"col="<<col<<" day="<<day<<" StartCol="<<m_dateStartCol<<" weekStartDay="<<KGlobal::locale()->weekStartDay()<<endl;
00669     return day;
00670 }
00671 
00672 int DateTable::column(int weekday) const {
00673     int col = weekday - KGlobal::locale()->weekStartDay();
00674     if (col < 0) col += 7;
00675     //kDebug()<<k_funcinfo<<"col="<<col<<" day="<<col<<" StartCol="<<m_dateStartCol<<" weekStartDay="<<KGlobal::locale()->weekStartDay()<<endl;
00676     return col + m_dateStartCol;
00677 }
00678 
00679 void DateTable::clear() {
00680     clearSelection();
00681     m_markedDates.clear();
00682     m_markedWeekdays.clear();
00683     repaintContents(false);
00684 }
00685 
00686 void DateTable::clearSelection() {
00687     m_selectedDates.clear();
00688     m_selectedWeekdays.clear();
00689     repaintContents(false);
00690 }
00691 
00692  void DateTable::setEnabled(bool yes) {
00693     if (m_enabled == yes)
00694         return;
00695     m_enabled=yes;
00696     updateCells();
00697 }
00698 
00699 void DateTable::markSelected(int state) {
00700     if (!m_selectedDates.isEmpty()) {
00701         DateMap::iterator it;
00702         for(it = m_selectedDates.begin(); it != m_selectedDates.end(); ++it) {
00703             m_markedDates.insert(it.key(), state);
00704             //kDebug()<<k_funcinfo<<"marked date: "<<it.key()<<"="<<state<<endl;
00705         }
00706     } else if (!m_selectedWeekdays.isEmpty()) {
00707         IntMap::iterator it;
00708         for(it = m_selectedWeekdays.begin(); it != m_selectedWeekdays.end(); ++it) {
00709             m_markedWeekdays.insert(it.key(), state);
00710             //kDebug()<<k_funcinfo<<"marked weekday: "<<it.key()<<"="<<state<<endl;
00711         }
00712     }
00713     updateSelectedCells();
00714     repaintContents(false);
00715 }
00716 
00717 DateInternalWeekSelector::DateInternalWeekSelector
00718 (int fontsize, QWidget* parent, const char* name)
00719   : QLineEdit(parent, name),
00720     val(new QIntValidator(this)),
00721     result(0)
00722 {
00723   QFont font;
00724   // -----
00725   font=KGlobalSettings::generalFont();
00726   font.setPointSize(fontsize);
00727   setFont(font);
00728   setFrame(false);
00729   val->setRange(1, 53);
00730   setValidator(val);
00731   connect(this, SIGNAL(returnPressed()), SLOT(weekEnteredSlot()));
00732 }
00733 
00734 void
00735 DateInternalWeekSelector::weekEnteredSlot()
00736 {
00737   bool ok;
00738   int week;
00739   // ----- check if this is a valid week:
00740   week=text().toInt(&ok);
00741   if(!ok)
00742     {
00743       KNotification::beep();
00744       return;
00745     }
00746   result=week;
00747   emit(closeMe(1));
00748 }
00749 
00750 int
00751 DateInternalWeekSelector::getWeek() const
00752 {
00753   return result;
00754 }
00755 
00756 void
00757 DateInternalWeekSelector::setWeek(int week)
00758 {
00759   QString temp;
00760   // -----
00761   temp.setNum(week);
00762   setText(temp);
00763 }
00764 
00765 DateInternalMonthPicker::DateInternalMonthPicker
00766 (int fontsize, QWidget* parent, const char* name)
00767   : Q3GridView(parent, name),
00768     result(0) // invalid
00769 {
00770   QRect rect;
00771   QFont font;
00772   // -----
00773   activeCol = -1;
00774   activeRow = -1;
00775   font=KGlobalSettings::generalFont();
00776   font.setPointSize(fontsize);
00777   setFont(font);
00778   setHScrollBarMode(AlwaysOff);
00779   setVScrollBarMode(AlwaysOff);
00780   setFrameStyle(Q3Frame::NoFrame);
00781   setNumRows(4);
00782   setNumCols(3);
00783   // enable to find drawing failures:
00784   // setTableFlags(Tbl_clipCellPainting);
00785   viewport()->setEraseColor(KGlobalSettings::baseColor()); // for consistency with the datepicker
00786   // ----- find the preferred size
00787   //       (this is slow, possibly, but unfortunately it is needed here):
00788   QFontMetrics metrics(font);
00789   for(int i=1; i <= 12; ++i)
00790     {
00791       rect=metrics.boundingRect(KGlobal::locale()->calendar()->monthName(i, false));
00792       if(max.width()<rect.width()) max.setWidth(rect.width());
00793       if(max.height()<rect.height()) max.setHeight(rect.height());
00794     }
00795 
00796 }
00797 
00798 QSize
00799 DateInternalMonthPicker::sizeHint() const
00800 {
00801   return QSize((max.width()+6)*numCols()+2*frameWidth(),
00802          (max.height()+6)*numRows()+2*frameWidth());
00803 }
00804 
00805 int
00806 DateInternalMonthPicker::getResult() const
00807 {
00808   return result;
00809 }
00810 
00811 void
00812 DateInternalMonthPicker::setupPainter(QPainter *p)
00813 {
00814   p->setPen(KGlobalSettings::textColor());
00815 }
00816 
00817 void
00818 DateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
00819 {
00820   setCellWidth(width()/3);
00821   setCellHeight(height()/4);
00822 }
00823 
00824 void
00825 DateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
00826 {
00827   int index;
00828   QString text;
00829   // ----- find the number of the cell:
00830   index=3*row+col+1;
00831   text=KGlobal::locale()->calendar()->monthName(index, false);
00832   painter->drawText(0, 0, cellWidth(), cellHeight(), Qt::AlignCenter, text);
00833   if ( activeCol == col && activeRow == row )
00834       painter->drawRect( 0, 0, cellWidth(), cellHeight() );
00835 }
00836 
00837 void
00838 DateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
00839 {
00840   if(!isEnabled() || e->button() != Qt::LeftButton)
00841     {
00842       KNotification::beep();
00843       return;
00844     }
00845   // -----
00846   int row, col;
00847   QPoint mouseCoord;
00848   // -----
00849   mouseCoord = e->pos();
00850   row=rowAt(mouseCoord.y());
00851   col=columnAt(mouseCoord.x());
00852 
00853   if(row<0 || col<0)
00854     { // the user clicked on the frame of the table
00855       activeCol = -1;
00856       activeRow = -1;
00857     } else {
00858       activeCol = col;
00859       activeRow = row;
00860       updateCell( row, col /*, false */ );
00861   }
00862 }
00863 
00864 void
00865 DateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
00866 {
00867   if (e->state() & Qt::LeftButton)
00868     {
00869       int row, col;
00870       QPoint mouseCoord;
00871       // -----
00872       mouseCoord = e->pos();
00873       row=rowAt(mouseCoord.y());
00874       col=columnAt(mouseCoord.x());
00875       int tmpRow = -1, tmpCol = -1;
00876       if(row<0 || col<0)
00877         { // the user clicked on the frame of the table
00878           if ( activeCol > -1 )
00879             {
00880               tmpRow = activeRow;
00881               tmpCol = activeCol;
00882             }
00883           activeCol = -1;
00884           activeRow = -1;
00885         } else {
00886           bool differentCell = (activeRow != row || activeCol != col);
00887           if ( activeCol > -1 && differentCell)
00888             {
00889               tmpRow = activeRow;
00890               tmpCol = activeCol;
00891             }
00892           if ( differentCell)
00893             {
00894               activeRow = row;
00895               activeCol = col;
00896               updateCell( row, col /*, false */ ); // mark the new active cell
00897             }
00898         }
00899       if ( tmpRow > -1 ) // repaint the former active cell
00900           updateCell( tmpRow, tmpCol /*, true */ );
00901     }
00902 }
00903 
00904 void
00905 DateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
00906 {
00907   if(!isEnabled())
00908     {
00909       return;
00910     }
00911   // -----
00912   int row, col, pos;
00913   QPoint mouseCoord;
00914   // -----
00915   mouseCoord = e->pos();
00916   row=rowAt(mouseCoord.y());
00917   col=columnAt(mouseCoord.x());
00918   if(row<0 || col<0)
00919     { // the user clicked on the frame of the table
00920       emit(closeMe(0));
00921     }
00922   pos=3*row+col+1;
00923   result=pos;
00924   emit(closeMe(1));
00925 }
00926 
00927 
00928 
00929 DateInternalYearSelector::DateInternalYearSelector
00930 (int fontsize, QWidget* parent, const char* name)
00931   : QLineEdit(parent, name),
00932     val(new QIntValidator(this)),
00933     result(0)
00934 {
00935   QFont font;
00936   // -----
00937   font=KGlobalSettings::generalFont();
00938   font.setPointSize(fontsize);
00939   setFont(font);
00940   setFrame(false);
00941   // we have to respect the limits of QDate here, I fear:
00942   val->setRange(0, 8000);
00943   setValidator(val);
00944   connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
00945 }
00946 
00947 void
00948 DateInternalYearSelector::yearEnteredSlot()
00949 {
00950   bool ok;
00951   int year;
00952   QDate date;
00953   // ----- check if this is a valid year:
00954   year=text().toInt(&ok);
00955   if(!ok)
00956     {
00957       KNotification::beep();
00958       return;
00959     }
00960   date.setYMD(year, 1, 1);
00961   if(!date.isValid())
00962     {
00963       KNotification::beep();
00964       return;
00965     }
00966   result=year;
00967   emit(closeMe(1));
00968 }
00969 
00970 int
00971 DateInternalYearSelector::getYear() const
00972 {
00973   return result;
00974 }
00975 
00976 void
00977 DateInternalYearSelector::setYear(int year)
00978 {
00979   QString temp;
00980   // -----
00981   temp.setNum(year);
00982   setText(temp);
00983 }
00984 
00985 PopupFrame::PopupFrame(QWidget* parent, const char*  name)
00986   : Q3Frame(parent, name, Qt::WType_Popup),
00987     result(0), // rejected
00988     main(0)
00989 {
00990   setFrameStyle(Q3Frame::Box|Q3Frame::Raised);
00991   setMidLineWidth(2);
00992 }
00993 
00994 void
00995 PopupFrame::keyPressEvent(QKeyEvent* e)
00996 {
00997   if(e->key()==Qt::Key_Escape)
00998     {
00999       result=0; // rejected
01000       qApp->exit_loop();
01001     }
01002 }
01003 
01004 void
01005 PopupFrame::close(int r)
01006 {
01007   result=r;
01008   qApp->exit_loop();
01009 }
01010 
01011 void
01012 PopupFrame::setMainWidget(QWidget* m)
01013 {
01014   main=m;
01015   if(main!=0)
01016     {
01017       resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
01018     }
01019 }
01020 
01021 void
01022 PopupFrame::resizeEvent(QResizeEvent*)
01023 {
01024   if(main!=0)
01025     {
01026       main->setGeometry(frameWidth(), frameWidth(),
01027           width()-2*frameWidth(), height()-2*frameWidth());
01028     }
01029 }
01030 
01031 void
01032 PopupFrame::popup(const QPoint &pos)
01033 {
01034   // Make sure the whole popup is visible.
01035   QRect d = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(pos));
01036   int x = pos.x();
01037   int y = pos.y();
01038   int w = width();
01039   int h = height();
01040   if (x+w > d.x()+d.width())
01041     x = d.width() - w;
01042   if (y+h > d.y()+d.height())
01043     y = d.height() - h;
01044   if (x < d.x())
01045     x = 0;
01046   if (y < d.y())
01047     y = 0;
01048 
01049   // Pop the thingy up.
01050   move(x, y);
01051   show();
01052 }
01053 
01054 int
01055 PopupFrame::exec(QPoint pos)
01056 {
01057   popup(pos);
01058   repaint();
01059   qApp->enter_loop();
01060   hide();
01061   return result;
01062 }
01063 
01064 int
01065 PopupFrame::exec(int x, int y)
01066 {
01067   return exec(QPoint(x, y));
01068 }
01069 
01070 void PopupFrame::virtual_hook( int, void* )
01071 { /*BASE::virtual_hook( id, data );*/ }
01072 
01073 void DateTable::virtual_hook( int, void* )
01074 { /*BASE::virtual_hook( id, data );*/ }
01075 
01076 }  //KPlato namespace
01077 
01078 #include "kptdatetable.moc"

Généré le Wed Nov 22 23:40:56 2006 pour KPlato par  doxygen 1.5.1-p1