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 % (24*60) == 0) { // divides evenly into days?
00414         useoffset = offset / (24*60);
00415         mAlarmIncrCombo->setCurrentItem(2);
00416       } else if (offset % 60 == 0) { // divides evenly into hours?
00417         useoffset = offset / 60;
00418         mAlarmIncrCombo->setCurrentItem(1);
00419       }
00420       mAlarmTimeEdit->setValue( useoffset );
00421     } else {
00422       mAlarmStack->raiseWidget( AdvancedAlarmLabel );
00423       mAlarmInfoLabel->setText( i18n("1 advanced reminder configured") );
00424       mAlarmEditButton->setEnabled( true );
00425     }
00426   }
00427 }
00428 
00429 void KOEditorGeneral::readIncidence(Incidence *event, Calendar *calendar)
00430 {
00431   mSummaryEdit->setText(event->summary());
00432   mLocationEdit->setText(event->location());
00433 
00434   mDescriptionEdit->setText(event->description());
00435 
00436 #if 0
00437   // organizer information
00438   mOwnerLabel->setText(i18n("Owner: ") + event->organizer().fullName() );
00439 #endif
00440 
00441   mSecrecyCombo->setCurrentItem(event->secrecy());
00442 
00443   // set up alarm stuff
00444   mAlarmList.clear();
00445   Alarm::List::ConstIterator it;
00446   Alarm::List alarms = event->alarms();
00447   for( it = alarms.begin(); it != alarms.end(); ++it ) {
00448     Alarm *al = new Alarm( *(*it) );
00449     al->setParent( 0 );
00450     mAlarmList.append( al );
00451   }
00452   updateDefaultAlarmTime();
00453   updateAlarmWidgets();
00454 
00455   setCategories(event->categories());
00456 
00457   mAttachments->readIncidence( event );
00458 
00459   QString resLabel = IncidenceFormatter::resourceString( calendar, event );
00460   if ( !resLabel.isEmpty() ) {
00461     mResourceLabel->setText( i18n( "Calendar: %1" ).arg( resLabel ) );
00462     mResourceLabel->show();
00463   }
00464 }
00465 
00466 Alarm *KOEditorGeneral::alarmFromSimplePage( Incidence *incidence ) const
00467 {
00468   if ( mAlarmButton->isChecked() ) {
00469     Alarm *alarm = new Alarm( 0 );
00470     alarm->setDisplayAlarm("");
00471     alarm->setEnabled(true);
00472     QString tmpStr = mAlarmTimeEdit->text();
00473     int j = mAlarmTimeEdit->value() * -60;
00474     if (mAlarmIncrCombo->currentItem() == 1)
00475       j = j * 60;
00476     else if (mAlarmIncrCombo->currentItem() == 2)
00477       j = j * (60 * 24);
00478     if ( mType == "Event" ) {
00479       alarm->setStartOffset( j );
00480     }
00481     if ( mType == "Todo" ) {
00482       Todo *todo = static_cast<Todo *>( incidence );
00483       if ( todo && todo->hasStartDate() ) {
00484         alarm->setStartOffset( j );
00485       } else {
00486         alarm->setEndOffset( j );
00487       }
00488     }
00489     return alarm;
00490   } else {
00491     return 0;
00492   }
00493 }
00494 void KOEditorGeneral::writeIncidence( Incidence *incidence )
00495 {
00496 //  kdDebug(5850) << "KOEditorGeneral::writeIncidence()" << endl;
00497 
00498   incidence->setSummary(mSummaryEdit->text());
00499   incidence->setLocation(mLocationEdit->text());
00500   incidence->setDescription(mDescriptionEdit->text());
00501   incidence->setCategories(mCategories);
00502   incidence->setSecrecy(mSecrecyCombo->currentItem());
00503 
00504   // alarm stuff
00505   incidence->clearAlarms();
00506   if ( mAlarmStack->id( mAlarmStack->visibleWidget() ) == SimpleAlarmPage ) {
00507     Alarm *al = alarmFromSimplePage( incidence );
00508     if ( al ) {
00509       al->setParent( incidence );
00510       incidence->addAlarm( al );
00511     }
00512   } else {
00513     // simply assign the list of alarms
00514     Alarm::List::ConstIterator it;
00515     for( it = mAlarmList.begin(); it != mAlarmList.end(); ++it ) {
00516       Alarm *al = new Alarm( *(*it) );
00517       al->setParent( incidence );
00518       al->setEnabled( true );
00519       incidence->addAlarm( al );
00520     }
00521   }
00522   mAttachments->writeIncidence( incidence );
00523 }
00524 
00525 void KOEditorGeneral::setSummary( const QString &text )
00526 {
00527   mSummaryEdit->setText( text );
00528 }
00529 
00530 void KOEditorGeneral::setDescription( const QString &text )
00531 {
00532   mDescriptionEdit->setText( text );
00533 }
00534 
00535 QObject *KOEditorGeneral::typeAheadReceiver() const
00536 {
00537   return mSummaryEdit;
00538 }
00539 
00540 void KOEditorGeneral::updateAttendeeSummary(int count)
00541 {
00542   if ( count <= 0 )
00543     mAttendeeSummaryLabel->setText( i18n("No attendees") );
00544   else
00545     mAttendeeSummaryLabel->setText( i18n( "One attendee", "%n attendees", count ) );
00546 }
KDE Home | KDE Accessibility Home | Description of Access Keys