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