00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 #include <libkcal/incidenceformatter.h>
00050
00051 #include "ktimeedit.h"
00052 #include <libkdepim/kdateedit.h>
00053
00054 #include "koprefs.h"
00055
00056 #include "koeditorgeneralevent.h"
00057 #include "koeditorgeneralevent.moc"
00058
00059 KOEditorGeneralEvent::KOEditorGeneralEvent(QObject* parent,
00060 const char* name) :
00061 KOEditorGeneral( parent, name)
00062 {
00063 connect( this, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & )),
00064 SLOT( setDuration() ) );
00065 connect( this, SIGNAL( dateTimesChanged( const QDateTime &, const QDateTime & )),
00066 SLOT( emitDateTimeStr() ));
00067 }
00068
00069 KOEditorGeneralEvent::~KOEditorGeneralEvent()
00070 {
00071 }
00072
00073 void KOEditorGeneralEvent::finishSetup()
00074 {
00075 QWidget::setTabOrder( mSummaryEdit, mLocationEdit );
00076 QWidget::setTabOrder( mLocationEdit, mStartDateEdit );
00077 QWidget::setTabOrder( mStartDateEdit, mStartTimeEdit );
00078 QWidget::setTabOrder( mStartTimeEdit, mEndDateEdit );
00079 QWidget::setTabOrder( mEndDateEdit, mEndTimeEdit );
00080 QWidget::setTabOrder( mEndTimeEdit, mAlldayEventCheckbox );
00081 QWidget::setTabOrder( mAlldayEventCheckbox, mAlarmButton );
00082 QWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
00083 QWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
00084
00085 QWidget::setTabOrder( mAlarmIncrCombo, mAlarmEditButton );
00086
00087
00088 QWidget::setTabOrder( mAlarmEditButton, mFreeTimeCombo );
00089 QWidget::setTabOrder( mFreeTimeCombo, mDescriptionEdit );
00090 QWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
00091 QWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
00092
00093
00094 mSummaryEdit->setFocus();
00095 }
00096
00097 void KOEditorGeneralEvent::initTime(QWidget *parent,QBoxLayout *topLayout)
00098 {
00099 QBoxLayout *timeLayout = new QVBoxLayout(topLayout);
00100
00101 QGroupBox *timeGroupBox = new QGroupBox(1,QGroupBox::Horizontal,
00102 i18n("Date && Time"),parent);
00103 QWhatsThis::add( timeGroupBox,
00104 i18n("Sets options related to the date and time of the "
00105 "event or to-do.") );
00106 timeLayout->addWidget(timeGroupBox);
00107
00108 QFrame *timeBoxFrame = new QFrame(timeGroupBox);
00109
00110 QGridLayout *layoutTimeBox = new QGridLayout( timeBoxFrame );
00111 layoutTimeBox->setSpacing(topLayout->spacing());
00112 layoutTimeBox->setColStretch( 3, 1 );
00113
00114 mStartDateLabel = new QLabel(i18n("&Start:"),timeBoxFrame);
00115 layoutTimeBox->addWidget(mStartDateLabel,0,0);
00116
00117 mStartDateEdit = new KDateEdit(timeBoxFrame);
00118 layoutTimeBox->addWidget(mStartDateEdit,0,1);
00119 mStartDateLabel->setBuddy( mStartDateEdit );
00120
00121 mStartTimeEdit = new KTimeEdit(timeBoxFrame);
00122 layoutTimeBox->addWidget(mStartTimeEdit,0,2);
00123
00124
00125 mEndDateLabel = new QLabel(i18n("&End:"),timeBoxFrame);
00126 layoutTimeBox->addWidget(mEndDateLabel,1,0);
00127
00128 mEndDateEdit = new KDateEdit(timeBoxFrame);
00129 layoutTimeBox->addWidget(mEndDateEdit,1,1);
00130 mEndDateLabel->setBuddy( mEndDateEdit );
00131
00132 mEndTimeEdit = new KTimeEdit(timeBoxFrame);
00133 layoutTimeBox->addWidget(mEndTimeEdit,1,2);
00134
00135 mAlldayEventCheckbox = new QCheckBox(i18n("All-&day"),timeBoxFrame);
00136 layoutTimeBox->addWidget( mAlldayEventCheckbox, 0, 3 );
00137 connect(mAlldayEventCheckbox, SIGNAL(toggled(bool)),SLOT(associateTime(bool)));
00138
00139 mDurationLabel = new QLabel( timeBoxFrame );
00140 layoutTimeBox->addWidget( mDurationLabel, 1, 3 );
00141
00142
00143 connect(mStartTimeEdit, SIGNAL(timeChanged(QTime)),
00144 this, SLOT(startTimeChanged(QTime)));
00145 connect(mEndTimeEdit, SIGNAL(timeChanged(QTime)),
00146 this, SLOT(endTimeChanged(QTime)));
00147
00148
00149 connect(mStartDateEdit, SIGNAL(dateChanged(const QDate&)),
00150 this, SLOT(startDateChanged(const QDate&)));
00151 connect(mEndDateEdit, SIGNAL(dateChanged(const QDate&)),
00152 this, SLOT(endDateChanged(const QDate&)));
00153
00154 QBoxLayout *recLayout = new QHBoxLayout();
00155 layoutTimeBox->addMultiCellLayout( recLayout, 2, 2, 1, 4 );
00156 mRecurrenceSummary = new QLabel( QString(), timeBoxFrame );
00157 recLayout->addWidget( mRecurrenceSummary );
00158 QPushButton *recEditButton = new QPushButton( i18n("Edit..."), timeBoxFrame );
00159 recLayout->addWidget( recEditButton );
00160 connect( recEditButton, SIGNAL(clicked()), SIGNAL(editRecurrence()) );
00161 recLayout->addStretch( 1 );
00162
00163 QLabel *label = new QLabel( i18n("Reminder:"), timeBoxFrame );
00164 layoutTimeBox->addWidget( label, 3, 0 );
00165 QBoxLayout *alarmLineLayout = new QHBoxLayout();
00166 layoutTimeBox->addMultiCellLayout( alarmLineLayout, 3, 3, 1, 4 );
00167 initAlarm( timeBoxFrame, alarmLineLayout );
00168 alarmLineLayout->addStretch( 1 );
00169
00170 QBoxLayout *secLayout = new QHBoxLayout();
00171 layoutTimeBox->addLayout( secLayout, 0, 4 );
00172 initSecrecy( timeBoxFrame, secLayout );
00173
00174 QBoxLayout *classLayout = new QHBoxLayout();
00175 layoutTimeBox->addLayout( classLayout, 1, 4 );
00176 initClass( timeBoxFrame, classLayout );
00177 }
00178
00179 void KOEditorGeneralEvent::initClass(QWidget *parent,QBoxLayout *topLayout)
00180 {
00181 QBoxLayout *classLayout = new QHBoxLayout(topLayout);
00182
00183 QLabel *freeTimeLabel = new QLabel(i18n("S&how time as:"),parent);
00184 QString whatsThis = i18n("Sets how this time will appear on your Free/Busy "
00185 "information.");
00186 QWhatsThis::add( freeTimeLabel, whatsThis );
00187 classLayout->addWidget(freeTimeLabel);
00188
00189 mFreeTimeCombo = new QComboBox(false, parent);
00190 QWhatsThis::add( mFreeTimeCombo, whatsThis );
00191 mFreeTimeCombo->insertItem(i18n("Busy"));
00192 mFreeTimeCombo->insertItem(i18n("Free"));
00193 classLayout->addWidget(mFreeTimeCombo);
00194 freeTimeLabel->setBuddy( mFreeTimeCombo );
00195 }
00196
00197 void KOEditorGeneralEvent::initInvitationBar(QWidget * parent, QBoxLayout * layout)
00198 {
00199 QBoxLayout *topLayout = new QHBoxLayout( layout );
00200 mInvitationBar = new QFrame( parent );
00201 mInvitationBar->setPaletteBackgroundColor( KGlobalSettings::alternateBackgroundColor() );
00202 topLayout->addWidget( mInvitationBar );
00203
00204 QBoxLayout *barLayout = new QHBoxLayout( mInvitationBar );
00205 barLayout->setSpacing( layout->spacing() );
00206 QLabel *label = new QLabel( i18n("You have not yet definitely responded to this invitation." ), mInvitationBar );
00207 barLayout->addWidget( label );
00208 barLayout->addStretch( 1 );
00209 QPushButton *button = new QPushButton( i18n("Accept"), mInvitationBar );
00210 connect( button, SIGNAL(clicked()), SIGNAL(acceptInvitation()) );
00211 connect( button, SIGNAL(clicked()), mInvitationBar, SLOT(hide()) );
00212 barLayout->addWidget( button );
00213 button = new QPushButton( i18n("Decline"), mInvitationBar );
00214 connect( button, SIGNAL(clicked()), SIGNAL(declineInvitation()) );
00215 connect( button, SIGNAL(clicked()), mInvitationBar, SLOT(hide()) );
00216 barLayout->addWidget( button );
00217
00218 mInvitationBar->hide();
00219 }
00220
00221 void KOEditorGeneralEvent::timeStuffDisable(bool disable)
00222 {
00223 mStartTimeEdit->setEnabled( !disable );
00224 mEndTimeEdit->setEnabled( !disable );
00225
00226 setDuration();
00227 emitDateTimeStr();
00228 }
00229
00230 void KOEditorGeneralEvent::associateTime(bool time)
00231 {
00232 timeStuffDisable(time);
00233
00234 allDayChanged(time);
00235 }
00236
00237 void KOEditorGeneralEvent::setDateTimes( const QDateTime &start, const QDateTime &end )
00238 {
00239
00240
00241 mStartDateEdit->setDate(start.date());
00242
00243 mStartTimeEdit->blockSignals( true );
00244 mStartTimeEdit->setTime(start.time());
00245 mStartTimeEdit->blockSignals( false );
00246 mEndDateEdit->setDate(end.date());
00247 mEndTimeEdit->setTime(end.time());
00248
00249 mCurrStartDateTime = start;
00250 mCurrEndDateTime = end;
00251
00252 setDuration();
00253 emitDateTimeStr();
00254 }
00255
00256 void KOEditorGeneralEvent::startTimeChanged( QTime newtime )
00257 {
00258 kdDebug(5850) << "KOEditorGeneralEvent::startTimeChanged() " << newtime.toString() << endl;
00259
00260 int secsep = mCurrStartDateTime.secsTo(mCurrEndDateTime);
00261
00262 mCurrStartDateTime.setTime(newtime);
00263
00264
00265 mCurrEndDateTime = mCurrStartDateTime.addSecs(secsep);
00266 mEndTimeEdit->setTime(mCurrEndDateTime.time());
00267 mEndDateEdit->setDate(mCurrEndDateTime.date());
00268
00269 emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00270 }
00271
00272 void KOEditorGeneralEvent::endTimeChanged( QTime newtime )
00273 {
00274
00275
00276 QDateTime newdt(mCurrEndDateTime.date(), newtime);
00277 mCurrEndDateTime = newdt;
00278
00279 emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00280 }
00281
00282 void KOEditorGeneralEvent::startDateChanged( const QDate &newdate )
00283 {
00284 if ( !newdate.isValid() )
00285 return;
00286
00287 int daysep = mCurrStartDateTime.daysTo(mCurrEndDateTime);
00288
00289 mCurrStartDateTime.setDate(newdate);
00290
00291
00292 mCurrEndDateTime.setDate(mCurrStartDateTime.date().addDays(daysep));
00293 mEndDateEdit->setDate(mCurrEndDateTime.date());
00294
00295 emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00296 }
00297
00298 void KOEditorGeneralEvent::endDateChanged( const QDate &newdate )
00299 {
00300 if ( !newdate.isValid() )
00301 return;
00302
00303 QDateTime newdt(newdate, mCurrEndDateTime.time());
00304 mCurrEndDateTime = newdt;
00305
00306 emit dateTimesChanged(mCurrStartDateTime,mCurrEndDateTime);
00307 }
00308
00309 void KOEditorGeneralEvent::setDefaults( const QDateTime &from,
00310 const QDateTime &to, bool allDay)
00311 {
00312 KOEditorGeneral::setDefaults(allDay);
00313
00314 mAlldayEventCheckbox->setChecked(allDay);
00315 timeStuffDisable(allDay);
00316
00317 setDateTimes(from,to);
00318 }
00319
00320 void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, bool tmpl )
00321 {
00322 QString tmpStr;
00323
00324 mAlldayEventCheckbox->setChecked(event->doesFloat());
00325 timeStuffDisable(event->doesFloat());
00326
00327 if ( !tmpl ) {
00328
00329 setDateTimes(event->dtStart(),event->dtEnd());
00330 }
00331
00332 switch( event->transparency() ) {
00333 case Event::Transparent:
00334 mFreeTimeCombo->setCurrentItem(1);
00335 break;
00336 case Event::Opaque:
00337 mFreeTimeCombo->setCurrentItem(0);
00338 break;
00339 }
00340
00341 mRecurrenceSummary->setText( IncidenceFormatter::recurrenceString( event ) );
00342
00343 Attendee *me = event->attendeeByMails( KOPrefs::instance()->allEmails() );
00344 if ( me && (me->status() == Attendee::NeedsAction || me->status() == Attendee::Tentative ||
00345 me->status() == Attendee::InProcess) ) {
00346 mInvitationBar->show();
00347 } else {
00348 mInvitationBar->hide();
00349 }
00350
00351 readIncidence(event, calendar);
00352 }
00353
00354 void KOEditorGeneralEvent::writeEvent(Event *event)
00355 {
00356
00357
00358 writeIncidence(event);
00359
00360 QDate tmpDate;
00361 QTime tmpTime;
00362 QDateTime tmpDT;
00363
00364
00365 QString tmpStr;
00366
00367 if (mAlldayEventCheckbox->isChecked()) {
00368 event->setFloats(true);
00369
00370 tmpDate = mStartDateEdit->date();
00371 tmpTime.setHMS(0,0,0);
00372 tmpDT.setDate(tmpDate);
00373 tmpDT.setTime(tmpTime);
00374 event->setDtStart(tmpDT);
00375
00376 tmpDate = mEndDateEdit->date();
00377 tmpTime.setHMS(0,0,0);
00378 tmpDT.setDate(tmpDate);
00379 tmpDT.setTime(tmpTime);
00380 event->setDtEnd(tmpDT);
00381 } else {
00382 event->setFloats(false);
00383
00384
00385 tmpDate = mEndDateEdit->date();
00386 tmpTime = mEndTimeEdit->getTime();
00387 tmpDT.setDate(tmpDate);
00388 tmpDT.setTime(tmpTime);
00389 event->setDtEnd(tmpDT);
00390
00391
00392 tmpDate = mStartDateEdit->date();
00393 tmpTime = mStartTimeEdit->getTime();
00394 tmpDT.setDate(tmpDate);
00395 tmpDT.setTime(tmpTime);
00396 event->setDtStart(tmpDT);
00397 }
00398
00399 event->setTransparency(mFreeTimeCombo->currentItem() > 0
00400 ? KCal::Event::Transparent
00401 : KCal::Event::Opaque);
00402
00403
00404 }
00405
00406 void KOEditorGeneralEvent::setDuration()
00407 {
00408 QString tmpStr, catStr;
00409 int hourdiff, minutediff;
00410
00411
00412 if(mCurrEndDateTime >= mCurrStartDateTime) {
00413
00414 if (mAlldayEventCheckbox->isChecked()) {
00415 int daydiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) + 1;
00416 tmpStr = i18n("Duration: ");
00417 tmpStr.append(i18n("1 Day","%n Days",daydiff));
00418 } else {
00419 hourdiff = mCurrStartDateTime.date().daysTo(mCurrEndDateTime.date()) * 24;
00420 hourdiff += mCurrEndDateTime.time().hour() -
00421 mCurrStartDateTime.time().hour();
00422 minutediff = mCurrEndDateTime.time().minute() -
00423 mCurrStartDateTime.time().minute();
00424
00425 if (minutediff < 0 && hourdiff > 0) {
00426 hourdiff -= 1;
00427 minutediff += 60;
00428 }
00429 if (hourdiff || minutediff){
00430 tmpStr = i18n("Duration: ");
00431 if (hourdiff){
00432 catStr = i18n("1 hour","%n hours",hourdiff);
00433 tmpStr.append(catStr);
00434 }
00435 if (hourdiff && minutediff){
00436 tmpStr += i18n(", ");
00437 }
00438 if (minutediff){
00439 catStr = i18n("1 minute","%n minutes",minutediff);
00440 tmpStr += catStr;
00441 }
00442 } else tmpStr = "";
00443 }
00444 }
00445 mDurationLabel->setText(tmpStr);
00446 QWhatsThis::add( mDurationLabel,
00447 i18n("Shows the duration of the event or to-do with the "
00448 "current start and end dates and times.") );
00449 }
00450
00451 void KOEditorGeneralEvent::emitDateTimeStr()
00452 {
00453 KLocale *l = KGlobal::locale();
00454
00455 QString from,to;
00456 if (mAlldayEventCheckbox->isChecked()) {
00457 from = l->formatDate(mCurrStartDateTime.date());
00458 to = l->formatDate(mCurrEndDateTime.date());
00459 } else {
00460 from = l->formatDateTime(mCurrStartDateTime);
00461 to = l->formatDateTime(mCurrEndDateTime);
00462 }
00463
00464 QString str = i18n("From: %1 To: %2 %3").arg(from).arg(to)
00465 .arg(mDurationLabel->text());
00466
00467 emit dateTimeStrChanged(str);
00468 }
00469
00470 bool KOEditorGeneralEvent::validateInput()
00471 {
00472
00473
00474 if (!mAlldayEventCheckbox->isChecked()) {
00475 if (!mStartTimeEdit->inputIsValid()) {
00476 KMessageBox::sorry( 0,
00477 i18n("Please specify a valid start time, for example '%1'.")
00478 .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00479 return false;
00480 }
00481
00482 if (!mEndTimeEdit->inputIsValid()) {
00483 KMessageBox::sorry( 0,
00484 i18n("Please specify a valid end time, for example '%1'.")
00485 .arg( KGlobal::locale()->formatTime( QTime::currentTime() ) ) );
00486 return false;
00487 }
00488 }
00489
00490 if (!mStartDateEdit->date().isValid()) {
00491 KMessageBox::sorry( 0,
00492 i18n("Please specify a valid start date, for example '%1'.")
00493 .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00494 return false;
00495 }
00496
00497 if (!mEndDateEdit->date().isValid()) {
00498 KMessageBox::sorry( 0,
00499 i18n("Please specify a valid end date, for example '%1'.")
00500 .arg( KGlobal::locale()->formatDate( QDate::currentDate() ) ) );
00501 return false;
00502 }
00503
00504 QDateTime startDt,endDt;
00505 startDt.setDate(mStartDateEdit->date());
00506 endDt.setDate(mEndDateEdit->date());
00507 if (!mAlldayEventCheckbox->isChecked()) {
00508 startDt.setTime(mStartTimeEdit->getTime());
00509 endDt.setTime(mEndTimeEdit->getTime());
00510 }
00511
00512 if (startDt > endDt) {
00513 KMessageBox::sorry(0,i18n("The event ends before it starts.\n"
00514 "Please correct dates and times."));
00515 return false;
00516 }
00517
00518 return KOEditorGeneral::validateInput();
00519 }
00520
00521 void KOEditorGeneralEvent::updateRecurrenceSummary(const QString & summary)
00522 {
00523 mRecurrenceSummary->setText( summary );
00524 }