/*********************************************************************************
* C++ Implementation: kbearfilesyspartiface.cpp
* Description:
*                              
* Begin : tis jan 18 2003
* Author : Björn Sahlström <kbjorn@users.sourceforge.net> (C) 2003
* Copyright : See COPYING file that comes with this distribution
**********************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qtextcodec.h>
#include <qtooltip.h>
#include <qpopupmenu.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qregexp.h>
#include <qwhatsthis.h>
#include <qlayout.h>
#include <qhbox.h>
#include <qlabel.h>
#include <qmime.h>
#include <qvbox.h>
#include <qtimer.h>
#include <kmessagebox.h>
#include <qclipboard.h>
#include <qfile.h>
#include <qguardedptr.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kparts/genericfactory.h>
#include <kparts/browserextension.h>
#include <kparts/componentfactory.h>
#include <kparts/partmanager.h>
#include <kfinddialog.h>
#include <klineedit.h>
#include <kconfig.h>
#include <ktempfile.h>
#include <kconfigbase.h>
#include <kservice.h>
#include <kuserprofile.h>
#include <kstandarddirs.h>
#include <kpopupmenu.h>
#include <kapplication.h>
#include <kaboutapplication.h>
#include <kiconloader.h>
#include <krun.h>
#include <klocale.h>
#include <kio/paste.h>
#include <kurldrag.h>
#include <kio/job.h>
#include <kfileview.h>
#include <kfileitem.h>
#include <kcharsets.h>
#include <kglobal.h>
#include <kinstance.h>
#include <kmainwindow.h>
#include <kstatusbar.h>
#include <ktoolbar.h>

#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// System specific include files
#include <unistd.h>
#include <X11/Xlib.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearfilesyspartiface.h"
#include "kbearapi.h"
#include "kbearcore.h"
#include "kbeardirview.h"
#include "transfermanager.h"
#include "kbeardirlisteriface.h"
#include "kbearmainwiniface.h"
#include "kbearfilecopyjob.h"
#include "misc.h"

#include "kbearfilesyspartiface.moc"

using namespace KBear;

//-----------------------------------------------
class KBearFileSysPartInterface::KBearFileSysPartInterfacePrivate {
	public:
		KBearFileSysPartInterfacePrivate()
			:	m_backStackIsBlocked( false ),
				m_numOfConnRetry( 0 ), m_connRetryTime( 0 ),
				m_isConnected( false ), m_findStr( QString::null ),
				m_lastFoundItem( 0L ), m_searchBackwards( false )
		{
			m_serviceActionList.setAutoDelete( true );
			m_backStack.setAutoDelete( true );
			m_forwardStack.setAutoDelete( true );
		}
		~KBearFileSysPartInterfacePrivate() {
			delete m_connectedTimer;
		}

		QDateTime m_myTime;
		QTimer* m_connectedTimer;
		QPtrList<KAction> m_serviceActionList;
		QPtrStack<KURL> m_backStack;
		QPtrStack<KURL> m_forwardStack;
		State m_state;
		QString m_tmpFile;
		QGuardedPtr<KParts::ReadOnlyPart> m_partViewer;
		KURL m_previewURL;
		bool m_backStackIsBlocked;
		int m_numOfConnRetry;
		int m_connRetryTime;
		bool m_isConnected;
		QString m_findStr;
		KFileItem* m_lastFoundItem;
		bool m_searchBackwards;
};
//-----------------------------------------------
const unsigned int KBearFileSysPartInterface::s_viewActionCount = 6;
//-----------------------------------------------
KBearFileSysPartInterface::KBearFileSysPartInterface( QWidget* parentWidget, const char* widgetName, QObject* parent, const char* name, const QStringList& )
	:	KParts::Part( parent, name ), KBearPartInterface( parent )
{
	m_myWidget = new KBearFileSysWidget( this, parentWidget, widgetName );
	setWidget( m_myWidget );
	d = new KBearFileSysPartInterfacePrivate;
	setupActions();
	QString xml = locate( "data", "kbear/kbearfilesyspartiface.rc" );
	setXMLFile( xml );
}
//-----------------------------------------------
KBearFileSysPartInterface::~KBearFileSysPartInterface() {
	delete d;
}
//-----------------------------------------------
KParts::Part* KBearFileSysPartInterface::activePart() {
	return this;
}
//-----------------------------------------------
void KBearFileSysPartInterface::openConnection( const SiteInfo& c ) {
	m_siteInfo = c;
	m_myWidget->setSiteInfo( m_siteInfo );
	slotOpenConnection();
	d->m_connectedTimer->start( 1000 );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotOpenConnection() {
	d->m_isConnected = false;
	d->m_connRetryTime = 0;
	d->m_backStackIsBlocked = false;
	clearHistory();
	m_myWidget->openConnection();
}
//-----------------------------------------------
void KBearFileSysPartInterface::setPath( const QString& path ) {
	KURL url = m_url;
	url.setPath( path );
	openURL( url );
}
//-----------------------------------------------
void KBearFileSysPartInterface::openURL( const KURL& url ) {
	// we have to stat the url since we don't know if it's a directory or a file
	d->m_backStackIsBlocked = false;
	clearHistory();
	m_myWidget->openURL( url );
}
//-----------------------------------------------
void KBearFileSysPartInterface::stop() {
	m_myWidget->stop();
}
//-----------------------------------------------
void KBearFileSysPartInterface::reload() {
	m_myWidget->reload();
}
//-----------------------------------------------
void KBearFileSysPartInterface::home() {
	d->m_forwardStack.clear();
	updateHistoryActions();
	m_myWidget->slotOpenDir( m_siteInfo.url() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::cdUp() {
	d->m_forwardStack.clear();
	addToBackHistory( m_url );

	unloadPreviewPart();

	m_myWidget->slotOpenDir( m_url.upURL() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::back() {
	if( d->m_backStack.isEmpty() ) {
		action( KStdAction::name(KStdAction::Back) )->setEnabled( false );
		return;
	}

	unloadPreviewPart();
	d->m_forwardStack.push( new KURL(m_url) );
	KURL* url = d->m_backStack.pop();

	d->m_backStackIsBlocked = true;

	// we have to stat the url since we don't know if it's a directory or a file
	m_myWidget->openURL( *url );
	updateHistoryActions();
	delete url;
}
//-----------------------------------------------
void KBearFileSysPartInterface::forward() {
	if( d->m_forwardStack.isEmpty() ) {
		action( KStdAction::name(KStdAction::Forward) )->setEnabled( false );
		return;
	}

	unloadPreviewPart();
	KURL* url = d->m_forwardStack.pop();
	// we have to stat the url since we don't know if it's a directory or a file
	m_myWidget->openURL( *url );
	updateHistoryActions();
	delete url;
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotNewDir( const KURL& url ){
	unloadPreviewPart();
	addToBackHistory( m_url );
	d->m_backStackIsBlocked = false;
	m_url = url;
	slotSetWindowCaption( m_url.prettyURL() );
	setState( ( state() & ~FilePreview ) | FileNormal );
}
//-----------------------------------------------
unsigned int KBearFileSysPartInterface::getPreviewMode() {
	KConfigGroupSaver cs( kapp->config(), kapp->config()->group() );
	kapp->config()->setGroup("General");
	return kapp->config()->readUnsignedNumEntry( "Preview Mode", 0 );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotConnected() {
	d->m_isConnected = true;
	d->m_numOfConnRetry = 0;
	d->m_connRetryTime = 0;
	d->m_myTime.setDate( QDateTime::currentDateTime().date() );
	d->m_myTime.setTime( QDateTime::currentDateTime().time() );
	QObject::disconnect( m_myWidget, SIGNAL( connected() ), this, SLOT( slotConnected() ) );

	m_myWidget->slotPathHasChanged();
	setState( ( state() & ~GUIDisabled ) | GUIEnabled );

	m_myWidget->openURL( m_siteInfo.url() );
}
//-----------------------------------------------
const KFileItemList* KBearFileSysPartInterface::selectedItems() const  {
	if( m_myWidget && m_myWidget->fileView() )
		return m_myWidget->fileView()->selectedItems();

	return 0L;
}
//-----------------------------------------------
const KURL::List KBearFileSysPartInterface::selectedURLs() const  {
	KURL::List lst;
	if( m_myWidget->fileView() ) {
		KFileItemListIterator it( * m_myWidget->fileView()->selectedItems() );
		for ( ; it.current(); ++it ){
			lst.append( (*it)->url() );
		}
	}
	return lst;
}
//-----------------------------------------------
void KBearFileSysPartInterface::setupConnections(){
	connect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) );
	// we need to call this first to initialize
	slotClipboardDataChanged();

	connect( actionCollection(), SIGNAL( actionStatusText( const QString& ) ), SIGNAL( setStatusBarText( const QString& ) ) );
	connect( actionCollection(), SIGNAL( clearStatusText() ), this, SLOT( slotClearStatusBar() ) );

	connect( action( "tree_view" ), SIGNAL( toggled(bool)), m_myWidget, SLOT( slotToggleTreeView(bool)));

	connect( d->m_connectedTimer, SIGNAL( timeout() ), this, SLOT( slotUpdateTime() ) );
	connect( static_cast<KActionMenu*>( action( "viewActionMenu" ) )->popupMenu(),
					SIGNAL( aboutToShow() ), this, SLOT( slotSetupViewMenu() ) );
	connect( action( "show_hidden" ), SIGNAL( toggled( bool ) ), m_myWidget, SLOT( slotToggleHidden( bool ) ));
	connect( action( "dirs_first" ), SIGNAL( toggled( bool ) ), m_myWidget, SLOT( slotToggleDirsFirst() ));
	connect( action( "case_insensitive" ), SIGNAL( toggled( bool ) ), m_myWidget, SLOT( slotToggleIgnoreCase() ));

	connect( m_actionMenu, SIGNAL( aboutToShow() ), this, SLOT( slotSetupPopupMenu() ) );

	connect( m_myWidget, SIGNAL( startedLoading() ), this, SLOT( slotStartLoading() ) );
	connect( m_myWidget, SIGNAL( finishedLoading() ), this, SLOT( slotFinishedLoading() ) );
	connect( m_myWidget, SIGNAL( pathChanged() ), this, SLOT( slotPathChanged() ) );
	connect( m_myWidget, SIGNAL( pathActivated( const QString& ) ), this, SLOT( slotPathActivated( const QString& ) ) );
	connect( m_myWidget, SIGNAL( connected() ), this, SLOT( slotConnected() ) );
	connect( m_myWidget, SIGNAL( newDir( const KURL& ) ), this, SLOT( slotNewDir( const KURL& ) ) );

	connect( dirLister(), SIGNAL( openFile( const KURL& ) ), this, SLOT( slotOpenFile( const KURL& ) ) );
	connect( dirLister(), SIGNAL( error( int, const QString& ) ), this, SLOT( slotError( int, const QString& ) ) );


}
//-----------------------------------------------
void KBearFileSysPartInterface::slotOpenFile( const KURL& url, bool inInternalEditor ) {
	QString serviceType;

	// save a reference to the old part if we are alreay displaying an internal part
	KParts::ReadOnlyPart* oldPart = d->m_partViewer;

	stateChanged( QString::fromLatin1("ItemSelectedState"), KXMLGUIClient:: StateReverse );
	setState( ( state() & ~FileNormal ) | FilePreview );

	// Open internal editor ?
	if( inInternalEditor ) {
		d->m_partViewer = KParts::ComponentFactory::createPartInstanceFromLibrary<KParts::ReadWritePart>
										( "libkatepart", 0L, "PreviewPartWidget", this, "PreviewPart" );

		if( d->m_partViewer ) {
			// this will get us notified when the file has been saved so we can upload it.
			connect( d->m_partViewer, SIGNAL( completed() ), m_myWidget, SLOT( slotStop() ) );
			connect( d->m_partViewer, SIGNAL( canceled( const QString& ) ), m_myWidget, SLOT( slotStop() ) );
		}
		else // We don't continue if user want internal editor without any part
			return;
	}
	else { // No, just a preview
		serviceType = dirLister()->lastMimeType();
		if( serviceType.isEmpty() )
			return;

		d->m_partViewer = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>
										( serviceType, QString::null, 0L, "PreviewPartWidget", this, "PreviewPart" );

		if( d->m_partViewer ) {
			connect( d->m_partViewer, SIGNAL( canceled( const QString& ) ), m_myWidget, SLOT( slotStop() ) );
			connect( d->m_partViewer, SIGNAL( completed() ), m_myWidget, SLOT( slotStop() ) );
			connect( d->m_partViewer, SIGNAL( setStatusBarText( const QString& ) ),
							m_myWidget, SLOT( slotStatusMessage( const QString& ) ) );
			connect( d->m_partViewer, SIGNAL( setWindowCaption( const QString& ) ),
							this, SLOT( slotSetWindowCaption( const QString& ) ) );
		}
	}


	if( ! d->m_partViewer ) { // we didn't receive any part so open it externally ?
		kdDebug()<<"KBearFileSysPartInterface::slotOpenFile() didn't received any part"<<endl;
		d->m_partViewer = 0L;
		setState( ( state() & ~FilePreview ) | FileNormal );
		openWith( url );
		m_myWidget->resetCursor();
		return;
	}
	// if we get here we have received a part
	// so lets prepare view to display it


	if( inInternalEditor ) {
		// Hack to remove the 'SaveAs' action
		// we have to do this in order to keep control over the connections

		KAction* action = d->m_partViewer->action( KStdAction::name( KStdAction::SaveAs ) );
		kdDebug()<<"KBearFileSysWidget::slotOpenFile action="<<action <<" name="<<(action?action->name():"")<<endl;
		if( action ) {
//			for( int i = 0; i < action->containerCount(); i++ )
//				action->unplug( action->container( i ) );

//			QObject::disconnect( action, 0, 0, 0 );
			delete action;
	 	}
	}

	d->m_previewURL = url;

	m_myWidget->embedPart( d->m_partViewer );

	m_myWidget->slotStatusMessage( i18n( "Opening file: %1").arg( d->m_previewURL.prettyURL() ) );


	if( oldPart ) {
		oldPart->manager()->replacePart( oldPart, d->m_partViewer );
		oldPart->widget()->hide();
		delete oldPart;
	}
	else
		manager()->replacePart( this, d->m_partViewer );

	QString fileName = d->m_previewURL.fileName();
	QFileInfo fileInfo( fileName );
	QString ext = fileInfo.extension();
	QString extension = QString::null;;
	if( ! ext.isEmpty() )
        extension = "."+ext; // keep the '.'
    KTempFile tmpFile( QString::null, extension );
	d->m_tmpFile = tmpFile.name();


	// Now we have to download the file
	KURL destURL;
	destURL.setPath( d->m_tmpFile );
	KIO::Job* job = copyFile( m_siteInfo.ID(), -1, d->m_previewURL, destURL );
	job->setAutoErrorHandlingEnabled( true, m_myWidget );

	connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotPreviewJobFinised ( KIO::Job * ) ) );
	connect( job, SIGNAL( percent( KIO::Job*, unsigned long ) ), this, SLOT( slotProgress( KIO::Job*, unsigned long ) ) );
	connect( job, SIGNAL( speed( KIO::Job*, unsigned long ) ), this, SLOT( slotSpeed( KIO::Job*, unsigned long ) ) );

	m_myWidget->slotStart();

	slotSetWindowCaption( d->m_previewURL.prettyURL() );
	m_myWidget->treeView()->slotSetURL( d->m_previewURL.upURL() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::unloadPreviewPart() {
	if( d->m_partViewer ) {
		m_myWidget->storeSplitterSize();

		d->m_partViewer->widget()->hide();
		d->m_partViewer->manager()->replacePart( d->m_partViewer, this );
		delete d->m_partViewer;
		m_myWidget->fileView()->widget()->show();

		m_myWidget->storeSplitterSize();

		unlink( QFile::encodeName( d->m_tmpFile ) );
		d->m_tmpFile = QString::null;
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotProgress( KIO::Job*, unsigned long p ) {
	m_myWidget->slotProgress( (int) p );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSpeed( KIO::Job*, unsigned long s ) {
	m_myWidget->slotSpeed( (int) s );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotFileNameChanged() {
	KParts::ReadOnlyPart* part = d->m_partViewer;
	KParts::ReadWritePart* rwPart = dynamic_cast<KParts::ReadWritePart*>( part );

	if( rwPart && rwPart->isModified() ) {
		kdDebug()<<"KBearFileSysPartInterface::slotFileNameChanged !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!="<<rwPart->url().prettyURL()<<endl;
		KURL sourceURL;
		sourceURL.setPath( d->m_tmpFile );
		KIO::Job* job = 0L;
		job = copyFile( -1, m_siteInfo.ID(), sourceURL, d->m_previewURL );
}	}
//-----------------------------------------------
void KBearFileSysPartInterface::slotPreviewJobFinised( KIO::Job* job ) {
	if( job->error() ) {
		// TODO: error handling
		m_myWidget->slotStop();

		unloadPreviewPart();
		addToBackHistory( m_url );
		slotSetWindowCaption( m_url.prettyURL() );
		setState( ( state() & ~FilePreview ) | FileNormal );

		d->m_backStackIsBlocked = false;
		d->m_previewURL = KURL();
	}
	else {
		addToBackHistory( m_url );
		slotPathChanged();
		m_url = d->m_previewURL;
		m_myWidget->addToHistory( m_url );
		d->m_partViewer->openURL( d->m_tmpFile );
		// If we are opening in ReadWrite mode we need to know when the file is saved so we can upload it
		KParts::ReadOnlyPart* part = d->m_partViewer;
		if( dynamic_cast<KParts::ReadWritePart*>( part ) ) {
			connect( part, SIGNAL( fileNameChanged() ), this, SLOT( slotFileNameChanged() ) );
		}
		// we set the caption to the original file name
		// since we don't want to confuse the user
		slotSetWindowCaption( m_url.prettyURL() );
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotPathChanged() {
	d->m_backStackIsBlocked = false;
	d->m_findStr = QString::null;
	d->m_lastFoundItem = 0L;
	d->m_forwardStack.clear();
	updateHistoryActions();
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotClearStatusBar() {
	emit setStatusBarText( QString::null );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSetupViewMenu() {
	// If we have a new viewActionCollection(), insert its actions
	//  into viewActionMenu.
	KActionMenu* viewActionMenu = static_cast<KActionMenu*>( action( "viewActionMenu" ) );
	if( m_myWidget->fileView() && m_viewActionCollection != m_myWidget->fileView()->actionCollection() ) {
		m_viewActionCollection = m_myWidget->fileView()->actionCollection();

		if ( ! m_viewActionCollection->isEmpty() ) {
			viewActionMenu->insert( action( "separator" ) );
			for ( uint i = 0; i < m_viewActionCollection->count(); i++ ) {
				viewActionMenu->insert( m_viewActionCollection->action( i ) );
			}
		}
		connect( m_viewActionCollection, SIGNAL( inserted( KAction * )), SLOT( slotViewActionAdded( KAction * )));
		connect( m_viewActionCollection, SIGNAL( removed( KAction * ) ), SLOT( slotViewActionRemoved( KAction * )));
		}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotStartLoading(){
//	kdDebug()<<"KBearFileSysPartInterface::slotStartLoading"<<endl;
	m_myWidget->slotStatusMessage( i18n( "Reading ..." ) );
	action( "view_stop" )->setEnabled( true );
	setState( ( state() & ~GUIEnabled ) | GUIDisabled | ListingState );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotFinishedLoading(){
//	kdDebug()<<"KBearFileSysPartInterface::slotFinishedLoading"<<endl;
	action( "view_stop" )->setEnabled( false );
	// we may end up here even if there were no listing
	// most likely when closing the view
	if( ! (state() & ListingState) )
		return;
	m_myWidget->resetCursor();
	setState( ( ( state() & ~GUIDisabled ) & ~ListingState ) | GUIEnabled );

}
//-----------------------------------------------
void KBearFileSysPartInterface::slotViewActionAdded( KAction* a ) {
	KActionMenu* viewActionMenu = static_cast<KActionMenu*>( action( "viewActionMenu" ) );
	if( viewActionMenu->popupMenu()->count() == s_viewActionCount ) { // need to add a separator
		viewActionMenu->insert( action( "separator" ) );
	}
	viewActionMenu->insert( a );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotViewActionRemoved( KAction* a ) {
	KActionMenu* viewActionMenu = static_cast<KActionMenu*>( action( "viewActionMenu" ) );
	viewActionMenu->remove( a );

	if( viewActionMenu->popupMenu()->count() == ( s_viewActionCount +1 ) ) // remove the separator
		viewActionMenu->remove( action( "separator" ) );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotClipboardDataChanged() {
	KAction* act = action( KStdAction::name( KStdAction::Paste ) );
	if( act )
		act->setEnabled( ! KIO::isClipboardEmpty() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotClearSelection(){
	m_myWidget->fileView()->clearSelection();
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSelectAll(){
	m_myWidget->fileView()->selectAll();
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotInvertSelection(){
	m_myWidget->fileView()->invertSelection();
}
//-----------------------------------------------
int KBearFileSysPartInterface::setupOpenWithMenu() {
	static const QString& app_str = KGlobal::staticQString("Application");
	if( ! m_myWidget->fileView() || ! action( "openWithMenu" ) )
		return 0;
	QPopupMenu* openMenu = static_cast<KActionMenu*> (action( "openWithMenu" ) )->popupMenu();
	openMenu->clear();
	d->m_serviceActionList.clear();  // remove and delete action from list
	//Now everything is cleared so lets see if we can find any services matching our selection
	QValueList<KServiceOffer> offers;
	if( m_myWidget->fileView()->currentFileItem() ) {
		 offers = KServiceTypeProfile::offers( m_myWidget->fileView()->currentFileItem()->mimetype(), app_str );
		QValueList<KServiceOffer>::Iterator iter;
		for( iter = offers.begin(); iter != offers.end(); ++iter) {
			// If we gets here there are matching services
			KService::Ptr servicePtr = (*iter).service();
			if( servicePtr ) {
				KAction* action = new KAction( servicePtr->name(), servicePtr->icon(), KShortcut(), this, servicePtr->exec().utf8());
				d->m_serviceActionList.append( action );
				action->plug( openMenu );
				connect( openMenu, SIGNAL(activated(int)), this, SLOT(slotOpenWithService( int ) ) );
			}
		}
	}
	action( "separator" )->plug( openMenu );
	actionCollection()->action("open_with_other")->plug( openMenu );
	return offers.count();
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSetupPopupMenu() {
	if( ! m_actionMenu )
		return;

	bool hasSelection = m_myWidget->fileView() && m_myWidget->fileView()->selectedItems() && ! m_myWidget->fileView()->selectedItems()->isEmpty();
	m_actionMenu->clear();
	action( KStdAction::name(KStdAction::Up) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Back) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Forward) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Home) )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Redisplay))->plug( m_actionMenu );
	action( "view_stop" )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( "edit_mkdir" )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( "edit_rename" )->plug( m_actionMenu );
	action( "edit_delete" )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Cut) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Copy) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Paste) )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Find) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::FindNext) )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::SelectAll) )->plug( m_actionMenu );
	action( KStdAction::name(KStdAction::Deselect) )->plug( m_actionMenu );
	action( "edit_invert_selection" )->plug( m_actionMenu );
	action( "separator" )->plug( m_actionMenu );
	if( hasSelection ) {
		m_openEditorAction->plug( m_actionMenu );
		action( "separator" )->plug( m_actionMenu );
		if( m_myWidget->fileView()->selectedItems()->count() == 1 && setupOpenWithMenu()>0 ) {
			action( "openWithMenu" )->plug( m_actionMenu );
		}
		else {
			action( "open_with" )->setText( i18n("&Open With...") );
			action( "open_with" )->plug( m_actionMenu );
		}
		action( "separator" )->plug( m_actionMenu );
	}
  	action( "sortActionMenu" )->plug( m_actionMenu );
 	action( "separator" )->plug( m_actionMenu );
  	action( "viewActionMenu" )->plug( m_actionMenu );
 	action( "separator" )->plug( m_actionMenu );
	action( "properties" )->plug( m_actionMenu );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSelectionChanged() {
	KFileView* fileView = m_myWidget->fileView();
	if( fileView && fileView->selectedItems()->count() ) {
		stateChanged( QString::fromLatin1("ItemSelectedState") );
		if( fileView->selectedItems()->count() == 1 ) {
			bool isFile = fileView->currentFileItem()->isFile();
			m_openEditorAction->setEnabled( isFile );
		}
		else {
			action( "edit_rename" )->setEnabled( false );
		}
	}
	else {
		stateChanged( QString::fromLatin1("ItemSelectedState"), KXMLGUIClient:: StateReverse );
	}
	emit selectionChanged();
}
//-----------------------------------------------
QPopupMenu* KBearFileSysPartInterface::popupMenu() {
	return m_actionMenu;
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotActivatedMenu( const KFileItem* , const QPoint& pos ) {
	kdDebug()<<"KBearFileSysPartInterface::slotActivatedMenu() part="<<this<<endl;
	if( m_actionMenu )
		m_actionMenu->popup( pos );
}
//-----------------------------------------------
void KBearFileSysPartInterface::init( const SiteInfo& info ) {
	m_siteInfo = info;
	readProperties( kapp->config(), "View Settings"  );

	m_myWidget->init( m_siteInfo );

	d->m_connectedTimer = new QTimer( this );
	setupConnections();
	//	plug the actions to the toolbar
	action( KStdAction::name(KStdAction::Up) )->plug( m_myWidget->toolBarUpper() );
	action( KStdAction::name(KStdAction::Back) )->plug( m_myWidget->toolBarUpper() );
	action( KStdAction::name(KStdAction::Forward) )->plug( m_myWidget->toolBarUpper() );
	action( KStdAction::name(KStdAction::Home) )->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( KStdAction::name(KStdAction::Redisplay))->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( "view_stop" )->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( "edit_open_editor" )->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( "edit_mkdir" )->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( "tree_view" )->plug( m_myWidget->toolBarUpper() );
	action( "separator" )->plug( m_myWidget->toolBarUpper() );
	action( "short_view" )->plug( m_myWidget->toolBarUpper() );
	action( "detailed_view" )->plug( m_myWidget->toolBarUpper() );

	setState( GUIDisabled );
}
//-----------------------------------------------
void KBearFileSysPartInterface::clearHistory() {
	m_myWidget->clearHistory();
	d->m_backStack.clear();
	d->m_forwardStack.clear();
	updateHistoryActions();
}
//-----------------------------------------------
void KBearFileSysPartInterface::updateSortActions() {
	QDir::SortSpec sorting = m_myWidget->sorting();
	if( KFile::isSortByName( sorting ) )
		static_cast<KRadioAction*>( action( "by_name" ) )->setChecked( true );
	else if( KFile::isSortByDate( sorting ) )
		static_cast<KRadioAction*>( action( "by_date" ) )->setChecked( true );
	else if( KFile::isSortBySize( sorting ) )
		static_cast<KRadioAction*>( action( "by_size" ) )->setChecked( true );

	static_cast<KRadioAction*>( action( "dirs_first" ) )->setChecked( KFile::isSortDirsFirst( sorting ));
	static_cast<KRadioAction*>( action( "case_insensitive" ) )->setChecked(KFile::isSortCaseInsensitive( sorting ));

	if( m_myWidget->fileView() )
		static_cast<KToggleAction*>( action( "reversed" ) )->setChecked( m_myWidget->fileView()->isReversed() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::updateViewActions() {
	KFile::FileView fv = m_myWidget->viewKind();
	static_cast<KRadioAction*>( action( "short_view" ) )->setChecked( KFile::isSimpleView( fv ));
	static_cast<KRadioAction*>( action( "detailed_view" ) )->setChecked( KFile::isDetailView( fv ));
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotPathActivated( const QString& path ) {
	KURL tmp( m_url );
	tmp.setPath( fromUnicode( path ) );
	if( tmp == m_url )
		return;
	addToBackHistory( m_url );
}
//------------------------------------------
void KBearFileSysPartInterface::slotResult( KIO::Job* job ) {
	if( job->error() ) {
		// TODO: error handling
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotDelete() {
	m_myWidget->deleteSelectedItems( false );
}
//-----------------------------------------------
KURL KBearFileSysPartInterface::lastURL() const {
	if( ! d->m_backStack.isEmpty() )
		return *d->m_backStack.top();

	return KURL();
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotCopy(){
	doCutCopy( false );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotCut(){
	doCutCopy( true );
}
//-----------------------------------------------
void KBearFileSysPartInterface::doCutCopy( bool cut ){
	if ( ! m_myWidget->fileView()->currentFileItem() ) // is there any selected items ?
		return;              // nope

	int ID = m_myWidget->dirLister()->siteInfo().ID();
	KURLDrag* dragObject  = KBear::createDragObject( ID, m_myWidget->fileView() );

	dragObject->metaData().insert("Action", cut ? "move" : "copy" );
	QApplication::clipboard()->setData( dragObject );
	action( KStdAction::name(KStdAction::Paste) )->setEnabled( true );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotPaste() {
	kdDebug()<<"KBearFileSysPartInterface::slotPaste()"<<endl;
	if( KIO::isClipboardEmpty() ) {
		action( KStdAction::name(KStdAction::Paste) )->setEnabled( false );
		return;
	}
	QMimeSource* data = QApplication::clipboard()->data();
	KURL::List urls;
	KIO::MetaData metaData;
	// we must create a new drag object since we do'nt know the source, could be non KBear view
	if( QUriDrag::canDecode( data ) && KURLDrag::decode( data, urls, metaData ) ) {
		int ID = m_myWidget->dirLister()->siteInfo().ID();
		metaData.insert("DestID", QString::number( ID ) );
		metaData.insert("DestURL", m_url.url() );
		KURLDrag* drag = KURLDrag::newDrag( urls, metaData, widget() );

		kdDebug()<<"KBearFileSysPartInterface::slotPaste()"<<endl;
		m_api->transferManager()->addTransfers( drag );

		if( /*! metaData.contains("Action") || */metaData["Action"] == "move" )
			QApplication::clipboard()->clear();
	}
	if( KIO::isClipboardEmpty() )
		action( KStdAction::stdName(KStdAction::Paste) )->setEnabled( false );

}
//-----------------------------------------------
void KBearFileSysPartInterface::slotDropped( QMimeSource* drop, const QPoint& pos ) {
	if( ! QUriDrag::canDecode( drop ) )
		return;

	QPopupMenu menu( widget() );
	int action;
	const int COPY = menu.insertItem( i18n("&Copy") );
	const int MOVE = menu.insertItem( i18n( "&Move" ) );

	if( KBear::isModifierKeysPressed( ControlMask ) ) {
		action = COPY;
	}
	else if( KBear::isModifierKeysPressed( ShiftMask ) ) {
		action = MOVE;
	}
	else {
		menu.setMouseTracking( true );
		action = menu.exec( pos );
	}

	KIO::MetaData sourceMeta;
	KURL::List urls;
	KURLDrag::decode( drop, urls, sourceMeta );

	if( action == COPY ) {
		sourceMeta.insert("Action", "copy" );
	}
	else if( action == MOVE ) {
		sourceMeta.insert("Action", "move" );
	}
	else
		return;

 	sourceMeta.insert("DestID", QString::number( m_myWidget->dirLister()->siteInfo().ID() ) );
	sourceMeta.insert("DestURL", m_url.url() );
	KURLDrag* drag = KURLDrag::newDrag( urls, sourceMeta, widget() );

	m_api->transferManager()->addTransfers( drag );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotFindNext(){
	if( d->m_lastFoundItem ) {
		KConfig* config = kapp->config();
		KConfigGroupSaver( config, config->group() );
		config->setGroup( QString::fromLatin1("FileSysSearchDialog") );
		QStringList historyList = config->readListEntry( QString::fromLatin1("History") );
		long options = 0;
		if( config->readBoolEntry( QString::fromLatin1("CaseSensitive"), true ) )
			options |= KFindDialog::CaseSensitive;

		if( d->m_searchBackwards )
			d->m_lastFoundItem = m_myWidget->fileView()->prevItem( d->m_lastFoundItem );
		else
			d->m_lastFoundItem = m_myWidget->fileView()->nextItem( d->m_lastFoundItem );

		searchView( d->m_findStr, options, d->m_lastFoundItem );
	}
	else {
		slotFind();
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotFind(){
	KConfig* config = kapp->config();
	KConfigGroupSaver( config, config->group() );
	config->setGroup( QString::fromLatin1("FileSysSearchDialog") );
	QStringList historyList = config->readListEntry( QString::fromLatin1("History") );
	long options = 0;
	if( config->readBoolEntry( QString::fromLatin1("CaseSensitive"), true ) )
		options |= KFindDialog::CaseSensitive;
	if( config->readBoolEntry( QString::fromLatin1("UseRegExp"), true ) )
		options |= KFindDialog::RegularExpression;

	KFindDialog dialog( widget(), "FindDialog", options, historyList  );
	dialog.setHasCursor( false );

	if( dialog.exec() == QDialog::Rejected )
		return;

	config->writeEntry( QString::fromLatin1("History"), dialog.findHistory() );
	config->writeEntry( QString::fromLatin1("CaseSensitive"), (dialog.options() & KFindDialog::CaseSensitive) );
	config->writeEntry( QString::fromLatin1("UseRegExp"), (dialog.options() & KFindDialog::RegularExpression) );
	config->sync();

	d->m_searchBackwards = ( dialog.options() & KFindDialog::FindBackwards );
	d->m_findStr = dialog.pattern();
	d->m_lastFoundItem = 0L;
	KFileItem* startItem = 0L;
	if( d->m_searchBackwards )
		startItem = m_myWidget->fileView()->items()->getLast();
	else
		startItem = m_myWidget->fileView()->firstFileItem();

	searchView( d->m_findStr, dialog.options(), startItem );
}
//-----------------------------------------------
void KBearFileSysPartInterface::searchView( const QString& pattern, long options, KFileItem* startItem ){
	bool caseSensitive = ( options & KFindDialog::CaseSensitive );

	QRegExp regExp;
	regExp.setWildcard( true );
	regExp.setPattern( pattern );
	regExp.setCaseSensitive( caseSensitive );

	KFileItem* item = startItem;
	while( item ) {
		if( regExp.search( item->name() ) >= 0 ) {
			d->m_lastFoundItem = item;
			m_myWidget->fileView()->clearSelection();
			m_myWidget->fileView()->setSelected( item, true );
			m_myWidget->fileView()->setCurrentItem( item );
			m_myWidget->fileView()->ensureItemVisible( item );
			return;
		}
		else if( ( d->m_searchBackwards && item == m_myWidget->fileView()->items()->getFirst() )
						|| ( ! d->m_searchBackwards && item == m_myWidget->fileView()->items()->getLast() ) ) {
			if( ! d->m_lastFoundItem ) {
				m_myWidget->fileView()->clearSelection();
				KMessageBox::information( widget(), i18n("Could not find any match for: %1").arg( pattern ),i18n("Not found...") );
				return;
			}
			else {
				if(KMessageBox::warningContinueCancel( widget(),
															i18n("End of view reached.\nContinue from beginning ?"),
															i18n("Find") ) == KMessageBox::Cancel )
				{
					d->m_lastFoundItem = 0L;
					return;
				}
				if( d->m_searchBackwards )
					item = m_myWidget->fileView()->items()->getLast();
				else
					item = m_myWidget->fileView()->firstFileItem();
			}
		}
		else if( d->m_searchBackwards )
			item = m_myWidget->fileView()->prevItem( item );
		else
			item = m_myWidget->fileView()->nextItem( item );
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotMakeDir() {
	setState( GUIDisabled );
    // Modal widget asking the user the name of a new directory
    //
    KDialogBase *lMakeDir;
    QLabel *label;
    KLineEdit *ed;
    QVBox *vbox;

    // Create widgets, and display using geometry management
    //
    lMakeDir = new KDialogBase( m_myWidget->fileView()->widget(), "MakeDir Dialog", true, i18n("New Directory"), KDialogBase::Ok | KDialogBase::Cancel );
    vbox = new QVBox( lMakeDir );
    vbox->setSpacing( KDialog::spacingHint() );
    lMakeDir->setMainWidget( vbox );
    label = new QLabel( vbox );
    label->setAlignment( AlignLeft | AlignVCenter );
    label->setText(i18n("Create new directory in: ") +
		   QString::fromLatin1( "\n" ) + /* don't break i18n now*/
		   m_url.prettyURL() );
    ed= new KLineEdit( vbox );
    ed->setText( i18n("New Directory") );
    ed->selectAll();
    connect(ed, SIGNAL(returnPressed()), lMakeDir, SLOT(accept()) );

    connect( lMakeDir->actionButton( KDialogBase::Ok ), SIGNAL(clicked()),
	     lMakeDir, SLOT(accept()) );
    connect( lMakeDir->actionButton( KDialogBase::Cancel ), SIGNAL(clicked()),
	     lMakeDir, SLOT(reject()) );


    // If the users presses enter (not escape) then create the dir
    // and insert it into the ListBox
    lMakeDir->setMinimumSize( 300, 120); // default size
    ed->grabKeyboard();
    if ( lMakeDir->exec() == QDialog::Accepted && !ed->text().isEmpty() ) {
		KURL tmp = m_url;
		tmp.setPath( m_url.path( +1 ) + ed->text() );
		dirLister()->mkdir( tmp );
	}

    delete lMakeDir;
	setState( GUIEnabled );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotOpenEditor() {
	if( m_myWidget->fileView()->selectedItems()->count() != 1 )
		return;

	KFileItem* item = m_myWidget->fileView()->selectedItems()->getFirst();
	if( item )
		slotOpenFile( item->url(), true );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotSetWindowCaption( const QString& str ) {
	if( ! d->m_partViewer ) {
		QString s = toUnicode( str );
		emit setWindowCaption( s );
	}
	else {
		emit setWindowCaption( m_url.prettyURL() );
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::setupActions(){
	actionCollection()->setHighlightingEnabled( true );

	new KActionSeparator( actionCollection(), "separator" );

	new KAction( i18n("&Open With..."), 0, this, SLOT( slotOpenWith() ), actionCollection(), "open_with" );
	new KAction( i18n("&Other..."), 0, this, SLOT( slotOpenWith() ), actionCollection(), "open_with_other" );
	new KActionMenu( i18n("Open With..."), actionCollection(), "openWithMenu" );

	m_openEditorAction = new KAction( i18n("Open in &Editor"), "edit", 0, this, SLOT( slotOpenEditor() ), actionCollection(), "edit_open_editor" );
	m_openEditorAction->setEnabled( false );

	new KAction( i18n("Properties..."), ALT+Key_Return, this, SLOT(slotProperties()), actionCollection(), "properties" );

	KAction* tmpAction = new KAction( i18n("New Directory..."), 0, this, SLOT( slotMakeDir() ), actionCollection(), "edit_mkdir" );
	tmpAction->setIcon( QString::fromLatin1("folder_new") );
	new KAction( i18n( "Rename" ), 0, Key_F2, m_myWidget, SLOT( slotRename() ), actionCollection(), "edit_rename" );
	new KAction( i18n( "Delete" ), "editdelete", SHIFT+Key_Delete, this, SLOT( slotDelete() ), actionCollection(), "edit_delete" );

	tmpAction = new KAction( i18n("S&top"),"stop", 0, this, SLOT( stop() ), actionCollection(), "view_stop" );
	tmpAction->setToolTip( i18n("Stop loading directory.") );

	tmpAction = KStdAction::up( this, SLOT( cdUp() ), actionCollection(), KStdAction::name(KStdAction::Up) );
	tmpAction->setText( i18n("Parent Directory") );
	KStdAction::back( this, SLOT( back() ), actionCollection(), KStdAction::name(KStdAction::Back) );
	KStdAction::forward( this, SLOT(forward()), actionCollection(), KStdAction::name(KStdAction::Forward));
	tmpAction = KStdAction::home( this, SLOT( home() ), actionCollection(), KStdAction::name(KStdAction::Home) );
	tmpAction->setText(i18n("Home Directory"));
	tmpAction = KStdAction::redisplay( this, SLOT(reload()), actionCollection(), KStdAction::name(KStdAction::Redisplay) );
	tmpAction->setText( i18n("Reload") );
	KStdAction::cut( this, SLOT( slotCut() ), actionCollection(), KStdAction::name(KStdAction::Cut) );
	KStdAction::copy( this, SLOT( slotCopy() ), actionCollection(), KStdAction::name(KStdAction::Copy));
	KStdAction::paste( this, SLOT( slotPaste() ), actionCollection(), KStdAction::name(KStdAction::Paste));
	KStdAction::find( this, SLOT( slotFind() ), actionCollection(), KStdAction::name(KStdAction::Find) );
	KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), KStdAction::name(KStdAction::FindNext) );
	KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), KStdAction::name(KStdAction::SelectAll) );
	KStdAction::deselect( this, SLOT( slotClearSelection() ), actionCollection(), KStdAction::name(KStdAction::Deselect) );
	new KAction( i18n("&Invert Selection"),CTRL+Key_I, this, SLOT( slotInvertSelection() ), actionCollection(), "edit_invert_selection" );

	//Now we set up the view and sort menu
	KActionMenu* sortActionMenu = new KActionMenu( i18n("Sorting"), actionCollection(), "sortActionMenu");
	KActionMenu* viewActionMenu = new KActionMenu( i18n("View" ), actionCollection(), "viewActionMenu" );
	m_actionMenu = new QPopupMenu( widget(), "actionMenu" );
	// Note: the actionMenu is setup in runtime in slotSetupPopupMenu

	// the view menu actions
	KRadioAction* shortView = new KRadioAction( i18n("Short View"), "view_icon", 0, m_myWidget, SLOT( slotSimpleView() ), actionCollection(), "short_view" );
	KRadioAction* detailedView = new KRadioAction( i18n("Detailed View"), "view_detailed", 0, m_myWidget, SLOT( slotDetailedView() ), actionCollection(), "detailed_view" );
	new KToggleAction( i18n("Directory &tree"), "view_tree",0,	this, 0, actionCollection(), "tree_view"  );

	new KToggleAction( i18n("Show Hidden Files"), 0, actionCollection(), "show_hidden" );
	QString viewGroup = QString::fromLatin1("view");
	shortView->setExclusiveGroup( viewGroup );
	detailedView->setExclusiveGroup( viewGroup );

	viewActionMenu->insert( action( "show_hidden" ) );
	viewActionMenu->insert( action( "separator" ) );
	viewActionMenu->insert( action( "short_view" ) );
	viewActionMenu->insert( action( "detailed_view" ) );
	viewActionMenu->insert( action( "separator" ) );
	viewActionMenu->insert( action( "tree_view" ) );

	// the sort menu actions
	KRadioAction* byName = new KRadioAction( i18n("By Name"), 0, m_myWidget, SLOT( slotSortByName() ), actionCollection(), "by_name" );
	KRadioAction* byDate = new KRadioAction( i18n("By Date"), 0, m_myWidget, SLOT( slotSortByDate() ), actionCollection(), "by_date" );
	KRadioAction* bySize = new KRadioAction( i18n("By Size"), 0, m_myWidget, SLOT( slotSortBySize() ), actionCollection(), "by_size" );
	new KToggleAction( i18n("Reverse"), 0, m_myWidget, SLOT( slotSortReversed() ), actionCollection(), "reversed" );

	QString sortGroup = QString::fromLatin1("sort");
	byName->setExclusiveGroup( sortGroup );
	byDate->setExclusiveGroup( sortGroup );
	bySize->setExclusiveGroup( sortGroup );

	new KToggleAction( i18n("Directories First"), 0, actionCollection(), "dirs_first");
	new KToggleAction(i18n("Case Insensitive"), 0, actionCollection(), "case_insensitive" );

	sortActionMenu->insert( action( "by_name" ) );
	sortActionMenu->insert( action( "by_date" ) );
	sortActionMenu->insert( action( "by_size" ) );
	sortActionMenu->insert( action( "reversed" ) );
	sortActionMenu->insert( action( "separator" ) );
	sortActionMenu->insert( action( "dirs_first" ) );
	sortActionMenu->insert( action( "case_insensitive" ) );


	action( KStdAction::name(KStdAction::Up) )->setWhatsThis( i18n("This button moves you up one step in the directory tree.") );
	action( KStdAction::name(KStdAction::Back) )->setWhatsThis( i18n("This button moves you one step back in history list.") );
	action( KStdAction::name(KStdAction::Forward) )->setWhatsThis( i18n("This button moves you one step forward in history list.") );
	action( KStdAction::name(KStdAction::Redisplay))->setWhatsThis( i18n("This button reloads current directory.") );
	action( "edit_mkdir" )->setWhatsThis( i18n("This button creates a new directory in current directory.") );
	action( "view_stop" )->setWhatsThis( i18n("This button stops loading the directory.") );
	action( "detailed_view" )->setWhatsThis( i18n("This button change the view to detailed list mode.") );
	action( "short_view" )->setWhatsThis( i18n("This button change the view to icon mode.") );
	action( KStdAction::name(KStdAction::Home) )->setWhatsThis( i18n("This button moves you to your home directory\n"
                                                                                    "On a remote system this will be your startup directory.") );
	action( "tree_view" )->setToolTip( i18n("This button toggles the directory tree.") );
	action( "tree_view" )->setWhatsThis( i18n("This button toggles the directory tree.") );
	action( KStdAction::name(KStdAction::Cut) )->setToolTip( i18n("Cut current selection from the active view into the clipboard.") );
	action( KStdAction::name(KStdAction::Copy) )->setToolTip( i18n("Copy current selection from the active view into the clipboard.") );
	action( KStdAction::name(KStdAction::Paste) )->setToolTip( i18n("Paste clipboard contents into the active view.") );
	action( KStdAction::name(KStdAction::Find) )->setToolTip( i18n("Open the find dialog.") );
	action( KStdAction::name(KStdAction::FindNext) )->setToolTip( i18n("Find next matching item.") );
	action( KStdAction::name(KStdAction::SelectAll) )->setToolTip( i18n("Select all items in the active view.") );
	action( KStdAction::name(KStdAction::Deselect) )->setToolTip( i18n("Deselect all items in the active view.") );
	action( "edit_invert_selection" )->setToolTip( i18n("Invert selection in the active view.") );

	action( KStdAction::name(KStdAction::Cut) )->setWhatsThis( i18n("Cut current selection from the active view into the clipboard.\n"
				"You can also select the 'Cut' command from the 'Edit' menu.") );
	action( KStdAction::name(KStdAction::Copy) )->setWhatsThis( i18n("Copy current selection from the active view into the clipboard.\n"
				"You can also select the 'Copy' command from the 'Edit' menu.") );
	action( KStdAction::name(KStdAction::Paste) )->setWhatsThis( i18n("Paste clipboard contents into the active view.\n"
				"You can also select the 'Paste' command from the 'Edit' menu.") );
	action( KStdAction::name(KStdAction::Find) )->setWhatsThis( i18n("Open the 'Find' dialog\n"
				"You can also select the 'Find' command from the 'Edit' menu.") );

}
//-----------------------------------------------
void KBearFileSysPartInterface::readProperties( KConfig* config, const QString& group ) {
	if( ! config )
		return;

	m_myWidget->readConfig( config, group );

	KConfigGroupSaver( config, config->group() );
	if( ! group.isEmpty() )
		config->setGroup( group );


	if( config->readBoolEntry( QString::fromLatin1("Show hidden files"),false ) ) {
		static_cast<KToggleAction*>( action( "show_hidden" ) )->setChecked( true );
	}

	showToolBarUpper( config->readBoolEntry( "Child ToolBar", true ) );
	showToolBarLower( config->readBoolEntry( "Child Path ToolBar", true ) );
	showStatusBarUpper( config->readBoolEntry( "Child StatusBar", true ) );
	showStatusBarLower( config->readBoolEntry( "Child InfoBar", true ) );

	updateViewActions();
}
//-----------------------------------------------
void KBearFileSysPartInterface::saveProperties( KConfig* config, const QString& group ) {
	if( ! config )
		return;

	m_myWidget->writeConfig( config, group );

	KConfigGroupSaver( config, config->group() );

	if( ! group.isEmpty() )
		config->setGroup( group );

}
//-----------------------------------------------
KBearFileSysPartInterface::State KBearFileSysPartInterface::state() const {
	return d->m_state;
}
//-----------------------------------------------
void KBearFileSysPartInterface::setState( unsigned int state ) {
	d->m_state = (State)state;
	m_myWidget->setState( state );
	if( d->m_state & GUIDisabled ) {
		stateChanged( QString::fromLatin1("GUIDisabledState") );
		return;
	}
	else if( d->m_state & GUIEnabled ) {
		stateChanged( QString::fromLatin1("GUIDisabledState"), KXMLGUIClient:: StateReverse );
		updateHistoryActions();
		updateSortActions();
		slotSelectionChanged();
	}
	if( d->m_state & ListingState ) {
		stateChanged( QString::fromLatin1("ListingState") );
		return;
	}
	else {
		stateChanged( QString::fromLatin1("ListingState"), KXMLGUIClient:: StateReverse );
	}
	if( d->m_state & FilePreview ) {
		stateChanged( QString::fromLatin1("FilePreviewState") );
	}
	else {
		stateChanged( QString::fromLatin1("FilePreviewState"), KXMLGUIClient:: StateReverse );
		slotSelectionChanged();
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::addToBackHistory( const KURL& url ) {
	if( ! url.isEmpty() ) {
		if( ! d->m_backStackIsBlocked && ( d->m_backStack.isEmpty() || url != *d->m_backStack.top() ) ) {
			d->m_backStack.push( new KURL( url ) );
		}
	}
	updateHistoryActions();
}
//-----------------------------------------------
void KBearFileSysPartInterface::updateHistoryActions() {
	action( KStdAction::name(KStdAction::Forward) )->setEnabled( ! d->m_forwardStack.isEmpty() );
	action( KStdAction::name(KStdAction::Back) )->setEnabled( ! d->m_backStack.isEmpty() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotOpenWith(){
	openWith( selectedURLs() );
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotOpenWithService( int id ) {
	KPopupMenu* openMenu = static_cast<KActionMenu*>( action( "openWithMenu" ) )->popupMenu();
	QObject::disconnect( openMenu, SIGNAL(activated(int)), this, SLOT(slotOpenWithService( int ) ) );
	for( unsigned int i = 0; i < d->m_serviceActionList.count(); i++ ) {
		if( openMenu->text( id ) == d->m_serviceActionList.at( i )->text() ) {
			executeService( QString::fromUtf8( d->m_serviceActionList.at( i )->name() ), selectedURLs(),
							d->m_serviceActionList.at( i )->text(), d->m_serviceActionList.at( i )->icon() );
		}
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::showToolBarUpper( bool show ) {
	if( ! m_myWidget->toolBarUpper() )
		return;
	if( show )
		m_myWidget->toolBarUpper()->show();
	else
		m_myWidget->toolBarUpper()->hide();
}
//-----------------------------------------------
void KBearFileSysPartInterface::showToolBarLower( bool show ) {
	if( ! m_myWidget->toolBarLower() )
		return;
	if( show )
		m_myWidget->toolBarLower()->show();
	else
		m_myWidget->toolBarLower()->hide();
}
//-----------------------------------------------
void KBearFileSysPartInterface::showStatusBarUpper( bool show ) {
	m_myWidget->toggleStatusBarUpper( show );
}
//-----------------------------------------------
void KBearFileSysPartInterface::showStatusBarLower( bool show ) {
	m_myWidget->toggleStatusBarLower( show );
}
//-----------------------------------------------
KIO::Job* KBearFileSysPartInterface::copyFile( int sID, int dID, const KURL& source, const KURL& dest ) {

	KIO::Job* job = KBearFileCopyJob::file_copy( dID, sID, source, dest, 0600, true, false, false );

	return job;
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotUpdateTime(){
	if( ! d->m_isConnected && d->m_numOfConnRetry > 0 ) {
		d->m_connRetryTime--;
		d->m_connRetryTime = d->m_connRetryTime<0?0:d->m_connRetryTime;
		m_myWidget->slotStatusMessage( i18n( "Reconnection nr: %1 in %2 seconds" ).
						arg( d->m_numOfConnRetry ).arg( d->m_connRetryTime ) );
	}
	else if( d->m_isConnected ) {
		d->m_numOfConnRetry = 0;
		int numOfSecs = d->m_myTime.secsTo( QDateTime::currentDateTime() );
		int mSecs = d->m_myTime.time().elapsed();
		QTime t;
		int numOfDays = numOfSecs / 86400; // 60*60*24
		QString tString = QString::null;
		if( numOfDays > 0 ){
			tString = QString("%1 days ").arg( numOfDays );
		}
		else {
			tString = QString::null;
		}
		tString += t.addMSecs( mSecs ).toString();
		m_myWidget->setInfoText( i18n("Connected: %1").arg( tString ) );
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::slotError( int err, const QString& errMsg ) {
	QApplication::restoreOverrideCursor();
	d->m_connectedTimer->stop();
	KMessageBox::error( m_myWidget, KIO::buildErrorString( err, errMsg ) );
	d->m_connectedTimer->start( 1000 );
	if( err == KIO::ERR_SLAVE_DIED
			|| err == KIO::ERR_UNKNOWN_HOST
			|| err == KIO::ERR_CONNECTION_BROKEN
			|| err == KIO::ERR_COULD_NOT_CONNECT
			|| err == KIO::ERR_COULD_NOT_LOGIN
			|| err == KIO::ERR_ABORTED
			|| err == KIO::ERR_SERVICE_NOT_AVAILABLE
			|| err == KIO::ERR_UNKNOWN
			|| err == KIO::ERR_UNKNOWN_INTERRUPT
			|| err == KIO::ERR_SERVER_TIMEOUT )
	{
		d->m_isConnected = false;
		if( m_siteInfo.autoReconnect() ) {
			d->m_numOfConnRetry++;
			int time = m_siteInfo.reconnectTime();
			if( d->m_numOfConnRetry <= m_siteInfo.numOfRetries() ) {
				setState( GUIDisabled );
//				m_myWidget->dirLister()->closeConnection();
				QTimer::singleShot( time*1000, this, SLOT(slotOpenConnection()));
				d->m_connRetryTime = time;
				m_myWidget->slotStatusMessage( i18n( "Reconnection nr: %1 in %2 seconds" ).arg(d->m_numOfConnRetry).arg( time) );
			}
			else {
				d->m_numOfConnRetry = 0;
				emit closeMe();
			}
		}
		else {
			d->m_numOfConnRetry = 0;
			emit closeMe();
		}
	}
}
//-----------------------------------------------
void KBearFileSysPartInterface::guiActivateEvent( KParts::GUIActivateEvent* event ) {
	if( event->activated() )
		slotSetWindowCaption( m_url.prettyURL() );
}
//-----------------------------------------------
