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