korganizer

koeditorgeneralevent.cpp

00001 /*
00002     This file is part of KOrganizer.
00003     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00004     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program 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
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include <qtooltip.h>
00026 #include <qlayout.h>
00027 #include <qvbox.h>
00028 #include <qbuttongroup.h>
00029 #include <qvgroupbox.h>
00030 #include <qwidgetstack.h>
00031 #include <qspinbox.h>
00032 #include <qdatetime.h>
00033 #include <qlabel.h>
00034 #include <qcheckbox.h>
00035 #include <qcombobox.h>
00036 #include <qpushbutton.h>
00037 #include <qwhatsthis.h>
00038 
00039 #include <kdebug.h>
00040 #include <kglobal.h>
00041 #include <klocale.h>
00042 #include <kiconloader.h>
00043 #include <kmessagebox.h>
00044 #include <kfiledialog.h>
00045 #include <kstandarddirs.h>
00046 #include <ktextedit.h>
00047 
00048 #include <libkcal/event.h>
00049 
00050 #include "ktimeedit.h"
00051 #include <libkdepim/kdateedit.h>
00052 
00053 #include "koprefs.h"
00054 
00055 #include "koeditorgeneralevent.h"
00056 #include "koeditorgeneralevent.moc"
00057 
00058 KOEditorGeneralEvent::KOEditorGeneralEvent(QObject* parent,
00059                                            const char* name) :
00060   KOEditorGeneral( parent, name)
00061 {
00062   connect( this, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & )),
00063            SLOT( setDuration() ) );
00064   connect( this, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & )),
00065            SLOT( emitDateTimeStr() ));
00066 }
00067 
00068 KOEditorGeneralEvent::~KOEditorGeneralEvent()
00069 {
00070 }
00071 
00072 void KOEditorGeneralEvent::finishSetup()
00073 {
00074   QWidget::setTabOrder( mSummaryEdit, mLocationEdit );
00075   QWidget::setTabOrder( mLocationEdit, mStartDateEdit );
00076   QWidget::setTabOrder( mStartDateEdit, mStartTimeEdit );
00077   QWidget::setTabOrder( mStartTimeEdit, mEndDateEdit );
00078   QWidget::setTabOrder( mEndDateEdit, mEndTimeEdit );
00079   QWidget::setTabOrder( mEndTimeEdit, mTimeAssociateButton );
00080   QWidget::setTabOrder( mTimeAssociateButton, mAlarmButton );
00081   QWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
00082   QWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
00083 //   QWidget::setTabOrder( mAlarmIncrCombo, mAlarmSoundButton );
00084   QWidget::setTabOrder( mAlarmIncrCombo, mAlarmEditButton );
00085 //   QWidget::setTabOrder( mAlarmSoundButton, mAlarmProgramButton );
00086 //   QWidget::setTabOrder( mAlarmProgramButton, mFreeTimeCombo );
00087   QWidget::setTabOrder( mAlarmEditButton, mFreeTimeCombo );
00088   QWidget::setTabOrder( mFreeTimeCombo, mDescriptionEdit );
00089   QWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
00090   QWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
00091 //  QWidget::setTabOrder( mSecrecyCombo, mDescriptionEdit );
00092 
00093   mSummaryEdit->setFocus();
00094 }
00095 
00096 void KOEditorGeneralEvent::initTime(QWidget *parent,QBoxLayout *topLayout)
00097 {
00098   QBoxLayout *timeLayout = new QVBoxLayout(topLayout);
00099 
00100   QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal,
00101                                           i18n("Date && Time"),parent);
00102   QWhatsThis::add( timeGroupBox,
00103        i18n("Sets options related to the date and time of the "
00104             "event or to-do.") );
00105   timeLayout->addWidget(timeGroupBox);
00106 
00107   QFrame *timeBoxFrame = new QFrame(timeGroupBox);
00108 
00109   QGridLayout *layoutTimeBox = new QGridLayout(timeBoxFrame,2,3);
00110   layoutTimeBox->setSpacing(topLayout->spacing());
00111 
00112 
00113   mStartDateLabel = new QLabel(i18n("&Start:"),timeBoxFrame);
00114   layoutTimeBox->addWidget(mStartDateLabel,0,0);
00115 
00116   mStartDateEdit = new KDateEdit(timeBoxFrame);
00117   layoutTimeBox->addWidget(mStartDateEdit,0,1);
00118   mStartDateLabel->setBuddy( mStartDateEdit );
00119 
00120   mStartTimeEdit = new KTimeEdit(timeBoxFrame);
00121   layoutTimeBox->addWidget(mStartTimeEdit,0,2);
00122 
00123 
00124   mEndDateLabel = new QLabel(i18n("&End:"),timeBoxFrame);
00125   layoutTimeBox->addWidget(mEndDateLabel,1,0);
00126 
00127   mEndDateEdit = new KDateEdit(timeBoxFrame);
00128   layoutTimeBox->addWidget(mEndDateEdit,1,1);
00129   mEndDateLabel->setBuddy( mEndDateEdit );
00130 
00131   mEndTimeEdit = new KTimeEdit(timeBoxFrame);
00132   layoutTimeBox->addWidget(mEndTimeEdit,1,2);
00133 
00134   QHBoxLayout *flagsBox = new QHBoxLayout();
00135 
00136   mTimeAssociateButton = new QCheckBox(i18n("T&ime associated"),timeBoxFrame);
00137   flagsBox->addWidget(mTimeAssociateButton);
00138   connect(mTimeAssociateButton, SIGNAL(toggled(bool)),SLOT(associateTime(bool)));
00139 
00140   mDurationLabel = new QLabel( timeBoxFrame );
00141   if ( KOPrefs::instance()->mCompactDialogs ) {
00142     layoutTimeBox->addMultiCellWidget( mDurationLabel, 3, 3, 0, 3 );
00143   } else {
00144     flagsBox->addWidget( mDurationLabel, 0, 2 );
00145   }
00146 
00147   layoutTimeBox->addMultiCellLayout( flagsBox, 2, 2, 0, 3 );
00148 
00149   // time widgets are checked if they contain a valid time
00150   connect(mStartTimeEdit, SIGNAL(timeChanged(QTime)),
00151           this, SLOT(startTimeChanged(QTime)));
00152   connect(mEndTimeEdit, SIGNAL(timeChanged(QTime)),
00153           this, SLOT(endTimeChanged(QTime)));
00154 
00155   // date widgets are checked if they contain a valid date
00156   connect(mStartDateEdit, SIGNAL(dateChanged(const QDate&)),
00157           this, SLOT(startDateChanged(const QDate&)));
00158   connect(mEndDateEdit, SIGNAL(dateChanged(const QDate&)),
00159           this, SLOT(endDateChanged(const QDate&)));
00160 }
00161 
00162 void KOEditorGeneralEvent::initClass(QWidget *parent,QBoxLayout *topLayout)
00163 {
00164   QBoxLayout *classLayout = new QHBoxLayout(topLayout);
00165 
00166   QLabel *freeTimeLabel = new QLabel(i18n("S&how time as:"),parent);
00167   QString whatsThis = i18n("Sets how this time will appear on your Free/Busy "
00168                            "information.");
00169   QWhatsThis::add( freeTimeLabel, whatsThis );
00170   classLayout->addWidget(freeTimeLabel);
00171 
00172   mFreeTimeCombo = new QComboBox(false, parent);
00173   QWhatsThis::add( mFreeTimeCombo, whatsThis );
00174   mFreeTimeCombo->insertItem(i18n("Busy"));
00175   mFreeTimeCombo->insertItem(i18n("Free"));
00176   classLayout->addWidget(mFreeTimeCombo);
00177   freeTimeLabel->setBuddy( mFreeTimeCombo );
00178 }
00179 
00180 void KOEditorGeneralEvent::timeStuffDisable(bool disable)
00181 {
00182   mStartTimeEdit->setEnabled( !disable );
00183   mEndTimeEdit->setEnabled( !disable );
00184 
00185   setDuration();
00186   emitDateTimeStr();
00187 }
00188 
00189 void KOEditorGeneralEvent::associateTime(bool time)
00190 {
00191   timeStuffDisable(!time);
00192   //if(alarmButton->isChecked()) alarmStuffDisable(noTime);
00193   allDayChanged(!time);
00194 }
00195 
00196 void KOEditorGeneralEvent::setDateTimes( const QDateTime &start, const QDateTime &end )
00197 {
00198 //  kdDebug(5850) << "KOEditorGeneralEvent::setDateTimes(): Start DateTime: " << start.toString() << endl;
00199 
00200   mStartDateEdit->setDate(start.date());
00201   // KTimeEdit seems to emit some signals when setTime() is called.
00202   mStartTimeEdit->blockSignals( true );
00203   mStartTimeEdit->setTime(start.time());
00204   mStartTimeEdit->blockSignals( false );
00205   mEndDateEdit->setDate(end.date());
00206   mEndTimeEdit->setTime(end.time());
00207 
00208   mCurrStartDateTime = start;
00209   mCurrEndDateTime = end;
00210 
00211   setDuration();
00212   emitDateTimeStr();
00213 }
00214 
00215 void KOEditorGeneralEvent::startTimeChanged( QTime newtime )
00216 {
00217   kdDebug(5850) << "KOEditorGeneralEvent::startTimeChanged() " << newtime.toString() << endl;
00218 
00219   int secsep = mCurrStartDateTime.secsTo(mCurrEndDateTime);
00220 
00221   mCurrStartDateTime.setTime(newtime);
00222 
00223   // adjust end time so that the event has the same duration as before.
00224   mCurrEndDateTime = mCurrStartDateTime.addSecs(secsep);
00225   mEndTimeEdit->setTime(mCurrEndDateTime.time());
00226   mEndDateEdit->setDate(mCurrEndDateTime.date());
00227 
00228   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00229 }
00230 
00231 void KOEditorGeneralEvent::endTimeChanged( QTime newtime )
00232 {
00233 //  kdDebug(5850) << "KOEditorGeneralEvent::endTimeChanged " << newtime.toString() << endl;
00234 
00235   QDateTime newdt(mCurrEndDateTime.date(), newtime);
00236   mCurrEndDateTime = newdt;
00237 
00238   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00239 }
00240 
00241 void KOEditorGeneralEvent::startDateChanged( const QDate &newdate )
00242 {
00243   if ( !newdate.isValid() )
00244     return;
00245 
00246   int daysep = mCurrStartDateTime.daysTo(mCurrEndDateTime);
00247 
00248   mCurrStartDateTime.setDate(newdate);
00249 
00250   // adjust end date so that the event has the same duration as before
00251   mCurrEndDateTime.setDate(mCurrStartDateTime.date().addDays(daysep));
00252   mEndDateEdit->setDate(mCurrEndDateTime.date());
00253 
00254   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00255 }
00256 
00257 void KOEditorGeneralEvent::endDateChanged( const QDate &newdate )
00258 {
00259   if ( !newdate.isValid() )
00260     return;
00261 
00262   QDateTime newdt(newdate, mCurrEndDateTime.time());
00263 
00264   if(newdt < mCurrStartDateTime) {
00265     // oops, we can't let that happen.
00266     newdt = mCurrStartDateTime;
00267     mEndDateEdit->setDate(newdt.date());
00268     mEndTimeEdit->setTime(newdt.time());
00269   }
00270   mCurrEndDateTime = newdt;
00271 
00272   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00273 }
00274 
00275 void KOEditorGeneralEvent::setDefaults( const QDateTime &from,
00276                                         const QDateTime &to, bool allDay)
00277 {
00278   KOEditorGeneral::setDefaults(allDay);
00279 
00280   mTimeAssociateButton->setChecked(!allDay);
00281   timeStuffDisable(allDay);
00282 
00283   setDateTimes(from,to);
00284 }
00285 
00286 void KOEditorGeneralEvent::readEvent( Event *event, bool tmpl )
00287 {
00288   QString tmpStr;
00289 
00290   mTimeAssociateButton->setChecked(!event->doesFloat());
00291   timeStuffDisable(event->doesFloat());
00292 
00293   if ( !tmpl ) {
00294     // the rest is for the events only
00295     setDateTimes(event->dtStart(),event->dtEnd());
00296   }
00297 
00298   switch( event->transparency() ) {
00299   case Event::Transparent:
00300     mFreeTimeCombo->setCurrentItem(1);
00301     break;
00302   case Event::Opaque:
00303     mFreeTimeCombo->setCurrentItem(0);
00304     break;
00305   }
00306 
00307   readIncidence(event);
00308 }
00309 
00310 void KOEditorGeneralEvent::writeEvent(Event *event)
00311 {
00312 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent()" << endl;
00313 
00314   writeIncidence(event);
00315 
00316   QDate tmpDate;
00317   QTime tmpTime;
00318   QDateTime tmpDT;
00319 
00320   // temp. until something better happens.
00321   QString tmpStr;
00322 
00323   if (!mTimeAssociateButton->isChecked()) {
00324     event->setFloats(true);
00325     // need to change this.
00326     tmpDate = mStartDateEdit->date();
00327     tmpTime.setHMS(0,0,0);
00328     tmpDT.setDate(tmpDate);
00329     tmpDT.setTime(tmpTime);
00330     event->setDtStart(tmpDT);
00331 
00332     tmpDate = mEndDateEdit->date();
00333     tmpTime.setHMS(0,0,0);
00334     tmpDT.setDate(tmpDate);
00335     tmpDT.setTime(tmpTime);
00336     event->setDtEnd(tmpDT);
00337   } else {
00338     event->setFloats(false);
00339 
00340     // set date/time end
00341     tmpDate = mEndDateEdit->date();
00342     tmpTime = mEndTimeEdit->getTime();
00343     tmpDT.setDate(tmpDate);
00344     tmpDT.setTime(tmpTime);
00345     event->setDtEnd(tmpDT);
00346 
00347     // set date/time start
00348     tmpDate = mStartDateEdit->date();
00349     tmpTime = mStartTimeEdit->getTime();
00350     tmpDT.setDate(tmpDate);
00351     tmpDT.setTime(tmpTime);
00352     event->setDtStart(tmpDT);
00353   } // check for float
00354 
00355   event->setTransparency(mFreeTimeCombo->currentItem() > 0
00356                          ? KCal::Event::Transparent
00357                          : KCal::Event::Opaque);
00358 
00359 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent() done" << endl;
00360 }
00361 
00362 void KOEditorGeneralEvent::setDuration()
00363 {
00364   QString tmpStr, catStr;
00365   int hourdiff, minutediff;
00366   // end<date is an accepted temporary state while typing, but don't show
00367   // any duration if this happens
00368   if(mCurrEndDateTime >= mCurrStartDateTime) {
00369 
00370     if (!mTimeAssociateButton->isChecked()) {
00371       int daydiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) + 1;
00372       tmpStr = i18n("Duration: ");
00373       tmpStr.append(i18n("1 Day","%n Days",daydiff));
00374     } else {
00375       hourdiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) * 24;
00376       hourdiff += mCurrEndDateTime.time().hour() -
00377                   mCurrStartDateTime.time().hour();
00378       minutediff = mCurrEndDateTime.time().minute() -
00379                    mCurrStartDateTime.time().minute();
00380       // If minutediff is negative, "borrow" 60 minutes from hourdiff
00381       if (minutediff < 0 && hourdiff > 0) {
00382         hourdiff -= 1;
00383         minutediff += 60;
00384       }
00385       if (hourdiff || minutediff){
00386         tmpStr = i18n("Duration: ");
00387         if (hourdiff){
00388           catStr = i18n("1 hour","%n hours",hourdiff);
00389           tmpStr.append(catStr);
00390         }
00391         if (hourdiff && minutediff){
00392           tmpStr += i18n(", ");
00393         }
00394         if (minutediff){
00395           catStr = i18n("1 minute","%n minutes",minutediff);
00396           tmpStr += catStr;
00397         }
00398       } else tmpStr = "";
00399     }
00400   }
00401   mDurationLabel->setText(tmpStr);
00402   QWhatsThis::add( mDurationLabel,
00403        i18n("Shows the duration of the event or to-do with the "
00404       "current start and end dates and times.") );
00405 }
00406 
00407 void KOEditorGeneralEvent::emitDateTimeStr()
00408 {
00409   KLocale *l = KGlobal::locale();
00410 
00411   QString from,to;
00412   if (!mTimeAssociateButton->isChecked()) {
00413     from = l->formatDate(mCurrStartDateTime.date());
00414     to = l->formatDate(mCurrEndDateTime.date());
00415   } else {
00416     from = l->formatDateTime(mCurrStartDateTime);
00417     to = l->formatDateTime(mCurrEndDateTime);
00418   }
00419 
00420   QString str = i18n("From: %1   To: %2   %3").arg(from).arg(to)
00421                 .arg(mDurationLabel->text());
00422 
00423   emit dateTimeStrChanged(str);
00424 }
00425 
00426 bool KOEditorGeneralEvent::validateInput()
00427 {
00428 //  kdDebug(5850) << "KOEditorGeneralEvent::validateInput()" << endl;
00429 
00430   if (mTimeAssociateButton->isChecked()) {
00431     if (!mStartTimeEdit->inputIsValid()) {
00432       KMessageBox::sorry( 0,
00433           i18n("Please specify a valid start time, for example '%1'.")
00434           .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00435       return false;
00436     }
00437 
00438     if (!mEndTimeEdit->inputIsValid()) {
00439       KMessageBox::sorry( 0,
00440           i18n("Please specify a valid end time, for example '%1'.")
00441           .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00442       return false;
00443     }
00444   }
00445 
00446   if (!mStartDateEdit->date().isValid()) {
00447     KMessageBox::sorry( 0,
00448         i18n("Please specify a valid start date, for example '%1'.")
00449         .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00450     return false;
00451   }
00452 
00453   if (!mEndDateEdit->date().isValid()) {
00454     KMessageBox::sorry( 0,
00455         i18n("Please specify a valid end date, for example '%1'.")
00456         .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00457     return false;
00458   }
00459 
00460   QDateTime startDt,endDt;
00461   startDt.setDate(mStartDateEdit->date());
00462   endDt.setDate(mEndDateEdit->date());
00463   if (mTimeAssociateButton->isChecked()) {
00464     startDt.setTime(mStartTimeEdit->getTime());
00465     endDt.setTime(mEndTimeEdit->getTime());
00466   }
00467 
00468   if (startDt > endDt) {
00469     KMessageBox::sorry(0,i18n("The event ends before it starts.\n"
00470                                  "Please correct dates and times."));
00471     return false;
00472   }
00473 
00474   return KOEditorGeneral::validateInput();
00475 }
KDE Home | KDE Accessibility Home | Description of Access Keys