00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qstring.h>
00025 #include <qtooltip.h>
00026 #include <qkeycode.h>
00027 #include <qpushbutton.h>
00028 #include <qlayout.h>
00029 #include <qtimer.h>
00030
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kglobal.h>
00034 #include <kiconloader.h>
00035
00036 #include "koprefs.h"
00037 #ifndef KORG_NOPLUGINS
00038 #include "kocore.h"
00039 #endif
00040
00041 #include <calendarsystem/kcalendarsystem.h>
00042
00043 #include "kdatenavigator.h"
00044 #include "kdatenavigator.moc"
00045
00046 KDateNavigator::KDateNavigator( QWidget *parent, Calendar *calendar,
00047 bool show_week_nums, const char *name,
00048 QDate startDate )
00049 : QFrame(parent, name),
00050 updateTimer(0L)
00051 {
00052 mCalendar = calendar;
00053
00054 setFrameStyle(QFrame::NoFrame);
00055
00056 QGridLayout *topLayout = new QGridLayout(this,8,8);
00057
00058 if (! startDate.isValid()) {
00059 kdDebug() << "KDateNavigator::KDateNavigator(): an invalid date was passed as a parameter!" << endl;
00060 startDate = QDate::currentDate();
00061 }
00062
00063 mSelectedDates.append(startDate);
00064 m_MthYr = startDate;
00065 m_bShowWeekNums = show_week_nums;
00066
00067
00068 ctrlFrame = new QFrame(this, "KDateNavigator::CtrlFrame");
00069 ctrlFrame->setFrameStyle(QFrame::Panel|QFrame::Raised);
00070 ctrlFrame->setLineWidth(1);
00071
00072 topLayout->addMultiCellWidget(ctrlFrame,0,0,0,7);
00073
00074 QFont tfont = font();
00075 tfont.setPointSize(10);
00076 tfont.setBold(FALSE);
00077
00078 bool isRTL = QApplication::reverseLayout();
00079
00080
00081 prevYear = new QPushButton(ctrlFrame);
00082 prevYear->setPixmap(SmallIcon(isRTL ? "2rightarrow" : "2leftarrow"));
00083 QToolTip::add(prevYear, i18n("Previous Year"));
00084
00085 prevMonth = new QPushButton(ctrlFrame);
00086 prevMonth->setPixmap(SmallIcon(isRTL ? "1rightarrow" : "1leftarrow"));
00087 QToolTip::add(prevMonth, i18n("Previous Month"));
00088
00089
00090 nextMonth = new QPushButton(ctrlFrame);
00091 nextMonth->setPixmap(SmallIcon(isRTL ? "1leftarrow" : "1rightarrow"));
00092 QToolTip::add(nextMonth, i18n("Next Month"));
00093
00094 nextYear = new QPushButton(ctrlFrame);
00095 nextYear->setPixmap(SmallIcon(isRTL ? "2leftarrow" : "2rightarrow"));
00096 QToolTip::add(nextYear, i18n("Next Year"));
00097
00098
00099 dateLabel = new QLabel(ctrlFrame);
00100 dateLabel->setFont(tfont);
00101 dateLabel->setAlignment(AlignCenter);
00102
00103
00104 int i;
00105 int maxwidth = 0;
00106 QFontMetrics fm = dateLabel->fontMetrics();
00107
00108 for(i=1;i<=12;++i) {
00109 int width = fm.width( KOCore::self()->calendarSystem()->monthName(i) + " 2000" );
00110 if (width > maxwidth) maxwidth = width;
00111 }
00112 dateLabel->setMinimumWidth(maxwidth);
00113
00114
00115 QBoxLayout *ctrlLayout = new QHBoxLayout(ctrlFrame,1);
00116 ctrlLayout->addWidget(prevYear,3);
00117 ctrlLayout->addWidget(prevMonth,3);
00118 ctrlLayout->addStretch(1);
00119 ctrlLayout->addSpacing(2);
00120 ctrlLayout->addWidget(dateLabel);
00121 ctrlLayout->addSpacing(2);
00122 ctrlLayout->addStretch(1);
00123 ctrlLayout->addWidget(nextMonth,3);
00124 ctrlLayout->addWidget(nextYear,3);
00125
00126 connect( prevYear, SIGNAL( clicked() ), SIGNAL( goPrevYear() ) );
00127 connect( prevMonth, SIGNAL( clicked() ), SIGNAL( goPrevMonth() ) );
00128 connect( nextMonth, SIGNAL( clicked() ), SIGNAL( goNextMonth() ) );
00129 connect( nextYear, SIGNAL( clicked() ), SIGNAL( goNextYear() ) );
00130
00131
00132 QDate dayone(m_MthYr.year(), m_MthYr.month(), 1);
00133 m_fstDayOfWk = dayone.dayOfWeek();
00134
00135
00136 for(i=0; i<7; i++) {
00137 headings[i] = new QLabel("",this);
00138 headings[i]->setFont(QFont("Arial", 10, QFont::Bold));
00139 headings[i]->setAlignment(AlignCenter);
00140
00141 topLayout->addWidget(headings[i],1,i+1);
00142 }
00143
00144
00145 for(i=0; i<6; i++) {
00146 weeknos[i] = new QLabel(this);
00147 weeknos[i]->setAlignment(AlignCenter);
00148 weeknos[i]->setFont(QFont("Arial", 10));
00149 if(!show_week_nums) {
00150 weeknos[i]->hide();
00151 }
00152 weeknos[i]->installEventFilter(this);
00153
00154 topLayout->addWidget(weeknos[i],i+2,0);
00155 }
00156
00157 daymatrix = new KODayMatrix( this, mCalendar, dayone,
00158 "KDateNavigator::DayMatrix");
00159 daymatrix->setFrameStyle(QFrame::Panel|QFrame::Sunken);
00160 daymatrix->setLineWidth(1);
00161
00162 connect( daymatrix, SIGNAL( selected( const KCal::DateList & ) ),
00163 SIGNAL( datesSelected( const KCal::DateList & ) ) );
00164
00165 connect( daymatrix, SIGNAL( eventDropped( Event * ) ),
00166 SIGNAL( eventDropped( Event * ) ) );
00167
00168 topLayout->addMultiCellWidget(daymatrix,2,7,1,7);
00169
00170
00171 updateConfig();
00172 enableRollover(FollowMonth);
00173 }
00174
00175 void KDateNavigator::enableRollover(RolloverType r)
00176 {
00177 switch(r)
00178 {
00179 case None :
00180 if (updateTimer)
00181 {
00182 updateTimer->stop();
00183 delete updateTimer;
00184 updateTimer=0L;
00185 }
00186 break;
00187 case FollowDay :
00188 case FollowMonth :
00189 if (!updateTimer)
00190 {
00191 updateTimer = new QTimer(this);
00192 QObject::connect(updateTimer,SIGNAL(timeout()),
00193 this,SLOT(possiblyPastMidnight()));
00194 }
00195 updateTimer->start(0,true);
00196 lastDayChecked = QDate::currentDate();
00197 }
00198 updateRollover=r;
00199 }
00200
00201
00202 KDateNavigator::~KDateNavigator()
00203 {
00204 }
00205
00206
00207 void KDateNavigator::passedMidnight()
00208 {
00209 QDate today = QDate::currentDate();
00210 bool emitMonth = false;
00211
00212 if (today.month() != lastDayChecked.month())
00213 {
00214 if (updateRollover==FollowMonth &&
00215 daymatrix->isEndOfMonth()) {
00216 goNextMonth();
00217 emitMonth=true;
00218 }
00219 }
00220 daymatrix->recalculateToday();
00221 daymatrix->repaint();
00222 emit dayPassed(today);
00223 if (emitMonth) { emit monthPassed(today); }
00224 }
00225
00226 void KDateNavigator::possiblyPastMidnight()
00227 {
00228 if (lastDayChecked!=QDate::currentDate())
00229 {
00230 passedMidnight();
00231 lastDayChecked=QDate::currentDate();
00232 }
00233
00234
00235 if (updateTimer)
00236 {
00237 QTime now = QTime::currentTime();
00238 QTime midnight = QTime(23,59,59);
00239 int msecsWait = QMIN(480000,now.msecsTo(midnight)+2000);
00240
00241
00242
00243
00244 updateTimer->stop();
00245 updateTimer->start(msecsWait,true);
00246 }
00247 }
00248
00249 void KDateNavigator::updateDates()
00250 {
00251
00252
00253 QDate dayone( m_MthYr.year(), m_MthYr.month(), m_MthYr.day() );
00254 int d2 = KOCore::self()->calendarSystem()->day( dayone );
00255
00256 dayone = dayone.addDays( -d2 + 1 );
00257
00258 int m_fstDayOfWkCalsys = KOCore::self()->calendarSystem()->dayOfTheWeek( dayone );
00259
00260
00261
00262 int nextLine = ( ( m_fstDayOfWkCalsys == 1) &&
00263 ( KGlobal::locale()->weekStartsMonday() == 1 ) ) ? 7 : 0;
00264
00265
00266 int index = (KGlobal::locale()->weekStartsMonday() ? 1 : 0) - m_fstDayOfWkCalsys - nextLine;
00267
00268
00269 daymatrix->updateView(dayone.addDays(index));
00270
00271
00272 }
00273
00274 void KDateNavigator::updateDayMatrix()
00275 {
00276 daymatrix->updateView();
00277 daymatrix->repaint();
00278 }
00279
00280
00281 void KDateNavigator::updateView()
00282 {
00283 setUpdatesEnabled( false );
00284
00285
00286 QDate cT( m_MthYr.year(), m_MthYr.month(), m_MthYr.day() );
00287 QString dtstr = KOCore::self()->calendarSystem()->monthName( cT ) + " " +
00288 QString::number(KOCore::self()->calendarSystem()->year( cT ) );
00289 dateLabel->setText(dtstr);
00290
00291 int i;
00292
00293
00294 daymatrix->updateView();
00295
00296
00297 for(i = 0; i < 6; i++) {
00298 QString weeknum;
00299
00300
00301
00302
00303
00304 int dayOfYear = KOCore::self()->calendarSystem()->numberOfDayInYear((daymatrix->getDate((i+1)*7-4)));
00305
00306 if (dayOfYear % 7 != 0)
00307 weeknum.setNum(dayOfYear / 7 + 1);
00308 else
00309 weeknum.setNum(dayOfYear / 7);
00310 weeknos[i]->setText(weeknum);
00311 }
00312
00313 setUpdatesEnabled( true );
00314
00315 repaint();
00316 daymatrix->repaint();
00317 }
00318
00319 void KDateNavigator::updateConfig()
00320 {
00321 int day;
00322 for(int i=0; i<7; i++) {
00323
00324 if (KGlobal::locale()->weekStartsMonday()) {
00325 day = i+1;
00326 } else {
00327 if (i==0) day = 7;
00328 else day = i;
00329 }
00330 headings[i]->setText( KOCore::self()->calendarSystem()->weekDayName(day, true) );
00331 }
00332 kdDebug() << "updateConfig() -> updateDates()" << endl;
00333 updateDates();
00334
00335 kdDebug() << "updateConfig() -> updateView()" << endl;
00336 updateView();
00337 }
00338
00339 void KDateNavigator::setShowWeekNums(bool enabled)
00340 {
00341 m_bShowWeekNums = enabled;
00342 for(int i=0; i<6; i++) {
00343 if(enabled)
00344 weeknos[i]->show();
00345 else
00346 weeknos[i]->hide();
00347 }
00348 resize(size());
00349 }
00350
00351 void KDateNavigator::selectDates(const DateList& dateList)
00352 {
00353 if (dateList.count() > 0) {
00354 mSelectedDates = dateList;
00355
00356
00357
00358 m_MthYr = mSelectedDates.first();
00359
00360
00361
00362
00363 QDate dayone(m_MthYr.year(), m_MthYr.month(), 1);
00364 m_fstDayOfWk = dayone.dayOfWeek();
00365
00366 updateDates();
00367
00368 daymatrix->setSelectedDaysFrom(*(dateList.begin()), *(--dateList.end()));
00369
00370 updateView();
00371 }
00372 }
00373
00374 int KDateNavigator::dayNum(int row, int col)
00375 {
00376 return 7 * (row - 1) + (col + 1) - m_fstDayOfWk;
00377 }
00378
00379 int KDateNavigator::dayToIndex(int dayNum)
00380 {
00381 int row, col;
00382
00383 row = (dayNum+m_fstDayOfWk-1-(KGlobal::locale()->weekStartsMonday() ? 1 : 0)) / 7;
00384 if (KGlobal::locale()->weekStartsMonday() && (m_fstDayOfWk == 1))
00385 row++;
00386 col = (dayNum+m_fstDayOfWk-1-(KGlobal::locale()->weekStartsMonday() ? 1 : 0)) % 7;
00387 return row * 7 + col;
00388 }
00389
00390 void KDateNavigator::wheelEvent (QWheelEvent *e)
00391 {
00392 if(e->delta()>0) emit goPrevious();
00393 else emit goNext();
00394
00395 e->accept();
00396 }
00397
00398 bool KDateNavigator::eventFilter (QObject *o,QEvent *e)
00399 {
00400 if (e->type() == QEvent::MouseButtonPress) {
00401 int i;
00402 for(i=0;i<6;++i) {
00403 if (o == weeknos[i]) {
00404 QDate weekstart = daymatrix->getDate(i*7);
00405 emit weekClicked(weekstart);
00406 break;
00407 }
00408 }
00409 return true;
00410 } else {
00411 return false;
00412 }
00413 }