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 }