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
00026 #include <qwidget.h>
00027 #include <qtooltip.h>
00028 #include <qlayout.h>
00029 #include <qvbox.h>
00030 #include <qhbox.h>
00031 #include <qbuttongroup.h>
00032 #include <qvgroupbox.h>
00033 #include <qwidgetstack.h>
00034 #include <qdatetime.h>
00035 #include <qlineedit.h>
00036 #include <qlabel.h>
00037 #include <qcheckbox.h>
00038 #include <qpushbutton.h>
00039 #include <qcombobox.h>
00040 #include <qspinbox.h>
00041 #include <qwhatsthis.h>
00042
00043 #include <kglobal.h>
00044 #include <kdialog.h>
00045 #include <kdebug.h>
00046 #include <klocale.h>
00047 #include <kiconloader.h>
00048 #include <kmessagebox.h>
00049 #include <kfiledialog.h>
00050 #include <ksqueezedtextlabel.h>
00051 #include <kstandarddirs.h>
00052 #include <ktextedit.h>
00053 #include <krestrictedline.h>
00054
00055 #include <libkcal/todo.h>
00056 #include <libkcal/event.h>
00057 #include <libkcal/incidenceformatter.h>
00058
00059 #include <libkdepim/kdateedit.h>
00060 #include <libkdepim/categoryselectdialog.h>
00061
00062 #include "koprefs.h"
00063 #include "koglobals.h"
00064
00065 #include "koeditorgeneral.h"
00066 #include "koeditoralarms.h"
00067 #include "koeditorattachments.h"
00068 #include "koeditorgeneral.moc"
00069 #include "kohelper.h"
00070
00071 KOEditorGeneral::KOEditorGeneral(QObject* parent, const char* name) :
00072 QObject( parent, name ), mAttachments(0)
00073 {
00074 mType = "Event";
00075 mAlarmList.setAutoDelete( true );
00076 }
00077
00078 KOEditorGeneral::~KOEditorGeneral()
00079 {
00080 }
00081
00082
00083 FocusLineEdit::FocusLineEdit( QWidget *parent )
00084 : QLineEdit( parent ), mSkipFirst( true )
00085 {
00086 }
00087
00088 void FocusLineEdit::focusInEvent ( QFocusEvent *e )
00089 {
00090 if ( !mSkipFirst ) {
00091 emit focusReceivedSignal();
00092 } else {
00093 mSkipFirst = false;
00094 }
00095 QLineEdit::focusInEvent( e );
00096 }
00097
00098
00099 void KOEditorGeneral::initHeader( QWidget *parent,QBoxLayout *topLayout)
00100 {
00101 QGridLayout *headerLayout = new QGridLayout();
00102 headerLayout->setSpacing( topLayout->spacing() );
00103 topLayout->addLayout( headerLayout );
00104
00105 #if 0
00106 mOwnerLabel = new QLabel(i18n("Owner:"),parent);
00107 headerLayout->addMultiCellWidget(mOwnerLabel,0,0,0,1);
00108 #endif
00109
00110 QString whatsThis = i18n("Sets the Title of this event or to-do.");
00111 QLabel *summaryLabel = new QLabel( i18n("T&itle:"), parent );
00112 QWhatsThis::add( summaryLabel, whatsThis );
00113 QFont f = summaryLabel->font();
00114 f.setBold( true );
00115 summaryLabel->setFont(f);
00116 headerLayout->addWidget(summaryLabel,1,0);
00117
00118 mSummaryEdit = new FocusLineEdit( parent );
00119 QWhatsThis::add( mSummaryEdit, whatsThis );
00120 connect( mSummaryEdit, SIGNAL( focusReceivedSignal() ),
00121 SIGNAL( focusReceivedSignal() ) );
00122 headerLayout->addWidget(mSummaryEdit,1,1);
00123 summaryLabel->setBuddy( mSummaryEdit );
00124
00125 mAttendeeSummaryLabel = new QLabel( parent );
00126 updateAttendeeSummary( 0 );
00127 headerLayout->addWidget( mAttendeeSummaryLabel, 1, 2 );
00128
00129 whatsThis = i18n("Sets where the event or to-do will take place.");
00130 QLabel *locationLabel = new QLabel( i18n("&Location:"), parent );
00131 QWhatsThis::add( locationLabel, whatsThis );
00132 headerLayout->addWidget(locationLabel,2,0);
00133
00134 mLocationEdit = new QLineEdit( parent );
00135 QWhatsThis::add( mLocationEdit, whatsThis );
00136 headerLayout->addMultiCellWidget( mLocationEdit, 2, 2, 1, 2 );
00137 locationLabel->setBuddy( mLocationEdit );
00138
00139 QBoxLayout *thirdLineLayout = new QHBoxLayout();
00140 headerLayout->addMultiCellLayout( thirdLineLayout, 3, 3, 0, 2 );
00141
00142 mResourceLabel = new QLabel( parent );
00143 mResourceLabel->hide();
00144 thirdLineLayout->addWidget( mResourceLabel );
00145
00146 whatsThis = i18n("Allows you to select the categories that this event or to-do belongs to.");
00147 QLabel *categoriesLabel = new QLabel( i18n("Categories:"), parent );
00148 QWhatsThis::add( categoriesLabel, whatsThis );
00149 thirdLineLayout->addWidget( categoriesLabel );
00150 mCategoriesLabel = new KSqueezedTextLabel( parent );
00151 QWhatsThis::add( mCategoriesLabel, whatsThis );
00152 mCategoriesLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);
00153 thirdLineLayout->addWidget( mCategoriesLabel );
00154
00155 mCategoriesButton = new QPushButton( parent );
00156 mCategoriesButton->setText(i18n("&Select..."));
00157 QWhatsThis::add( mCategoriesButton, whatsThis );
00158 connect(mCategoriesButton,SIGNAL(clicked()),SLOT(selectCategories()));
00159 thirdLineLayout->addWidget( mCategoriesButton );
00160 }
00161
00162 void KOEditorGeneral::initSecrecy(QWidget *parent, QBoxLayout *topLayout)
00163 {
00164 QBoxLayout *secrecyLayout = new QHBoxLayout( topLayout );
00165
00166 QLabel *secrecyLabel = new QLabel(i18n("Acc&ess:"),parent);
00167 QString whatsThis = i18n("Sets whether the access to this event or to-do "
00168 "is restricted. Please note that KOrganizer "
00169 "currently does not use this setting, so the "
00170 "implementation of the restrictions will depend "
00171 "on the groupware server. This means that events "
00172 "or to-dos marked as private or confidential may "
00173 "be visible to others.");
00174 QWhatsThis::add( secrecyLabel, whatsThis );
00175 secrecyLayout->addWidget(secrecyLabel);
00176
00177 mSecrecyCombo = new QComboBox(parent);
00178 QWhatsThis::add( mSecrecyCombo, whatsThis );
00179 mSecrecyCombo->insertStringList(Incidence::secrecyList());
00180 secrecyLayout->addWidget(mSecrecyCombo);
00181 secrecyLabel->setBuddy( mSecrecyCombo );
00182 }
00183
00184 void KOEditorGeneral::initDescription(QWidget *parent,QBoxLayout *topLayout)
00185 {
00186 mDescriptionEdit = new KTextEdit(parent);
00187 QWhatsThis::add( mDescriptionEdit,
00188 i18n("Sets the description for this event or to-do. This "
00189 "will be displayed in a reminder if one is set, "
00190 "as well as in a tooltip when you hover over the "
00191 "event.") );
00192 mDescriptionEdit->append("");
00193 mDescriptionEdit->setReadOnly(false);
00194 mDescriptionEdit->setOverwriteMode(false);
00195 mDescriptionEdit->setWordWrap( KTextEdit::WidgetWidth );
00196 mDescriptionEdit->setTabChangesFocus( true );;
00197 topLayout->addWidget(mDescriptionEdit, 4);
00198 }
00199
00200 void KOEditorGeneral::initAlarm(QWidget *parent,QBoxLayout *topLayout)
00201 {
00202 QBoxLayout *alarmLayout = new QHBoxLayout(topLayout);
00203
00204 mAlarmBell = new QLabel(parent);
00205 mAlarmBell->setPixmap(KOGlobals::self()->smallIcon("bell"));
00206 alarmLayout->addWidget( mAlarmBell );
00207
00208
00209 mAlarmStack = new QWidgetStack( parent );
00210 alarmLayout->addWidget( mAlarmStack );
00211
00212 mAlarmInfoLabel = new QLabel( i18n("No reminders configured"), mAlarmStack );
00213 mAlarmStack->addWidget( mAlarmInfoLabel, AdvancedAlarmLabel );
00214
00215 QHBox *simpleAlarmBox = new QHBox( mAlarmStack );
00216 mAlarmStack->addWidget( simpleAlarmBox, SimpleAlarmPage );
00217
00218 mAlarmButton = new QCheckBox(i18n("&Reminder:"), simpleAlarmBox );
00219 QWhatsThis::add( mAlarmButton,
00220 i18n("Activates a reminder for this event or to-do.") );
00221
00222 QString whatsThis = i18n("Sets how long before the event occurs "
00223 "the reminder will be triggered.");
00224 mAlarmTimeEdit = new QSpinBox( 0, 99999, 1, simpleAlarmBox, "alarmTimeEdit" );
00225 mAlarmTimeEdit->setValue( 0 );
00226 QWhatsThis::add( mAlarmTimeEdit, whatsThis );
00227
00228 mAlarmIncrCombo = new QComboBox( false, simpleAlarmBox );
00229 QWhatsThis::add( mAlarmIncrCombo, whatsThis );
00230 mAlarmIncrCombo->insertItem( i18n("minute(s)") );
00231 mAlarmIncrCombo->insertItem( i18n("hour(s)") );
00232 mAlarmIncrCombo->insertItem( i18n("day(s)") );
00233
00234 connect(mAlarmButton, SIGNAL(toggled(bool)), mAlarmTimeEdit, SLOT(setEnabled(bool)));
00235 connect(mAlarmButton, SIGNAL(toggled(bool)), mAlarmIncrCombo, SLOT(setEnabled(bool)));
00236 mAlarmTimeEdit->setEnabled( false );
00237 mAlarmIncrCombo->setEnabled( false );
00238
00239 mAlarmEditButton = new QPushButton( i18n("Advanced..."), parent );
00240 mAlarmEditButton->setEnabled( false );
00241 alarmLayout->addWidget( mAlarmEditButton );
00242 connect( mAlarmButton, SIGNAL(toggled(bool)), mAlarmEditButton, SLOT(setEnabled( bool)));
00243 connect( mAlarmEditButton, SIGNAL( clicked() ),
00244 SLOT( editAlarms() ) );
00245
00246 }
00247
00248 void KOEditorGeneral::initAttachments(QWidget *parent,QBoxLayout *topLayout)
00249 {
00250 mAttachments = new KOEditorAttachments( KDialog::spacingHint(), parent );
00251 connect( mAttachments, SIGNAL( openURL( const KURL & ) ) ,
00252 this, SIGNAL( openURL( const KURL & ) ) );
00253 topLayout->addWidget( mAttachments, 1 );
00254 }
00255
00256 void KOEditorGeneral::setType( const QCString &type )
00257 {
00258
00259 mType = type;
00260 }
00261
00262 void KOEditorGeneral::addAttachments( const QStringList &attachments,
00263 const QStringList &mimeTypes,
00264 bool inlineAttachments )
00265 {
00266 QStringList::ConstIterator it;
00267 uint i = 0;
00268 for ( it = attachments.begin(); it != attachments.end(); ++it, ++i ) {
00269 QString mimeType;
00270 if ( mimeTypes.count() > i )
00271 mimeType = mimeTypes[ i ];
00272 mAttachments->addUriAttachment( *it, mimeType, QString(), inlineAttachments );
00273 }
00274 }
00275
00276 void KOEditorGeneral::selectCategories()
00277 {
00278 KPIM::CategorySelectDialog *categoryDialog = new KPIM::CategorySelectDialog( KOPrefs::instance(), mCategoriesButton );
00279 KOGlobals::fitDialogToScreen( categoryDialog );
00280 categoryDialog->setSelected( mCategories );
00281
00282 connect(categoryDialog, SIGNAL(editCategories()), this, SIGNAL(openCategoryDialog()));
00283 connect(this, SIGNAL(updateCategoryConfig()), categoryDialog, SLOT(updateCategoryConfig()));
00284
00285 if ( categoryDialog->exec() ) {
00286 setCategories( categoryDialog->selectedCategories() );
00287 }
00288 delete categoryDialog;
00289 }
00290
00291
00292 void KOEditorGeneral::editAlarms()
00293 {
00294 if ( mAlarmStack->id( mAlarmStack->visibleWidget() ) == SimpleAlarmPage ) {
00295 mAlarmList.clear();
00296 Alarm *al = alarmFromSimplePage( 0 );
00297 if ( al ) {
00298 mAlarmList.append( al );
00299 }
00300 }
00301
00302 KOEditorAlarms *dlg = new KOEditorAlarms( mType, &mAlarmList, mAlarmEditButton );
00303 if ( dlg->exec() != KDialogBase::Cancel ) {
00304 updateAlarmWidgets();
00305 }
00306 }
00307
00308
00309 void KOEditorGeneral::enableAlarm( bool enable )
00310 {
00311 mAlarmStack->setEnabled( enable );
00312 mAlarmEditButton->setEnabled( enable );
00313 }
00314
00315
00316 void KOEditorGeneral::toggleAlarm( bool on )
00317 {
00318 mAlarmButton->setChecked( on );
00319 }
00320
00321 void KOEditorGeneral::setCategories( const QStringList &categories )
00322 {
00323 mCategoriesLabel->setText( categories.join(",") );
00324 mCategories = categories;
00325 }
00326
00327 void KOEditorGeneral::setDefaults(bool )
00328 {
00329 #if 0
00330 mOwnerLabel->setText(i18n("Owner: ") + KOPrefs::instance()->fullName());
00331 #endif
00332
00333 mAlarmList.clear();
00334 updateDefaultAlarmTime();
00335 updateAlarmWidgets();
00336
00337 mSecrecyCombo->setCurrentItem(Incidence::SecrecyPublic);
00338 mAttachments->setDefaults();
00339 }
00340
00341 void KOEditorGeneral::updateDefaultAlarmTime()
00342 {
00343 int reminderTime = KOPrefs::instance()->mReminderTime;
00344 int index = KOPrefs::instance()->mReminderTimeUnits;
00345 if ( index < 0 || index > 2 ) {
00346 index = 0;
00347 }
00348 mAlarmTimeEdit->setValue( reminderTime );
00349 mAlarmIncrCombo->setCurrentItem( index );
00350 }
00351
00352 bool KOEditorGeneral::isSimpleAlarm( Alarm *alarm ) const
00353 {
00354
00355
00356
00357 bool simple = false;
00358 if ( alarm->type() == Alarm::Display && alarm->text().isEmpty() &&
00359 alarm->repeatCount() == 0 && !alarm->hasTime() ) {
00360 if ( mType == "Event" &&
00361 alarm->hasStartOffset() && alarm->startOffset().asSeconds() <= 0 ) {
00362 simple = true;
00363 }
00364 if ( mType == "Todo" ) {
00365 if ( ( alarm->hasStartOffset() && alarm->startOffset().asSeconds() <= 0 ) ||
00366 ( alarm->hasEndOffset() && alarm->endOffset().asSeconds() <= 0 ) ) {
00367 simple = true;
00368 }
00369 }
00370 }
00371 return simple;
00372 }
00373
00374 void KOEditorGeneral::updateAlarmWidgets()
00375 {
00376 if ( mAlarmList.isEmpty() ) {
00377 mAlarmStack->raiseWidget( SimpleAlarmPage );
00378 bool on;
00379 if ( mType == "Event" ) {
00380 on = KOPrefs::instance()->defaultEventReminders();
00381 } else if ( mType == "Todo" ) {
00382 on = KOPrefs::instance()->defaultTodoReminders();
00383 } else {
00384 on = false;
00385 }
00386 mAlarmButton->setChecked( on );
00387 mAlarmEditButton->setEnabled( on );
00388 } else if ( mAlarmList.count() > 1 ) {
00389 mAlarmStack->raiseWidget( AdvancedAlarmLabel );
00390 mAlarmInfoLabel->setText( i18n("1 advanced reminder configured",
00391 "%n advanced reminders configured",
00392 mAlarmList.count() ) );
00393 mAlarmEditButton->setEnabled( true );
00394 } else {
00395 Alarm *alarm = mAlarmList.first();
00396 if ( isSimpleAlarm( alarm ) ) {
00397 mAlarmStack->raiseWidget( SimpleAlarmPage );
00398 mAlarmButton->setChecked( true );
00399 int offset;
00400 if ( mType == "Event" ) {
00401 offset = alarm->startOffset().asSeconds();
00402 }
00403 if ( mType == "Todo" ) {
00404 if ( alarm->hasStartOffset() ) {
00405 offset = alarm->startOffset().asSeconds();
00406 } else {
00407 offset = alarm->endOffset().asSeconds();
00408 }
00409 }
00410
00411 offset = offset / -60;
00412 int useoffset = offset;
00413 if ( offset == 0 ) {
00414 mAlarmIncrCombo->setCurrentItem( 0 );
00415 } else if (offset % (24*60) == 0) {
00416 useoffset = offset / (24*60);
00417 mAlarmIncrCombo->setCurrentItem(2);
00418 } else if (offset % 60 == 0) {
00419 useoffset = offset / 60;
00420 mAlarmIncrCombo->setCurrentItem(1);
00421 }
00422 mAlarmTimeEdit->setValue( useoffset );
00423 } else {
00424 mAlarmStack->raiseWidget( AdvancedAlarmLabel );
00425 mAlarmInfoLabel->setText( i18n("1 advanced reminder configured") );
00426 mAlarmEditButton->setEnabled( true );
00427 }
00428 }
00429 }
00430
00431 void KOEditorGeneral::readIncidence(Incidence *event, Calendar *calendar)
00432 {
00433 mSummaryEdit->setText(event->summary());
00434 mLocationEdit->setText(event->location());
00435
00436 mDescriptionEdit->setText(event->description());
00437
00438 #if 0
00439
00440 mOwnerLabel->setText(i18n("Owner: ") + event->organizer().fullName() );
00441 #endif
00442
00443 mSecrecyCombo->setCurrentItem(event->secrecy());
00444
00445
00446 mAlarmList.clear();
00447 Alarm::List::ConstIterator it;
00448 Alarm::List alarms = event->alarms();
00449 for( it = alarms.begin(); it != alarms.end(); ++it ) {
00450 Alarm *al = new Alarm( *(*it) );
00451 al->setParent( 0 );
00452 mAlarmList.append( al );
00453 }
00454 updateDefaultAlarmTime();
00455 updateAlarmWidgets();
00456
00457 setCategories(event->categories());
00458
00459 mAttachments->readIncidence( event );
00460
00461 QString resLabel = IncidenceFormatter::resourceString( calendar, event );
00462 if ( !resLabel.isEmpty() ) {
00463 mResourceLabel->setText( i18n( "Calendar: %1" ).arg( resLabel ) );
00464 mResourceLabel->show();
00465 }
00466 }
00467
00468 Alarm *KOEditorGeneral::alarmFromSimplePage( Incidence *incidence ) const
00469 {
00470 if ( mAlarmButton->isChecked() ) {
00471 Alarm *alarm = new Alarm( 0 );
00472 alarm->setDisplayAlarm("");
00473 alarm->setEnabled(true);
00474 QString tmpStr = mAlarmTimeEdit->text();
00475 int j = mAlarmTimeEdit->value() * -60;
00476 if (mAlarmIncrCombo->currentItem() == 1)
00477 j = j * 60;
00478 else if (mAlarmIncrCombo->currentItem() == 2)
00479 j = j * (60 * 24);
00480 if ( mType == "Event" ) {
00481 alarm->setStartOffset( j );
00482 }
00483 if ( mType == "Todo" ) {
00484 Todo *todo = static_cast<Todo *>( incidence );
00485 if ( todo && todo->hasStartDate() ) {
00486 alarm->setStartOffset( j );
00487 } else {
00488 alarm->setEndOffset( j );
00489 }
00490 }
00491 return alarm;
00492 } else {
00493 return 0;
00494 }
00495 }
00496 void KOEditorGeneral::writeIncidence( Incidence *incidence )
00497 {
00498
00499
00500 incidence->setSummary(mSummaryEdit->text());
00501 incidence->setLocation(mLocationEdit->text());
00502 incidence->setDescription(mDescriptionEdit->text());
00503 incidence->setCategories(mCategories);
00504 incidence->setSecrecy(mSecrecyCombo->currentItem());
00505
00506
00507 incidence->clearAlarms();
00508 if ( mAlarmStack->id( mAlarmStack->visibleWidget() ) == SimpleAlarmPage ) {
00509 Alarm *al = alarmFromSimplePage( incidence );
00510 if ( al ) {
00511 al->setParent( incidence );
00512 incidence->addAlarm( al );
00513 }
00514 } else {
00515
00516 Alarm::List::ConstIterator it;
00517 for( it = mAlarmList.begin(); it != mAlarmList.end(); ++it ) {
00518 Alarm *al = new Alarm( *(*it) );
00519 al->setParent( incidence );
00520 al->setEnabled( true );
00521 incidence->addAlarm( al );
00522 }
00523 }
00524 mAttachments->writeIncidence( incidence );
00525 }
00526
00527 void KOEditorGeneral::setSummary( const QString &text )
00528 {
00529 mSummaryEdit->setText( text );
00530 }
00531
00532 void KOEditorGeneral::setDescription( const QString &text )
00533 {
00534 mDescriptionEdit->setText( text );
00535 }
00536
00537 QObject *KOEditorGeneral::typeAheadReceiver() const
00538 {
00539 return mSummaryEdit;
00540 }
00541
00542 void KOEditorGeneral::updateAttendeeSummary(int count)
00543 {
00544 if ( count <= 0 )
00545 mAttendeeSummaryLabel->setText( i18n("No attendees") );
00546 else
00547 mAttendeeSummaryLabel->setText( i18n( "One attendee", "%n attendees", count ) );
00548 }