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 QToolTip::add( mPrintButton, i18n("Print this journal entry") );
00235 QWhatsThis::add( mPrintButton, i18n("Opens the print dialog for this journal entry") );
00236 mLayout->addWidget( mPrintButton, 0, 6 );
00237 connect( mPrintButton, SIGNAL(clicked()), this, SLOT( printItem() ) );
00238 #endif
00239 mEditor = new KTextEdit(this);
00240 mLayout->addMultiCellWidget( mEditor, 1, 2, 0, 6 );
00241
00242 connect( mTitleEdit, SIGNAL(textChanged( const QString& )), SLOT(setDirty()) );
00243 connect( mTimeCheck, SIGNAL(toggled(bool)), SLOT(setDirty()) );
00244 connect( mTimeEdit, SIGNAL(timeChanged(QTime)), SLOT(setDirty()) );
00245 connect( mEditor, SIGNAL(textChanged()), SLOT(setDirty()) );
00246
00247 mEditor->installEventFilter(this);
00248
00249 readJournal( mJournal );
00250 mDirty = false;
00251 }
00252
00253 JournalEntry::~JournalEntry()
00254 {
00255 writeJournal();
00256 }
00257
00258 void JournalEntry::deleteItem()
00259 {
00260
00261
00262
00263
00264
00265
00266 if ( mJournal )
00267 emit deleteIncidence( mJournal );
00268
00269 }
00270
00271 void JournalEntry::editItem()
00272 {
00273 writeJournal();
00274 if ( mJournal )
00275 emit editIncidence( mJournal );
00276 }
00277
00278 void JournalEntry::printItem()
00279 {
00280 #ifndef KORG_NOPRINTER
00281 writeJournal();
00282 if ( mJournal ) {
00283 Calendar *cal;
00284 KOCoreHelper helper;
00285 CalPrinter printer( this, cal, &helper );
00286 connect( this, SIGNAL(configChanged()), &printer, SLOT(updateConfig()) );
00287
00288 Incidence::List selectedIncidences;
00289 selectedIncidences.append( mJournal );
00290
00291 printer.print( KOrg::CalPrinterBase::Incidence,
00292 QDate(), QDate(), selectedIncidences );
00293 }
00294 #endif
00295 }
00296
00297 void JournalEntry::setReadOnly( bool readonly )
00298 {
00299 mReadOnly = readonly;
00300 mTitleEdit->setReadOnly( mReadOnly );
00301 mEditor->setReadOnly( mReadOnly );
00302 mTimeCheck->setEnabled( !mReadOnly );
00303 mTimeEdit->setEnabled( !mReadOnly && mTimeCheck->isChecked() );
00304 mDeleteButton->setEnabled( !mReadOnly );
00305 }
00306
00307
00308 void JournalEntry::setDate(const QDate &date)
00309 {
00310 writeJournal();
00311 mDate = date;
00312 }
00313
00314 void JournalEntry::setJournal(Journal *journal)
00315 {
00316 if ( !mWriteInProgress )
00317 writeJournal();
00318 if ( !journal ) return;
00319
00320 mJournal = journal;
00321 readJournal( journal );
00322
00323 mDirty = false;
00324 }
00325
00326 void JournalEntry::setDirty()
00327 {
00328 mDirty = true;
00329 kdDebug(5850) << "JournalEntry::setDirty()" << endl;
00330 }
00331
00332 bool JournalEntry::eventFilter( QObject *o, QEvent *e )
00333 {
00334
00335
00336 if ( e->type() == QEvent::FocusOut || e->type() == QEvent::Hide ||
00337 e->type() == QEvent::Close ) {
00338 writeJournal();
00339 }
00340 return QWidget::eventFilter( o, e );
00341 }
00342
00343
00344 void JournalEntry::readJournal( Journal *j )
00345 {
00346 mJournal = j;
00347 mTitleEdit->setText( mJournal->summary() );
00348 bool hasTime = !mJournal->doesFloat();
00349 mTimeCheck->setChecked( hasTime );
00350 mTimeEdit->setEnabled( hasTime );
00351 if ( hasTime ) {
00352 mTimeEdit->setTime( mJournal->dtStart().time() );
00353 }
00354 mEditor->setText( mJournal->description() );
00355 setReadOnly( mJournal->isReadOnly() );
00356 }
00357
00358 void JournalEntry::writeJournalPrivate( Journal *j )
00359 {
00360 j->setSummary( mTitleEdit->text() );
00361 bool hasTime = mTimeCheck->isChecked();
00362 QTime tm( mTimeEdit->getTime() );
00363 j->setDtStart( QDateTime( mDate, hasTime?tm:QTime(0,0,0) ) );
00364 j->setFloats( !hasTime );
00365 j->setDescription( mEditor->text() );
00366 }
00367
00368 void JournalEntry::writeJournal()
00369 {
00370
00371
00372 if ( mReadOnly || !mDirty || !mChanger ) {
00373 kdDebug(5850)<<"Journal either read-only, unchanged or no changer object available"<<endl;
00374 return;
00375 }
00376 bool newJournal = false;
00377 mWriteInProgress = true;
00378
00379 Journal *oldJournal = 0;
00380
00381 if ( !mJournal ) {
00382 newJournal = true;
00383 mJournal = new Journal;
00384 writeJournalPrivate( mJournal );
00385 if ( !mChanger->addIncidence( mJournal, this ) ) {
00386 KODialogManager::errorSaveIncidence( this, mJournal );
00387 delete mJournal;
00388 mJournal = 0;
00389 }
00390 } else {
00391 oldJournal = mJournal->clone();
00392 if ( mChanger->beginChange( mJournal ) ) {
00393 writeJournalPrivate( mJournal );
00394 mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::DESCRIPTION_MODIFIED );
00395 mChanger->endChange( mJournal );
00396 }
00397 delete oldJournal;
00398 }
00399 mDirty = false;
00400 mWriteInProgress = false;
00401 }
00402
00403 void JournalEntry::flushEntry()
00404 {
00405 if (!mDirty) return;
00406
00407 writeJournal();
00408 }
00409
00410 void JournalEntry::timeCheckBoxToggled(bool on)
00411 {
00412 mTimeEdit->setEnabled(on);
00413 if(on)
00414 mTimeEdit->setFocus();
00415 }