knotes Library API Documentation

knotesapp.cpp

00001 /******************************************************************* 00002 KNotes -- Notes for the KDE project 00003 00004 Copyright (c) 1997-2004, The KNotes Developers 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 *******************************************************************/ 00020 00021 #include <qclipboard.h> 00022 #include <qptrlist.h> 00023 00024 #include <kdebug.h> 00025 #include <kaction.h> 00026 #include <kxmlguifactory.h> 00027 #include <ksystemtray.h> 00028 #include <klocale.h> 00029 #include <kiconloader.h> 00030 #include <kstandarddirs.h> 00031 #include <kpopupmenu.h> 00032 #include <khelpmenu.h> 00033 #include <kkeydialog.h> 00034 #include <kglobalaccel.h> 00035 #include <kmessagebox.h> 00036 #include <ksimpleconfig.h> 00037 #include <kio/netaccess.h> 00038 #include <kwin.h> 00039 00040 #include <libkcal/journal.h> 00041 #include <libkcal/icalformat.h> 00042 00043 #include "knotesapp.h" 00044 #include "knote.h" 00045 #include "knoteconfig.h" 00046 #include "knoteconfigdlg.h" 00047 #include "knoteslegacy.h" 00048 00049 00050 int KNotesApp::KNoteActionList::compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 ) 00051 { 00052 if ( ((KAction*)s1)->text() == ((KAction*)s2)->text() ) 00053 return 0; 00054 return ( ((KAction*)s1)->text() < ((KAction*)s2)->text() ? -1 : 1 ); 00055 } 00056 00057 00058 KNotesApp::KNotesApp() 00059 : DCOPObject("KNotesIface"), QLabel( 0, 0, WType_TopLevel ), 00060 KXMLGUIBuilder( this ), 00061 m_defaultConfig( 0 ) 00062 { 00063 connect( kapp, SIGNAL(lastWindowClosed()), kapp, SLOT(quit()) ); 00064 00065 m_noteList.setAutoDelete( true ); 00066 m_noteActions.setAutoDelete( true ); 00067 00068 // create the dock widget... 00069 KWin::setSystemTrayWindowFor( winId(), qt_xrootwin() ); 00070 setBackgroundMode( X11ParentRelative ); 00071 setPixmap( KSystemTray::loadIcon( "knotes" ) ); 00072 00073 // create the GUI... 00074 new KAction( i18n("New Note"), "filenew", 0, 00075 this, SLOT(newNote()), actionCollection(), "new_note" ); 00076 new KAction( i18n("New Note From Clipboard"), "editpaste", 0, 00077 this, SLOT(newNoteFromClipboard()), actionCollection(), "new_note_clipboard" ); 00078 new KHelpMenu( this, kapp->aboutData(), false, actionCollection() ); 00079 00080 KStdAction::preferences( this, SLOT(slotPreferences()), actionCollection() ); 00081 KStdAction::keyBindings( this, SLOT(slotConfigureAccels()), actionCollection() ); 00082 KStdAction::quit( this, SLOT(slotQuit()), actionCollection() )->setShortcut( 0 ); 00083 00084 setXMLFile( QString( instance()->instanceName() + "ui.rc" ) ); 00085 00086 m_guiFactory = new KXMLGUIFactory( this, this, "guifactory" ); 00087 m_guiFactory->addClient( this ); 00088 00089 m_context_menu = static_cast<KPopupMenu*>(m_guiFactory->container( "knotes_context", this )); 00090 m_note_menu = static_cast<KPopupMenu*>(m_guiFactory->container( "notes_menu", this )); 00091 00092 // create accels for global shortcuts 00093 m_globalAccel = new KGlobalAccel( this, "global accel" ); 00094 m_globalAccel->insert( "global_new_note", i18n("New Note"), "", 00095 ALT+SHIFT+Key_N, ALT+SHIFT+Key_N , 00096 this, SLOT(newNote()), true, true ); 00097 m_globalAccel->insert( "global_new_note_clipboard", i18n("New Note From Clipboard"), "", 00098 ALT+SHIFT+Key_C, ALT+SHIFT+Key_C, 00099 this, SLOT(newNoteFromClipboard()), true, true ); 00100 00101 m_globalAccel->readSettings(); 00102 00103 KConfig *config = KGlobal::config(); 00104 config->setGroup( "Global Keybindings" ); 00105 m_globalAccel->setEnabled( config->readBoolEntry( "Enabled", true ) ); 00106 00107 updateGlobalAccels(); 00108 00109 // clean up old config files 00110 KNotesLegacy::cleanUp(); 00111 00112 // read the notes 00113 m_calendar.load( KGlobal::dirs()->saveLocation( "appdata" ) + "notes.ics" ); 00114 00115 // TODO 00116 // initialize the Calendar 00117 //mCalendar.setOwner(..); 00118 //mCalendar.setEmail(..); 00119 00120 // read the old config files into mCalendar and convert them 00121 if ( KNotesLegacy::convert( &m_calendar ) ) 00122 saveNotes(); 00123 00124 // create the note widgets out of the journals 00125 KCal::Journal::List notes = m_calendar.journals(); 00126 KCal::Journal::List::ConstIterator end = notes.end(); 00127 for ( KCal::Journal::List::ConstIterator it = notes.begin(); it != end; ++it ) 00128 createNote( *it ); 00129 00130 kapp->installEventFilter( this ); 00131 00132 if ( m_noteList.count() == 0 && !kapp->isRestored() ) 00133 newNote(); 00134 } 00135 00136 KNotesApp::~KNotesApp() 00137 { 00138 saveNotes(); 00139 00140 blockSignals( true ); 00141 m_noteList.clear(); 00142 blockSignals( false ); 00143 00144 delete m_defaultConfig; 00145 } 00146 00147 bool KNotesApp::commitData( QSessionManager& ) 00148 { 00149 saveConfigs(); 00150 return true; 00151 } 00152 00153 // -------------------- public DCOP interface -------------------- // 00154 00155 QString KNotesApp::newNote( const QString& name, const QString& text ) 00156 { 00157 // create the new note 00158 KCal::Journal *note = new KCal::Journal(); 00159 00160 // new notes have the current date/time as title if none was given 00161 if ( !name.isEmpty() ) 00162 note->setSummary( name ); 00163 else 00164 note->setSummary( KGlobal::locale()->formatDateTime( QDateTime::currentDateTime() ) ); 00165 00166 // the body of the note 00167 note->setDescription( text ); 00168 00169 m_calendar.addJournal( note ); 00170 00171 createNote( note ); 00172 showNote( note->uid() ); 00173 00174 return note->uid(); 00175 } 00176 00177 QString KNotesApp::newNoteFromClipboard( const QString& name ) 00178 { 00179 const QString& text = KApplication::clipboard()->text(); 00180 return newNote( name, text ); 00181 } 00182 00183 void KNotesApp::showNote( const QString& id ) const 00184 { 00185 KNote* note = m_noteList[id]; 00186 if ( note ) 00187 showNote( note ); 00188 else 00189 kdWarning(5500) << "No note with id: " << id << endl; 00190 } 00191 00192 void KNotesApp::hideNote( const QString& id ) const 00193 { 00194 KNote* note = m_noteList[id]; 00195 if ( note ) 00196 note->hide(); 00197 else 00198 kdWarning(5500) << "No note with id: " << id << endl; 00199 } 00200 00201 void KNotesApp::killNote( const QString& id, bool force ) 00202 { 00203 KNote* note = m_noteList[id]; 00204 if ( note ) 00205 note->slotKill( force ); 00206 else 00207 kdWarning(5500) << "No note with id: " << id << endl; 00208 } 00209 00210 // "bool force = false" doesn't work with dcop 00211 void KNotesApp::killNote( const QString& id ) 00212 { 00213 killNote( id, false ); 00214 } 00215 00216 QMap<QString,QString> KNotesApp::notes() const 00217 { 00218 QMap<QString,QString> notes; 00219 QDictIterator<KNote> it( m_noteList ); 00220 00221 for ( ; it.current(); ++it ) 00222 notes.insert( it.current()->noteId(), it.current()->name() ); 00223 00224 return notes; 00225 } 00226 00227 QString KNotesApp::name( const QString& id ) const 00228 { 00229 KNote* note = m_noteList[id]; 00230 if ( note ) 00231 return note->name(); 00232 else 00233 return QString::null; 00234 } 00235 00236 QString KNotesApp::text( const QString& id ) const 00237 { 00238 KNote* note = m_noteList[id]; 00239 if ( note ) 00240 return note->text(); 00241 else 00242 return QString::null; 00243 } 00244 00245 void KNotesApp::setName( const QString& id, const QString& newName ) 00246 { 00247 KNote* note = m_noteList[id]; 00248 if ( note ) 00249 note->setName( newName ); 00250 else 00251 kdWarning(5500) << "No note with id: " << id << endl; 00252 } 00253 00254 void KNotesApp::setText( const QString& id, const QString& newText ) 00255 { 00256 KNote* note = m_noteList[id]; 00257 if ( note ) 00258 note->setText( newText ); 00259 else 00260 kdWarning(5500) << "No note with id: " << id << endl; 00261 } 00262 00263 void KNotesApp::sync( const QString& app ) 00264 { 00265 QDictIterator<KNote> it( m_noteList ); 00266 00267 for ( ; it.current(); ++it ) 00268 it.current()->sync( app ); 00269 } 00270 00271 bool KNotesApp::isNew( const QString& app, const QString& id ) const 00272 { 00273 KNote* note = m_noteList[id]; 00274 if ( note ) 00275 return note->isNew( app ); 00276 else 00277 return false; 00278 } 00279 00280 bool KNotesApp::isModified( const QString& app, const QString& id ) const 00281 { 00282 KNote* note = m_noteList[id]; 00283 if ( note ) 00284 return note->isModified( app ); 00285 else 00286 return false; 00287 } 00288 00289 00290 // ------------------- protected methods ------------------- // 00291 00292 void KNotesApp::mousePressEvent( QMouseEvent* e ) 00293 { 00294 if ( !rect().contains( e->pos() ) ) 00295 return; 00296 00297 switch ( e->button() ) 00298 { 00299 case LeftButton: 00300 if ( m_noteList.count() == 1 ) 00301 { 00302 QDictIterator<KNote> it( m_noteList ); 00303 showNote( it.toFirst() ); 00304 } 00305 else if ( m_note_menu->count() > 0 ) 00306 m_note_menu->popup( e->globalPos() ); 00307 break; 00308 case MidButton: 00309 newNote(); 00310 break; 00311 case RightButton: 00312 m_context_menu->popup( e->globalPos() ); 00313 default: break; 00314 } 00315 } 00316 00317 bool KNotesApp::eventFilter( QObject* o, QEvent* ev ) 00318 { 00319 if ( ev->type() == QEvent::KeyPress ) 00320 { 00321 QKeyEvent* ke = (QKeyEvent*)ev; 00322 00323 if ( ke->key() == Key_BackTab ) // Shift+Tab 00324 { 00325 // show next note 00326 QDictIterator<KNote> it( m_noteList ); 00327 KNote *first = it.toFirst(); 00328 for ( ; it.current(); ++it ) 00329 if ( it.current()->hasFocus() ) 00330 { 00331 if ( ++it ) 00332 showNote( it.current() ); 00333 else 00334 showNote( first ); 00335 break; 00336 } 00337 00338 ke->accept(); 00339 return true; 00340 } 00341 else 00342 ke->ignore(); 00343 } 00344 00345 return QLabel::eventFilter( o, ev ); 00346 } 00347 00348 00349 // -------------------- protected slots -------------------- // 00350 00351 void KNotesApp::slotShowNote() 00352 { 00353 // tell the WM to give this note focus 00354 showNote( QString::fromUtf8( sender()->name() ) ); 00355 } 00356 00357 void KNotesApp::slotPreferences() 00358 { 00359 // reuse the dialog if possible 00360 if ( KNoteConfigDlg::showDialog( "KNotes Default Settings" ) ) 00361 return; 00362 00363 // create the KNoteConfig if needed 00364 if ( !m_defaultConfig ) 00365 { 00366 QString configFile = KGlobal::dirs()->saveLocation( "config" ) + "knotesrc"; 00367 KSharedConfig::Ptr config = KSharedConfig::openConfig( configFile, false, false ); 00368 m_defaultConfig = new KNoteConfig( config ); 00369 } 00370 00371 // create a new preferences dialog... 00372 KNoteConfigDlg *dialog = new KNoteConfigDlg( m_defaultConfig, 00373 i18n("KNotes Defaults"), true, this, "KNotes Default Settings" ); 00374 dialog->show(); 00375 } 00376 00377 void KNotesApp::slotConfigureAccels() 00378 { 00379 KKeyDialog::configure( m_globalAccel, this, false ); 00380 m_globalAccel->writeSettings(); 00381 updateGlobalAccels(); 00382 } 00383 00384 void KNotesApp::slotNoteKilled( KCal::Journal *journal ) 00385 { 00386 // this kills the KNote object 00387 m_noteList.remove( journal->uid() ); 00388 m_calendar.deleteJournal( journal ); 00389 00390 saveNotes(); 00391 updateNoteActions(); 00392 } 00393 00394 void KNotesApp::slotQuit() 00395 { 00396 saveConfigs(); 00397 kapp->quit(); 00398 } 00399 00400 00401 // -------------------- private methods -------------------- // 00402 00403 void KNotesApp::showNote( KNote* note ) const 00404 { 00405 if ( !note->isHidden() ) 00406 { 00407 // if it's already showing, we need to change to its desktop 00408 // and give it focus 00409 KWin::setCurrentDesktop( KWin::windowInfo( note->winId() ).desktop() ); 00410 KWin::forceActiveWindow( note->winId() ); 00411 note->setFocus(); 00412 } 00413 else 00414 { 00415 // if not, show note on the current desktop 00416 note->show(); 00417 note->toDesktop( KWin::currentDesktop() ); 00418 KWin::forceActiveWindow( note->winId() ); 00419 note->setFocus(); 00420 } 00421 } 00422 00423 void KNotesApp::createNote( KCal::Journal *journal ) 00424 { 00425 KNote *newNote = new KNote( this, domDocument(), journal, 00426 0, journal->uid().utf8() ); 00427 m_noteList.insert( newNote->noteId(), newNote ); 00428 00429 connect( newNote, SIGNAL(sigRequestNewNote()), SLOT(newNote()) ); 00430 connect( newNote, SIGNAL(sigKillNote( KCal::Journal* )), 00431 SLOT(slotNoteKilled( KCal::Journal* )) ); 00432 connect( newNote, SIGNAL(sigNameChanged()), SLOT(updateNoteActions()) ); 00433 connect( newNote, SIGNAL(sigDataChanged()), SLOT(saveNotes()) ); 00434 connect( newNote, SIGNAL(sigColorChanged()), SLOT(updateNoteActions()) ); 00435 00436 updateNoteActions(); 00437 } 00438 00439 void KNotesApp::saveNotes() 00440 { 00441 QString file = KGlobal::dirs()->saveLocation( "appdata" ) + "notes.ics"; 00442 QString backup = file + "~"; 00443 00444 // if the backup fails don't even try to save the current notes 00445 // (might just destroy the file that's already there) 00446 00447 if ( KIO::NetAccess::exists( KURL( file ), true, 0 ) && 00448 !KIO::NetAccess::file_copy( KURL( file ), KURL( backup ), -1, true ) ) 00449 { 00450 KMessageBox::error( 0, 00451 i18n("<qt>Unable to save the notes backup to " 00452 "<b>%1</b>! Check that there is sufficient " 00453 "disk space!</qt>").arg( backup ) ); 00454 } 00455 else if ( !m_calendar.save( file, new KCal::ICalFormat() ) ) 00456 { 00457 KMessageBox::error( 0, 00458 i18n("<qt>Unable to save the notes to <b>%1</b>! " 00459 "Check that there is sufficient disk space." 00460 "<br>There should be a backup in <b>%2</b> " 00461 "though.</qt>").arg( file ).arg( backup ) ); 00462 } 00463 } 00464 00465 void KNotesApp::saveConfigs() 00466 { 00467 QDictIterator<KNote> it( m_noteList ); 00468 for ( ; it.current(); ++it ) 00469 it.current()->saveConfig(); 00470 } 00471 00472 void KNotesApp::updateNoteActions() 00473 { 00474 unplugActionList( "notes" ); 00475 m_noteActions.clear(); 00476 00477 for ( QDictIterator<KNote> it( m_noteList ); it.current(); ++it ) 00478 { 00479 KAction *action = new KAction( it.current()->name().replace("&", "&&"), 00480 KShortcut(), this, SLOT(slotShowNote()), 00481 (QObject *)0, 00482 it.current()->noteId().utf8() ); 00483 QPixmap pix( 16, 16 ); 00484 pix.fill( it.current()->paletteBackgroundColor() ); 00485 action->setIconSet( pix ); 00486 m_noteActions.append( action ); 00487 } 00488 00489 m_noteActions.sort(); 00490 00491 if ( m_noteActions.isEmpty() ) 00492 { 00493 KAction *action = new KAction( i18n("No Notes") ); 00494 m_noteActions.append( action ); 00495 } 00496 00497 plugActionList( "notes", m_noteActions ); 00498 } 00499 00500 void KNotesApp::updateGlobalAccels() 00501 { 00502 if ( m_globalAccel->isEnabled() ) 00503 { 00504 KAction *action = actionCollection()->action( "new_note" ); 00505 if ( action ) 00506 action->setShortcut( m_globalAccel->shortcut( "global_new_note" ) ); 00507 action = actionCollection()->action( "new_note_clipboard" ); 00508 if ( action ) 00509 action->setShortcut( m_globalAccel->shortcut( "global_new_note_clipboard" ) ); 00510 00511 m_globalAccel->updateConnections(); 00512 } 00513 else 00514 { 00515 KAction *action = actionCollection()->action( "new_note" ); 00516 if ( action ) 00517 action->setShortcut( 0 ); 00518 action = actionCollection()->action( "new_note_clipboard" ); 00519 if ( action ) 00520 action->setShortcut( 0 ); 00521 } 00522 } 00523 00524 #include "knotesapp.moc"
KDE Logo
This file is part of the documentation for knotes Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:46 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003