/*********************************************************************************
* C++ Implementation: kbearfilesyswidget.cpp
* Description:
*
* Begin : mån apr 28 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 <qhbox.h>
#include <qlabel.h>
#include <qwhatsthis.h>
#include <qtooltip.h>
#include <qlayout.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <ktoolbar.h>
#include <kparts/part.h>
#include <kaction.h>
#include <kstdaction.h>
#include <klocale.h>
#include <kcombobox.h>
#include <kfileview.h>
#include <kurl.h>
#include <kfileitem.h>
#include <klineedit.h>
#include <kanimwidget.h>
#include <kprogress.h>
#include <kcombobox.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kio/global.h>
//////////////////////////////////////////////////////////////////////
// System specific include files
#include <X11/Xlib.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearfilesyswidget.h"
#include "kbearfilesyspartiface.h"
#include "kbearfileviewinterface.h"
#include "kbeardirview.h"
#include "misc.h"
#include "kbeardirlisteriface.h"

#include "kbearfilesyswidget.moc"

using namespace KBear;
//-----------------------------------------------
class KBearFileSysWidget::KBearFileSysWidgetPrivate {
	public:
		KBearFileSysWidgetPrivate()
			:	m_treeView( 0L ), m_fileView( 0L ),
				m_dirLister( 0L ), m_splitter( 0L ),
				m_infoIsSet( false ), m_currentSize( 0 ),
				m_numFiles( 0 ), m_numDirs( 0 )
			{}
		~KBearFileSysWidgetPrivate() {
			delete m_splitter;
			delete m_toolBarUpper;
			delete m_toolBarLower;
			delete m_statusBarUpper;
			delete m_statusBarLower;
		}
	public:
		KBearDirView* m_treeView;
		KFileView* m_fileView;
		KBearDirListerIface* m_dirLister;
		QSplitter* m_splitter;
		KProgress* m_progress;
		KToolBar* m_toolBarUpper;
		KToolBar* m_toolBarLower;
		QLabel* m_statusBarUpper;
		QHBox* m_statusBarLower;
		KComboBox* m_pathCombo;
		KHistoryCombo* m_filterCombo;
		QLabel* m_speedLabel;
		QLabel* m_directoryLabel;
		QLabel* m_endLabel;
		KBearFileSysPartInterface* m_part;
		int m_currentViewKind;
		QDir::SortSpec m_mySorting;
		SiteInfo m_info;
		bool m_infoIsSet;
		QValueList<int> m_splitterSizes;
		KIO::filesize_t m_currentSize;
		int m_numFiles;
		int m_numDirs;
};
//-----------------------------------------------
KBearFileSysWidget::KBearFileSysWidget( KBearFileSysPartInterface* part, QWidget* parent, const char* name, WFlags f )
 : QWidget( parent, name, f )
{
	setFocusPolicy(QWidget::WheelFocus);

	d = new KBearFileSysWidgetPrivate;
	d->m_part = part;
	setup();
}
//-----------------------------------------------
KBearFileSysWidget::~KBearFileSysWidget() {
	resetCursor();
	delete d;
	d =0;
}
//-----------------------------------------------
void KBearFileSysWidget::slotProgress( int percent ) {
	d->m_progress->setProgress( percent );
	// we have to redraw this in as fast as possible
	if( ! d->m_progress->isHidden() )
		QApplication::flushX();
}
//-----------------------------------------------
void KBearFileSysWidget::showProgress() {
	d->m_progress->raise();
	d->m_progress->show();
	QApplication::flushX();
}
//-----------------------------------------------
void KBearFileSysWidget::hideProgress() {
	d->m_progress->hide();
}
//-----------------------------------------------
void KBearFileSysWidget::slotDetailedView() {
	setView( KFile::Detail );
}
//-----------------------------------------------
void KBearFileSysWidget::slotSimpleView() {
	setView( KFile::Simple );
}
//-----------------------------------------------
void KBearFileSysWidget::slotStart() {
	d->m_progress->setProgress( 0 );
	showProgress();
	d->m_toolBarUpper->animatedWidget(1)->start(); // start wheel animation
	d->m_treeView->slotStartAnimation();

	emit startedLoading();
}
//-----------------------------------------------
void KBearFileSysWidget::slotStop() {
	d->m_toolBarUpper->animatedWidget(1)->stop(); // stop wheel animation
	d->m_treeView->slotStopAnimation();
	d->m_speedLabel->setText( QString::null );
	slotProgress( 100 );
	d->m_progress->hide();
	if( d->m_fileView )
		d->m_fileView->listingCompleted();

	emit finishedLoading();
}
//-----------------------------------------------
void KBearFileSysWidget::clearHistory(){
	d->m_pathCombo->clear();
	d->m_pathCombo->completionObject()->clear();
}
//-----------------------------------------------
void KBearFileSysWidget::addToHistory( const KURL& url ) {
	QString path = d->m_part->toUnicode( url.path() );
	bool found = false;
	for( int i = 0; i < d->m_pathCombo->count(); i++ ) {
		// try to fix so dirs always have a trailing slash
		// Normally we will be given this but if user writes a directory without
		// trailing slash this will not be the case.
		if( d->m_pathCombo->text( i ) == path.left( path.length() -1 ) ) {
			d->m_pathCombo->changeItem( path, i );
			d->m_pathCombo->setCurrentItem( path, true );
			found = true;
		}
		else if( d->m_pathCombo->text( i ) == path ) {
			d->m_pathCombo->setCurrentItem( path, true );
			found = true;
		}
		else if( d->m_pathCombo->text( i ).isEmpty() ) {
			d->m_pathCombo->removeItem( i );
			--i;
		}
	}
	if( ! found ) {
		d->m_pathCombo->setCurrentItem( path, true );
	}
}
//-----------------------------------------------
void KBearFileSysWidget::setView( KFile::FileView view ) {
	d->m_currentViewKind = static_cast<int>(view);

	KFileView* newView = d->m_part->createView( d->m_splitter, view );

	setFocusProxy(newView->widget());
	newView->setSorting( d->m_mySorting );
	newView->setOnlyDoubleClickSelectsFiles( false );
	connectView(newView ); // also deletes the old view
}
//-----------------------------------------------
void KBearFileSysWidget::slotPathActivated( int item ) {
	QString path = d->m_pathCombo->text( item );

	if( path.isEmpty() ) {
		d->m_pathCombo->removeItem( item );
		return;
	}

	emit pathActivated( path );

	KURL tmp = d->m_info.url();
	tmp.setPath( path );
	openURL( tmp );
}
//-----------------------------------------------
void KBearFileSysWidget::slotFilterChanged( const QString& nameFilter ) {
	d->m_dirLister->setNameFilter( nameFilter );
	reload();
}
//-----------------------------------------------
void KBearFileSysWidget::slotStatusMessage( const QString& mess){
	d->m_statusBarUpper->setText( mess );
}
//-----------------------------------------------
void KBearFileSysWidget::slotSpeed( int speed ){
	QString s;
	if( speed == 0)
		s = i18n("Stalled");
	else
		s = ( i18n( "%1/s" ).arg( KIO::convertSize( (KIO::filesize_t)speed ) ) );
	d->m_speedLabel->setText( s );
}
//-----------------------------------------------
void KBearFileSysWidget::slotDeleteItem( KFileItem *item ) {
	d->m_fileView->removeItem( item );
	if( item->isDir() )
		d->m_numDirs = d->m_numDirs -1;
	else
		d->m_numFiles = d->m_numFiles -1;

	d->m_currentSize = d->m_currentSize - item->size();

	QString tmp = KIO::itemsSummaryString (d->m_numFiles + d->m_numDirs, d->m_numFiles, d->m_numDirs, d->m_currentSize, true );
	d->m_directoryLabel->setText( tmp );

}
//-----------------------------------------------
void KBearFileSysWidget::resetCursor() {
	QApplication::restoreOverrideCursor();
 	slotStatusMessage( i18n( "No Operation in Progress" ) );
}
//-----------------------------------------------
KBearDirListerIface* KBearFileSysWidget::dirLister() const {
	return d->m_dirLister;
}
//-----------------------------------------------
void KBearFileSysWidget::setState( unsigned int state ) {
	if( state & KBearFileSysPartInterface::GUIDisabled ) {
		d->m_treeView->setEnabled( false );
		d->m_treeView->blockSignals( true );
		d->m_filterCombo->blockSignals( true );
		d->m_pathCombo->setEnabled( false );
		d->m_filterCombo->setEnabled( false );
		if( d->m_fileView )
			d->m_fileView->signaler()->blockSignals( true );
		return;
	}
	else if( state & KBearFileSysPartInterface::GUIEnabled ) {
		d->m_treeView->setEnabled( true );
		d->m_treeView->blockSignals( false );
		d->m_filterCombo->blockSignals( false );
		d->m_pathCombo->setEnabled( true );
		d->m_filterCombo->setEnabled( true );
		d->m_treeView->setDNDEnabled( true );
		if( d->m_fileView )
			d->m_fileView->signaler()->blockSignals( false );
	}
	if( state & KBearFileSysPartInterface::FilePreview ) {
		d->m_treeView->setDNDEnabled( false );
		if( d->m_fileView )
			d->m_fileView->signaler()->blockSignals( true );
	}
	else {
		d->m_treeView->setDNDEnabled( true );
		if( d->m_fileView )
			d->m_fileView->signaler()->blockSignals( false );
	}
}
//-----------------------------------------------
void KBearFileSysWidget::toggleStatusBarUpper( bool show ) {
	if( ! d->m_statusBarUpper )
		return;
	if( show )
		d->m_statusBarUpper->show();
	else
		d->m_statusBarUpper->hide();
}
//-----------------------------------------------
void KBearFileSysWidget::toggleStatusBarLower( bool show ) {
	if( ! d->m_statusBarLower )
		return;
	if( show )
		d->m_statusBarLower->show();
	else
		d->m_statusBarLower->hide();
}
//-----------------------------------------------
void KBearFileSysWidget::slotRefreshItems( const KFileItemList& items ) {
	if( ! d->m_fileView )
		return;

	KFileItemListIterator it( items );
	for ( ; it.current(); ++it )
		d->m_fileView->updateView( it.current() );
}
//-----------------------------------------------
void KBearFileSysWidget::stop() {
	d->m_dirLister->stop();
}
//-----------------------------------------------
void KBearFileSysWidget::reload() {
	slotPathHasChanged();
	d->m_treeView->slotPrepareForReread( d->m_part->currentURL() );
	openURL( d->m_part->currentURL(), true, true );
}
//-----------------------------------------------
void KBearFileSysWidget::openConnection() {
	if( ! d->m_infoIsSet || ! d->m_dirLister )
		return;

	clearHistory();

	d->m_dirLister->openConnection();
}
//-----------------------------------------------
void KBearFileSysWidget::setSiteInfo( const SiteInfo& info ) {
	d->m_info = info;
	d->m_infoIsSet = true;
	d->m_dirLister->setSiteInfo( info );
	d->m_treeView->setHomeURL( d->m_info.url() );
}
//-----------------------------------------------
void KBearFileSysWidget::setDirLister( KBearDirListerIface* dirLister ) {
	if( ! dirLister )
		return;
	if( d->m_dirLister )
		delete d->m_dirLister;

	d->m_dirLister = dirLister;

	KActionCollection* ac = d->m_part->actionCollection();
	d->m_dirLister->setShowingDotFiles( static_cast<KToggleAction*>( ac->action( "show_hidden" ) )->isChecked() );

	connect( d->m_dirLister, SIGNAL( progress( int ) ), this, SLOT( slotProgress( int ) ) );
	connect( d->m_dirLister, SIGNAL( started() ), this, SLOT( slotStart() ) );
	connect( d->m_dirLister, SIGNAL( newItems( const KFileItemList &) ), this, SLOT( slotNewItems( const KFileItemList &) ) );
	connect( d->m_dirLister, SIGNAL( finishedLoading() ), this, SLOT( slotStop() ) );
	connect( d->m_dirLister, SIGNAL( deleteItem( KFileItem* ) ), this, SLOT( slotDeleteItem( KFileItem* ) ) );
	connect( d->m_dirLister, SIGNAL( openDir( const KURL& ) ), this, SLOT( slotOpenDir( const KURL& ) ) );
	connect( d->m_dirLister, SIGNAL( redirection( const KURL& ) ), this, SLOT( slotRedirected( const KURL& ) ) );
	connect( d->m_dirLister, SIGNAL( clear() ), this, SLOT( slotPathHasChanged() ) );
	connect( d->m_dirLister, SIGNAL( speed(int) ), this, SLOT( slotSpeed(int) ) );
	connect( d->m_dirLister, SIGNAL( refreshItems(  const KFileItemList& ) ), this, SLOT( slotRefreshItems( const KFileItemList& ) ) );
	connect( d->m_dirLister, SIGNAL( infoMessage( const QString& ) ), this, SLOT( slotStatusMessage( const QString& ) ) );
	connect( d->m_dirLister, SIGNAL( connected() ), this, SIGNAL( connected() ) );
}
//-----------------------------------------------
void KBearFileSysWidget::init( const SiteInfo& info ) {
	d->m_info = info;

	if( ! d->m_treeView )
		d->m_treeView = d->m_part->createTreeView( d->m_splitter, info );

	connect( d->m_treeView, SIGNAL( folderSelected( const KFileItem* ) ), this,SLOT( slotDirActivated( const KFileItem* ) ) );
	connect( d->m_dirLister, SIGNAL( deleteItem( KFileItem* ) ), d->m_treeView, SLOT( slotDeleteItem( KFileItem* )));
	connect( d->m_dirLister, SIGNAL( newItems( const KFileItemList &) ), d->m_treeView, SLOT( slotInsertItems( const KFileItemList &) ) );
	connect( d->m_treeView, SIGNAL( selectionChanged() ), d->m_part, SLOT( slotSelectionChanged() ) );

	resetCursor();

}
//-----------------------------------------------
KBearDirView* KBearFileSysWidget::treeView() const {
	return d->m_treeView;
}
//-----------------------------------------------
KFileView* KBearFileSysWidget::fileView() const {
	return d->m_fileView;
}
//-----------------------------------------------
KToolBar* KBearFileSysWidget::toolBarUpper() const {
	return d->m_toolBarUpper;
}
//-----------------------------------------------
KToolBar* KBearFileSysWidget::toolBarLower() const {
	return d->m_toolBarLower;
}
//-----------------------------------------------
void KBearFileSysWidget::embedPart( KParts::Part* part ) {
	if( part ) {
		// Save splitter sizes
		storeSplitterSize();

		part->embed( d->m_splitter );

		d->m_fileView->widget()->hide();
		part->widget()->show();

		// restore splitter size
		restoreSplitterSize();
	}
}
//-----------------------------------------------
void KBearFileSysWidget::storeSplitterSize() {
	d->m_splitterSizes = d->m_splitter->sizes();
	d->m_splitterSizes.append( d->m_splitterSizes[1] );
}
//-----------------------------------------------
void KBearFileSysWidget::restoreSplitterSize() {
	d->m_splitter->setSizes( d->m_splitterSizes );
}
//-----------------------------------------------
KFile::FileView KBearFileSysWidget::viewKind() const {
	return (KFile::FileView)d->m_currentViewKind;
}
//-----------------------------------------------
void KBearFileSysWidget::deleteSelectedItems( bool shred ) {
	if( ! d->m_fileView )
		return;
	const KFileItemList* items = d->m_fileView->selectedItems();
	if( ! items )
		return;

	if( items->isEmpty() ) { // shouldn't happend, but just in case
		KMessageBox::information( this, i18n("You didn't select anything to delete."),i18n("Nothing to delete") );
		return;
	}
	KURL::List urls;
	QStringList files;
	KFileItemListIterator it( *items );
	for( ; it; ++it ) {
		urls.append( (*it)->url() );
		if( (*it)->url().isLocalFile() )
			files.append( (*it)->url().path() );
		else
			files.append( (*it)->url().prettyURL() );
	}
	int ret;
	if( items->count() == 1 ) {
		ret = KMessageBox::warningContinueCancel( this,
						i18n( "<qt>Do you really want to %1\n <b>'%2'</b>?</qt>" )
						.arg( shred?i18n("shred"):i18n("delete") ).arg( files.first() ),
						i18n("%1 file").arg(shred?i18n("Shred"):i18n("Delete")),
						shred?i18n("Shred"):i18n("Delete") );
	}
	else {
		ret = KMessageBox::warningContinueCancelList( this,
						i18n("Do you really want to %1 these items?").arg( shred?i18n("shred"):i18n("delete") ),
						 files, i18n("%1 file").arg(shred?i18n("Shred"):i18n("Delete")),
						shred?i18n("Shred"):i18n("Delete") );
	}
	if( (ret == KMessageBox::Continue) ) {
		d->m_dirLister->deleteFiles( urls, shred, true  );

		if( shred )
			slotStatusMessage( i18n("Shredding file(s)...") );
		else
			slotStatusMessage( i18n("Deleting file(s)...") );
	}
}
//-----------------------------------------------
void KBearFileSysWidget::connectView( KFileView *view ) {
//	kdDebug()<<"KBearFileSysPartInterface::connectView()="<<view<<endl;

//	m_splitter->blockSignals( true );

	view->setViewMode(KFileView::All);
	view->setSelectionMode( KFile::Extended );
	QValueList<int> sizes = d->m_splitter->sizes(); // save splitter sizes so we can restore it for the new view

	if( d->m_fileView ) {
		// transfer the state from old view to new view
		view->clear();
		view->addItemList( *(d->m_fileView)->items() );

		KFileItem *oldCurrentItem = d->m_fileView->currentFileItem();
		if( oldCurrentItem ) {
			view->setCurrentItem( oldCurrentItem );
			view->setSelected( oldCurrentItem, false );
			view->ensureItemVisible( oldCurrentItem );
		}

		const KFileItemList *oldSelected = d->m_fileView->selectedItems();
		if ( !oldSelected->isEmpty() ) {
			KFileItemListIterator it( *oldSelected );
			for ( ; it.current(); ++it )
				view->setSelected( it.current(), true );
		}

		if( d->m_fileView->widget()->hasFocus() )
			view->widget()->setFocus();


		d->m_fileView->widget()->hide();
		delete d->m_fileView;
	}

	d->m_fileView = view;

	KFileViewSignaler *sig = view->signaler();

	connect(sig, SIGNAL( activatedMenu(const KFileItem *, const QPoint& ) ), d->m_part, SLOT( slotActivatedMenu(const KFileItem *, const QPoint& )));
	connect(sig, SIGNAL( dirActivated(const KFileItem *) ), this, SLOT( slotDirActivated(const KFileItem*) ) );
	connect(sig, SIGNAL( fileSelected(const KFileItem *) ), this, SLOT( slotFileSelected(const KFileItem*) ) );
	connect(sig, SIGNAL( fileHighlighted(const KFileItem *) ), d->m_part, SIGNAL( selectionChanged() ) );
	connect(sig, SIGNAL( sortingChanged( QDir::SortSpec ) ), this, SIGNAL( sortingChanged() ) );

	d->m_fileView->widget()->show();
	d->m_splitter->setSizes( sizes ); // restore splitter sizes

	KActionCollection* ac = d->m_part->actionCollection();
	if( static_cast<KToggleAction*>( ac->action( "reversed" ) )->isChecked() != d->m_fileView->isReversed() )
		slotSortReversed();
	view->listingCompleted();
}
//-----------------------------------------------
void KBearFileSysWidget::openURL( const KURL& url, bool reload, bool stat ){
	if( ! reload && url.equals( d->m_dirLister->url(), true ) ) {
		KURL tmp = url;
		tmp.adjustPath( +1 );
		d->m_treeView->slotSetURL( tmp );
		emit newDir( tmp );
		addToHistory( tmp );
		emit finishedLoading();
		return;
	}
	if( reload && stat ) {
		if( ! d->m_fileView->widget()->isHidden() ) {
			d->m_dirLister->openURL( url, true );
		}
		else {
			d->m_dirLister->statURL( url );
		}
	}
	else if( stat ) {
		d->m_dirLister->statURL( url );
	}
	else {
		emit newDir( url );
		d->m_dirLister->openURL( url, reload );
	}
}
//-----------------------------------------------
void KBearFileSysWidget::slotDirActivated( const KFileItem* item ){
//	kdDebug()<<"KBearFileSysPartInterface::slotDirActivated"<<endl;
	if( ! item )
		return;
	//Don't open the dir if control or shift was pressed
	//because we want the user to be able to make multi selections with these keys
	if( isModifierKeysPressed( ControlMask | ShiftMask ) )
		return;
	if(  item->url().url(+1) != d->m_part->currentURL().url( +1 ) ) {
		emit pathChanged();
		slotOpenDir( item->url() );
	}
}
//-----------------------------------------------
void KBearFileSysWidget::slotOpenDir( const KURL& u ){
	KURL url = u;
	// We now know it's a directory so we add a trailing slash
	url.adjustPath( +1 );

	d->m_treeView->slotSetURL( url );
	addToHistory( url );
	openURL( url, false, false );
}
//-----------------------------------------------
void KBearFileSysWidget::slotFileSelected( const KFileItem* item ){
	if( ! item )
		return;
	//Don't open the file if control or shift was pressed
	//because we want the user to be able to make multi selections with these keys
	if( isModifierKeysPressed( ControlMask | ShiftMask ) )
		return;

	openURL( item->url() );
}
//-----------------------------------------------
void KBearFileSysWidget::slotSortByName() {
	int sorting = (d->m_fileView->sorting()) & ~QDir::SortByMask;
	setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Name ));
}
//-----------------------------------------------
void KBearFileSysWidget::slotSortBySize() {
	int sorting = (d->m_fileView->sorting()) & ~QDir::SortByMask;
	setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Size ));
}
//-----------------------------------------------
void KBearFileSysWidget::slotSortByDate() {
	int sorting = (d->m_fileView->sorting()) & ~QDir::SortByMask;
	setSorting( static_cast<QDir::SortSpec>( sorting | QDir::Time ));
}
//-----------------------------------------------
void KBearFileSysWidget::slotToggleDirsFirst() {
	QDir::SortSpec sorting = d->m_fileView->sorting();
	if( !KFile::isSortDirsFirst( sorting ) )
		setSorting( static_cast<QDir::SortSpec>( sorting | QDir::DirsFirst ));
	else
		setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::DirsFirst));
}
//-----------------------------------------------
void KBearFileSysWidget::slotToggleIgnoreCase() {
	QDir::SortSpec sorting = d->m_fileView->sorting();
	if( !KFile::isSortCaseInsensitive( sorting ) )
		setSorting( static_cast<QDir::SortSpec>( sorting | QDir::IgnoreCase ));
	else
		setSorting( static_cast<QDir::SortSpec>( sorting & ~QDir::IgnoreCase));
}
//-----------------------------------------------
void KBearFileSysWidget::slotSortReversed() {
	if( d->m_fileView )
		d->m_fileView->sortReversed();

	d->m_mySorting = d->m_fileView->sorting();
	emit sortingChanged();
}
//-----------------------------------------------
void KBearFileSysWidget::setSorting( QDir::SortSpec spec ) {
	 if ( d->m_fileView ) {
		d->m_fileView->setSorting( spec );
		d->m_mySorting = d->m_fileView->sorting();
		d->m_part->updateSortActions();
	}
}
//-----------------------------------------------
QDir::SortSpec KBearFileSysWidget::sorting() const {
	return d->m_mySorting;
}
//-----------------------------------------------
void KBearFileSysWidget::slotToggleHidden( bool show ) {
	d->m_dirLister->setShowingDotFiles( show );
//	if( ! d->m_dirLister->isLocal() )
		d->m_part->reload();
/*
	if( d->m_fileView )
		d->m_fileView->listingCompleted();
*/
}
//-----------------------------------------------
void KBearFileSysWidget::slotToggleTreeView( bool show ){
	if( ! d->m_treeView )
		return;
	if( show )
		d->m_treeView->show();
	else{
		d->m_treeView->hide();
	}
}
//-----------------------------------------------
void KBearFileSysWidget::slotPathHasChanged() {
	if( d->m_fileView ) {
		d->m_fileView->clear();
	}
	d->m_currentSize = 0;
	d->m_numFiles = 0;
	d->m_numDirs = 0;
	QString tmp = KIO::itemsSummaryString (d->m_numFiles + d->m_numDirs, d->m_numFiles, d->m_numDirs, d->m_currentSize, true );
	d->m_directoryLabel->setText( tmp );

	d->m_pathCombo->completionObject()->clear();
	QApplication::restoreOverrideCursor();
	// when KIO::Job emits finished, the slot will restore the cursor
	QApplication::setOverrideCursor( waitCursor );
}
//-----------------------------------------------
void KBearFileSysWidget::slotNewItems(const KFileItemList &newone) {
	if( newone.isEmpty() || ! d->m_fileView )
		return;

	d->m_fileView->addItemList( newone );

	KFileItem* item;
	KFileItemListIterator it( newone );

	KURL lastURL = d->m_part->lastURL();

	QString tmp;
	while( (item = it.current()) ) {
		if( item->isDir() ) {
			// highlight the dir we come from, if possible
			if( item->url().url(+1) == lastURL.url(+1) ) {
				d->m_fileView->setCurrentItem( item );
				d->m_fileView->ensureItemVisible( item );
			}
			tmp = item->url().path( +1 );
			d->m_numDirs++;
		}
		else {
			tmp = item->url().path( -1 );
			d->m_numFiles++;
		}

		d->m_pathCombo->completionObject()->addItem( d->m_part->toUnicode( tmp ) );

		d->m_currentSize = d->m_currentSize + item->size();
		++it;
	}
	tmp = KIO::itemsSummaryString (d->m_numFiles + d->m_numDirs, d->m_numFiles, d->m_numDirs, d->m_currentSize, true );
	d->m_directoryLabel->setText( tmp );
	QTimer::singleShot(200, this, SLOT(resetCursor()));
}
//-----------------------------------------------
void KBearFileSysWidget::slotRename() {
	KBearFileViewInterface* view = dynamic_cast<KBearFileViewInterface*>( d->m_fileView );
	if( view ) {
		view->rename();
	}
}
//-----------------------------------------------
void KBearFileSysWidget::setInfoText( const QString& txt ) {
	d->m_endLabel->setText( txt );
}
//-----------------------------------------------
void KBearFileSysWidget::readConfig( KConfig* config, const QString& group ) {
	if( ! config )
		return;
	KConfigGroupSaver( config, config->group() );
	if( ! group.isEmpty() )
		config->setGroup( group );

	if( ! d->m_treeView )
		d->m_treeView = d->m_part->createTreeView( d->m_splitter, d->m_info );

	d->m_currentViewKind = 0;
	int sorting = 0;

	QString viewStyle = config->readEntry( QString::fromLatin1("View Style"), QString::fromLatin1("Detail") );
	if( viewStyle == QString::fromLatin1("Detail") ) {
		d->m_currentViewKind = KFile::Detail;
	}
	else {
		d->m_currentViewKind = KFile::Simple;
	}

	if( config->readBoolEntry( QString::fromLatin1("Sort reversed"), false ) )
	 	slotSortReversed();

	if( config->readBoolEntry( QString::fromLatin1("Sort case insensitively"), true ) )
		sorting |= QDir::IgnoreCase;
	if( config->readBoolEntry( QString::fromLatin1("Sort directories first"), true ) )
		sorting |= QDir::DirsFirst;

	QString name = QString::fromLatin1("Name");
	QString sortBy = config->readEntry( QString::fromLatin1("Sort by"), name );
	if( sortBy == name )
		sorting |= QDir::Name;
	else if( sortBy == QString::fromLatin1("Size") )
		sorting |= QDir::Size;
	else if( sortBy == QString::fromLatin1("Date") )
		sorting |= QDir::Time;

	d->m_mySorting = static_cast<QDir::SortSpec>( sorting );
	setSorting( d->m_mySorting );

	slotToggleTreeView( config->readBoolEntry( "Show Tree View", true ) );

	KActionCollection* ac = d->m_part->actionCollection();
	static_cast<KToggleAction*>( ac->action( "tree_view" ) )->setChecked( config->readBoolEntry( "Show Tree View", true ) );

	setView( (KFile::FileView)d->m_currentViewKind );

	d->m_part->updateViewActions();

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

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

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

	QString sortBy = QString::fromLatin1("Name");
	if( KFile::isSortBySize( d->m_mySorting ) )
		sortBy = QString::fromLatin1("Size");
	else if ( KFile::isSortByDate( d->m_mySorting ) )
		sortBy = QString::fromLatin1("Date");
	config->writeEntry( QString::fromLatin1("Sort by"), sortBy );

	config->writeEntry( QString::fromLatin1("Sort reversed"), d->m_fileView->isReversed() );;
	config->writeEntry( QString::fromLatin1("Sort case insensitively"), KFile::isSortCaseInsensitive( d->m_mySorting ) );
	config->writeEntry( QString::fromLatin1("Sort directories first"), KFile::isSortDirsFirst( d->m_mySorting ) );


	KFile::FileView fv = static_cast<KFile::FileView>( d->m_currentViewKind );
	QString style;
	if( KFile::isDetailView( fv ) )
		style = QString::fromLatin1("Detail");
	else if ( KFile::isSimpleView( fv ) )
		style = QString::fromLatin1("Simple");

	config->writeEntry( QString::fromLatin1("View Style"), style );

	config->writeEntry( "Show Tree View", ! d->m_treeView->isHidden() );

	KActionCollection* ac = d->m_part->actionCollection();
	config->writeEntry( QString::fromLatin1("Show hidden files"), static_cast<KToggleAction*>( ac->action( "show_hidden" ) )->isChecked() );

	d->m_fileView->writeConfig( config, group );

}
//-----------------------------------------------
void KBearFileSysWidget::setup(){
	////////////////////////////////////////////////////////////////////////
	// Setup the GUI
	QVBoxLayout* m_layout = new QVBoxLayout( this );
	d->m_toolBarUpper = new KToolBar( this, "ToolBarUpper", false, false );
	d->m_toolBarLower = new KToolBar( this, "ToolBarLower", false, false );
	d->m_toolBarUpper->setEnableContextMenu( false );
	d->m_toolBarUpper->enableMoving( false );
	d->m_toolBarUpper->enableFloating( false );
	d->m_toolBarUpper->setFullSize(true);
	d->m_toolBarLower->setEnableContextMenu( false );
	d->m_toolBarLower->enableMoving( false );
	d->m_toolBarLower->enableFloating( false );
	d->m_toolBarLower->setFullSize(true);

	d->m_splitter = new QSplitter( this );
	d->m_splitter->setOpaqueResize( true );
	d->m_splitter->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));

 	// insert a path label
	QLabel* pathLabel = new QLabel( i18n( "Path: " ), d->m_toolBarLower );
	d->m_toolBarLower->insertWidget( 0, 35, pathLabel, 0 );

	d->m_toolBarLower->insertCombo( QString::null,1,true, SIGNAL( activated( int ) ),
						this, SLOT( slotPathActivated( int ) ),true,i18n("This field displays the current path."), -1,1 );
	d->m_pathCombo = d->m_toolBarLower->getCombo( 1 );
	d->m_pathCombo->setMaxCount( 25 );
	d->m_pathCombo->setSizeLimit( 25 );
	d->m_pathCombo->setDuplicatesEnabled( false );
	d->m_pathCombo->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed));
	QWhatsThis::add( d->m_pathCombo, i18n("This field displays the current path.\n"
							"You can use this to select a new path.") );

	// insert a filter label
	QLabel* filterLabel = new QLabel( d->m_toolBarLower );
	filterLabel->setPixmap( BarIcon("filter") );
	d->m_toolBarLower->insertWidget( 2, 32, filterLabel, 2 );
	// insert a combobox for displaying current filter
	d->m_filterCombo = new KHistoryCombo(d->m_toolBarLower, "Filter");
	d->m_filterCombo->setDuplicatesEnabled( false );
	d->m_toolBarLower->insertWidget( 3, 120, d->m_filterCombo, 3 );
	QToolTip::add( d->m_filterCombo, i18n("This field displays the current filter.") );
	QWhatsThis::add( d->m_filterCombo, i18n("This field displays the current filter. "
							"By changing the filter you can change what is shown in the view.\n"
							"You can use wildcards here to filter the view") );
	d->m_filterCombo->setFixedWidth( 120 );
	d->m_filterCombo->addToHistory( "*" );

	d->m_toolBarLower->alignItemRight( 2, true );
	d->m_toolBarLower->alignItemRight( 3, true );

	d->m_toolBarLower->setItemAutoSized( 1, true );
	d->m_toolBarLower->setStretchableWidget(d->m_pathCombo);

	d->m_toolBarUpper->updateRects(true);
	d->m_toolBarLower->updateRects(true);

	m_layout->addWidget( d->m_toolBarUpper );
	m_layout->addWidget( d->m_toolBarLower );
	m_layout->addWidget( d->m_splitter,10 );

	d->m_statusBarUpper = new QLabel( this, "StatusLabel" );
	QWhatsThis::add( d->m_statusBarUpper,
					i18n("This field displays current state of the connection as well as some other useful information.") );
	m_layout->addWidget( d->m_statusBarUpper );			
	d->m_statusBarUpper->setSizePolicy( QSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred) );
	d->m_statusBarUpper->setFrameStyle ( QFrame::StyledPanel | QFrame::Sunken );

	d->m_statusBarLower = new QHBox( this, "StatusBarLower"  );
	d->m_statusBarLower->setFrameStyle ( QFrame::StyledPanel | QFrame::Sunken );
	// insert a progress bar
	d->m_progress = new KProgress( d->m_statusBarLower, "progress" );
	d->m_speedLabel = new QLabel( d->m_statusBarLower, "SpeedLabel");
	d->m_speedLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
	d->m_speedLabel->setFrameStyle ( QFrame::StyledPanel | QFrame::Sunken );

	// insert labels for displaying numbers of dirs and files in current path
	d->m_directoryLabel = new QLabel( d->m_statusBarLower, "DirectoryLabel");
	QWhatsThis::add( d->m_directoryLabel, i18n("This field displays the number of directories and files in current directory.") );
	d->m_directoryLabel->setFrameStyle ( QFrame::StyledPanel | QFrame::Sunken );

	d->m_endLabel = new QLabel( d->m_statusBarLower, "EndLabel");
	d->m_endLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter | Qt::ExpandTabs );
	d->m_endLabel->setFrameStyle ( QFrame::StyledPanel | QFrame::Sunken );
	d->m_endLabel->setText( i18n("Not connected") );

	d->m_statusBarLower->setStretchFactor( d->m_progress, 7 );
	d->m_statusBarLower->setStretchFactor( d->m_speedLabel, 10 );
	d->m_statusBarLower->setStretchFactor( d->m_directoryLabel, 0 );
	d->m_statusBarLower->setStretchFactor( d->m_endLabel, 10 );
	m_layout->addWidget( d->m_statusBarLower );

	// add 'wheel' animation
	d->m_toolBarUpper->insertAnimatedWidget( 1, 0, 0, QString("kde") );
	d->m_toolBarUpper->alignItemRight( 1, true );
	QWhatsThis::add( d->m_toolBarUpper->animatedWidget(1),
			i18n("This animation is active during directory loading and will stop as soon as the directory is completely loaded.") );

	connect( d->m_filterCombo, SIGNAL( activated( const QString& ) ), this, SLOT( slotFilterChanged(const QString&) ) );
	connect( d->m_filterCombo, SIGNAL( returnPressed(const QString&) ), d->m_filterCombo, SLOT( addToHistory(const QString&) ) );

}
//-----------------------------------------------
