korganizer

journalentry.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 TQt, and distribute the resulting executable,
00022     without including the source code for TQt in the source distribution.
00023 */
00024 
00025 //
00026 // Journal Entry
00027 
00028 #include <tqlabel.h>
00029 #include <tqlayout.h>
00030 #include <tqcheckbox.h>
00031 #include <tqwhatsthis.h>
00032 #include <tqtooltip.h>
00033 #include <tqtoolbutton.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( TQWidget *parent, const char *name=0 ) : KActiveLabel( parent, name ) {}
00064 
00065   void openLink( const TQString &/*link*/ ) {}
00066 };
00067 
00068 
00069 JournalDateEntry::JournalDateEntry( Calendar *calendar, TQWidget *parent ) :
00070   TQVBox( parent ), mCalendar( calendar )
00071 {
00072 //kdDebug(5850)<<"JournalEntry::JournalEntry, parent="<<parent<<endl;
00073   mChanger = 0;
00074 
00075   mTitle = new JournalTitleLable( this );
00076   mTitle->setMargin(2);
00077   mTitle->setSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed );
00078   connect( mTitle, TQT_SIGNAL( linkClicked( const TQString & ) ),
00079            this, TQT_SLOT( emitNewJournal() ) );
00080 }
00081 
00082 JournalDateEntry::~JournalDateEntry()
00083 {
00084 }
00085 
00086 void JournalDateEntry::setDate(const TQDate &date)
00087 {
00088   TQString dtstring = TQString( "<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   TQValueList<JournalEntry*> values( mEntries.values() );
00103 
00104   TQValueList<JournalEntry*>::Iterator it = values.begin();
00105   for ( ; it != values.end(); ++it ) {
00106     delete (*it);
00107   }
00108   mEntries.clear();
00109 }
00110 
00111 // should only be called by the KOJournalView now.
00112 void JournalDateEntry::addJournal( Journal *j )
00113 {
00114   TQMap<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, TQT_SIGNAL( setIncidenceChangerSignal( IncidenceChangerBase * ) ),
00124            entry, TQT_SLOT( setIncidenceChanger( IncidenceChangerBase * ) ) );
00125   connect( this, TQT_SIGNAL( setDateSignal( const TQDate & ) ),
00126            entry, TQT_SLOT( setDate( const TQDate & ) ) );
00127   connect( this, TQT_SIGNAL( flushEntries() ),
00128            entry, TQT_SLOT( flushEntry() ) );
00129   connect( entry, TQT_SIGNAL( deleteIncidence( Incidence* ) ),
00130            this, TQT_SIGNAL( deleteIncidence( Incidence* ) ) );
00131   connect( entry, TQT_SIGNAL( editIncidence( Incidence*, const TQDate& ) ),
00132            this, TQT_SIGNAL( editIncidence( Incidence*, const TQDate& ) ) );
00133 }
00134 
00135 Journal::List JournalDateEntry::journals() const
00136 {
00137   TQValueList<Journal*> jList( mEntries.keys() );
00138   Journal::List l;
00139   TQValueList<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( 0/*ResourceCalendar*/, TQString()/*subResource*/, mDate );
00155 }
00156 
00157 void JournalDateEntry::journalEdited( Journal *journal )
00158 {
00159   TQMap<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   TQMap<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, TQWidget *parent ) :
00179   TQWidget( parent ), mJournal( j )
00180 {
00181 //kdDebug(5850)<<"JournalEntry::JournalEntry, parent="<<parent<<endl;
00182   mDirty = false;
00183   mWriteInProgress = false;
00184   mChanger = 0;
00185   mReadOnly = false;
00186 
00187   mLayout = new TQGridLayout( this );
00188   mLayout->setSpacing( KDialog::spacingHint() );
00189   mLayout->setMargin( KDialog::marginHint() );
00190 
00191   TQString whatsThis = i18n("Sets the Title of this journal entry.");
00192 
00193   mTitleLabel = new TQLabel( 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   TQWhatsThis::add( mTitleLabel, whatsThis );
00200   TQWhatsThis::add( mTitleEdit, whatsThis );
00201 
00202   mTimeCheck = new TQCheckBox( i18n("Ti&me: "), this );
00203   mLayout->addWidget( mTimeCheck, 0, 2 );
00204   mTimeEdit = new KTimeEdit( this );
00205   mLayout->addWidget( mTimeEdit, 0, 3 );
00206   connect( mTimeCheck, TQT_SIGNAL(toggled(bool)),
00207            this, TQT_SLOT(timeCheckBoxToggled(bool)) );
00208   TQWhatsThis::add( mTimeCheck, i18n("Determines whether this journal entry has "
00209                                     "a time associated with it") );
00210   TQWhatsThis::add( mTimeEdit, i18n( "Sets the time associated with this journal "
00211                                     "entry" ) );
00212 
00213   mDeleteButton = new TQToolButton( this, "deleteButton" );
00214   TQPixmap pix = KOGlobals::self()->smallIcon( "editdelete" );
00215   mDeleteButton->setPixmap( pix );
00216   mDeleteButton->setSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
00217   TQToolTip::add( mDeleteButton, i18n("Delete this journal entry") );
00218   TQWhatsThis::add( mDeleteButton, i18n("Delete this journal entry") );
00219   mLayout->addWidget( mDeleteButton, 0, 4 );
00220   connect( mDeleteButton, TQT_SIGNAL(pressed()), this, TQT_SLOT(deleteItem()) );
00221 
00222   mEditButton = new TQToolButton( this, "editButton" );
00223   mEditButton->setPixmap( KOGlobals::self()->smallIcon( "edit" ) );
00224   mEditButton->setSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
00225   TQToolTip::add( mEditButton, i18n("Edit this journal entry") );
00226   TQWhatsThis::add( mEditButton, i18n("Opens an editor dialog for this journal entry") );
00227   mLayout->addWidget( mEditButton, 0, 5 );
00228   connect( mEditButton, TQT_SIGNAL(clicked()), this, TQT_SLOT( editItem() ) );
00229 
00230 #ifndef KORG_NOPRINTER
00231   mPrintButton = new TQToolButton( this, "printButton" );
00232   mPrintButton->setPixmap( KOGlobals::self()->smallIcon( "printer1" ) );
00233   mPrintButton->setSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed );
00234   TQToolTip::add( mPrintButton, i18n("Print this journal entry") );
00235   TQWhatsThis::add( mPrintButton, i18n("Opens the print dialog for this journal entry") );
00236   mLayout->addWidget( mPrintButton, 0, 6 );
00237   connect( mPrintButton, TQT_SIGNAL(clicked()), this, TQT_SLOT( printItem() ) );
00238 #endif
00239   mEditor = new KTextEdit(this);
00240   mLayout->addMultiCellWidget( mEditor, 1, 2, 0, 6 );
00241 
00242   connect( mTitleEdit, TQT_SIGNAL(textChanged( const TQString& )), TQT_SLOT(setDirty()) );
00243   connect( mTimeCheck, TQT_SIGNAL(toggled(bool)), TQT_SLOT(setDirty()) );
00244   connect( mTimeEdit, TQT_SIGNAL(timeChanged(TQTime)), TQT_SLOT(setDirty()) );
00245   connect( mEditor, TQT_SIGNAL(textChanged()), TQT_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 /*  KMessageBox::ButtonCode *code = KMessageBox::warningContinueCancel(this,
00261       i18n("The journal \"%1\" on %2 will be permanently deleted.")
00262                .arg( mJournal->summary() )
00263                .arg( mJournal->dtStartStr() ),
00264   i18n("KOrganizer Confirmation"), KStdGuiItem::del() );
00265   if ( code == KMessageBox::Yes ) {*/
00266     if ( mJournal )
00267       emit deleteIncidence( mJournal );
00268 //   }
00269 }
00270 
00271 void JournalEntry::editItem()
00272 {
00273   writeJournal();
00274   if ( mJournal ) {
00275     emit editIncidence( mJournal, mJournal->dtStart().date() );
00276   }
00277 }
00278 
00279 void JournalEntry::printItem()
00280 {
00281 #ifndef KORG_NOPRINTER
00282   writeJournal();
00283   if ( mJournal ) {
00284     KOCoreHelper helper;
00285     CalPrinter printer( this, 0, &helper );
00286     connect( this, TQT_SIGNAL(configChanged()), &printer, TQT_SLOT(updateConfig()) );
00287 
00288     Incidence::List selectedIncidences;
00289     selectedIncidences.append( mJournal );
00290 
00291     printer.print( KOrg::CalPrinterBase::Incidence,
00292                  TQDate(), TQDate(), 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 TQDate &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( TQObject *o, TQEvent *e )
00333 {
00334 //  kdDebug(5850) << "JournalEntry::event received " << e->type() << endl;
00335 
00336   if ( e->type() == TQEvent::FocusOut || e->type() == TQEvent::Hide ||
00337        e->type() == TQEvent::Close ) {
00338     writeJournal();
00339   }
00340   return TQWidget::eventFilter( o, e );    // standard event processing
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   TQTime tm( mTimeEdit->getTime() );
00363   j->setDtStart( TQDateTime( mDate, hasTime?tm:TQTime(0,0,0) ) );
00364   j->setFloats( !hasTime );
00365   j->setDescription( mEditor->text() );
00366 }
00367 
00368 void JournalEntry::writeJournal()
00369 {
00370 //  kdDebug(5850) << "JournalEntry::writeJournal()" << endl;
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, 0, TQString(), this ) ) {
00386       KODialogManager::errorSaveIncidence( this, mJournal );
00387       delete mJournal;
00388       mJournal = 0;
00389     }
00390   } else {
00391     oldJournal = mJournal->clone();
00392     if ( mChanger->beginChange( mJournal, 0, TQString() ) ) {
00393       writeJournalPrivate( mJournal );
00394       mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::DESCRIPTION_MODIFIED, this );
00395       mChanger->endChange( mJournal, 0, TQString() );
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 }