/***************************************************************************
                          directoryview.cpp  -  description
                             -------------------
    begin                : Sat Dec 1 2001
    copyright            : (C) 2001 by Richard Groult
    email                : rgroult@jalix.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
 *   General Public License for more details.                              *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   *
 *   USA.                                                                  *
 *                                                                         *
 *   For license exceptions see LICENSE.EXC file, attached with the source *
 *   code.                                                                 *
 *                                                                         *
 ***************************************************************************/

#include "directoryview.h"

// Local
#include "describeAlbum.h"
#include "directory.h"
#include "imageviewer.h"
#include "imagefileiconitem.h"
#include "compressedimagefileiconitem.h"
#include "imagelistview.h"
#include "mainwindow.h"
#include "album.h"
#include "listitem.h"
#include "cdarchivecreatordialog.h"
#ifdef HAVE_KIPI
#include "kipiplugins/kipipluginmanager.h"
#endif /* HAVE_KIPI */

// Qt
#include <qstring.h>
#include <qfile.h>
#include <qptrlist.h>
#include <qtimer.h>
#include <qprogressdialog.h>
#include <qdropsite.h>
#include <qdragobject.h>
#include <qtooltip.h>
#include <qdatastream.h>
#include <qmessagebox.h>
#include <qprogressdialog.h>
#include <qdir.h>
#include <qclipboard.h>
#include <qpopupmenu.h>
#include <qheader.h>

// KDE
#include <kurlrequesterdlg.h>
#include <kio/job.h>
#include <kio/jobclasses.h>
#include <kmessagebox.h>
#include <klineeditdlg.h>
#include <kglobalsettings.h>
#include <kpropertiesdialog.h>
#include <kfiledialog.h>
#include <klocale.h>
#include <kiconloader.h>
#include <klistview.h>
#include <kdirwatch.h>
#include <kapplication.h>
#include <kaction.h>
#include <kpopupmenu.h>
#ifndef Q_WS_WIN
#include <konq_operations.h>
#endif
#include <kurldrag.h>
#include <kimageio.h>
#include <kmimetype.h>
#if  KDE_VERSION >= 0x30200
#include <kinputdialog.h>
#endif


#define MYDEBUG kdDebug()<<__FILE__<<" " <<__LINE__ << " " << __FUNCTION__ << " "

DirectoryView::DirectoryView (QWidget * parent, ImageViewer * iv,
	ImageListView* imageList, MainWindow * mw)
	:KListView (parent, "DirectoryView")
{
	this->iv = iv;
	this->imageList = imageList;
	this->mw = mw;

	addColumn (i18n("Name"));
	addColumn (i18n("Type"));
	addColumn (i18n("Size"));
	addColumn (" ");

	setColumnAlignment( COLUMN_TYPE, Qt::AlignLeft );
	setColumnAlignment( COLUMN_SIZE, Qt::AlignRight );

	setAcceptDrops (true);
	setAllColumnsShowFocus(true);
	setShowToolTips(true);
	setShowSortIndicator(true);
	setSelectionModeExt (KListView::Extended);

	setFullWidth(true);

	header()->setClickEnabled(FALSE, COLUMN_SELECT);
	header()->setStretchEnabled(true, COLUMN_NAME);
	header()->setMovingEnabled ( false );

	setColumnWidthMode (COLUMN_SELECT, Manual );
	setColumnWidth(COLUMN_SELECT, 3*ListItem::TREE_CHECKBOX_MAXSIZE/2);
	header()->setResizeEnabled (false, COLUMN_SELECT );

	setSorting (COLUMN_TYPE);
	sort();
	setColumnWidthMode (COLUMN_TYPE, Manual );
	//hideColumn ( COLUMN_TYPE ) ;
	setColumnWidth (COLUMN_TYPE, 0 );

	setShowHiddenDir(false);
	dropping = false;

	currentOperation=NONE;
	autoSkip=false;
	replaceAll=false;
	currentOperation=NONE;
	fileToProcess=NULL;
	destDir=NULL;
	clickedItem=NULL;

	image_pixmap=NULL;

	autoopenTime = 750;
	autoopen_timer = new QTimer (this);
	connect (autoopen_timer, SIGNAL (timeout ()),
			this, SLOT (openFolder ()));

	//////////////
	dirWatch = new KDirWatch();
#ifndef SHOWIMG_NO_CDARCHIVE
	dirWatch->addDir(QDir::homeDirPath()+"/.showimg/cdarchive/");
#endif
	connect(dirWatch, SIGNAL(dirty (const QString&)),
			mw, SLOT(slotDirChange(const QString&)));
	connect(dirWatch, SIGNAL(created (const QString&)),
			mw, SLOT(slotDirChange_created(const QString&)));
	connect(dirWatch, SIGNAL(deleted (const QString&)),
			mw, SLOT(slotDirChange_deleted(const QString&)));
	startWatchDir();

	///
	connect(this, SIGNAL(selectionChanged ()), SLOT(slotSelectionChanged ()));
}


DirectoryView::~DirectoryView()
{
}

void
DirectoryView::initMenu(KActionCollection *actionCollection)
{
	this->actionCollection=actionCollection;

	popup = new KPopupMenu();
		popup->insertTitle("", 1);
	actionCollection->action("create_new_items")->plug(popup);
	actionCollection->action("dirRecOpen")->plug(popup);
	popup->insertSeparator();
	actionCollection->action("editdircopy")->plug(popup);
	actionCollection->action("editdirmove")->plug(popup);
	actionCollection->action("editdirrename")->plug(popup);
	actionCollection->action("editdirtrash")->plug(popup);
	actionCollection->action("editdirdelete")->plug(popup);
	popup->insertSeparator();
	actionCollection->action("editdirpaste files")->plug(popup);
	popup->insertSeparator();
	actionCollection->action("Dir Info")->plug(popup);
	actionCollection->action("Dir Properties")->plug(popup);
}


ListItem*
DirectoryView::getDir(const QString& path)
{
	ListItem *ssrep;
	ListItem *rootItems = firstChild ();
	while(rootItems)
	{
		if(path.startsWith(rootItems->fullName()))
		{
			ssrep = rootItems->find(path);
			if (ssrep)
			{
				return ssrep;
			}
		}
		rootItems = rootItems->nextSibling();
	}
	return NULL;
}

void
DirectoryView::removeDir(const QString& dirfullname)
{
	ListItem * item = getDir(dirfullname);
	if(item)
	{
		if(item->isSelected()) item->unLoad();
		delete(item);
	}
}


void
DirectoryView::slotDirInfo()
{
	if(clickedItem)
	{
		   (void)DescribeAlbum(mw, clickedItem->fullName()).exec();
	}
}

void
DirectoryView::slotDirProperty()
{
	if(clickedItem)
	{
		KApplication::setOverrideCursor (waitCursor);
		KFileItem *item = new KFileItem(KFileItem::Unknown,
				KFileItem::Unknown,
				clickedItem->getURL(),
				true);
        	KPropertiesDialog prop( item,
			mw->iv, "KPropertiesDialog",
			true, false);

		KApplication::restoreOverrideCursor ();
		prop.exec();
		delete(item);
	}
}

bool
DirectoryView::isDropping()
{
	return dropping;
}

void
DirectoryView::slotShowItem (QListViewItem * item)
{
	ensureItemVisible(item);
}

void
DirectoryView::startWatchDir(QString dir)
{
	if(dirWatch->contains(dir)) return;
	
	dirWatch->stopScan();
	QFileInfo info(dir);
	if(info.isDir())
	{
		dirWatch->addDir(dir);
	}
	else
	if(info.isFile())
	{
		dirWatch->addFile(dir);
	}
	dirWatch->startScan();
}

void DirectoryView::stopWatchDir(QString dir)
{
	if(QFileInfo(dir).isDir())
		dirWatch->removeDir(dir);
	else
	if(QFileInfo(dir).isFile())
		dirWatch->removeFile(dir);
}

void
DirectoryView::startWatchDir()
{
	  dirWatch->startScan();
}


void
DirectoryView::stopWatchDir()
{
	dirWatch->stopScan();
}


void
DirectoryView::updateActions(ListItem *item)
{
	if(!item)
	{
		imageList->load(NULL);
		return;
	}
	bool enableAction=true;
	if(item->text (1) != i18n("Directory"))
		enableAction=false;
	actionCollection->action("editpaste")->setEnabled(enableAction);
	actionCollection->action("editdirnew")->setEnabled(enableAction);
	actionCollection->action("editalbumnew")->setEnabled(enableAction);
	actionCollection->action("dirRecOpen")->setEnabled(enableAction);
	actionCollection->action("editdircopy")->setEnabled(enableAction);

	enableAction = !item->isReadOnly();
	actionCollection->action("editdirmove")->setEnabled(enableAction);
	actionCollection->action("editdirrename")->setEnabled(enableAction);
	actionCollection->action("editdirtrash")->setEnabled(enableAction);
	actionCollection->action("editdirdelete")->setEnabled(enableAction);
	actionCollection->action("editdirpaste files")->setEnabled(enableAction);
	actionCollection->action("Dir Info")->setEnabled(enableAction);

}


void
DirectoryView::slotSelectionChanged ()
{
	if(isDropping()) return;
	updateActions(currentItem());
	if(!imageList->hasImageSelected()) imageList->load(NULL);
#ifdef HAVE_KIPI
	mw->pluginManager()->currentAlbumChanged(currentItem()->fullName());
#endif
}



void
DirectoryView::contentsDragEnterEvent (QDragEnterEvent * event)
{
	dropping = true;
	initSelectedListItem();
	if (QTextDrag::canDecode (event))
	{
		event->acceptAction ();
		ListItem *i = itemAt (contentsToViewport (event->pos ()));
		if (i)
		{
			dropItem = i;
			autoopen_timer->start (autoopenTime);
		}
	}
}

void
DirectoryView::contentsDragLeaveEvent (QDragLeaveEvent *)
{
	autoopen_timer->stop ();
	restoreSelectedListItem();
	dropping = false;
}

void
DirectoryView::contentsDragMoveEvent (QDragMoveEvent * e)
{
	if(!dropping)
		return;

	if (!QTextDrag::canDecode (e))
	{
		e->ignore ();
		return;
	}

	ListItem *i = itemAt (contentsToViewport ( e->pos ()));
	if (i)
	{
		setSelected (i, TRUE);
		e->acceptAction ();
		if (i != dropItem)
		{
			autoopen_timer->stop ();
			dropItem = i;
			autoopen_timer->start (autoopenTime);
		}
	}
	else
	{
		e->ignore ();
		autoopen_timer->stop ();
		dropItem = NULL;
	}
}


void
DirectoryView::contentsDropEvent (QDropEvent * event)
{
	autoopen_timer->stop ();

	if ( !QUriDrag::canDecode(event) || !dropItem)
	{
		event->ignore();
	}
	else
	{
		event->acceptAction(true);
		imageList->stopLoading();

		QImage image;
		QStrList lst;

		if (QUriDrag::decode (event, lst))
		{
			event->acceptAction();
			if (dropItem->text(1) == i18n("Album"))
				((Album*)dropItem)->addURL(QStringList::fromStrList(lst));
			else
			if (dropItem->text(1) != i18n("Directory"))
			{
				KMessageBox::error (this,
						"<qt>"+i18n("Adding file in '%1' is not yet implemented")
							.arg(((ListItem*) dropItem)->text (1))+"</qt>",
					 	i18n("File(s) Copy/Move"));
			}
			else
			if(!QFileInfo(((Directory*)dropItem)->fullName()).isWritable ())
			{
				KMessageBox::error (this,
						i18n("The destination directory is not writable"),
						i18n("File(s) Copy/Move"));
			}
			else
			switch (event->action ())
			{


				case QDropEvent::Copy:
				case QDropEvent::Move:
				{
					bool canBeMoved = true;
					if(event->source() == imageList)
						canBeMoved = imageList->currentDragItemAreMovable();

					destDir=new QString( ((ListItem*)dropItem)->fullName());
					contentsDragLeaveEvent(NULL);
					if (event->action () == QDropEvent::Move && canBeMoved )
						move(QStringList::fromStrList(lst), *destDir);
					else
						copy(QStringList::fromStrList(lst), *destDir);
				}
		 		return;
		 		default:return;
			}
		}
	}
	restoreSelectedListItem();
	dropping = false;
}


QString
DirectoryView::getDestName(const QString& /*orgFile*/, const QString& /*destDir*/)
{
	return QString::null;
}

void
DirectoryView::copyNext()
{
	kdWarning() << __FILE__ << __LINE__ << " DirectoryView::copyNext()"   << endl;
}

void
DirectoryView:: moveNext()
{
	kdWarning() << __FILE__ << __LINE__ << " DirectoryView:: moveNext()"   << endl;
}

ListItem*
DirectoryView::itemAt ( const QPoint & viewPos ) const
{
	return (ListItem*)KListView::itemAt(viewPos);
}
ListItem*
DirectoryView::currentItem () const
{
	return (ListItem*)KListView::currentItem ();
}
ListItem*
DirectoryView::firstChild() const
{
	return (ListItem*)KListView::firstChild ();
}

void
DirectoryView::contentsMouseReleaseEvent(QMouseEvent* e)
{
	if (e->button () == LeftButton)
	{
		ListItem *item=itemAt(contentsToViewport(e->pos()));
		if(item)
			if(item->isSelected())
				return;
	}
	KListView::contentsMouseReleaseEvent(e);
}


void
DirectoryView::contentsMousePressEvent(QMouseEvent * e)
{
	if (e->button () == RightButton)
	{
		clickedItem = itemAt(contentsToViewport(e->pos()));
		updateActions(clickedItem);
		popup->changeTitle(1, clickedItem->text(0));
		popup->exec(e->globalPos());
	}
	else
	if (e->button () == MidButton)
		contentsMouseDoubleClickEvent(e);
	else
	if (e->button () == LeftButton)
	{
		if(header()->sectionAt(e->x())!=3)
			KListView::contentsMousePressEvent (e);
		else
		{
			ListItem *item = itemAt(contentsToViewport(e->pos()));
			setSelected(item, !item->isSelected());
		}
	}

}

void
DirectoryView::contentsMouseDoubleClickEvent ( QMouseEvent * e )
{
	QListViewItem *item=itemAt(contentsToViewport(e->pos()));
	if(!item)
		return;
	if(item->isOpen())
		item->setOpen(false);
	else
		item->setOpen(true);
}

void
DirectoryView::contentsMouseMoveEvent ( QMouseEvent * e )
{
	if(e->state () != LeftButton)
		KListView::contentsMouseMoveEvent(e);
}

void
DirectoryView::copyingDirDone( KIO::Job *job)
{
	if(job->error()==0)
	{
		//pas d'erreurs
		ListItem* dest=getDir(dirDest);
		if(dest)
		{
			if(!dest->isOpen())
			{
				//rien a faire
			}
			else
			{
				QString name=QDir(dirOrg).dirName();
				if(!getDir(dirDest+name))
				{
					//ajout du rep
					if(dest->text(1)==i18n("Directory"))
					{
						(void)new Directory( (Directory*)dest, name, this, iv, imageList, mw);
					}
					dest->setExpandable(true);
				}
			}
		}
		else
		{
		}
	}
	else
	{
		//erreur
		job->showErrorDialog(mw);
	}

}

void
DirectoryView::movingDirDone( KIO::Job *job)
{
	if(job->error()==0)
	{
		//pas d'erreurs
	}
	else
	{
		//erreur
		job->showErrorDialog(mw);
	}
}

void
DirectoryView::copyingDone( KIO::Job *job)
{
	if(job->error()==0)
	{
		//pas d'erreurs
	}
	else
	{
		//erreur
		job->showErrorDialog();
	}
}

void
DirectoryView::movingDone( KIO::Job *job )
{
	if(job->error()==0)
	{
		//pas d'erreurs
		mw->slotRefresh();
	}
	else
	{
		//erreur
		job->showErrorDialog();
	}
}

bool
DirectoryView::copy (QString *dep, QString *dest)
{
	copy(QStringList(*dep), *dest);
	return true;
}


bool
DirectoryView::move (QString *dep, QString *dest)
{
	move(QStringList(*dep), *dest);
	return true;
}



void
DirectoryView::copy(const QStringList& uris, const QString& dest)
{
#ifndef Q_WS_WIN
	if(!QFileInfo(dest).isDir())
	{
		 KMessageBox::error(mw->iv, "<qt>"
		 	+i18n("Unable to copy files into '%1' because it is not a directory.").arg(dest)
			+"</qt>",
			i18n("File(s) Copy"));
		 return;
	}
	KURL urldest;
	urldest.setPath(dest);
	//
	KURL::List list;
	QStringList _uris_=uris;
	KURL url;
	for ( QStringList::Iterator it = _uris_.begin(); it != _uris_.end(); ++it )
	{
		KURL tmp_url(*it);
		url.setPath(tmp_url.path());
		list.append(url);
	}
	KIO::CopyJob *job = KIO::copy(list, urldest);
	connect(job, SIGNAL(result( KIO::Job *)),
		this, SLOT(copyingDone( KIO::Job *)));
#endif
}


void
DirectoryView::move(const QStringList& uris, const QString& dest)
{
#ifndef Q_WS_WIN
	if(!QFileInfo(dest).isDir())
	{
		 KMessageBox::error(mw->iv, "<qt>"
		 	+i18n("Unable to move files into '%1' because it is not a directory.").arg(dest)
			+"</qt>",
			i18n("File(s) Copy"));
		 return;
	}
	KURL urldest;
	urldest.setPath(dest);
	//
	KURL::List list;
	QStringList _uris_=uris;
	KURL url;
	for ( QStringList::Iterator it = _uris_.begin(); it != _uris_.end(); ++it )
	{
		KURL tmp_url(*it);
		url.setPath(tmp_url.path());
		list.append(url);
	}
	KIO::CopyJob *job = KIO::move(list, urldest);
	connect(job, SIGNAL(result( KIO::Job *)),
		this, SLOT(movingDone( KIO::Job *)));
#endif
}



void
DirectoryView::openFolder ()
{
	autoopen_timer->stop ();
	if (dropItem && !dropItem->isOpen ())
	{
		setOpen(dropItem, true);
	}
}


void
DirectoryView::slotDirPasteFiles()
{
	KURL::List uris;
	if(KURLDrag::decode(KApplication::clipboard()->data(), uris))
	{
		if(!uris.isEmpty())
			copy(uris.toStringList(), clickedItem->fullName());
	}

}


void
DirectoryView::slotRename ()
{
  if(!clickedItem) clickedItem=currentItem();
	slotRename(clickedItem);
}


void
DirectoryView::slotRename (QListViewItem *item)
{
	if(!item) return;

	ListItem *dir=(ListItem*)item;
	QString fullname=dir->fullName();
	QString name=dir->name();
	bool ok;
	#if  KDE_VERSION < 0x30200
	const QString newName(KLineEditDlg::getText("<qt>"+i18n("Rename '<b>%1</b>':").arg(shrinkdn(fullname)+"</qt>"),
				name,
				&ok, mw)
			.stripWhiteSpace());
	#else
	const QString newName(KInputDialog::getText(i18n("Rename %1").arg(name),
					i18n("Enter new name:"),
					 name,
					 &ok, mw->iv).stripWhiteSpace());
	#endif
	if(ok && !newName.isEmpty() && newName!=name)
	{
		QString newDirName=dir->path()+"/"+newName;
		if(QFileInfo(newDirName).exists())
		{
			KMessageBox::error(mw->iv, "<qt>"+i18n("The directory '<b>%1</b>' already exists").arg(shrinkdn(newDirName))+"</qt>");
			return;
		}
		dir->rename(newName);
	}
}
void
DirectoryView::renameDone( KIO::Job *job)
{
	if(job->error()==0)
	{
		//pas d'erreurs
		clickedItem->rename();
	}
	else
	{
		//erreur
		job->showErrorDialog(mw);
	}

}

void
DirectoryView::slotNewAlbum()
{
  if(!clickedItem) clickedItem=currentItem();
	slotNewAlbum(clickedItem);
}


void
DirectoryView::slotNewAlbum (QListViewItem *item)
{
  if(!item) return;
	bool ok;
	#if  KDE_VERSION < 0x30200
	const QString newName(KLineEditDlg::getText("<qt>"+i18n("Create New Album in %1").arg(shrinkdn(((Directory*)item)->fullName())+"</qt>"),
				i18n("Album"),
				&ok, mw).stripWhiteSpace());
	#else
	const QString newName(KInputDialog::getText(i18n("Create New Album in %1").arg(shrinkdn(((Directory*)item)->fullName())),
					i18n("Enter album name:"),
					 i18n("Album"),
					 &ok, mw->iv).stripWhiteSpace());
	#endif
	if(!ok || newName.isEmpty())
		return;

	KURL url("file:"+((Directory*)item)->fullName()+"/"+newName+".sia");
	if(url.fileName()!=NULL)
	{
		if(QFileInfo(url.path()).exists())
		{
		 	 KMessageBox::error(mw->iv, "<qt>"+i18n("The album <b>%1</b> already exists").arg(url.fileName())+"</qt>");
		 	 return;
		}
		((Directory*)item)->createAlbum(url.fileName());
	}
}


void
DirectoryView::slotNewDir()
{
	if(!clickedItem) clickedItem=currentItem();
	slotNewDir(clickedItem);
}

void
DirectoryView::slotNewDir (QListViewItem *item)
{
  if(!item) return;
	bool ok;
	#if  KDE_VERSION < 0x30200
	const QString newName(KLineEditDlg::getText("<qt>"+i18n("Create new directory in %1").arg(shrinkdn(((Directory*)item)->fullName()))+"</qt>",
				i18n("Directory"),
				&ok, mw).stripWhiteSpace());
	#else
	const QString newName(KInputDialog::getText(i18n("Create New Directory in %1").arg(shrinkdn(((Directory*)item)->fullName())),
					i18n("Enter directory name:"),
					 i18n("Directory"),
					 &ok, mw->iv).stripWhiteSpace());
	#endif
	if(!ok || newName.isEmpty())
		return;

	KURL url("file:"+((Directory*)item)->fullName()+"/"+newName);
	if(url.fileName()!=NULL)
	{
		if(QFileInfo(url.path()).exists())
		{
		 	 KMessageBox::error(mw->iv, "<qt>"+i18n("The directory '<b>%1</b>' already exists").arg(url.fileName())+"</qt>");
		 	 return;
		}
		((Directory*)item)->createDir(url.fileName());
	}
}

void
DirectoryView:: slotTrash()
{
	if(!clickedItem) clickedItem=currentItem();
	slotTrash(clickedItem);
}

void
DirectoryView::slotTrash (QListViewItem *item)
{
#ifndef Q_WS_WIN
	if(!item) return;
	ListItem *dir=(ListItem*)item;
	dir->setOpen(false);
	KonqOperations::del(mw, KonqOperations::TRASH, dir->getURL());
#endif
}


void
DirectoryView:: slotSuppr()
{
	if(!clickedItem) clickedItem=currentItem();
	slotSuppr(clickedItem);
}

void
DirectoryView::slotSuppr (QListViewItem *item)
{
#ifndef Q_WS_WIN
	if(!item) return;
	Directory *dir=(Directory*)item;
	dir->setOpen(false);
	KonqOperations::del(mw, KonqOperations::DEL, dir->getURL());
#endif
}

void
DirectoryView::recursivelyOpen()
{
  if(!clickedItem) clickedItem=currentItem();
	recursivelyOpen(clickedItem);
}

void
DirectoryView::recursivelyOpen(QListViewItem *item)
{
  if(!clickedItem) clickedItem=currentItem();
  if(!clickedItem) return;
	((Directory*)item)->recursivelyOpen();
}


void
DirectoryView::slotDirCopy()
{
	Directory* item=(Directory*)clickedItem;
	if(!item)
		return;

	QString destDir =
		KFileDialog::getExistingDirectory(lastDestDir.isEmpty()?item->fullName():lastDestDir,
									mw,
									i18n("Copy Directory %1 To").arg(shrinkdn(item->fullName())));

	if(!destDir.isEmpty())
	{
		lastDestDir=destDir;
		QString dest=destDir+"/";

		KURL
			urlorg("file:"+item->fullName()),
			urldest("file:"+dest);
		dirOrg=item->fullName();
		dirDest=dest;

		KIO::CopyJob *job = KIO::copy(urlorg, urldest, true);
		connect(job, SIGNAL(result( KIO::Job *)), this, SLOT(copyingDirDone( KIO::Job *)));
	}
}

void
DirectoryView::slotDirMove()
{
	Directory* item=(Directory*)clickedItem;
	if(!item)
		return;

		QString destDir=KFileDialog::getExistingDirectory(lastDestDir.isEmpty()?item->fullName():lastDestDir,
								mw,
								i18n("Move Directory %1 To").arg(shrinkdn(item->fullName())));

	if(!destDir.isEmpty())
	{
		lastDestDir=destDir;
		QString dest=destDir+"/"+item->text(0);
		if(QFileInfo(dest).exists())
		{
		 	 KMessageBox::error(mw->iv, "<qt>"
			 	+i18n("The directory '<b>%1</b>' already exists").arg(shrinkdn(dest))+"</qt>");
		 	 return;
		}

		if(!QFileInfo(QFileInfo(dest).dirPath()).isWritable())
		{
		 	 KMessageBox::error(mw->iv, "<qt>"
			 	+i18n("The directory '<b>%1</b>' is not writable").arg(shrinkdn(dest))+"</qt>");
		 	 return;
		}

		KURL
			urlorg("file:"+item->fullName()),
			urldest("file:"+dest);

		dirOrg=item->fullName();
		dirDest=destDir+"/";

		KIO::FileCopyJob *job = KIO::file_move(urlorg, urldest, -1, true, false, true);
		connect(job, SIGNAL(result( KIO::Job *)), this, SLOT(movingDirDone( KIO::Job *)));
	}
}

void
DirectoryView::setShowHiddenDir(bool show)
{
	__showHiddenDir__=show;
}

bool
DirectoryView::showHiddenDir()
{
	return __showHiddenDir__;
}

void
DirectoryView::setLoadFirstImage(bool load)
{
	__loadfirstimage__=load;
}

bool
DirectoryView::loadFirstImage()
{
	return __loadfirstimage__;
}


void
DirectoryView::setShowHiddenFile(bool show)
{
	__showHiddenFile__=show;
}

bool
DirectoryView::showHiddenFile()
{
	return __showHiddenFile__;
}

void
DirectoryView::setShowAllFile(bool show)
{
	__showAllFile__=show;
}
void
DirectoryView::setShowDir(bool show)
{
	__showDir__=show;
}

bool
DirectoryView::showDir()
{
	return __showDir__;
}


int
DirectoryView::filter ()
{
	int fil;
	if(showHiddenFile())
		fil = QDir::Hidden|QDir::Files;
	else
		fil = QDir::Files;
	if(showDir())
		fil = fil | QDir::Dirs;
	return fil;
}

bool
DirectoryView::isImage(const QString& info)
{
	QFileInfo *finfo = new QFileInfo(info);
	bool isImg=isImage(finfo);
	delete(finfo);
	return isImg;
}

bool
DirectoryView::isImage(QFileInfo *info)
{

        KMimeType::Ptr mime = KMimeType::findByPath( info->absFilePath(), 0, true );
#if KDE_VERSION < 0x30200
	if( mime->name() == KMimeType::defaultMimeType())
		mime = KMimeType::findByFileContent( info->absFilePath() );
        if(
            mime->name() == "image/jpeg"
         || mime->name() == "image/gif"
         || mime->name() == "image/png"
         || mime->name() == "image/x-bmp"
         || mime->name() == "image/tiff"
         || mime->name() == "image/xpm"
         || mime->name() == "image/x-xcf"
         || mime->name() == "image/x-gimp"
         || mime->name() == "image/x-xcf-gimp"
         || mime->name() == "image/x-ico"
         || mime->name() == "image/pbm"
         || mime->name() == "image/x-eps"
         || mime->name() == "image/krl"
         || mime->name() == "image/ppm"
         || mime->name() == "image/x-psd"
         || mime->name() == "image/xbm"
         || mime->name() == "image/pgm")
            return true;
	else
		return KImageIO::canRead(KImageIO::type(info->filePath ()));
#else
	if( mime->is(KMimeType::defaultMimeType()) )
		mime = KMimeType::findByFileContent( info->absFilePath() );
        if(
            mime->is("image/jpeg")
         || mime->is("image/gif")
         || mime->is("image/png")
         || mime->is("image/bmp")
         || mime->is("image/tiff")
         || mime->is("image/xpm")
         || mime->is("image/xcf")
         || mime->is("image/x-xcf")
         || mime->is("image/x-gimp")
         || mime->is("image/x-xcf-gimp")
         || mime->is("image/xcf")
         || mime->is("image/ico")
         || mime->is("image/pbm")
         || mime->is("image/eps")
         || mime->is("image/krl")
         || mime->is("image/ppm")
         || mime->is("image/x-psd")
         || mime->is("image/xbm")
         || mime->is("image/pgm"))
            return true;
	else
		return KImageIO::canRead(KImageIO::type(info->filePath ()));
#endif
}


QString
DirectoryView::shrinkdn(const QString& str)
{
	const unsigned int len=20;
	if(str.length()<=len)
		return str;
	else
		return QString(str.left(len/2) + "..." + str.right(len/2));
}


QDragObject*
DirectoryView::dragObject ()
{
	return NULL;
}

void
DirectoryView::slotNewCDArchive()
{
#ifndef SHOWIMG_NO_CDARCHIVE
	CDArchiveCreatorDialog dial(mw->getcdromPath(), mw);
	dial.exec();
#endif
}

void
DirectoryView::initSelectedListItem()
{
	ListItem *rootItems = firstChild ();
	while(rootItems)
	{
		initSelectedListItem(rootItems);
		rootItems = rootItems->nextSibling();
	}
	setSelectionMode (QListView::Single);
	oldCurrent=currentItem();
}
void
DirectoryView::initSelectedListItem(ListItem *item)
{
	ListItem *myChild = item->firstChild();
	if(item->isSelected())
		oldCurrents.append(item);
	while( myChild )
	{
		initSelectedListItem( myChild );
		myChild = myChild->nextSibling();
        }
}

void
DirectoryView::restoreSelectedListItem()
{
	setUpdatesEnabled(FALSE);

	clearSelection ();
	setSelectionMode (QListView::Extended);
	ListItem *item;
	for ( item = oldCurrents.first(); item; item = oldCurrents.next() )
		setSelected (item, TRUE);
	setCurrentItem (oldCurrent);
	oldCurrents.clear();
	oldCurrent=NULL;

	setUpdatesEnabled(TRUE);
}

int
DirectoryView::getIconSize()
{
	return KIcon::SizeSmall;
	//return KIcon::SizeMedium;
}

void
DirectoryView::goToNextDir()
{
	if(!currentItem()) return;
	ListItem * item = currentItem()->itemBelow();
	if(!item) return;
	clearSelection ();
	setCurrentItem(item);
	item->setSelected(true);
	ensureItemVisible(item);
}

void
DirectoryView::goToPreviousDir()
{
	if(!currentItem()) return;
	ListItem * item = currentItem()->itemAbove();
	if(!item) return;
	clearSelection ();
	setCurrentItem(item);
	item->setSelected(true);
	ensureItemVisible(item);
}


#include "directoryview.moc"
