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
00027
00028 #include <qlabel.h>
00029 #include <qlayout.h>
00030 #include <qcheckbox.h>
00031 #include <qwhatsthis.h>
00032 #include <qtooltip.h>
00033 #include <qtoolbutton.h>
00034
00035 #include <kdebug.h>
00036 #include <kdialog.h>
00037 #include <kglobal.h>
00038 #include <klocale.h>
00039 #include <ktextedit.h>
00040 #include <ktimeedit.h>
00041 #include <klineedit.h>
00042 #include <kactivelabel.h>
00043 #include <kstdguiitem.h>
00044 #include <kmessagebox.h>
00045
00046 #include <libkcal/journal.h>
00047 #include <libkcal/calendar.h>
00048
00049 #include "kodialogmanager.h"
00050 #include "incidencechanger.h"
00051 #include "koglobals.h"
00052
00053 #include "journalentry.h"
00054 #include "journalentry.moc"
00055
00056 class JournalTitleLable : public KActiveLabel
00057 {
00058 public:
00059 JournalTitleLable( QWidget *parent, const char *name=0 ) : KActiveLabel( parent, name ) {}
00060
00061 void openLink( const QString & ) {}
00062 };
00063
00064
00065 JournalDateEntry::JournalDateEntry( Calendar *calendar, QWidget *parent ) :
00066 QVBox( parent ), mCalendar( calendar )
00067 {
00068
00069 mChanger = 0;
00070
00071 mTitle = new JournalTitleLable( this );
00072 mTitle->setMargin(2);
00073 mTitle->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
00074 connect( mTitle, SIGNAL( linkClicked( const QString & ) ),
00075 this, SLOT( emitNewJournal() ) );
00076 }
00077
00078 JournalDateEntry::~JournalDateEntry()
00079 {
00080 }
00081
00082 void JournalDateEntry::setDate(const QDate &date)
00083 {
00084 QString dtstring = QString( "<qt><center><b><i>%1</i></b> " )
00085 .arg( KGlobal::locale()->formatDate(date) );
00086
00087 dtstring += " <font size=\"-1\"><a href=\"#\">" +
00088 i18n("[Add Journal Entry]") +
00089 "</a></font></center></qt>";
00090
00091 mTitle->setText( dtstring );
00092 mDate = date;
00093 emit setDateSignal( date );
00094 }
00095
00096 void JournalDateEntry::clear()
00097 {
00098 QValueList<JournalEntry*> values( mEntries.values() );
00099
00100 QValueList<JournalEntry*>::Iterator it = values.begin();
00101 for ( ; it != values.end(); ++it ) {
00102 delete (*it);
00103 }
00104 mEntries.clear();
00105 }
00106
00107
00108 void JournalDateEntry::addJournal( Journal *j )
00109 {
00110 QMap<Journal*,JournalEntry*>::Iterator pos = mEntries.find( j );
00111 if ( pos != mEntries.end() ) return;
00112
00113 JournalEntry *entry = new JournalEntry( j, this );
00114 entry->show();
00115 entry->setDate( mDate );
00116 entry->setIncidenceChanger( mChanger );
00117
00118 mEntries.insert( j, entry );
00119 connect( this, SIGNAL( setIncidenceChangerSignal( IncidenceChangerBase * ) ),
00120 entry, SLOT( setIncidenceChanger( IncidenceChangerBase * ) ) );
00121 connect( this, SIGNAL( setDateSignal( const QDate & ) ),
00122 entry, SLOT( setDate( const QDate & ) ) );
00123 connect( this, SIGNAL( flushEntries() ),
00124 entry, SLOT( flushEntry() ) );
00125 connect( entry, SIGNAL( deleteIncidence( Incidence* ) ),
00126 this, SIGNAL( deleteIncidence( Incidence* ) ) );
00127 connect( entry, SIGNAL( editIncidence( Incidence* ) ),
00128 this, SIGNAL( editIncidence( Incidence* ) ) );
00129 }
00130
00131 Journal::List JournalDateEntry::journals() const
00132 {
00133 QValueList<Journal*> jList( mEntries.keys() );
00134 Journal::List l;
00135 QValueList<Journal*>::Iterator it = jList.begin();
00136 for ( ; it != jList.end(); ++it ) {
00137 l.append( *it );
00138 }
00139 return l;
00140 }
00141
00142 void JournalDateEntry::setIncidenceChanger( IncidenceChangerBase *changer )
00143 {
00144 mChanger = changer;
00145 emit setIncidenceChangerSignal( changer );
00146 }
00147
00148 void JournalDateEntry::emitNewJournal()
00149 {
00150 emit newJournal( mDate );
00151 }
00152
00153 void JournalDateEntry::journalEdited( Journal *journal )
00154 {
00155 QMap<Journal*,JournalEntry*>::Iterator pos = mEntries.find( journal );
00156 if ( pos == mEntries.end() ) return;
00157
00158 pos.data()->setJournal( journal );
00159
00160 }
00161
00162 void JournalDateEntry::journalDeleted( Journal *journal )
00163 {
00164 QMap<Journal*,JournalEntry*>::Iterator pos = mEntries.find( journal );
00165 if ( pos == mEntries.end() ) return;
00166
00167 delete pos.data();
00168 }
00169
00170
00171
00172
00173
00174 JournalEntry::JournalEntry( Journal* j, QWidget *parent ) :
00175 QWidget( parent ), mJournal( j )
00176 {
00177
00178 mDirty = false;
00179 mWriteInProgress = false;
00180 mChanger = 0;
00181 mReadOnly = false;
00182
00183 mLayout = new QGridLayout( this );
00184 mLayout->setSpacing( KDialog::spacingHint() );
00185 mLayout->setMargin( KDialog::marginHint() );
00186
00187 QString whatsThis = i18n("Sets the Title of this journal entry.");
00188
00189 mTitleLabel = new QLabel( i18n("&Title: "), this );
00190 mLayout->addWidget( mTitleLabel, 0, 0 );
00191 mTitleEdit = new KLineEdit( this );
00192 mLayout->addWidget( mTitleEdit, 0, 1 );
00193 mTitleLabel->setBuddy( mTitleEdit );
00194
00195 QWhatsThis::add( mTitleLabel, whatsThis );
00196 QWhatsThis::add( mTitleEdit, whatsThis );
00197
00198 mTimeCheck = new QCheckBox( i18n("Ti&me: "), this );
00199 mLayout->addWidget( mTimeCheck, 0, 2 );
00200 mTimeEdit = new KTimeEdit( this );
00201 mLayout->addWidget( mTimeEdit, 0, 3 );
00202 connect( mTimeCheck, SIGNAL(toggled(bool)),
00203 this, SLOT(timeCheckBoxToggled(bool)) );
00204 QWhatsThis::add( mTimeCheck, i18n("Determines whether this journal entry has "
00205 "a time associated with it") );
00206 QWhatsThis::add( mTimeEdit, i18n( "Sets the time associated with this journal "
00207 "entry" ) );
00208
00209 mDeleteButton = new QToolButton( this, "deleteButton" );
00210 QPixmap pix = KOGlobals::self()->smallIcon( "editdelete" );
00211 mDeleteButton->setPixmap( pix );
00212 mDeleteButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00213 QToolTip::add( mDeleteButton, i18n("Delete this journal entry") );
00214 QWhatsThis::add( mDeleteButton, i18n("Delete this journal entry") );
00215 mLayout->addWidget( mDeleteButton, 0, 4 );
00216 connect( mDeleteButton, SIGNAL(pressed()), this, SLOT(deleteItem()) );
00217
00218 mEditButton = new QToolButton( this, "editButton" );
00219 mEditButton->setPixmap( KOGlobals::self()->smallIcon( "edit" ) );
00220 mEditButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
00221 QToolTip::add( mEditButton, i18n("Edit this journal entry") );
00222 QWhatsThis::add( mEditButton, i18n("Opens an editor dialog for this journal entry") );
00223 mLayout->addWidget( mEditButton, 0, 5 );
00224 connect( mEditButton, SIGNAL(clicked()), this, SLOT( editItem() ) );
00225
00226
00227 mEditor = new KTextEdit(this);
00228 mLayout->addMultiCellWidget( mEditor, 1, 2, 0, 5 );
00229
00230 connect( mTitleEdit, SIGNAL(textChanged( const QString& )), SLOT(setDirty()) );
00231 connect( mTimeCheck, SIGNAL(toggled(bool)), SLOT(setDirty()) );
00232 connect( mTimeEdit, SIGNAL(timeChanged(QTime)), SLOT(setDirty()) );
00233 connect( mEditor, SIGNAL(textChanged()), SLOT(setDirty()) );
00234
00235 mEditor->installEventFilter(this);
00236
00237 readJournal( mJournal );
00238 mDirty = false;
00239 }
00240
00241 JournalEntry::~JournalEntry()
00242 {
00243 writeJournal();
00244 }
00245
00246 void JournalEntry::deleteItem()
00247 {
00248
00249
00250
00251
00252
00253
00254 if ( mJournal )
00255 emit deleteIncidence( mJournal );
00256
00257 }
00258
00259 void JournalEntry::editItem()
00260 {
00261 writeJournal();
00262 if ( mJournal )
00263 emit editIncidence( mJournal );
00264 }
00265
00266 void JournalEntry::setReadOnly( bool readonly )
00267 {
00268 mReadOnly = readonly;
00269 mTitleEdit->setReadOnly( mReadOnly );
00270 mEditor->setReadOnly( mReadOnly );
00271 mTimeCheck->setEnabled( !mReadOnly );
00272 mTimeEdit->setEnabled( !mReadOnly && mTimeCheck->isChecked() );
00273 mDeleteButton->setEnabled( !mReadOnly );
00274 }
00275
00276
00277 void JournalEntry::setDate(const QDate &date)
00278 {
00279 writeJournal();
00280 mDate = date;
00281 }
00282
00283 void JournalEntry::setJournal(Journal *journal)
00284 {
00285 if ( !mWriteInProgress )
00286 writeJournal();
00287 if ( !journal ) return;
00288
00289 mJournal = journal;
00290 readJournal( journal );
00291
00292 mDirty = false;
00293 }
00294
00295 void JournalEntry::setDirty()
00296 {
00297 mDirty = true;
00298 kdDebug(5850) << "JournalEntry::setDirty()" << endl;
00299 }
00300
00301 bool JournalEntry::eventFilter( QObject *o, QEvent *e )
00302 {
00303
00304
00305 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Hide ||
00306 e->type() == QEvent::Close ) {
00307 writeJournal();
00308 }
00309 return QWidget::eventFilter( o, e );
00310 }
00311
00312
00313 void JournalEntry::readJournal( Journal *j )
00314 {
00315 mJournal = j;
00316 mTitleEdit->setText( mJournal->summary() );
00317 bool hasTime = !mJournal->doesFloat();
00318 mTimeCheck->setChecked( hasTime );
00319 mTimeEdit->setEnabled( hasTime );
00320 if ( hasTime ) {
00321 mTimeEdit->setTime( mJournal->dtStart().time() );
00322 }
00323 mEditor->setText( mJournal->description() );
00324 setReadOnly( mJournal->isReadOnly() );
00325 }
00326
00327 void JournalEntry::writeJournalPrivate( Journal *j )
00328 {
00329 j->setSummary( mTitleEdit->text() );
00330 bool hasTime = mTimeCheck->isChecked();
00331 QTime tm( mTimeEdit->getTime() );
00332 j->setDtStart( QDateTime( mDate, hasTime?tm:QTime(0,0,0) ) );
00333 j->setFloats( !hasTime );
00334 j->setDescription( mEditor->text() );
00335 }
00336
00337 void JournalEntry::writeJournal()
00338 {
00339
00340
00341 if ( mReadOnly || !mDirty || !mChanger ) {
00342 kdDebug(5850)<<"Journal either read-only, unchanged or no changer object available"<<endl;
00343 return;
00344 }
00345 bool newJournal = false;
00346 mWriteInProgress = true;
00347
00348 Journal *oldJournal = 0;
00349
00350 if ( !mJournal ) {
00351 newJournal = true;
00352 mJournal = new Journal;
00353 writeJournalPrivate( mJournal );
00354 if ( !mChanger->addIncidence( mJournal ) ) {
00355 KODialogManager::errorSaveIncidence( this, mJournal );
00356 delete mJournal;
00357 mJournal = 0;
00358 }
00359 } else {
00360 oldJournal = mJournal->clone();
00361 if ( mChanger->beginChange( mJournal ) ) {
00362 writeJournalPrivate( mJournal );
00363 mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::DESCRIPTION_MODIFIED );
00364 mChanger->endChange( mJournal );
00365 }
00366 delete oldJournal;
00367 }
00368 mDirty = false;
00369 mWriteInProgress = false;
00370 }
00371
00372 void JournalEntry::flushEntry()
00373 {
00374 if (!mDirty) return;
00375
00376 writeJournal();
00377 }
00378
00379 void JournalEntry::timeCheckBoxToggled(bool on)
00380 {
00381 mTimeEdit->setEnabled(on);
00382 if(on)
00383 mTimeEdit->setFocus();
00384 }