korganizer

koeditorgeneral.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 
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 //  mAlarmIncrCombo->setMinimumHeight(20);
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   // must be "Event", "Todo", "Journal", etc.
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 /*allDay*/)
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   // Check if its the trivial type of alarm, which can be
00355   // configured with a simply spin box...
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; // make minutes
00412       int useoffset = offset;
00413       if ( offset == 0 ) {
00414         mAlarmIncrCombo->setCurrentItem( 0 ); // use minute units for 0 offset
00415       } else if (offset % (24*60) == 0) { // divides evenly into days?
00416         useoffset = offset / (24*60);
00417         mAlarmIncrCombo->setCurrentItem(2);
00418       } else if (offset % 60 == 0) { // divides evenly into hours?
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   // organizer information
00440   mOwnerLabel->setText(i18n("Owner: ") + event->organizer().fullName() );
00441 #endif
00442 
00443   mSecrecyCombo->setCurrentItem(event->secrecy());
00444 
00445   // set up alarm stuff
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 //  kdDebug(5850) << "KOEditorGeneral::writeIncidence()" << endl;
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   // alarm stuff
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     // simply assign the list of alarms
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys