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   mCurrEndDateTime = newdt;
00264 
00265   emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00266 }
00267 
00268 void KOEditorGeneralEvent::setDefaults( const QDateTime &from,
00269                                         const QDateTime &to, bool allDay)
00270 {
00271   KOEditorGeneral::setDefaults(allDay);
00272 
00273   mTimeAssociateButton->setChecked(!allDay);
00274   timeStuffDisable(allDay);
00275 
00276   setDateTimes(from,to);
00277 }
00278 
00279 void KOEditorGeneralEvent::readEvent( Event *event, bool tmpl )
00280 {
00281   QString tmpStr;
00282 
00283   mTimeAssociateButton->setChecked(!event->doesFloat());
00284   timeStuffDisable(event->doesFloat());
00285 
00286   if ( !tmpl ) {
00287     // the rest is for the events only
00288     setDateTimes(event->dtStart(),event->dtEnd());
00289   }
00290 
00291   switch( event->transparency() ) {
00292   case Event::Transparent:
00293     mFreeTimeCombo->setCurrentItem(1);
00294     break;
00295   case Event::Opaque:
00296     mFreeTimeCombo->setCurrentItem(0);
00297     break;
00298   }
00299 
00300   readIncidence(event);
00301 }
00302 
00303 void KOEditorGeneralEvent::writeEvent(Event *event)
00304 {
00305 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent()" << endl;
00306 
00307   writeIncidence(event);
00308 
00309   QDate tmpDate;
00310   QTime tmpTime;
00311   QDateTime tmpDT;
00312 
00313   // temp. until something better happens.
00314   QString tmpStr;
00315 
00316   if (!mTimeAssociateButton->isChecked()) {
00317     event->setFloats(true);
00318     // need to change this.
00319     tmpDate = mStartDateEdit->date();
00320     tmpTime.setHMS(0,0,0);
00321     tmpDT.setDate(tmpDate);
00322     tmpDT.setTime(tmpTime);
00323     event->setDtStart(tmpDT);
00324 
00325     tmpDate = mEndDateEdit->date();
00326     tmpTime.setHMS(0,0,0);
00327     tmpDT.setDate(tmpDate);
00328     tmpDT.setTime(tmpTime);
00329     event->setDtEnd(tmpDT);
00330   } else {
00331     event->setFloats(false);
00332 
00333     // set date/time end
00334     tmpDate = mEndDateEdit->date();
00335     tmpTime = mEndTimeEdit->getTime();
00336     tmpDT.setDate(tmpDate);
00337     tmpDT.setTime(tmpTime);
00338     event->setDtEnd(tmpDT);
00339 
00340     // set date/time start
00341     tmpDate = mStartDateEdit->date();
00342     tmpTime = mStartTimeEdit->getTime();
00343     tmpDT.setDate(tmpDate);
00344     tmpDT.setTime(tmpTime);
00345     event->setDtStart(tmpDT);
00346   } // check for float
00347 
00348   event->setTransparency(mFreeTimeCombo->currentItem() > 0
00349                          ? KCal::Event::Transparent
00350                          : KCal::Event::Opaque);
00351 
00352 //  kdDebug(5850) << "KOEditorGeneralEvent::writeEvent() done" << endl;
00353 }
00354 
00355 void KOEditorGeneralEvent::setDuration()
00356 {
00357   QString tmpStr, catStr;
00358   int hourdiff, minutediff;
00359   // end<date is an accepted temporary state while typing, but don't show
00360   // any duration if this happens
00361   if(mCurrEndDateTime >= mCurrStartDateTime) {
00362 
00363     if (!mTimeAssociateButton->isChecked()) {
00364       int daydiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) + 1;
00365       tmpStr = i18n("Duration: ");
00366       tmpStr.append(i18n("1 Day","%n Days",daydiff));
00367     } else {
00368       hourdiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) * 24;
00369       hourdiff += mCurrEndDateTime.time().hour() -
00370                   mCurrStartDateTime.time().hour();
00371       minutediff = mCurrEndDateTime.time().minute() -
00372                    mCurrStartDateTime.time().minute();
00373       // If minutediff is negative, "borrow" 60 minutes from hourdiff
00374       if (minutediff < 0 && hourdiff > 0) {
00375         hourdiff -= 1;
00376         minutediff += 60;
00377       }
00378       if (hourdiff || minutediff){
00379         tmpStr = i18n("Duration: ");
00380         if (hourdiff){
00381           catStr = i18n("1 hour","%n hours",hourdiff);
00382           tmpStr.append(catStr);
00383         }
00384         if (hourdiff && minutediff){
00385           tmpStr += i18n(", ");
00386         }
00387         if (minutediff){
00388           catStr = i18n("1 minute","%n minutes",minutediff);
00389           tmpStr += catStr;
00390         }
00391       } else tmpStr = "";
00392     }
00393   }
00394   mDurationLabel->setText(tmpStr);
00395   QWhatsThis::add( mDurationLabel,
00396        i18n("Shows the duration of the event or to-do with the "
00397       "current start and end dates and times.") );
00398 }
00399 
00400 void KOEditorGeneralEvent::emitDateTimeStr()
00401 {
00402   KLocale *l = KGlobal::locale();
00403 
00404   QString from,to;
00405   if (!mTimeAssociateButton->isChecked()) {
00406     from = l->formatDate(mCurrStartDateTime.date());
00407     to = l->formatDate(mCurrEndDateTime.date());
00408   } else {
00409     from = l->formatDateTime(mCurrStartDateTime);
00410     to = l->formatDateTime(mCurrEndDateTime);
00411   }
00412 
00413   QString str = i18n("From: %1   To: %2   %3").arg(from).arg(to)
00414                 .arg(mDurationLabel->text());
00415 
00416   emit dateTimeStrChanged(str);
00417 }
00418 
00419 bool KOEditorGeneralEvent::validateInput()
00420 {
00421 //  kdDebug(5850) << "KOEditorGeneralEvent::validateInput()" << endl;
00422 
00423   if (mTimeAssociateButton->isChecked()) {
00424     if (!mStartTimeEdit->inputIsValid()) {
00425       KMessageBox::sorry( 0,
00426           i18n("Please specify a valid start time, for example '%1'.")
00427           .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00428       return false;
00429     }
00430 
00431     if (!mEndTimeEdit->inputIsValid()) {
00432       KMessageBox::sorry( 0,
00433           i18n("Please specify a valid end time, for example '%1'.")
00434           .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00435       return false;
00436     }
00437   }
00438 
00439   if (!mStartDateEdit->date().isValid()) {
00440     KMessageBox::sorry( 0,
00441         i18n("Please specify a valid start date, for example '%1'.")
00442         .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00443     return false;
00444   }
00445 
00446   if (!mEndDateEdit->date().isValid()) {
00447     KMessageBox::sorry( 0,
00448         i18n("Please specify a valid end date, for example '%1'.")
00449         .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00450     return false;
00451   }
00452 
00453   QDateTime startDt,endDt;
00454   startDt.setDate(mStartDateEdit->date());
00455   endDt.setDate(mEndDateEdit->date());
00456   if (mTimeAssociateButton->isChecked()) {
00457     startDt.setTime(mStartTimeEdit->getTime());
00458     endDt.setTime(mEndTimeEdit->getTime());
00459   }
00460 
00461   if (startDt > endDt) {
00462     KMessageBox::sorry(0,i18n("The event ends before it starts.\n"
00463                                  "Please correct dates and times."));
00464     return false;
00465   }
00466 
00467   return KOEditorGeneral::validateInput();
00468 }
KDE Home | KDE Accessibility Home | Description of Access Keys