/*******************************************************************
 KNotes -- Notes for the KDE project

 Copyright (c) 1997-2006, The KNotes Developers

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*******************************************************************/

#include <tqclipboard.h>
#include <tqptrlist.h>
#include <tqtooltip.h>

#include <kdebug.h>
#include <tdeaction.h>
#include <kxmlguifactory.h>
#include <kxmlguibuilder.h>
#include <ksystemtray.h>
#include <tdelocale.h>
#include <kiconeffect.h>
#include <kstandarddirs.h>
#include <tdepopupmenu.h>
#include <khelpmenu.h>
#include <kfind.h>
#include <kfinddialog.h>
#include <kkeydialog.h>
#include <kglobalaccel.h>
#include <ksimpleconfig.h>
#include <twin.h>
#include <kbufferedsocket.h>
#include <kserversocket.h>

#include <libkcal/journal.h>
#include <libkcal/calendarlocal.h>

#include "knotesapp.h"
#include "knote.h"
#include "knotesalarm.h"
#include "knoteconfigdlg.h"
#include "knotesglobalconfig.h"
#include "knoteslegacy.h"
#include "knotesnetrecv.h"

#include "knotes/resourcemanager.h"

using namespace KNetwork;


class KNotesKeyDialog : public KDialogBase
{
public:
    KNotesKeyDialog( TDEGlobalAccel *globals, TQWidget *parent, const char* name = 0 )
        : KDialogBase( parent, name, true, i18n("Configure Shortcuts"), Default|Ok|Cancel, Ok )
    {
        m_keyChooser = new KKeyChooser( globals, this );
        setMainWidget( m_keyChooser );
        connect( this, TQT_SIGNAL(defaultClicked()), m_keyChooser, TQT_SLOT(allDefault()) );
    }

    void insert( TDEActionCollection *actions )
    {
        m_keyChooser->insert( actions, i18n("Note Actions") );
    }

    void configure()
    {
        if ( exec() == Accepted )
            m_keyChooser->save();
    }

private:
    KKeyChooser *m_keyChooser;
};


int KNotesApp::KNoteActionList::compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
{
    if ( ((TDEAction*)s1)->text() == ((TDEAction*)s2)->text() )
        return 0;
    return ( ((TDEAction*)s1)->text() < ((TDEAction*)s2)->text() ? -1 : 1 );
}


KNotesApp::KNotesApp()
    : DCOPObject("KNotesIface"), TQLabel( 0, 0, WType_TopLevel ),
      m_alarm( 0 ), m_listener( 0 ), m_find( 0 ), m_findPos( 0 )
{
    connect( kapp, TQT_SIGNAL(lastWindowClosed()), kapp, TQT_SLOT(quit()) );

    m_noteList.setAutoDelete( true );
    m_noteActions.setAutoDelete( true );

    // create the dock widget...
    KWin::setSystemTrayWindowFor( winId(), tqt_xrootwin() );
    TQToolTip::add( this, i18n( "KNotes: Sticky notes for TDE" ) );
    setBackgroundMode( X11ParentRelative );
    setPixmap( KSystemTray::loadIcon( "knotes" ) );

    // set the initial style
    KNote::setStyle( KNotesGlobalConfig::style() );

    // create the GUI...
    new TDEAction( i18n("New Note"), "document-new", 0,
        TQT_TQOBJECT(this), TQT_SLOT(newNote()), actionCollection(), "new_note" );
    new TDEAction( i18n("New Note From Clipboard"), "edit-paste", 0,
        TQT_TQOBJECT(this), TQT_SLOT(newNoteFromClipboard()), actionCollection(), "new_note_clipboard" );
    new TDEAction( i18n("Show All Notes"), "knotes", 0,
        TQT_TQOBJECT(this), TQT_SLOT(showAllNotes()), actionCollection(), "show_all_notes" );
    new TDEAction( i18n("Hide All Notes"), "window-close", 0,
        TQT_TQOBJECT(this), TQT_SLOT(hideAllNotes()), actionCollection(), "hide_all_notes" );
    new KHelpMenu( this, kapp->aboutData(), false, actionCollection() );

    m_findAction = KStdAction::find( TQT_TQOBJECT(this), TQT_SLOT(slotOpenFindDialog()), actionCollection() );
    KStdAction::preferences( TQT_TQOBJECT(this), TQT_SLOT(slotPreferences()), actionCollection() );
    KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT(slotConfigureAccels()), actionCollection() );
    //FIXME: no shortcut removing!?
    KStdAction::quit( TQT_TQOBJECT(this), TQT_SLOT(slotQuit()), actionCollection() )->setShortcut( 0 );

    setXMLFile( instance()->instanceName() + "appui.rc" );

    m_guiBuilder = new KXMLGUIBuilder( this );
    m_guiFactory = new KXMLGUIFactory( m_guiBuilder, TQT_TQOBJECT(this) );
    m_guiFactory->addClient( this );

    m_context_menu = static_cast<TDEPopupMenu*>(m_guiFactory->container( "knotes_context", this ));
    m_note_menu = static_cast<TDEPopupMenu*>(m_guiFactory->container( "notes_menu", this ));

    // get the most recent XML UI file
    TQString xmlFileName = instance()->instanceName() + "ui.rc";
    TQString filter = TQString::fromLatin1( instance()->instanceName() + '/' ) + xmlFileName;
    TQStringList fileList = instance()->dirs()->findAllResources( "data", filter ) +
                           instance()->dirs()->findAllResources( "data", xmlFileName );

    TQString doc;
    KXMLGUIClient::findMostRecentXMLFile( fileList, doc );
    m_noteGUI.setContent( doc );

    // create accels for global shortcuts
    m_globalAccel = new TDEGlobalAccel( TQT_TQOBJECT(this), "global accel" );
    m_globalAccel->insert( "global_new_note", i18n("New Note"), "",
                           ALT+SHIFT+Key_N, ALT+SHIFT+Key_N ,
                           TQT_TQOBJECT(this), TQT_SLOT(newNote()), true, true );
    m_globalAccel->insert( "global_new_note_clipboard", i18n("New Note From Clipboard"), "",
                           ALT+SHIFT+Key_C, ALT+SHIFT+Key_C,
                           TQT_TQOBJECT(this), TQT_SLOT(newNoteFromClipboard()), true, true );
    m_globalAccel->insert( "global_hide_all_notes", i18n("Hide All Notes"), "",
                           ALT+SHIFT+Key_H, ALT+SHIFT+Key_H ,
                           TQT_TQOBJECT(this), TQT_SLOT(hideAllNotes()), true, true );
    m_globalAccel->insert( "global_show_all_notes", i18n("Show All Notes"), "",
                           ALT+SHIFT+Key_S, ALT+SHIFT+Key_S,
                           TQT_TQOBJECT(this), TQT_SLOT(showAllNotes()), true, true );

    m_globalAccel->readSettings();

    TDEConfig *config = TDEGlobal::config();
    config->setGroup( "Global Keybindings" );
    m_globalAccel->setEnabled( config->readBoolEntry( "Enabled", true ) );

    updateGlobalAccels();

    // clean up old config files
    KNotesLegacy::cleanUp();

    // create the resource manager
    m_manager = new KNotesResourceManager();
    connect( m_manager, TQT_SIGNAL(sigRegisteredNote( KCal::Journal * )),
             this,      TQT_SLOT(createNote( KCal::Journal * )) );
    connect( m_manager, TQT_SIGNAL(sigDeregisteredNote( KCal::Journal * )),
             this,      TQT_SLOT(killNote( KCal::Journal * )) );

    // read the notes
    m_manager->load();

    // read the old config files, convert and add them
    KCal::CalendarLocal calendar( TQString::fromLatin1( "UTC" ) );
    if ( KNotesLegacy::convert( &calendar ) )
    {
        KCal::Journal::List notes = calendar.journals();
        KCal::Journal::List::ConstIterator it;
        for ( it = notes.constBegin(); it != notes.constEnd(); ++it )
            m_manager->addNewNote( *it );

        m_manager->save();
    }

    // set up the alarm reminder - do it after loading the notes because this
    // is used as a check if updateNoteActions has to be called for a new note
    m_alarm = new KNotesAlarm( m_manager, TQT_TQOBJECT(this) );

    // create the socket and possibly start listening for connections
    m_listener = new TDEServerSocket();
    m_listener->setResolutionEnabled( true );
    connect( m_listener, TQT_SIGNAL(readyAccept()), TQT_SLOT(acceptConnection()) );
    updateNetworkListener();

    if ( m_noteList.count() == 0 && !kapp->isRestored() )
        newNote();

    updateNoteActions();
}

void KNotesApp::resizeTrayIcon ()
{
	// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes
	TQPixmap origpixmap;
	TQPixmap scaledpixmap;
	TQImage newIcon;
	origpixmap = KSystemTray::loadSizedIcon( "knotes", TQWidget::width() );
	newIcon = origpixmap;
	newIcon = newIcon.smoothScale(TQWidget::width(), TQWidget::height());
	scaledpixmap = newIcon;
	setPixmap(scaledpixmap);
}

void KNotesApp::resizeEvent ( TQResizeEvent * )
{
	// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes
	resizeTrayIcon();
}

void KNotesApp::showEvent ( TQShowEvent * )
{
	// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes
	resizeTrayIcon();
}

KNotesApp::~KNotesApp()
{
    saveNotes();

    blockSignals( true );
    m_noteList.clear();
    blockSignals( false );

    delete m_listener;
    delete m_manager;
    delete m_guiBuilder;
}

bool KNotesApp::commitData( TQSessionManager& )
{
    saveConfigs();
    return true;
}

// -------------------- public DCOP interface -------------------- //

TQString KNotesApp::newNote( const TQString& name, const TQString& text )
{
    // create the new note
    KCal::Journal *journal = new KCal::Journal();

    // new notes have the current date/time as title if none was given
    if ( !name.isEmpty() )
        journal->setSummary( name );
    else
        journal->setSummary( TDEGlobal::locale()->formatDateTime( TQDateTime::currentDateTime() ) );

    // the body of the note
    journal->setDescription( text );

    if ( m_manager->addNewNote( journal ) ) {
        showNote( journal->uid() );
    }
    return journal->uid();
}

TQString KNotesApp::newNoteFromClipboard( const TQString& name )
{
    const TQString& text = TDEApplication::clipboard()->text();
    return newNote( name, text );
}

void KNotesApp::hideAllNotes() const
{
    TQDictIterator<KNote> it( m_noteList );
    for ( ; *it; ++it )
        (*it)->close();
}

void KNotesApp::showAllNotes() const
{
    TQDictIterator<KNote> it( m_noteList );
    for ( ; *it; ++it )
    {
        (*it)->show();
    }
}

void KNotesApp::showNote( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        showNote( note );
    else
        kdWarning(5500) << "showNote: no note with id: " << id << endl;
}

void KNotesApp::hideNote( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        note->hide();
    else
        kdWarning(5500) << "hideNote: no note with id: " << id << endl;
}

void KNotesApp::killNote( const TQString& id, bool force )
{
    KNote* note = m_noteList[id];
    if ( note )
        note->slotKill( force );
    else
        kdWarning(5500) << "killNote: no note with id: " << id << endl;
}

// "bool force = false" doesn't work with dcop
void KNotesApp::killNote( const TQString& id )
{
    killNote( id, false );
}

TQMap<TQString,TQString> KNotesApp::notes() const
{
    TQMap<TQString,TQString> notes;
    TQDictIterator<KNote> it( m_noteList );

    for ( ; it.current(); ++it )
        notes.insert( it.current()->noteId(), it.current()->name() );

    return notes;
}

TQString KNotesApp::name( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->name();
    else
        return TQString();
}

TQString KNotesApp::text( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->text();
    else
        return TQString();
}

void KNotesApp::setName( const TQString& id, const TQString& newName )
{
    KNote* note = m_noteList[id];
    if ( note )
        note->setName( newName );
    else
        kdWarning(5500) << "setName: no note with id: " << id << endl;
}

void KNotesApp::setText( const TQString& id, const TQString& newText )
{
    KNote* note = m_noteList[id];
    if ( note )
        note->setText( newText );
    else
        kdWarning(5500) << "setText: no note with id: " << id << endl;
}

TQString KNotesApp::fgColor( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->fgColor().name();
    else
        return TQString();
}

TQString KNotesApp::bgColor( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->bgColor().name();
    else
        return TQString();
}

void KNotesApp::setColor( const TQString& id, const TQString& fgColor, const TQString& bgColor )
{
    KNote* note = m_noteList[id];
    if ( note )
        note->setColor( TQColor( fgColor ), TQColor( bgColor ) );
    else
        kdWarning(5500) << "setColor: no note with id: " << id << endl;
}

int KNotesApp::width( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->width();
    else
        return 0;
}

int KNotesApp::height( const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->height();
    else
        return 0;
}

void KNotesApp::move( const TQString& id, int x, int y ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->move( x, y );
    else
        kdWarning(5500) << "move: no note with id: " << id << endl;
}

void KNotesApp::resize( const TQString& id, int width, int height ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->resize( width, height );
    else
        kdWarning(5500) << "resize: no note with id: " << id << endl;
}

void KNotesApp::sync( const TQString& app )
{
    TQDictIterator<KNote> it( m_noteList );

    for ( ; it.current(); ++it )
        it.current()->sync( app );
}

bool KNotesApp::isNew( const TQString& app, const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->isNew( app );
    else
        return false;
}

bool KNotesApp::isModified( const TQString& app, const TQString& id ) const
{
    KNote* note = m_noteList[id];
    if ( note )
        return note->isModified( app );
    else
        return false;
}


// ------------------- protected methods ------------------- //

void KNotesApp::mousePressEvent( TQMouseEvent* e )
{
    if ( !rect().contains( e->pos() ) )
        return;

    switch ( e->button() )
    {
    case Qt::LeftButton:
        if ( m_noteList.count() == 1 )
        {
            TQDictIterator<KNote> it( m_noteList );
            showNote( it.toFirst() );
        }
        else if ( m_note_menu->count() > 0 )
            m_note_menu->popup( e->globalPos() );
        break;
    case Qt::MidButton:
        newNote();
        break;
    case Qt::RightButton:
        m_context_menu->popup( e->globalPos() );
    default: break;
    }
}

// -------------------- protected slots -------------------- //

void KNotesApp::slotShowNote()
{
    // tell the WM to give this note focus
    showNote( TQString::fromUtf8( TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->name() ) );
}

void KNotesApp::slotWalkThroughNotes()
{
    // show next note
    TQDictIterator<KNote> it( m_noteList );
    KNote *first = it.toFirst();
    for ( ; *it; ++it )
        if ( (*it)->hasFocus() )
        {
            if ( ++it )
                showNote( *it );
            else
                showNote( first );
            break;
        }
}

void KNotesApp::slotOpenFindDialog()
{
    KFindDialog findDia( this, "find_dialog" );
    findDia.setHasSelection( false );
    findDia.setHasCursor( false );
    findDia.setSupportsBackwardsFind( false );

    if ( (findDia.exec() != TQDialog::Accepted) || findDia.pattern().isEmpty() )
        return;

    delete m_findPos;
    m_findPos = new TQDictIterator<KNote>( m_noteList );

    // this could be in an own method if searching without a dialog should be possible
    delete m_find;
    m_find = new KFind( findDia.pattern(), findDia.options(), this );

    slotFindNext();
}

void KNotesApp::slotFindNext()
{
    if ( **m_findPos )
    {
        KNote *note = **m_findPos;
        ++*m_findPos;
        note->find( m_find->pattern(), m_find->options() );
    }
    else
    {
        m_find->displayFinalDialog();
        delete m_find;
        m_find = 0;
        delete m_findPos;
        m_findPos = 0;
    }
}

void KNotesApp::slotPreferences()
{
    // reuse the dialog if possible
    if ( KNoteConfigDlg::showDialog( "KNotes Default Settings" ) )
        return;

    // create a new preferences dialog...
    KNoteConfigDlg *dialog = new KNoteConfigDlg( 0, i18n("Settings"), this,
                                                 "KNotes Settings" );
    connect( dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(this), TQT_SLOT(updateNetworkListener()) );
    connect( dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(this), TQT_SLOT(updateStyle()) );
    dialog->show();
}

void KNotesApp::slotConfigureAccels()
{
    KNotesKeyDialog keys( m_globalAccel, this );
    TQDictIterator<KNote> notes( m_noteList );
    if ( !m_noteList.isEmpty() )
        keys.insert( (*notes)->actionCollection() );
    keys.configure();

    m_globalAccel->writeSettings();
    updateGlobalAccels();

    // update GUI doc for new notes
    m_noteGUI.setContent(
        KXMLGUIFactory::readConfigFile( instance()->instanceName() + "ui.rc", instance() )
    );

    if ( m_noteList.isEmpty() )
        return;

    notes.toFirst();
    TQValueList<TDEAction *> list = (*notes)->actionCollection()->actions();
    for ( TQValueList<TDEAction *>::iterator it = list.begin(); it != list.end(); ++it )
    {
        notes.toFirst();
        for ( ++notes; *notes; ++notes )
        {
            TDEAction *toChange = (*notes)->actionCollection()->action( (*it)->name() );
            if ( toChange->shortcut() != (*it)->shortcut() )
                toChange->setShortcut( (*it)->shortcut() );
        }
    }
}

void KNotesApp::slotNoteKilled( KCal::Journal *journal )
{
    m_noteUidModify="";
    m_manager->deleteNote( journal );
    saveNotes();
}

void KNotesApp::slotQuit()
{
    TQDictIterator<KNote> it( m_noteList );

    for ( ; *it; ++it )
        if ( (*it)->isModified() )
            (*it)->saveData(false);

    saveConfigs();
    kapp->quit();
}


// -------------------- private methods -------------------- //

void KNotesApp::showNote( KNote* note ) const
{
    note->show();
    KWin::setCurrentDesktop( KWin::windowInfo( note->winId() ).desktop() );
    KWin::forceActiveWindow( note->winId() );
    note->setFocus();
}

void KNotesApp::createNote( KCal::Journal *journal )
{
  if( journal->uid() == m_noteUidModify)
  {
         KNote *note = m_noteList[m_noteUidModify];
         if ( note )
                 note->changeJournal(journal);

         return;
  }
  m_noteUidModify = journal->uid();
    KNote *newNote = new KNote( m_noteGUI, journal, 0, journal->uid().utf8() );
    m_noteList.insert( newNote->noteId(), newNote );

    connect( newNote, TQT_SIGNAL(sigRequestNewNote()), TQT_SLOT(newNote()) );
    connect( newNote, TQT_SIGNAL(sigShowNextNote()), TQT_SLOT(slotWalkThroughNotes()) );
    connect( newNote, TQT_SIGNAL(sigKillNote( KCal::Journal* )),
                        TQT_SLOT(slotNoteKilled( KCal::Journal* )) );
    connect( newNote, TQT_SIGNAL(sigNameChanged()), TQT_SLOT(updateNoteActions()) );
    connect( newNote, TQT_SIGNAL(sigDataChanged(const TQString &)), TQT_SLOT(saveNotes(const TQString &)) );
    connect( newNote, TQT_SIGNAL(sigColorChanged()), TQT_SLOT(updateNoteActions()) );
    connect( newNote, TQT_SIGNAL(sigFindFinished()), TQT_SLOT(slotFindNext()) );

    // don't call this during startup for each and every loaded note
    if ( m_alarm )
        updateNoteActions();
}

void KNotesApp::killNote( KCal::Journal *journal )
{
  if(m_noteUidModify == journal->uid())
  {
         return;
  }
    // this kills the KNote object
    KNote *note = m_noteList.take( journal->uid() );
    if ( note )
    {
        note->deleteWhenIdle();
        updateNoteActions();
    }
}

void KNotesApp::acceptConnection()
{
    // Accept the connection and make KNotesNetworkReceiver do the job
    TDEBufferedSocket *s = static_cast<TDEBufferedSocket *>(m_listener->accept());
    if ( s )
    {
        KNotesNetworkReceiver *recv = new KNotesNetworkReceiver( s );
        connect( recv, TQT_SIGNAL(sigNoteReceived( const TQString &, const TQString & )),
                 TQT_TQOBJECT(this), TQT_SLOT(newNote( const TQString &, const TQString & )) );
    }
}

void KNotesApp::saveNotes( const TQString & uid )
{
  m_noteUidModify = uid;
  saveNotes();
}

void KNotesApp::saveNotes()
{
    KNotesGlobalConfig::writeConfig();
    m_manager->save();
}

void KNotesApp::saveConfigs()
{
    TQDictIterator<KNote> it( m_noteList );
    for ( ; it.current(); ++it )
        it.current()->saveConfig();
}

void KNotesApp::updateNoteActions()
{
    unplugActionList( "notes" );
    m_noteActions.clear();

    for ( TQDictIterator<KNote> it( m_noteList ); it.current(); ++it )
    {
        TDEAction *action = new TDEAction( it.current()->name().replace("&", "&&"),
                                       TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotShowNote()),
                                       (TQObject *)0,
                                       it.current()->noteId().utf8() );
        TDEIconEffect effect;
        TQPixmap icon = effect.apply( kapp->miniIcon(), TDEIconEffect::Colorize, 1,
                                     it.current()->paletteBackgroundColor(), false );
        action->setIconSet( icon );
        m_noteActions.append( action );
    }

    if ( m_noteActions.isEmpty() )
    {
        actionCollection()->action( "hide_all_notes" )->setEnabled( false );
        actionCollection()->action( "show_all_notes" )->setEnabled( false );
        m_findAction->setEnabled( false );
        TDEAction *action = new TDEAction( i18n("No Notes") );
        m_noteActions.append( action );
    }
    else
    {
        actionCollection()->action( "hide_all_notes" )->setEnabled( true );
        actionCollection()->action( "show_all_notes" )->setEnabled( true );
        m_findAction->setEnabled( true );
        m_noteActions.sort();
    }
    plugActionList( "notes", m_noteActions );
}

void KNotesApp::updateGlobalAccels()
{
    if ( m_globalAccel->isEnabled() )
    {
        TDEAction *action = actionCollection()->action( "new_note" );
        if ( action )
            action->setShortcut( m_globalAccel->shortcut( "global_new_note" ) );
        action = actionCollection()->action( "new_note_clipboard" );
        if ( action )
            action->setShortcut( m_globalAccel->shortcut( "global_new_note_clipboard" ) );
        action = actionCollection()->action( "hide_all_notes" );
        if ( action )
            action->setShortcut( m_globalAccel->shortcut( "global_hide_all_notes" ) );
        action = actionCollection()->action( "show_all_notes" );
        if ( action )
            action->setShortcut( m_globalAccel->shortcut( "global_show_all_notes" ) );

        m_globalAccel->updateConnections();
    }
    else
    {
        TDEAction *action = actionCollection()->action( "new_note" );
        if ( action )
            action->setShortcut( 0 );
        action = actionCollection()->action( "new_note_clipboard" );
        if ( action )
            action->setShortcut( 0 );
        action = actionCollection()->action( "hide_all_notes" );
        if ( action )
            action->setShortcut( 0 );
        action = actionCollection()->action( "show_all_notes" );
        if ( action )
            action->setShortcut( 0 );
    }
}

void KNotesApp::updateNetworkListener()
{
    m_listener->close();

    if ( KNotesGlobalConfig::receiveNotes() )
    {
        m_listener->setAddress( TQString::number( KNotesGlobalConfig::port() ) );
        m_listener->bind();
        m_listener->listen();
    }
}

void KNotesApp::updateStyle()
{
    KNote::setStyle( KNotesGlobalConfig::style() );

    TQDictIterator<KNote> it( m_noteList );
    for ( ; it.current(); ++it )
        TQApplication::postEvent( *it, new TQEvent( TQEvent::LayoutHint ) );
}

#include "knotesapp.moc"