21 #include <tqclipboard.h>
22 #include <tqptrlist.h>
23 #include <tqtooltip.h>
27 #include <kxmlguifactory.h>
28 #include <kxmlguibuilder.h>
29 #include <ksystemtray.h>
31 #include <kiconeffect.h>
32 #include <kstandarddirs.h>
33 #include <kpopupmenu.h>
34 #include <khelpmenu.h>
36 #include <kfinddialog.h>
37 #include <kkeydialog.h>
38 #include <kglobalaccel.h>
39 #include <ksimpleconfig.h>
41 #include <kbufferedsocket.h>
42 #include <kserversocket.h>
44 #include <libkcal/journal.h>
45 #include <libkcal/calendarlocal.h>
47 #include "knotesapp.h"
49 #include "knotesalarm.h"
50 #include "knoteconfigdlg.h"
51 #include "knotesglobalconfig.h"
52 #include "knoteslegacy.h"
53 #include "knotesnetrecv.h"
55 #include "knotes/resourcemanager.h"
57 using namespace KNetwork;
60 class KNotesKeyDialog :
public KDialogBase
63 KNotesKeyDialog( KGlobalAccel *globals, TQWidget *parent,
const char* name = 0 )
64 : KDialogBase( parent, name, true, i18n(
"Configure Shortcuts"), Default|Ok|Cancel, Ok )
66 m_keyChooser =
new KKeyChooser( globals,
this );
67 setMainWidget( m_keyChooser );
68 connect(
this, TQT_SIGNAL(defaultClicked()), m_keyChooser, TQT_SLOT(allDefault()) );
71 void insert( KActionCollection *actions )
73 m_keyChooser->insert( actions, i18n(
"Note Actions") );
78 if ( exec() == Accepted )
83 KKeyChooser *m_keyChooser;
87 int KNotesApp::KNoteActionList::compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
89 if ( ((KAction*)s1)->text() == ((KAction*)s2)->text() )
91 return ( ((KAction*)s1)->text() < ((KAction*)s2)->text() ? -1 : 1 );
95 KNotesApp::KNotesApp()
96 : DCOPObject(
"KNotesIface"), TQLabel( 0, 0, WType_TopLevel ),
97 m_alarm( 0 ), m_listener( 0 ), m_find( 0 ), m_findPos( 0 )
99 connect( kapp, TQT_SIGNAL(lastWindowClosed()), kapp, TQT_SLOT(quit()) );
101 m_noteList.setAutoDelete(
true );
102 m_noteActions.setAutoDelete(
true );
105 KWin::setSystemTrayWindowFor( winId(), qt_xrootwin() );
106 TQToolTip::add(
this, i18n(
"KNotes: Sticky notes for KDE" ) );
107 setBackgroundMode( X11ParentRelative );
108 setPixmap( KSystemTray::loadSizedIcon(
"knotes", TQWidget::width() ) );
111 KNote::setStyle( KNotesGlobalConfig::style() );
114 new KAction( i18n(
"New Note"),
"filenew", 0,
115 TQT_TQOBJECT(
this), TQT_SLOT(newNote()), actionCollection(),
"new_note" );
116 new KAction( i18n(
"New Note From Clipboard"),
"editpaste", 0,
117 TQT_TQOBJECT(
this), TQT_SLOT(newNoteFromClipboard()), actionCollection(),
"new_note_clipboard" );
118 new KAction( i18n(
"Show All Notes"),
"knotes", 0,
119 TQT_TQOBJECT(
this), TQT_SLOT(showAllNotes()), actionCollection(),
"show_all_notes" );
120 new KAction( i18n(
"Hide All Notes"),
"fileclose", 0,
121 TQT_TQOBJECT(
this), TQT_SLOT(hideAllNotes()), actionCollection(),
"hide_all_notes" );
122 new KHelpMenu(
this, kapp->aboutData(),
false, actionCollection() );
124 m_findAction = KStdAction::find( TQT_TQOBJECT(
this), TQT_SLOT(slotOpenFindDialog()), actionCollection() );
125 KStdAction::preferences( TQT_TQOBJECT(
this), TQT_SLOT(slotPreferences()), actionCollection() );
126 KStdAction::keyBindings( TQT_TQOBJECT(
this), TQT_SLOT(slotConfigureAccels()), actionCollection() );
128 KStdAction::quit( TQT_TQOBJECT(
this), TQT_SLOT(slotQuit()), actionCollection() )->setShortcut( 0 );
130 setXMLFile( instance()->instanceName() +
"appui.rc" );
132 m_guiBuilder =
new KXMLGUIBuilder(
this );
133 m_guiFactory =
new KXMLGUIFactory( m_guiBuilder, TQT_TQOBJECT(
this) );
134 m_guiFactory->addClient(
this );
136 m_context_menu =
static_cast<KPopupMenu*
>(m_guiFactory->container(
"knotes_context",
this ));
137 m_note_menu =
static_cast<KPopupMenu*
>(m_guiFactory->container(
"notes_menu",
this ));
140 TQString xmlFileName = instance()->instanceName() +
"ui.rc";
141 TQString filter = TQString::fromLatin1( instance()->instanceName() +
'/' ) + xmlFileName;
142 TQStringList fileList = instance()->dirs()->findAllResources(
"data", filter ) +
143 instance()->dirs()->findAllResources(
"data", xmlFileName );
146 KXMLGUIClient::findMostRecentXMLFile( fileList, doc );
147 m_noteGUI.setContent( doc );
150 m_globalAccel =
new KGlobalAccel( TQT_TQOBJECT(
this),
"global accel" );
151 m_globalAccel->insert(
"global_new_note", i18n(
"New Note"),
"",
152 ALT+SHIFT+Key_N, ALT+SHIFT+Key_N ,
153 TQT_TQOBJECT(
this), TQT_SLOT(newNote()),
true,
true );
154 m_globalAccel->insert(
"global_new_note_clipboard", i18n(
"New Note From Clipboard"),
"",
155 ALT+SHIFT+Key_C, ALT+SHIFT+Key_C,
156 TQT_TQOBJECT(
this), TQT_SLOT(newNoteFromClipboard()),
true,
true );
157 m_globalAccel->insert(
"global_hide_all_notes", i18n(
"Hide All Notes"),
"",
158 ALT+SHIFT+Key_H, ALT+SHIFT+Key_H ,
159 TQT_TQOBJECT(
this), TQT_SLOT(hideAllNotes()),
true,
true );
160 m_globalAccel->insert(
"global_show_all_notes", i18n(
"Show All Notes"),
"",
161 ALT+SHIFT+Key_S, ALT+SHIFT+Key_S,
162 TQT_TQOBJECT(
this), TQT_SLOT(showAllNotes()),
true,
true );
164 m_globalAccel->readSettings();
166 KConfig *config = KGlobal::config();
167 config->setGroup(
"Global Keybindings" );
168 m_globalAccel->setEnabled( config->readBoolEntry(
"Enabled",
true ) );
170 updateGlobalAccels();
173 KNotesLegacy::cleanUp();
176 m_manager =
new KNotesResourceManager();
177 connect( m_manager, TQT_SIGNAL(sigRegisteredNote( KCal::Journal * )),
178 this, TQT_SLOT(createNote( KCal::Journal * )) );
179 connect( m_manager, TQT_SIGNAL(sigDeregisteredNote( KCal::Journal * )),
180 this, TQT_SLOT(killNote( KCal::Journal * )) );
186 KCal::CalendarLocal calendar( TQString::fromLatin1(
"UTC" ) );
187 if ( KNotesLegacy::convert( &calendar ) )
189 KCal::Journal::List notes = calendar.journals();
190 KCal::Journal::List::ConstIterator it;
191 for ( it = notes.constBegin(); it != notes.constEnd(); ++it )
192 m_manager->addNewNote( *it );
199 m_alarm =
new KNotesAlarm( m_manager, TQT_TQOBJECT(
this) );
202 m_listener =
new KServerSocket();
203 m_listener->setResolutionEnabled(
true );
204 connect( m_listener, TQT_SIGNAL(readyAccept()), TQT_SLOT(acceptConnection()) );
205 updateNetworkListener();
207 if ( m_noteList.count() == 0 && !kapp->isRestored() )
213 void KNotesApp::resizeEvent ( TQResizeEvent * )
217 TQPixmap scaledpixmap;
219 origpixmap = KSystemTray::loadSizedIcon(
"knotes", TQWidget::width() );
220 newIcon = origpixmap;
221 newIcon = newIcon.smoothScale(TQWidget::width(), TQWidget::height());
222 scaledpixmap = newIcon;
223 setPixmap(scaledpixmap);
226 KNotesApp::~KNotesApp()
230 blockSignals(
true );
232 blockSignals(
false );
239 bool KNotesApp::commitData( TQSessionManager& )
247 TQString KNotesApp::newNote(
const TQString& name,
const TQString& text )
250 KCal::Journal *journal =
new KCal::Journal();
253 if ( !name.isEmpty() )
254 journal->setSummary( name );
256 journal->setSummary( KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime() ) );
259 journal->setDescription( text );
261 if ( m_manager->addNewNote( journal ) ) {
262 showNote( journal->uid() );
264 return journal->uid();
267 TQString KNotesApp::newNoteFromClipboard(
const TQString& name )
269 const TQString& text = KApplication::clipboard()->text();
270 return newNote( name, text );
273 void KNotesApp::hideAllNotes()
const
275 TQDictIterator<KNote> it( m_noteList );
280 void KNotesApp::showAllNotes()
const
282 TQDictIterator<KNote> it( m_noteList );
289 void KNotesApp::showNote(
const TQString&
id )
const
291 KNote* note = m_noteList[id];
295 kdWarning(5500) <<
"showNote: no note with id: " <<
id << endl;
298 void KNotesApp::hideNote(
const TQString&
id )
const
300 KNote* note = m_noteList[id];
304 kdWarning(5500) <<
"hideNote: no note with id: " <<
id << endl;
307 void KNotesApp::killNote(
const TQString&
id,
bool force )
309 KNote* note = m_noteList[id];
311 note->slotKill( force );
313 kdWarning(5500) <<
"killNote: no note with id: " <<
id << endl;
317 void KNotesApp::killNote(
const TQString&
id )
319 killNote(
id,
false );
322 TQMap<TQString,TQString> KNotesApp::notes()
const
324 TQMap<TQString,TQString> notes;
325 TQDictIterator<KNote> it( m_noteList );
327 for ( ; it.current(); ++it )
328 notes.insert( it.current()->noteId(), it.current()->name() );
333 TQString KNotesApp::name(
const TQString&
id )
const
335 KNote* note = m_noteList[id];
342 TQString KNotesApp::text(
const TQString&
id )
const
344 KNote* note = m_noteList[id];
351 void KNotesApp::setName(
const TQString&
id,
const TQString& newName )
353 KNote* note = m_noteList[id];
355 note->setName( newName );
357 kdWarning(5500) <<
"setName: no note with id: " <<
id << endl;
360 void KNotesApp::setText(
const TQString&
id,
const TQString& newText )
362 KNote* note = m_noteList[id];
364 note->setText( newText );
366 kdWarning(5500) <<
"setText: no note with id: " <<
id << endl;
369 TQString KNotesApp::fgColor(
const TQString&
id )
const
371 KNote* note = m_noteList[id];
373 return note->fgColor().name();
378 TQString KNotesApp::bgColor(
const TQString&
id )
const
380 KNote* note = m_noteList[id];
382 return note->bgColor().name();
387 void KNotesApp::setColor(
const TQString&
id,
const TQString& fgColor,
const TQString& bgColor )
389 KNote* note = m_noteList[id];
391 note->setColor( TQColor( fgColor ), TQColor( bgColor ) );
393 kdWarning(5500) <<
"setColor: no note with id: " <<
id << endl;
396 int KNotesApp::width(
const TQString&
id )
const
398 KNote* note = m_noteList[id];
400 return note->width();
405 int KNotesApp::height(
const TQString&
id )
const
407 KNote* note = m_noteList[id];
409 return note->height();
414 void KNotesApp::move(
const TQString&
id,
int x,
int y )
const
416 KNote* note = m_noteList[id];
418 return note->move( x, y );
420 kdWarning(5500) <<
"move: no note with id: " <<
id << endl;
423 void KNotesApp::resize(
const TQString&
id,
int width,
int height )
const
425 KNote* note = m_noteList[id];
427 return note->resize( width, height );
429 kdWarning(5500) <<
"resize: no note with id: " <<
id << endl;
432 void KNotesApp::sync(
const TQString& app )
434 TQDictIterator<KNote> it( m_noteList );
436 for ( ; it.current(); ++it )
437 it.current()->sync( app );
440 bool KNotesApp::isNew(
const TQString& app,
const TQString&
id )
const
442 KNote* note = m_noteList[id];
444 return note->isNew( app );
449 bool KNotesApp::isModified(
const TQString& app,
const TQString&
id )
const
451 KNote* note = m_noteList[id];
453 return note->isModified( app );
461 void KNotesApp::mousePressEvent( TQMouseEvent* e )
463 if ( !rect().contains( e->pos() ) )
466 switch ( e->button() )
469 if ( m_noteList.count() == 1 )
471 TQDictIterator<KNote> it( m_noteList );
472 showNote( it.toFirst() );
474 else if ( m_note_menu->count() > 0 )
475 m_note_menu->popup( e->globalPos() );
480 case Qt::RightButton:
481 m_context_menu->popup( e->globalPos() );
488 void KNotesApp::slotShowNote()
491 showNote( TQString::fromUtf8( TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name() ) );
494 void KNotesApp::slotWalkThroughNotes()
497 TQDictIterator<KNote> it( m_noteList );
498 KNote *first = it.toFirst();
500 if ( (*it)->hasFocus() )
510 void KNotesApp::slotOpenFindDialog()
512 KFindDialog findDia(
this,
"find_dialog" );
513 findDia.setHasSelection(
false );
514 findDia.setHasCursor(
false );
515 findDia.setSupportsBackwardsFind(
false );
517 if ( (findDia.exec() != TQDialog::Accepted) || findDia.pattern().isEmpty() )
521 m_findPos =
new TQDictIterator<KNote>( m_noteList );
525 m_find =
new KFind( findDia.pattern(), findDia.options(), this );
530 void KNotesApp::slotFindNext()
534 KNote *note = **m_findPos;
536 note->find( m_find->pattern(), m_find->options() );
540 m_find->displayFinalDialog();
548 void KNotesApp::slotPreferences()
551 if ( KNoteConfigDlg::showDialog(
"KNotes Default Settings" ) )
555 KNoteConfigDlg *dialog =
new KNoteConfigDlg( 0, i18n(
"Settings"),
this,
557 connect( dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(
this), TQT_SLOT(updateNetworkListener()) );
558 connect( dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(
this), TQT_SLOT(updateStyle()) );
562 void KNotesApp::slotConfigureAccels()
564 KNotesKeyDialog keys( m_globalAccel,
this );
565 TQDictIterator<KNote> notes( m_noteList );
566 if ( !m_noteList.isEmpty() )
567 keys.insert( (*notes)->actionCollection() );
570 m_globalAccel->writeSettings();
571 updateGlobalAccels();
574 m_noteGUI.setContent(
575 KXMLGUIFactory::readConfigFile( instance()->instanceName() +
"ui.rc", instance() )
578 if ( m_noteList.isEmpty() )
582 TQValueList<KAction *> list = (*notes)->actionCollection()->actions();
583 for ( TQValueList<KAction *>::iterator it = list.begin(); it != list.end(); ++it )
586 for ( ++notes; *notes; ++notes )
588 KAction *toChange = (*notes)->actionCollection()->action( (*it)->name() );
589 if ( toChange->shortcut() != (*it)->shortcut() )
590 toChange->setShortcut( (*it)->shortcut() );
595 void KNotesApp::slotNoteKilled( KCal::Journal *journal )
598 m_manager->deleteNote( journal );
602 void KNotesApp::slotQuit()
604 TQDictIterator<KNote> it( m_noteList );
607 if ( (*it)->isModified() )
608 (*it)->saveData(
false);
617 void KNotesApp::showNote( KNote* note )
const
620 KWin::setCurrentDesktop( KWin::windowInfo( note->winId() ).desktop() );
621 KWin::forceActiveWindow( note->winId() );
625 void KNotesApp::createNote( KCal::Journal *journal )
627 if( journal->uid() == m_noteUidModify)
629 KNote *note = m_noteList[m_noteUidModify];
631 note->changeJournal(journal);
635 m_noteUidModify = journal->uid();
636 KNote *newNote =
new KNote( m_noteGUI, journal, 0, journal->uid().utf8() );
637 m_noteList.insert( newNote->noteId(), newNote );
639 connect( newNote, TQT_SIGNAL(sigRequestNewNote()), TQT_SLOT(newNote()) );
640 connect( newNote, TQT_SIGNAL(sigShowNextNote()), TQT_SLOT(slotWalkThroughNotes()) );
641 connect( newNote, TQT_SIGNAL(sigKillNote( KCal::Journal* )),
642 TQT_SLOT(slotNoteKilled( KCal::Journal* )) );
643 connect( newNote, TQT_SIGNAL(sigNameChanged()), TQT_SLOT(updateNoteActions()) );
644 connect( newNote, TQT_SIGNAL(sigDataChanged(
const TQString &)), TQT_SLOT(saveNotes(
const TQString &)) );
645 connect( newNote, TQT_SIGNAL(sigColorChanged()), TQT_SLOT(updateNoteActions()) );
646 connect( newNote, TQT_SIGNAL(sigFindFinished()), TQT_SLOT(slotFindNext()) );
653 void KNotesApp::killNote( KCal::Journal *journal )
655 if(m_noteUidModify == journal->uid())
660 KNote *note = m_noteList.take( journal->uid() );
663 note->deleteWhenIdle();
668 void KNotesApp::acceptConnection()
671 KBufferedSocket *s =
static_cast<KBufferedSocket *
>(m_listener->accept());
674 KNotesNetworkReceiver *recv =
new KNotesNetworkReceiver( s );
675 connect( recv, TQT_SIGNAL(sigNoteReceived(
const TQString &,
const TQString & )),
676 TQT_TQOBJECT(
this), TQT_SLOT(newNote(
const TQString &,
const TQString & )) );
680 void KNotesApp::saveNotes(
const TQString & uid )
682 m_noteUidModify = uid;
686 void KNotesApp::saveNotes()
688 KNotesGlobalConfig::writeConfig();
692 void KNotesApp::saveConfigs()
694 TQDictIterator<KNote> it( m_noteList );
695 for ( ; it.current(); ++it )
696 it.current()->saveConfig();
699 void KNotesApp::updateNoteActions()
701 unplugActionList(
"notes" );
702 m_noteActions.clear();
704 for ( TQDictIterator<KNote> it( m_noteList ); it.current(); ++it )
706 KAction *action =
new KAction( it.current()->name().replace(
"&",
"&&"),
707 KShortcut(), TQT_TQOBJECT(
this), TQT_SLOT(slotShowNote()),
709 it.current()->noteId().utf8() );
711 TQPixmap icon = effect.apply( kapp->miniIcon(), KIconEffect::Colorize, 1,
712 it.current()->paletteBackgroundColor(), false );
713 action->setIconSet( icon );
714 m_noteActions.append( action );
717 if ( m_noteActions.isEmpty() )
719 actionCollection()->action(
"hide_all_notes" )->setEnabled(
false );
720 actionCollection()->action(
"show_all_notes" )->setEnabled(
false );
721 m_findAction->setEnabled(
false );
722 KAction *action =
new KAction( i18n(
"No Notes") );
723 m_noteActions.append( action );
727 actionCollection()->action(
"hide_all_notes" )->setEnabled(
true );
728 actionCollection()->action(
"show_all_notes" )->setEnabled(
true );
729 m_findAction->setEnabled(
true );
730 m_noteActions.sort();
732 plugActionList(
"notes", m_noteActions );
735 void KNotesApp::updateGlobalAccels()
737 if ( m_globalAccel->isEnabled() )
739 KAction *action = actionCollection()->action(
"new_note" );
741 action->setShortcut( m_globalAccel->shortcut(
"global_new_note" ) );
742 action = actionCollection()->action(
"new_note_clipboard" );
744 action->setShortcut( m_globalAccel->shortcut(
"global_new_note_clipboard" ) );
745 action = actionCollection()->action(
"hide_all_notes" );
747 action->setShortcut( m_globalAccel->shortcut(
"global_hide_all_notes" ) );
748 action = actionCollection()->action(
"show_all_notes" );
750 action->setShortcut( m_globalAccel->shortcut(
"global_show_all_notes" ) );
752 m_globalAccel->updateConnections();
756 KAction *action = actionCollection()->action(
"new_note" );
758 action->setShortcut( 0 );
759 action = actionCollection()->action(
"new_note_clipboard" );
761 action->setShortcut( 0 );
762 action = actionCollection()->action(
"hide_all_notes" );
764 action->setShortcut( 0 );
765 action = actionCollection()->action(
"show_all_notes" );
767 action->setShortcut( 0 );
771 void KNotesApp::updateNetworkListener()
775 if ( KNotesGlobalConfig::receiveNotes() )
777 m_listener->setAddress( TQString::number( KNotesGlobalConfig::port() ) );
779 m_listener->listen();
783 void KNotesApp::updateStyle()
785 KNote::setStyle( KNotesGlobalConfig::style() );
787 TQDictIterator<KNote> it( m_noteList );
788 for ( ; it.current(); ++it )
789 TQApplication::postEvent( *it,
new TQEvent( TQEvent::LayoutHint ) );
792 #include "knotesapp.moc"