/***************************************************************************
                          kbearsitemanagerplugin.cpp  -  description
                             -------------------
    begin                : sön mar 17 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qlayout.h>
#include <qiconset.h>
#include <qcheckbox.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kio/slaveconfig.h>
#include <kprotocolinfo.h>
#include <kparts/part.h>
#include <kparts/dockmainwindow.h>
#include <kparts/browserextension.h>
#include <kservice.h>
#include <ktrader.h>
#include <kapplication.h>
#include <kmainwindow.h>
#include <kpopupmenu.h>
#include <dcopclient.h>
#include <dcopref.h>
#include <kinstance.h>
#include <kgenericfactory.h>
#include <klineedit.h>
#include <kcharsets.h>
#include <kcombobox.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <krun.h>
#include <klocale.h>
#include <kconfig.h>
#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearsitemanagerplugin.h"
#include "kbearsitemanager.h"
#include "kbearsitemanagertreeview.h"
#include "kbearsiteimportfilterpluginiface.h"
#include "siteimportwidget.h"
#include "siteinfo.h"
#include "kbearapi.h"
#include "kbearmainwiniface.h"
#include "kbearcore.h"
#include "kbeartags.h"
#include "misc.h"
#include "group.h"

using namespace KBear;
//-----------------------------------------------
typedef KGenericFactory<KBearSiteManagerPlugin> KBearSiteManagerPluginFactory;
K_EXPORT_COMPONENT_FACTORY( kbearsitemanager, KBearSiteManagerPluginFactory( "kbearsitemanager" ) );
//-----------------------------------------------
KBearSiteManagerPlugin::KBearSiteManagerPlugin(QObject* parent, const char* , const QStringList& )
	:	KBear::KBearPlugin( parent, "KBearSiteManagerPlugin" ),
		DCOPObject("KBearSiteManagerInterface"),
		m_DB_DCOP_Name("kbearsitemanagerdb"),
		m_DB_DCOP_ID("SiteManagerDBInterface"),
		m_idleTimer( this ), m_hasSelectedSite( false ),
		m_pendingSelectedSite( 0L )
{
	KRun::run( "kbearsitemanagerdb", KURL::List() );
	(void) KGlobal::locale()->insertCatalogue("kbear");
	setInstance( KBearSiteManagerPluginFactory::instance() );

	m_privateActionCollection = new KActionCollection( 0L, this, "PrivateActionCollection"/*, instance*/ );
	KMainWindow* mainWin = dynamic_cast<KMainWindow*>(kapp->mainWidget());
	if( mainWin ) {
		connect( actionCollection(), SIGNAL( actionStatusText(const QString &) ), mainWin->statusBar(), SLOT( message(const QString &) ) );
		connect( actionCollection(), SIGNAL( clearStatusText() ), mainWin->statusBar(), SLOT( clear() ) );
	}
	m_siteManager = new KBearSiteManager( kapp->mainWidget(), "SiteManager" );

	m_kbearMode = (m_api != 0L);

	setXMLFile("kbearsitemanagerui.rc");
	setupActions();
	setupConnections();
	QByteArray data;
	QCString tmp1;
	// First see if sitemanager daemon is registered, if not wait until it is.
	if( kapp->dcopClient()->findObject(m_DB_DCOP_Name, m_DB_DCOP_ID, "ping()", data, tmp1, tmp1, true) )
	{
		slotInitialize();
	}
	else
		kdDebug()<<"KBearSiteManagerPlugin kbearsitemanagerdb not registered, will initialize later !!!!!!"<<endl;

	connect( &m_idleTimer, SIGNAL( timeout() ), this, SLOT( slotIdleTimeout() ) );
}
//-----------------------------------------------
KBearSiteManagerPlugin::~KBearSiteManagerPlugin(){
	QByteArray data;
	if( ! kapp->dcopClient()->send(m_DB_DCOP_Name, m_DB_DCOP_ID, "unregReferer()", data ) )
		kdDebug()<<"DCOP call unregReferer() failed !!!!"<<endl;
	
	m_idleTimer.stop();
	if( m_pendingSelectedSite )
		delete m_pendingSelectedSite;
	delete m_privateActionCollection;
	delete m_siteManager;
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotImportOldSitemanager( QString fileName ) {
	QValueList<KService::Ptr> pluginList = m_siteManager->m_importWidget->pluginList();
	KTrader::OfferList::Iterator it( pluginList.begin() );
	for( ; it != pluginList.end(); ++it ) {
		KService::Ptr ptr = (*it);
		if( ptr->property( "X-KBear-OldSiteManager" ).toBool() ) {
			SiteImportFilterPluginIface* plugin = static_cast<SiteImportFilterPluginIface*>( KParts::Plugin::loadPlugin( this, ptr->library().latin1() ) );
			m_siteManager->m_importWidget->startImport( plugin, fileName );
		}
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::setupActions() {
	m_siteManagerMenu = new KActionMenu( i18n("S&itemanager"), actionCollection(), "kbearsitemanager_menu");
	KAction* action = KStdAction::redisplay( this, SLOT( slotUpdate() ), actionCollection(), KStdAction::name(KStdAction::Redisplay) );
	action->setText( i18n("&Reload"));
	action->setToolTip( i18n("Reload from database") );
	m_siteManagerAction = new KAction( i18n("&KBear Sitemanager"), "kbearsitemanager", CTRL+SHIFT+Key_O, this, SLOT( slotOpenSiteManager() ), actionCollection(), "kbearsitemanager" );
	m_siteManagerAction->setToolTip( i18n("Open the Sitemanager") );

	KStdAction::addBookmark( this, SLOT( slotAddBookmark() ), actionCollection(), "add_bookmark" );
	action = new KAction( i18n("&New Group"), "folder_new", 0, this, SLOT(slotAddGroup()), actionCollection(), "new_group" );

	m_siteManagerMenu->insert( actionCollection()->action( KStdAction::name(KStdAction::Redisplay) ) );
	m_siteManagerMenu->insert( actionCollection()->action( "kbearsitemanager" ) );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotIdleTimeout() {
	QByteArray data;
	QCString tmp1;
	if( ! kapp->dcopClient()->findObject(m_DB_DCOP_Name, m_DB_DCOP_ID,"ping()", data, tmp1, tmp1 ) )
	{
		if( m_hasSelectedSite ) {
			m_pendingSelectedSite = new SiteInfo;
			*m_pendingSelectedSite = m_siteManager->getCurrentSite();
		}
		KRun::run( "kbearsitemanagerdb",KURL::List() );
		connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "initialize()", "slotInit()", false );
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotInitialize() {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	if( !kapp->dcopClient()->send(m_DB_DCOP_Name, m_DB_DCOP_ID, "regReferer()", data ) )
		kdDebug()<<"DCOP call regReferer() failed !!!!"<<endl;
	disconnectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "initialize()", "slotInitialize()" );

	kdDebug()<<"DCOP Database found name="<<m_DB_DCOP_Name<<" ID="<<m_DB_DCOP_ID<<endl;
	
	slotUpdate();

	if( m_pendingSelectedSite && m_hasSelectedSite ) {
		slotSiteSelected( *m_pendingSelectedSite );
		delete m_pendingSelectedSite;
		m_pendingSelectedSite = 0L;
	}
	KConfig config( "kbearsitemanagerrc" );
//	setShowSystemTray( config.readBoolEntry( "ShowSysemTrayIcon", true ) );
	setPlugInKonq( config.readBoolEntry( "PlugInKonq", false ) );
	

	// this will check every 5 second if sitemanager database is up and running
	// if not it will restart it
	m_idleTimer.start( 5000 );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotInit() {
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotUpdate() {
	QApplication::setOverrideCursor( waitCursor );
	QByteArray data, replyData;
	QDataStream arg( data, IO_WriteOnly );
	QCString replyType;
	if( m_hasSelectedSite ) {
		m_pendingSelectedSite = new SiteInfo;
		*m_pendingSelectedSite = m_siteManager->getCurrentSite();
	}
	if( kapp->dcopClient()->call(m_DB_DCOP_Name, m_DB_DCOP_ID, "getSiteDataBase()", data, replyType, replyData, true ) ) {
		QDataStream answer( replyData, IO_ReadOnly );
		QString XMLDataBase;
		answer >> XMLDataBase;
		m_siteManager->siteTreeView->clear();
		parseDatabase( XMLDataBase );
		if( m_pendingSelectedSite && m_hasSelectedSite ) {
			slotSiteSelected( *m_pendingSelectedSite );
			delete m_pendingSelectedSite;
			m_pendingSelectedSite = 0L;
		}
	}
	else {
		kdDebug()<<"DCOP call getSiteDataBase() failed !!!!"<<endl;
		slotIdleTimeout();
		QTimer::singleShot( 1000, this, SLOT( slotUpdate() ) );
	}
	QApplication::restoreOverrideCursor();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::setupConnections() {
	//DCOP connections
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "initialize()", "slotInitialize()", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "updateDatabase(QString)", "slotUpdateDatabase(QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "newSite(SiteInfo)", "slotNewSite(SiteInfo)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "siteChanged(SiteInfo,QString)", "slotSiteChanged(SiteInfo,QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "siteRemoved(SiteInfo)", "slotSiteRemoved(SiteInfo)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "siteMoved(SiteInfo,QString,QString)", "slotSiteMoved(SiteInfo,QString,QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "newGroup(Group)", "slotNewGroup(Group)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "groupChanged(Group,QString)", "slotGroupChanged(Group,QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "groupRemoved(Group)", "slotGroupRemoved(Group)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "groupMoved(Group,QString)", "slotGroupMoved(Group,QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "newEncoding(QString)", "slotEncodingChanged(QString)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "importOldSitemanager(QString)", "slotImportOldSitemanager(QString)", false );
//	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "showSystemTray(bool)", "setShowSystemTray(bool)", false );
	connectDCOPSignal( m_DB_DCOP_Name, m_DB_DCOP_ID, "plugInKonq(bool)", "setPlugInKonq(bool)", false );
	//Ordinary connections
//	connect( m_siteManager, SIGNAL( showSystemTray(bool) ),
//				this, SLOT( slotShowSystemTray( bool ) ) );
	connect( m_siteManager, SIGNAL( plugInKonq(bool) ),
				this, SLOT( slotPlugInKonq( bool ) ) );
	connect( m_siteManager, SIGNAL( importSites( const QString& ) ),
				this, SLOT( slotImportSites( const QString&) ) );
	connect( m_siteManager, SIGNAL( siteSelected( const SiteInfo& ) ),
				this, SLOT( slotSiteSelected( const SiteInfo& ) ) );
	connect( m_siteManager, SIGNAL( selectionCleared() ),
				this, SLOT( slotSelectionCleared() ) );
	connect( m_siteManager, SIGNAL( openConnection( const SiteInfo& ) ),
				this, SLOT( slotOpenConnection( const SiteInfo& ) ) );
	connect( m_siteManager, SIGNAL( newGroup( const Group& ) ),
				this, SLOT( slotAddGroup( const Group& ) ) );
	connect( m_siteManager, SIGNAL( moveSite( const SiteInfo&, const QString& ) ),
				this, SLOT( slotMoveSite( const SiteInfo&, const QString& ) ) );
	connect( m_siteManager, SIGNAL( moveGroup( const Group&, const QString& ) ),
				this, SLOT( slotMoveGroup( const Group&, const QString& ) ) );
	connect( m_siteManager, SIGNAL( changeGroup( const Group&, const QString& ) ),
				this, SLOT( slotChangeGroup( const Group&, const QString& ) ) );
	connect( m_siteManager, SIGNAL( changeSite( const SiteInfo&, const QString& ) ),
				this, SLOT( slotChangeSite( const SiteInfo&, const QString& ) ) );
	connect( m_siteManager, SIGNAL( newEncoding( const QString& ) ),
				this, SLOT( slotNewEncoding( const QString& ) ) );
	connect( m_siteManager, SIGNAL( saveSite( const SiteInfo& ) ),
				this, SLOT( slotSaveSite( const SiteInfo& ) ) );
	connect( m_siteManager, SIGNAL( removeSite( const SiteInfo& ) ),
				this, SLOT( slotRemoveSite( const SiteInfo& ) ) );
	connect( m_siteManager, SIGNAL( update() ), this, SLOT( slotUpdate() ) );
	connect( m_siteManager, SIGNAL( removeGroup( const Group& ) ),
				this, SLOT( slotRemoveGroup( const Group& ) ) );
	// connect so sitemanager menu is displayed in systray menu
	if( m_kbearMode )
		connect( m_api->core(), SIGNAL( systemTrayMenuNeeded( KPopupMenu* ) ), this, SLOT( slotSystemTrayMenuNeeded( KPopupMenu* ) ) );
}
//-----------------------------------------------
/*
void KBearSiteManagerPlugin::setShowSystemTray(bool show) {
	kdDebug()<<"KBearSiteManagerPlugin::setShowSystemTray="<<show<<endl;
//	m_siteManager->p_showSystemTrayCheckBox->setChecked( show );
}
*/
//-----------------------------------------------
/*
void KBearSiteManagerPlugin::slotShowSystemTray(bool show) {
kdDebug()<<"KBearSiteManagerPlugin::slotShowSystemTray="<<show<<endl;
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << show;
	DCOPClient* client = kapp->dcopClient();
	if( ! client->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "showSystemTrayIcon(bool)", data ) ) {
		kdDebug()<<"DCOP send showSystemTrayIcon(bool) failed !!!!"<<endl;
		slotIdleTimeout();
	}
	KConfig config( "kbearsitemanagerrc" );
	config.writeEntry( "ShowSysemTrayIcon", show );
	config.sync();
}
*/
//-----------------------------------------------
void KBearSiteManagerPlugin::setPlugInKonq(bool plug) {
	m_siteManager->setPlugIntoKonq( plug );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotPlugInKonq(bool plug ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << plug;
	DCOPClient* client = kapp->dcopClient();
	if( ! client->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "setPlugInKonq(bool)", data ) ) {
		kdDebug()<<"DCOP send setPlugInKonq(bool) failed !!!!"<<endl;
		slotIdleTimeout();
	}
	KConfig config( "kbearsitemanagerrc" );
	config.writeEntry( "PlugInKonq", plug );
	config.sync();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotOpenConnection( const SiteInfo& site ) {
	if( m_kbearMode ) {
		m_api->core()->openSite( site );
	}
	else { // we're not plugged into KBear, probably konqueror
		KIO::MetaData metaData;
		metaData.insert( "EnableLog", site.enableLog()?"true":"false" );
		metaData.insert( "DisablePassiveMode", site.passiveMode()?"false":"true" );
		metaData.insert( "DisableEPSV", site.extendedPassiveMode()?"false":"true" );
		metaData.insert( "ListCommand", site.listCommand() );
		metaData.insert( "MarkPartial", site.markPartial()?"true":"false" );
		metaData.insert( "FileSysEncoding", site.fileSysEncoding() );
		SiteInfo s =(SiteInfo)site;
		KIO::SlaveConfig::self()->reset();
		KIO::SlaveConfig::self()->setConfigData( s.protocol(), s.host(), metaData );

		KParts::BrowserExtension* extension = KParts::BrowserExtension::childObject( parent() );
		if( extension ) {
			KParts::URLArgs args;
			args.metaData() = metaData;
			args.reload = true;
			emit extension->openURLRequest( s.url(), args );
		}
		else
			static_cast<KParts::ReadOnlyPart*>(parent())->openURL( s.url() );
	}
//	slotAddToRecent( site );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSelectionCleared() {
	m_hasSelectedSite = false;
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSiteSelected( const SiteInfo& site ) {
	if( !site.label().isNull() ) {
		QByteArray data, replyData;
		QDataStream arg( data, IO_WriteOnly );
		QCString replyType;
		arg << site;
		if( kapp->dcopClient()->call(m_DB_DCOP_Name, m_DB_DCOP_ID, "getSite(SiteInfo)", data, replyType, replyData, true ) ) {
			QDataStream answer( replyData, IO_ReadOnly );
			SiteInfo s;
			answer >> s;
			m_siteManager->setSite( s );
			m_hasSelectedSite = true;
		}
		else {
			kdDebug()<<"DCOP call getSite(SiteInfo) failed !!!!"<<endl;
			slotIdleTimeout();
		}
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotImportSites( const QString& sites) {
	QByteArray data;
	QDataStream stream( data, IO_WriteOnly );
	stream << sites;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID,"importDomDocument(QString)", data ) ) {
		kdDebug()<<"DCOP call importDomDocument(QString) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotUpdateDatabase( QString domTree ) {
	parseDatabase( domTree );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::parseDatabase( const QString& XMLString ) {
	m_siteManager->siteTreeView->clear();
	m_siteManagerMenu->popupMenu()->clear();
	m_privateActionCollection->clear();
	m_actionSeparator = new KActionSeparator( m_privateActionCollection, "separator" );
	QDomDocument document;
	document.setContent( XMLString );
	QString encoding = document.documentElement().attribute( ATT_ENCODING );
	for( int i = 0; i < m_siteManager->m_encodingComboBox->count(); i++ ) {
		QString tmp = KGlobal::charsets()->encodingForName( m_siteManager->m_encodingComboBox->text( i ) );
		if( tmp == encoding )
			m_siteManager->m_encodingComboBox->setCurrentItem( i );
	}
	m_siteManagerMenu->insert( m_siteManagerAction );
	m_siteManagerMenu->insert( m_actionSeparator );
	m_siteManagerMenu->insert( actionCollection()->action( KStdAction::name(KStdAction::Redisplay) ) );
	m_siteManagerMenu->insert( m_actionSeparator );
	m_siteManagerMenu->insert( actionCollection()->action( "add_bookmark" ) );
	m_siteManagerMenu->insert( actionCollection()->action( "new_group" ) );
	m_siteManagerMenu->insert( m_actionSeparator );
	buildTree( document.documentElement(), 0L, m_siteManagerMenu );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::buildTree( QDomElement parentElement, QListViewItem* parentItem,  KActionMenu* parentMenu ) {
	static QString parentStr = QString::null;
	QListViewItem* item = 0L;
	KActionMenu* menu = 0L;
	KAction* action = 0L;
	QDomNode node = parentElement.firstChild();

	if( parentElement !=  parentElement.ownerDocument().documentElement() ) {
		action = new KAction( i18n("&Add Bookmark"), QIconSet(BarIcon("bookmark_add")), 0, this, SLOT(slotAddBookmark()), m_privateActionCollection, QString("addbookmark_"+parentStr).utf8() );
		parentMenu->insert( action );
		action = new KAction( i18n("&New Group"), QIconSet(BarIcon("folder_new")), 0, this, SLOT(slotAddGroup()), m_privateActionCollection, QString("new_group"+parentStr).utf8() );
		parentMenu->insert( action );
		parentMenu->insert( m_actionSeparator );
	}
	while( ! node.isNull() ) {
		QString name;
		if( node.toElement().tagName() == TAG_GROUP ) {
			name = node.toElement().attribute( ATT_LABEL );
			item = m_siteManager->siteTreeView->findItemByName( parentItem, name );
			if( ! item ) {
				item = m_siteManager->siteTreeView->addGroup( parentItem, name );
			}
			parentStr = parentStr + "/" + name;
			menu = new KActionMenu( name, "bookmark_folder", m_privateActionCollection, parentStr.utf8() );
			parentMenu->insert( menu );
			// recursive build of the tree
			buildTree( node.toElement(), item, menu );
		}
		else if( node.toElement().tagName()  == TAG_SITE ) {
			name = node.toElement().attribute( ATT_LABEL );
			item = m_siteManager->siteTreeView->findItemByName( parentItem, name );
			if( ! item ) {
				item = m_siteManager->siteTreeView->addSite( parentItem, name );
			}
			QString fullName = parentStr + "/" + name;
			action = new KAction( name, "ftp", 0, this, SLOT( slotBookmarkActivated() ), m_privateActionCollection, fullName.utf8() );
			action->setToolTip( i18n("Open the site %1").arg( name ) );
			parentMenu->insert( action );
		}
		node = node.nextSibling();
	}
	int length = parentStr.length() - parentElement.attribute(ATT_LABEL).length() -1;
	parentStr = parentStr.left( length >= 0 ? length : 0 );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotAddGroup( const Group& group ) {
	// now we're done so lets save the bookmark
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << group;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "saveGroup(Group)", data ) ) {
		kdDebug()<<"DCOP call saveGroup(Group) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotChangeGroup( const Group& group, const QString& oldName ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << group << oldName;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "changeGroup(Group,QString)", data ) ) {
		kdDebug()<<"DCOP call changeGroup(Group,String) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotChangeSite( const SiteInfo& site, const QString& oldName ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << site << oldName;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "changeSite(SiteInfo,QString)", data ) ) {
		kdDebug()<<"DCOP call changeSite(SiteInfo,String) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotAddGroup() {
	QString senderName =  QString::fromUtf8( QObject::sender()->name() );
	QString name = m_siteManager->promptForGroupName();
	if( name.isNull() )
		return;
	Group group;
	group.setLabel( name );
	if( senderName == "new_group" ) {
		group.setParent( QString::null );
	}
	else {
		senderName = senderName.right( senderName.length() - 9 ); // minus length of "new_group"
		group.setParent( senderName );
	}
	slotAddGroup( group );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotAddBookmark() {
	QString senderName( QObject::sender()->name() );
	SiteInfo site;
	QByteArray data, replyData;
	QCString replyType;
	DCOPClient* client = kapp->dcopClient();
	if( client->call( client->appId(), client->defaultObject(), "currentMdiChildView()", data, replyType, replyData, true ) ) {
		DCOPRef ref;
		QDataStream answer( replyData, IO_ReadOnly );
		answer >> ref;
		if( client->call( ref.app(), ref.object(), "siteInfo()", data, replyType, replyData, true ) ) {
			SiteInfo c;
			QDataStream answer( replyData, IO_ReadOnly );
			answer >> c;
			site = SiteInfo( c );
		}
		else {
			kdDebug()<<"DCOP call currentURL() failed !!!!"<<endl;
			slotIdleTimeout();
			return;
		}
	}
	else {
		kdDebug()<<"DCOP call currentMdiChildView() failed !!!!"<<endl;
		slotIdleTimeout();
		return;
	}
	if( senderName == "add_bookmark" ) {
		site.setParent( QString::null );
	}
	else {
		senderName = senderName.right( senderName.length() - 12 ); // minus length of "addbookmark_"
		site.setParent( senderName );
	}

	// now we're done so lets save the bookmark
	QDataStream arg( data, IO_WriteOnly );
	arg << site;
	if( ! client->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "saveSite(SiteInfo)", data ) ) {
		kdDebug()<<"DCOP call saveSite(SiteInfo) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSaveSite( const SiteInfo& site ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << site;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "saveSite(SiteInfo)", data ) ) {
		kdDebug()<<"DCOP call saveSite(SiteInfo) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotBookmarkActivated() {
	QString fullName = QString::fromUtf8( QObject::sender()->name() );
	QStringList list = QStringList::split( "/", fullName );
	SiteInfo site;
	site.setLabel( list.last() );
	site.setParent( fullName.left( fullName.length() - site.label().length() - 1 ) );
	QByteArray data, replyData;
	QDataStream arg( data, IO_WriteOnly );
	QCString replyType;
	arg << site;
	if( kapp->dcopClient()->call(m_DB_DCOP_Name, m_DB_DCOP_ID, "getSite(SiteInfo)", data, replyType, replyData, true ) ) {
		QDataStream answer( replyData, IO_ReadOnly );
		SiteInfo s;
		answer >> s;
		if( s.protocol() == "ftp" && m_siteManager->hasKBearFTP() )
			s.setProtocol( "kbearftp" );
		s.setPass( decodePassword( s.pass() ) );
		slotOpenConnection( s );
	}
	else {
		kdDebug()<<"DCOP call getSite(SiteInfo) failed in slotBookmarkActivated !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotMoveSite( const SiteInfo& site, const QString& newParent ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << site << newParent;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "moveSite(SiteInfo,QString)", data ) ) {
		kdDebug()<<"DCOP call moveSite(SiteInfo,QString) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotMoveGroup( const Group& group, const QString& newParent ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << group << newParent;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "moveGroup(Group,QString)", data ) ){
		kdDebug()<<"DCOP call moveGroup(Group,QString) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotNewSite( SiteInfo site ) {
	QListViewItem* parent = m_siteManager->siteTreeView->findParentByFullName( site.parent() );
	QListViewItem* siteItem = m_siteManager->siteTreeView->addSite( parent, site.label() );
	if( m_siteManager->siteTreeView->selectedItem()
		&& site.parent() == m_siteManager->siteTreeView->getFullPath(m_siteManager->siteTreeView->selectedItem() )
		&& site.label() == m_siteManager->m_siteEdit->text() )
	{
		m_siteManager->siteTreeView->setSelected( siteItem, true );
	}

	KActionMenu* menu;
	if( ! parent )
		menu = m_siteManagerMenu;
	else
		menu = static_cast<KActionMenu*>(m_privateActionCollection->action( site.parent().latin1() ) );
	QString fullName = site.parent() + QString::fromLatin1("/") + site.label();
	KAction* action = new KAction( site.label(), QString::fromLatin1("ftp"), 0, this, SLOT( slotBookmarkActivated() ), m_privateActionCollection, fullName.utf8() );
	menu->insert( action );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSiteChanged( SiteInfo site, QString oldName ) {
	QListViewItem* parentItem = m_siteManager->siteTreeView->findParentByFullName( site.parent() );
	//First we look for oldName
	QListViewItem* item = m_siteManager->siteTreeView->findItemByName( parentItem, oldName );
	if( item ) { // the item was found
		item->setText( 0, site.label() );
	}
	else { // If we get here is the SiteInfo was renamed in this sitemanager
		item = m_siteManager->siteTreeView->findItemByName( parentItem, site.label() );
		kdDebug()<<"KBearSiteManagerPlugin::slotSiteChanged in sitemanager="<<(item?item->text(0):QString::null)<<endl;
	}
	if( item ) {
		if( item == m_siteManager->siteTreeView->selectedItem() ){ // is it the selected SiteInfo ?
			kdDebug()<<"KBearSiteManagerPlugin::slotSiteChanged selected item="<<item->text(0)<<endl;
			m_siteManager->slotSelectedSite( item );
		}
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSiteRemoved( SiteInfo site ) {
	QListViewItem* parent = m_siteManager->siteTreeView->findParentByFullName( site.parent() );
	QListViewItem* item = m_siteManager->siteTreeView->findItemByName( parent, site.label() );
	QListViewItem* newSelection = 0L;
	if( item ==  m_siteManager->siteTreeView->selectedItem() )
		newSelection = item->parent();
	if( item )
		delete item;
	if( newSelection )
		m_siteManager->siteTreeView->setSelected( newSelection, true );

	slotUpdate();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSiteMoved( SiteInfo site, QString oldParent, QString oldName ) {
	QListViewItem* oldParentItem = m_siteManager->siteTreeView->findParentByFullName( oldParent );
	QListViewItem* newParentItem = m_siteManager->siteTreeView->findParentByFullName( site.parent() );
	QListViewItem* siteItem = m_siteManager->siteTreeView->findItemByName( oldParentItem, oldName );
	siteItem->setText( 0, site.label() );
	m_siteManager->siteTreeView->moveItem( siteItem, newParentItem, newParentItem );

	slotUpdate();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotNewGroup( Group group ) {
	QListViewItem* parent = m_siteManager->siteTreeView->findParentByFullName( group.parent() );
	m_siteManager->siteTreeView->addGroup( parent, group.label() );

	KActionMenu* menu;
	if( ! parent )
		menu = m_siteManagerMenu;
	else
		menu = static_cast<KActionMenu*>(m_privateActionCollection->action( group.parent().latin1() ) );
	QString fullName = group.parent() + "/" + group.label();
	KActionMenu* newMenu = new KActionMenu( group.label(), QString::fromLatin1("bookmark_folder"), m_privateActionCollection, fullName.utf8() );
	KAction* action = KStdAction::addBookmark( this, SLOT( slotAddBookmark() ), m_privateActionCollection, "addbookmark_"+fullName.utf8() );
	action->setShortcut( KShortcut() );
	newMenu->insert( action );
	action = new KAction( i18n("&New Group"), QString::fromLatin1("folder_new"), 0, this, SLOT(slotAddGroup()), m_privateActionCollection, "new_group"+fullName.utf8() );
	newMenu->insert( action );
	newMenu->insert( m_actionSeparator );

	menu->insert( newMenu );
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotGroupChanged( Group group, QString oldName ) {
	QListViewItem* parentItem = m_siteManager->siteTreeView->findParentByFullName( group.parent() );
	// First look for old name
	QListViewItem* item = m_siteManager->siteTreeView->findItemByName( parentItem, oldName );
	if( item ) { // this is the case for all sitemanager except the one were the actual change was
		item->setText( 0, group.label() );
	}
	else  // this is the case for the sitemanager were the actual change was
		item = m_siteManager->siteTreeView->findItemByName( parentItem, group.label() );

	if( item ) { // we should have an item here, otherwise something is wrong
		if( item == m_siteManager->siteTreeView->selectedItem() ) {
			//if the changed item is the selected on we have to update the selection
			m_siteManager->slotSelectedSite( item );
		}
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotRemoveSite( const SiteInfo& site ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << site;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "removeSite(SiteInfo)", data ) ) {
		kdDebug()<<"DCOP call removeSite(SiteInfo) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotRemoveGroup( const Group& group ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << group;
	kdDebug()<<"KBearSiteManagerPlugin::slotRemoveGroup"<<endl;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "removeGroup(Group)", data ) ) {
		kdDebug()<<"DCOP call removeGroup(Group) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotGroupRemoved( Group group ) {
	kdDebug()<<"KBearSiteManagerPlugin::slotGroupRemoved"<<endl;
	QListViewItem* parent = m_siteManager->siteTreeView->findParentByFullName( group.parent() );
	QListViewItem* item = m_siteManager->siteTreeView->findItemByName( parent, group.label() );
	QListViewItem* newSelection = 0L;
	if( item ==  m_siteManager->siteTreeView->selectedItem() )
		newSelection = item->parent();
	if( item )
		delete item;
	if( newSelection )
		m_siteManager->siteTreeView->setSelected( newSelection, true );
		kdDebug()<<"KBearSiteManagerPlugin::slotGroupRemoved 22"<<endl;
	slotUpdate();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotGroupMoved( Group group, QString oldParent ) {
	QListViewItem* oldParentItem = m_siteManager->siteTreeView->findParentByFullName( oldParent );
	QListViewItem* newParentItem = m_siteManager->siteTreeView->findParentByFullName( group.parent() );
	QListViewItem* siteItem = m_siteManager->siteTreeView->findItemByName( oldParentItem, group.label() );
	m_siteManager->siteTreeView->moveItem( siteItem, newParentItem, newParentItem );

	slotUpdate();
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotEncodingChanged( QString encoding ) {
	for( int i = 0; i < m_siteManager->m_encodingComboBox->count(); i++ ) {
		QString tmp = KGlobal::charsets()->encodingForName( m_siteManager->m_encodingComboBox->text( i ) );
		if( tmp == encoding )
			m_siteManager->m_encodingComboBox->setCurrentItem( i );
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotNewEncoding( const QString& encoding ) {
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << encoding;
	if( ! kapp->dcopClient()->send( m_DB_DCOP_Name, m_DB_DCOP_ID, "setEncoding(QString)", data ) ) {
		kdDebug()<<"DCOP call setEncoding(QString) failed !!!!"<<endl;
		slotIdleTimeout();
	}
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotOpenSiteManager() {
	m_siteManager->adjustSize();
	m_siteManager->exec();
}
//-----------------------------------------------
QString KBearSiteManagerPlugin::unloadWarning() const {
	return i18n("If you unload the Sitemanager plugin you can't access the site database.");
}
//-----------------------------------------------
void KBearSiteManagerPlugin::slotSystemTrayMenuNeeded( KPopupMenu* menu )  {
	if( menu && m_siteManagerMenu )
		menu->insertItem( m_siteManagerMenu->text(), m_siteManagerMenu->popupMenu() );
}
//-----------------------------------------------

#ifndef NO_INCLUDE_MOCFILES
#include "kbearsitemanagerplugin.moc"
#endif
