/***************************************************************************
                          imagelistview.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 "imagelistview.h"

// Local
#include "imageloader.h"
#include "directoryview.h"
#include "mainwindow.h"

#include "kexifpropsplugin.h"
#ifndef Q_WS_WIN
#include "khexeditpropsplugin.h"
#endif
#include "qtfileicondrag.h"
#include "imagefileiconitem.h"
#include "dirfileiconitem.h"
#include "imageviewer.h"
#include "imagemetainfo.h"

#ifdef HAVE_KIPI
#include "kipiplugins/kipipluginmanager.h"
#endif /* HAVE_KIPI */

#ifdef HAVE_LIBKEXIF
        #if LIBKEXIF_VERSION < 020
        #warning LIBKEXIF_VERSION < 020
        #include <libkexif/kexif.h>
        #else
        #warning LIBKEXIF_VERSION >= 020
        #include <libkexif/kexifdialog.h>
        #endif
#else
#ifdef __GNUC__
#warning no HAVE_LIBKEXIF
#endif
#endif /* HAVE_LIBKEXIF */

// KDE
#include <kprocess.h>
#include <kiconview.h>
#include <kfileiconview.h>
#include <kaccel.h>
#include <kaction.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kpropsdlg.h>
#include <kopenwith.h>
#include <klineeditdlg.h>
#include <kurlrequesterdlg.h>
#include <kglobalsettings.h>
#include <kio/job.h>
#include <kfiledialog.h>
#include <kfileitem.h>
#include <klocale.h>
#include <kpopupmenu.h>
#include <kiconeffect.h>
#include <kpixmapio.h>
#include <kcursor.h>
#include <kglobalsettings.h>
#ifndef Q_WS_WIN
#include <konq_operations.h>
#endif
#include <kapplication.h>
#include <kmimetype.h>
#if  KDE_VERSION >= 0x30200
#include <kinputdialog.h>
#endif

// QT
#include <qmessagebox.h>
#include <qevent.h>
#include <qmime.h>
#include <qiconview.h>
#include <qevent.h>
#include <qkeycode.h>
#include <qpopupmenu.h>
#include <qdragobject.h>
#include <qstringlist.h>
#include <qlistview.h>
#include <qtextcodec.h>

#include <stdlib.h>

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

KToolTip::KToolTip(QWidget *parent, ImageListView *imageList)
: QToolTip(parent)
{
	this->imageList=imageList;
}


void
KToolTip::maybeTip(const QPoint &pos)
{
	FileIconItem *item = (FileIconItem*)imageList->itemAt(
					imageList->viewportToContents(pos));
	if(!item)
		return;
	QRect r = item->pixmapRect(false);
	r.moveTopLeft(imageList->contentsToViewport(r.topLeft()));
	if ( !r.isValid() )
		return;
	tip(r, item->toolTipStr());
}


void
KToolTip::tip ( const QRect & r, const QString& text )
{
	QToolTip::tip(r, text);
}

/////////////////////////
ImageListView::ImageListView (QWidget * parent, const char *name,
				MainWindow * mw)
	:KIconView (parent, name)
{
	this->mw = mw;

	m_popup = new KPopupMenu (); m_popup->insertTitle("", 1);
	m_popup_openWith = new KPopupMenu ();
	m_popupEmpty = new KPopupMenu ();

	il = new ImageLoader (this);

	sortMode=0;
	loop_=true;
	preload_=true;
	random_=false;

	curIt=NULL;
	dscr=NULL;
	isLoadingThumbnail=false;
	mouseIsPressed=false;
	m_currentDragItemAreMovable=false;
	toolTips = new KToolTip(viewport(), this);
	//toolTips = NULL;

	currentIconItem=NULL;

	connect(this, SIGNAL(selectionChanged()),
			SLOT(selectionChanged()));
	connect(this, SIGNAL(onItem(QIconViewItem*)),
			SLOT(highlight(QIconViewItem *)));
	connect(this, SIGNAL(onViewport()),
			SLOT(onViewport()));
	connect(this, SIGNAL(contextMenuRequested(QIconViewItem *, const QPoint &)),
			SLOT(popup(QIconViewItem *, const QPoint &)));

	setResizeMode (Adjust);
	setWordWrapIconText(true);
	setSelectionMode (Extended);
	setItemsMovable ( true );
	setItemTextPos( Bottom );
	setArrangement(LeftToRight);
	setSpacing(5);


	iconEffect=new KIconEffect();
}


KPopupMenu*
ImageListView::popupOpenWith()
{
	popup(currentItem(), QPoint());
	return m_popup_openWith;
}

void
ImageListView::popup(QIconViewItem *item, const QPoint &)
{
	m_popup_openWith->clear();
	m_popup_openWith->disconnect();

	if(!item)
	{
		m_popup_openWith->setEnabled(false);
		return;
	}
	else
	{
		m_popup_openWith->setEnabled(true);
	}

	if(((FileIconItem*)item)->mimetype().left(5)=="image")
	{
		actionCollection->action("Open with Gimp")->plug(m_popup_openWith);
		m_popup_openWith->insertSeparator ();
	}
	//
	m_offerList = KTrader::self()->query(((FileIconItem*)item)->mimetype(), "Type == 'Application'");
	for (uint i=0; i < m_offerList.count(); i++)
	{
		m_popup_openWith->insertItem(SmallIcon(m_offerList[i]->icon()), m_offerList[i]->name(), i+1);
	}
	if(m_offerList.size()!=0)
		m_popup_openWith->insertSeparator ();

	actionCollection->action("Open with")->plug(m_popup_openWith);
	connect(m_popup_openWith, SIGNAL(activated(int)),
		this, SLOT(slotRun(int)));
	mouseIsPressed=false;
}

void
ImageListView::slotRun(int  id)
{
	if((uint)id>=1 && (uint)id<=m_offerList.size())
	{
		KURL::List list;
		for ( FileIconItem *item = firstItem(); item; item = item->nextItem() )
		{
			if ( item->isSelected() )
				list << item->getURL();
		}
		if (KRun::run(*m_offerList[id-1], list)==0)
		{
			KMessageBox::error(this, "<qt>"+i18n("Error while running %1.").arg((*m_offerList[id-1]).name())+"</qt>");
		}
	}
}


bool
ImageListView::doPreload()
{
	return preload_;
}

void
ImageListView::setPreload(bool p)
{
	this->preload_=p;
}

bool
ImageListView::doLoop()
{
	return loop_;
}

void
ImageListView::setLoop(bool loop)
{
	this->loop_=loop;
}

bool
ImageListView::doRandom()
{
	return random_;
}

void
ImageListView::setRandom(bool ran)
{
	this->random_=ran;
}


void
ImageListView::setShowToolTips(bool s)
{
	sToolTips_=s;
/*
	if(getShowToolTips() && !toolTips)
	{
		toolTips = new KToolTip(viewport(), this);
	}
	else
	{
		delete(toolTips);
		toolTips=NULL;
	}
*/
}

bool
ImageListView::getShowToolTips()
{
	return sToolTips_;
}

FileIconItem*
ImageListView::itemAt(const QPoint pos)
{
	return (FileIconItem*)QIconView::findItem(pos);
}

void
ImageListView::setThumbnailSize(const QSize newSize, bool )
{
	currentIconSize = new QSize(newSize);
	il->setThumbnailSize(getCurrentIconSize());

	setUpdatesEnabled(false);

	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
	{
		i->setHasPreview (false);
		if(!mw->preview())
			i->setPixmap(i->fileInfo()->pixmap(
				getCurrentIconSize().width()/2));
		else
			i->calcRect();
	}

	setUpdatesEnabled(true);
	slotUpdate();
	arrangeItemsInGrid();
	ensureItemVisible(currentItem());
}


QSize
ImageListView::getCurrentIconSize()
{

	if(!mw->preview())
		return (*currentIconSize/2);
	else
		return *currentIconSize;
}

void
ImageListView::slotUpdate ()
{
	repaint(); repaintContents();
	KIconView::slotUpdate();
	kapp->processEvents();
}

void
ImageListView::slotResetThumbnail()
{
 	stopLoading();
	setUpdatesEnabled(false);
	for (FileIconItem * item = firstItem ();
		item != 0;
		item = item->nextItem ())
	{
		item->setPixmap(item->fileInfo()->pixmap(
			getCurrentIconSize().width()/2));
	}
	setUpdatesEnabled(true);
}


void
ImageListView::slotRename()
{
	if(KIconView::currentItem())
	{
		bool ok;
		QString name=((ImageFileIconItem*)KIconView::currentItem())->text(0);
	#if  KDE_VERSION < 0x30200
		const QString newName(KLineEditDlg::getText(i18n("Rename '<b>%1</b>':").arg(name),
					 name,
					 &ok, mw->iv).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())
		{
			((ImageFileIconItem*)KIconView::currentItem())->setText(newName);
		}
	}
}

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

	actionCollection->action("create_new_items")->plug(m_popupEmpty);
	actionCollection->action("editpaste")->plug(m_popupEmpty);

	m_popupEmpty->insertSeparator();
	actionCollection->action("view_icons")->plug(m_popupEmpty);
	actionCollection->action("view_sort")->plug(m_popupEmpty);

	m_popupEmpty->insertSeparator();
	actionCollection->action("SelectAll")->plug(m_popupEmpty);
	actionCollection->action("Unselect All")->plug(m_popupEmpty);
	actionCollection->action("Invert Selection")->plug(m_popupEmpty);

	/////////////
	actionCollection->action("editcopy")->plug(m_popup);

	m_popup->insertSeparator();
	actionCollection->action("rename")->plug(m_popup);
	actionCollection->action("edittrash")->plug(m_popup);
	actionCollection->action("editdelete")->plug(m_popup);

	m_popup->insertSeparator();
	actionCollection->action("copyFilesTo")->plug(m_popup);
	actionCollection->action("moveFilesTo")->plug(m_popup);


	m_popup->insertSeparator();
	m_popup_openWith = new KPopupMenu ();
	m_popup->insertItem(i18n("Open With"), m_popup_openWith);
	
	////////
	KActionMenu *aEXIF = new KActionMenu( i18n("EXIF"), 0, actionCollection, "EXIF actions" );
	aEXIF->popupMenu()->insertTitle(i18n("Exif Information"));
	////////
	aEXIF_Orientation_normal=new KToggleAction(i18n("Top Left"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation normal");
	aEXIF_Orientation_hflip=new KToggleAction(i18n("Top Right"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation hflip");
	//aEXIF_Orientation_rot180=new KToggleAction(i18n("normal"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation ");
	aEXIF_Orientation_vflip=new KToggleAction(i18n("Bottom Left"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation vflip");
	//aEXIF_Orientation_rot90hflip=new KToggleAction(i18n("normal"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation ");
	aEXIF_Orientation_rot90=new KToggleAction(i18n("Right Top"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation rot90");
	//aEXIF_Orientation_rot90vflip=new KToggleAction(i18n("normal"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation ");
	aEXIF_Orientation_rot270=new KToggleAction(i18n("Left Bottom"),0, this,SLOT(slotEXIFOrientation()), actionCollection,"EXIF orientation rot270");

	KActionMenu *aEXIF_Orientation = new KActionMenu( i18n("Orientation"), "rotate", actionCollection, "EXIF orientation" );
	aEXIF_Orientation->insert(aEXIF_Orientation_normal);
	aEXIF_Orientation->insert(aEXIF_Orientation_hflip);
	aEXIF_Orientation->insert(aEXIF_Orientation_vflip);
	aEXIF_Orientation->insert(aEXIF_Orientation_rot90);
	aEXIF_Orientation->insert(aEXIF_Orientation_rot270);

	aEXIF->insert(aEXIF_Orientation);

	////////
	KAction *a_regenEXIFThumb=new KAction(i18n("(Re)generate EXIF Thumbnail"), "thumbnail", 0, this, SLOT(generateEXIFThumbnails()), actionCollection,"Regenerate EXIF thumbnail" );
	aEXIF->insert(a_regenEXIFThumb);
	a_regenEXIFThumb->setEnabled(false);

	////////
	if(actionCollection->action("files_Display_Exif_Information"))
	{
		aEXIF->insert(new KActionSeparator());
		actionCollection->action("files_Display_Exif_Information")->plug(aEXIF->popupMenu());
	}

	aEXIF->plug(m_popup);
	////////
	KAction *a_regen=new KAction(i18n("Regenerate Thumbnail"), 0, this, SLOT(forceGenerateThumbnails()), actionCollection,"Regenerate thumbnail" );
	a_regen->plug(m_popup);
	a_regen->setEnabled(false);

	////////
	m_popup->insertSeparator();
	actionCollection->action("Image Info")->plug(m_popup);
	actionCollection->action("Properties")->plug(m_popup);
}


void
ImageListView::refresh ()
{
	mw->slotRefresh();
}


QString
ImageListView::currentItemName()
{
	if(currentItem())
		return currentItem()->text();
	else
		return QString();
}


void
ImageListView::setCurrentItemName(const QString& itemName, bool select)
{
	 KIconView::setCurrentItem(findItem(itemName));
	 if(currentItem())
	 {
	 	KIconView::setSelected(currentItem(), select, false);
		KIconView::ensureItemVisible (currentItem());
		kapp->processEvents();
	 	if(select) currentItem()->setSelected(true);
	}
}

bool
ImageListView::hasImages()
{
	return KIconView::count()!=0;
}

bool
ImageListView::hasImageSelected()
{
	if(!hasImages())
		return false;
	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
	{
		if(i->isSelected() && i->isImage())
			return true;
	}
	return false;
}

bool
ImageListView::hasSelection()
{
	if(!hasImages())
		return false;
	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
	{
		if(i->isSelected() )
			return true;
	}
	return false;
}

int
ImageListView::countSelected()
{
	int number=0;
	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
		if(i->isSelected())
			number++;
	return number;
}


bool
ImageListView::hasOnlyOneImageSelected()
{
	int number=0;
	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
	{
		if(i->isSelected())
			number++;
		if(number>=2) return false;

	}
	return true;
}


FileIconItem*
ImageListView::firstSelected()
{
	for (FileIconItem *i = firstItem(); i; i=i->nextItem() )
	{
		if(i->isSelected())
			return i;
	}
	return NULL;
}



void
ImageListView::selectionChanged()
{
	int nbrSel=selectedURLs().count();
	mw->setHasImageSelected(nbrSel>0);
	if(nbrSel>1)
		mw->setMessage(i18n("%1 selected files").arg(nbrSel));
	else
		mw->setMessage(i18n("Ready"));

#ifdef HAVE_KIPI
	mw->pluginManager()->selectionChanged(hasImageSelected());
#endif /* HAVE_KIPI */
}

void
ImageListView::slotLoadFirst(bool force, bool forceEXIF)
{
	if (mw->preview() && count()>0 && !isLoadingThumbnail)
	{
		stopLoading();

		mw->slotReset ();
		imageLoading = firstItem();
		if(count()==1)
		{
			if(!imageLoading->hasPreview() && imageLoading->isImage())
			{
				isLoadingThumbnail=true;
				QFileInfo *fi = new QFileInfo(imageLoading->fullName());
				il->loadMiniImage (fi, true, force, forceEXIF);
			}
			else imageLoading=NULL;
		}
		else
		{
			int nbr=0;
			while(   imageLoading &&
				( (imageLoading->hasPreview() || !imageLoading->isImage())) ||
				  (forceEXIF && ! imageLoading->isSelected()))
			{
				if(imageLoading->isImage()) nbr++;
				imageLoading=imageLoading->nextItem ();

			}
			mw->slotPreviewDone (nbr);
			if(imageLoading)
			{
				actionCollection->action("Regenerate thumbnail")->setEnabled(false);
				actionCollection->action("Regenerate EXIF thumbnail")->setEnabled(false);
				isLoadingThumbnail=true;
				slotLoadNext (force, forceEXIF);
			}
		}
		if(!imageLoading) mw->slotDone();
	}
}

void
ImageListView::slotLoadFirst(FileIconItem *item)
{
	if (mw->preview())
	{

		mw->slotReset (false);
		imageLoading = item;
		if(imageLoading)
		{
			isLoadingThumbnail=true;
			slotLoadNext ();
		}
		else
			mw->slotDone ();
	}
}

void
ImageListView::slotLoadNext (bool force, bool forceEXIF)
{
	if(!isLoadingThumbnail) return;
	if(imageLoading)
	{
		while(! imageLoading->isImage()
			|| imageLoading->hasPreview()
			|| QFileInfo(imageLoading->fullName()).extension(true).lower()=="psd"
			|| forceEXIF && ! imageLoading->isSelected())
		{
			imageLoading = imageLoading->nextItem ();
			if(!imageLoading)break;
		}
	}
	if(imageLoading)
	{
		QFileInfo *fi = new QFileInfo(imageLoading->fullName());
		il->loadMiniImage (fi, true, force, forceEXIF);
	}
	else
	{
		stopLoading();
	}
}


void
ImageListView::slotSetPixmap (const QPixmap pm, QFileInfo *imgFile, bool success, bool force, bool forceEXIF)
{
	if(!isLoadingThumbnail) return;
	nbrTh++;
	if(imageLoading)
	{
		if(imgFile->absFilePath() != imageLoading->fullName())
			imageLoading = findItem (imgFile->absFilePath(), true);
		if(imageLoading)
		{
			imageLoading->setPixmap (pm, success);
			if((force || forceEXIF) && imageLoading->isSelected()) reload();
		}
		mw->slotPreviewDone ();
		repaint(imageLoading); kapp->processEvents();
		if(imageLoading) imageLoading = imageLoading->nextItem ();
	}
	if (imageLoading)
		slotLoadNext (force, forceEXIF);
	else
		stopLoading ();
}

void
ImageListView::stopLoading ()
{
	il->stopLoading (true);
	imageLoading=NULL;
	isLoadingThumbnail=false;
	mw->slotDone();
	nbrTh=0;
}


void
ImageListView::next ()
{
	if(!hasImages())
		return;

	FileIconItem *item=NULL;
	if(doRandom())
	{
		srand(time(NULL));
		while(item==NULL)
		{
			int x = (int)(rand()/(RAND_MAX+1.0)*contentsWidth());
			int y = (int)(rand()/(RAND_MAX+1.0)*contentsHeight());
			item=(FileIconItem *)KIconView::findItem((const QPoint&)QPoint(x,y));
		}
	}
	else
	{
		item=currentItem();
		if(!item)
			item=firstItem();
		else
			item=item->nextItem();
	}
	
	if(item)
	{
		while(item && !item->isImage())
			item=item->nextItem ();
		if(item)
		{
	 		KIconView::ensureItemVisible (item);
	 		KIconView::setCurrentItem (item);
	 		KIconView::setSelected (item, true, false);
	 		item ->setSelected (true);
			if(dscr) slotImageInfo();
			
			return;
		}
	}
	if(doLoop()) 
	{
		first();
		/* FIXME
		if(!mw->fullScreen())
			first();
		else
			mw->dirView->goToNextDir();
		*/
	}
}


void
ImageListView::previous ()
{
	if(!hasImages())
		return;

	FileIconItem *item=NULL;
	if(doRandom())
	{
		srand(time(NULL));
		while(item==NULL)
		{
			int x = (int)(rand()/(RAND_MAX+1.0)*contentsWidth());
			int y = (int)(rand()/(RAND_MAX+1.0)*contentsHeight());
			item=(FileIconItem *)KIconView::findItem((const QPoint&)QPoint(x,y));
		}
	}
	else
	{
		item=currentItem();
		if(!item)
			item=firstItem();
		else
			item=item->prevItem();
	}
	if(item)
	{
		while(item && !item->isImage())
			item=item->prevItem ();
		if(item)
		{
	 		KIconView::ensureItemVisible (item);
	 		KIconView::setCurrentItem (item);
	 		KIconView::setSelected (item, true, false);
	 		item ->setSelected (true);
			if(dscr)slotImageInfo();
		}
		else if(doLoop()) last();
	}
	else if(doLoop()) last();
}

void
ImageListView::contentsMousePressEvent (QMouseEvent * e)
{
	KIconView::contentsMousePressEvent (e);
	mouseIsPressed=true;

	if (e->button () == RightButton)
	{
		int nbS = countSelected();
		if(nbS != 0)
		{
			if(nbS == 1)
				m_popup->changeTitle(1, currentItem()->text());
			else
				m_popup->changeTitle(1, i18n("%1 selected files").arg(nbS));

			popup(currentItem(), e->globalPos ());
			m_popup->exec(e->globalPos ());
		}
		else
			m_popupEmpty->exec (e->globalPos ());
	}
}

void
ImageListView::contentsMouseReleaseEvent (QMouseEvent * e)
{
	mouseIsPressed=false;
	if (e->button () == LeftButton)
	{
		int nbs=0;
		for (FileIconItem * item = firstItem (); item != 0; item = item->nextItem ())
		{
			if (item->isSelected () )
			{
				nbs++;
				if(nbs==2) break;
			}
		}
		if(nbs!=1)
		{
			KIconView::contentsMouseReleaseEvent ( e );
			return;
		}
	}
	mousePress(e);
}


void
ImageListView::mousePress (QMouseEvent * e)
{
	FileIconItem *si = firstSelected();
	if (e->button () == MidButton)
	{
		contentsMouseDoubleClickEvent(e);
	}
	else
	if (e->button () == LeftButton)
	{
		KIconView::contentsMouseReleaseEvent ( e );
		if(!KGlobalSettings::singleClick())
		{
			if(si)
			{
				si->setSelected (true);
				if(dscr)slotImageInfo();
			}
		}
		else
		{
			if(!si) return;
			QString dirName=si->fullName();
			if(si->fileInfo()->mimetype().right(9)=="directory")
			{
				curIt=NULL;
				KApplication::restoreOverrideCursor ();
				mw->openDir(dirName);
			}
			else
			{
				si->setSelected (true);
			}
		}
	}
	mouseIsPressed=false;
}

void
ImageListView::contentsMouseDoubleClickEvent ( QMouseEvent * e)
{
	if (!currentItem () || e->button () == RightButton) return;
	if( currentItem()->isImage())
	{
		mw->slotFullScreen ();
		currentItem ()->setSelected (true);
	}
	else
	if(currentItem()->fileInfo()->mimetype().right(9)=="directory")
	{
		curIt=NULL;KApplication::restoreOverrideCursor ();
		mw->openDir(QDir::cleanDirPath(((FileIconItem*)currentItem())->fullName()));
	}
	else
		KRun::runURL(currentItem()->getURL(), currentItem()->fileInfo()->mimetype());
}

QString
ImageListView::getCurrentKey()
{
	switch(sortMode)
	{
		case 0:return "name";
		case 1:return "type";
		case 2:return "size";
		case 3:return "date";
		case 4:return "dirname";
		default:return "name";
	}
}


void
ImageListView::sort()
{
	KIconView::sort();
}


void
ImageListView::slotByName()
{
	sortMode=0;
	FileIconItem *i;
	for (i=firstItem(); i; i = i->nextItem() )
		i->setKey("name");
	sort();
}

void
ImageListView::slotByDirName()
{
	sortMode=4;
	FileIconItem *i;
	for (i=firstItem(); i; i = i->nextItem() )
		i->setKey("dirname");
	sort();
}


void
ImageListView::slotByExtension()
{
	sortMode=1;
	FileIconItem *i;
	for (i=firstItem(); i; i = i->nextItem() )
		i->setKey("type");
	sort();
}


void
ImageListView::slotBySize()
{
	sortMode=2;
	FileIconItem *i;
	for (i=firstItem(); i; i = i->nextItem() )
		i->setKey("size");
	sort();
}


void
ImageListView::slotByDate()
{
	sortMode=3;
	FileIconItem *i;
	for (i=firstItem(); i; i = i->nextItem() )
		i->setKey("date");
	sort();
}


QDragObject *
ImageListView::dragObject ()
{
	if ( !currentItem() )
		return 0;
	QPoint orig = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) );
	QtFileIconDrag *drag = new QtFileIconDrag( this, "ImageListView::dragObject()" );
	drag->setPixmap( *currentItem()->pixmap(),
				QPoint( currentItem()->pixmapRect().width() / 2,
					currentItem()->pixmapRect().height() / 2 ) );
	m_currentDragItemAreMovable = true;
	for ( FileIconItem *item = firstItem(); item; item = item->nextItem() )
	{
		if ( item->isSelected() )
		{
			QIconDragItem id;

			QCString curl = item->getURL().url().utf8();
			id.setData(curl);
			drag->append( id,
				QRect(	item->pixmapRect( FALSE ).x() - orig.x(),
					item->pixmapRect( FALSE ).y() - orig.y(),
					item->pixmapRect().width(), item->pixmapRect().height() ),
				QRect(	item->textRect( FALSE ).x() - orig.x(),
					item->textRect( FALSE ).y() - orig.y(),
					item->textRect().width(), item->textRect().height() ),
				item->getURL().url());
			m_currentDragItemAreMovable = m_currentDragItemAreMovable && item->isMovable();
		}
	}
	return drag;
}


void
ImageListView::slotWallpaper ()
{
	FileIconItem *item = currentItem ();
	if (!item)
		return;
	currentItem ()->setWallpaper ();
}


void
ImageListView::slotFileProperty()
{
	if(!currentItem())
		return;
	KApplication::setOverrideCursor (waitCursor);
	//
	KFileItemList itemList;
	for (FileIconItem * item = firstItem (); item != 0; item = item->nextItem ())
	{
		if (item->isSelected ())
		{
			itemList.append(item->fileInfo());
		}
	}
	KPropertiesDialog *prop	= new KPropertiesDialog( itemList,
		mw->iv, "KPropertiesDialog",
		true, false);
	//
	if(itemList.count()==1)
	{
		KEXIFPropsPlugin *exifProp=NULL;
		if(showMeta() && currentItem()->mimetype()=="image/jpeg")
		{
			exifProp= new KEXIFPropsPlugin(prop, currentItem()->fullName());
			prop->insertPlugin(exifProp);
		}
		//
		if(currentItem()->fileInfo()->mimetype().right(9)!="directory")
		{
			QFile::Offset big = 0x500000;// 5MB
			QFile qfile( currentItem()->fullName() );
			if(showHexa() && qfile.size() < big)
			{
#ifndef Q_WS_WIN
				KHexeditPropsPlugin *hexeditProp = new KHexeditPropsPlugin(prop, currentItem()->fullName());
				prop->insertPlugin(hexeditProp);
#endif
			}
		}
	}
	//
	KApplication::restoreOverrideCursor ();
	if(prop->exec())
	{
		//prop->applyChanges();
	}
}



void
ImageListView::slotImageInfo()
{
 	if(!currentItem()) return;

	KApplication::setOverrideCursor (waitCursor);
	if(!dscr)
	{
		dscr = new Describe(mw->iv, currentItem()->fullName(), "ImageInfo");
		connect(dscr, SIGNAL(close()), SLOT(slotDescribeClose()));
	}
	else
		dscr->setImageFile(currentItem()->fullName());
	KApplication::restoreOverrideCursor ();
	dscr->show();
}

void
ImageListView::slotDescribeClose()
{
	delete(dscr); dscr=NULL;
}

void
ImageListView::slotKhexedit()
{
	FileIconItem *item = currentItem ();
	if (!item)
		return;
	KRun::run("khexedit",
		KURL::List(QStringList(item->getURL().url())));
}


void
ImageListView::slotGimp ()
{
	KURL::List list;
	for ( FileIconItem *item = firstItem(); item; item = item->nextItem() )
	{
		if ( item->isSelected() )
		list << item->getURL();
	}
	if (list.isEmpty()) return;
	if (KRun::run(getgimpPath() ,list, "gimp", "gimp")==0)
	{
		KMessageBox::error(this, "<qt>"+i18n("Error while running Gimp.<br>Please check \"gimp-remote\" on your system.")+"</qt>");
	}
}


void
ImageListView::slotEndGimp (KProcess *proc)
{
	if(proc->exitStatus()!=0)
	{
		FileIconItem* item = currentItem ();
		if (!item)
			return;
		KRun::run("gimp", item->getURL());
	}
}



void
ImageListView::slotSupprimmer ()
{
	KURL::List list;
	QPtrList < FileIconItem > iconList;
	FileIconItem *nextItem = 0;
	for (FileIconItem * item = firstItem (); item != 0; item = item->nextItem ())
	{
		if (item->isSelected ())
		{
			nextItem = item->nextItem ();
			if (item->text (3) == "file")
			{
				list.append(item->getURL());
			}
			else
			{
				iconList.append(item);
			}
		}
	}
	if(!list.empty())
	{
#ifndef Q_WS_WIN
		KonqOperations::del(mw, KonqOperations::DEL, list);
#endif
	}

	for ( FileIconItem * item = iconList.first(); item; item = iconList.next() )
		item->suppression(false);


	if (nextItem)
	{
		KIconView::setCurrentItem (nextItem);
		nextItem->setSelected (true);
		ensureItemVisible (currentItem());
	}
}


void
ImageListView::deletionDone( KIO::Job *job)
{
	if(job->error()!=0) job->showErrorDialog();
	refresh();
}


void
ImageListView::slotMoveToTrash()
{
	FileIconItem *nextItem = NULL;
	QPtrList < FileIconItem > iconList;
	KURL::List list;
	for (FileIconItem * item = firstItem (); item != 0; item = item->nextItem ())
	{
		if (item->isSelected ())
		{
			nextItem = item->nextItem ();
			if (item->text (3) == "file")
			{
				list.append(item->getURL());
			}
			else
			{
				iconList.append(item);
			}
		}
	}
	if(!list.empty())
	{
#ifndef Q_WS_WIN
		KonqOperations::del(mw, KonqOperations::TRASH, list);
#endif
	}
	for ( FileIconItem * item = iconList.first(); item; item = iconList.next() )
		item->moveToTrash();

	if (nextItem)
	{
		KIconView::setCurrentItem (nextItem);
		nextItem->setSelected (true);
		ensureItemVisible (currentItem());
	}
}


void
ImageListView::slotShred()
{
	KURL::List list;
	QPtrList < FileIconItem > iconList;
	FileIconItem *nextItem = 0;
	for (FileIconItem * item = firstItem ();
	    item != 0; item =  item->nextItem ())
	{
		if (item->isSelected ())
		{
			nextItem = item->nextItem ();
			if (item->text (3) == "file")
			{
				list.append(item->getURL());
			}
			else
			{
				iconList.append(item);
			}
		}
	}
	if(!list.empty())
	{
#ifndef Q_WS_WIN
		KonqOperations::del(mw, KonqOperations::SHRED, list);
#endif
	}
	for ( FileIconItem * item = iconList.first(); item; item = iconList.next() )
		item->shred();

	if (nextItem)
	{
		KIconView::setCurrentItem (nextItem);
		nextItem->setSelected (true);
		ensureItemVisible (currentItem());
	}
}



void ImageListView::first ()
{
	if(!hasImages())
	{
		mw->setEmptyImage();
		return;
	}
	FileIconItem *item=firstItem();
	while(item && !item->isImage())
		item=item->nextItem ();
	if(!item) {mw->setEmptyImage(); return;}
	KIconView::ensureItemVisible (item);
	KIconView::setCurrentItem (item);
	KIconView::setSelected (item, true, false);
	item ->setSelected (true);
	if(dscr)slotImageInfo();

}


void ImageListView::last ()
{
	if(!hasImages())
		return;

	FileIconItem *item=lastItem();
	while(item && !item->isImage())
		item=item->prevItem ();
	if(!item) return;
	KIconView::ensureItemVisible (item);
	KIconView::setCurrentItem (item);
	KIconView::setSelected (item, true, false);
	item ->setSelected (true);
	if(dscr)slotImageInfo();
}


FileIconItem*
ImageListView::findItem (const QString& text, bool fullname)
{
	for (FileIconItem *i=firstItem(); i; i=i->nextItem())
	{
		if(fullname && i->fullName()==text)
			return i;
		else
		if(i->text()==text)
			return i;
	}
	return NULL;
}

void ImageListView::slotOpenWith()
{
	FileIconItem *item = currentItem ();
	if (!item)
		return;
	if(mw->fullScreen())
		mw->slotFullScreen();
	KURL::List url(item->getURL());
	KOpenWithDlg dialog(url, mw);
	if(dialog.exec()!=0)
		KRun::run(dialog.text(),
			item->getURL());
}

void
ImageListView::slotUnselectAll()
{
	clearSelection ();
}

void
ImageListView::slotInvertSelection()
{
	KIconView::invertSelection () ;
}

void
ImageListView::slotSelectAll()
{
	KIconView::selectAll(true);
}


void
ImageListView::setPreloadIm(bool prel)
{
	preload_=prel;
}
bool
ImageListView::preloadIm()
{
	return preload_;
}


bool
ImageListView::showMeta()
{
	return sMeta_;
}
void
ImageListView::setShowMeta(bool sMeta)
{
	sMeta_=sMeta;
}
bool
ImageListView::showHexa()
{
	return sHexa_;
}
void
ImageListView::setShowHexa(bool sHexa)
{
	sHexa_=sHexa;
}

bool
ImageListView::getShowMimeType()
{
	return sMimeType_;
}
void
ImageListView::setShowMimeType(bool s)
{
	sMimeType_=s;
}
bool
ImageListView::getShowSize()
{
	return sSize_;
}
void
ImageListView::setShowSize(bool s)
{
	sSize_=s;
}
bool
ImageListView::getShowDate()
{
	return sDate_;
}
void
ImageListView::setShowDate(bool s)
{
	sDate_=s;
}
bool
ImageListView::getShowDimension()
{
	return sDimension_;
}
void
ImageListView::setShowDimension(bool s)
{
	sDimension_=s;
}


void
ImageListView::setItemTextPos ( ItemTextPos pos )
{
	if(itemTextPos()==pos)
		return;
	if(pos==Bottom)
	{
		setGridX(gridX()-200+10);
		setWordWrapIconText (true);
}
	else
	{
		setGridX(gridX()+200-10);
		setWordWrapIconText (true);
	}
	KIconView::setItemTextPos(pos);
}


void
ImageListView::slotFilesMoveTo()
{
	QStringList uris;
	for (FileIconItem* item = firstItem (); item != 0; item =  item->nextItem ())
	{
		if (item->isSelected () )
		{
			uris.append(QUriDrag::localFileToUri(item->fullName()));
		}
	}
	if(!uris.isEmpty())
	{
		QString destDir=KFileDialog::getExistingDirectory(!lastDestDir.isEmpty()?lastDestDir:mw->currentURL(),
						mw, i18n("Move Selected Files To"));
		if(!destDir.isEmpty())
		{
			lastDestDir=destDir;
			mw->moveFilesTo(uris, destDir+"/");
		}
	}
}

void
ImageListView::slotFilesCopyTo()
{
	QStringList uris;
	for (FileIconItem* item = firstItem (); item != 0; item = item->nextItem())
	{
		if (item->isSelected () )
		{
			uris.append(QUriDrag::localFileToUri(item->fullName()));
		}
	}
	if(!uris.isEmpty())
	{
		QString destDir=KFileDialog::getExistingDirectory(!lastDestDir.isEmpty()?lastDestDir:mw->currentURL(),
					mw, i18n("Copy Selected Files To"));
		if(!destDir.isEmpty())
		{
			lastDestDir=destDir;
			mw->copyFilesTo(uris, destDir+"/");
		}
	}
}

void
ImageListView::highlight(QIconViewItem *item)
{
	if (curIt) onViewport();
	if (!item || ! iconEffect->hasEffect(0,1))
	{
		if(KGlobalSettings::changeCursorOverIcon())
			KApplication::restoreOverrideCursor ();
		return;
	}
	if(KGlobalSettings::changeCursorOverIcon()) KApplication::setOverrideCursor (KCursor::handCursor());
	if(mouseIsPressed) { curIt=NULL; return; }

	curIt = (FileIconItem *)item;
	if(!curIt->isSelectable()){ curIt=NULL; return; }

	setUpdatesEnabled( FALSE );
	delete(currentIconItem);
	currentIconItem = new QPixmap(*(curIt->pixmap()));
	currentIconItemName = curIt->fullName();
	currentIconItemHasPreview = curIt->hasPreview();
	curIt->setPixmap(iconEffect->apply(*curIt->pixmap(),0,1), curIt->hasPreview());
	setUpdatesEnabled( TRUE );
	repaintItem(curIt);
}


void
ImageListView::onViewport()
{
	if(KGlobalSettings::changeCursorOverIcon()) KApplication::restoreOverrideCursor ();
	if(curIt==NULL) return;
	if(!curIt->isSelectable()) { curIt=NULL; return; }
	if(currentIconItemName != curIt->fullName() ) { curIt=NULL; return; }
	if(currentIconItemHasPreview != curIt->hasPreview()) { curIt=NULL; return; }

	setUpdatesEnabled( FALSE );
	curIt->setPixmap(*currentIconItem, curIt->hasPreview());

	setUpdatesEnabled( true );
	repaintItem(curIt);
	curIt=NULL;
}

void
ImageListView::leaveEvent(QEvent *e)
{
	KIconView::leaveEvent(e);
	onViewport();
}

FileIconItem*
ImageListView::firstItem ()
{
	return (FileIconItem *) KIconView::firstItem ();
}

FileIconItem*
ImageListView::currentItem()
{
	return (FileIconItem *)KIconView::currentItem ();
}

FileIconItem*
ImageListView::lastItem()
{
	return (FileIconItem *)KIconView::lastItem ();
}


/** functions for Digikam::AlbumItemHandler*/
QStringList
ImageListView::allItems()
{
	QStringList itemList;

	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
	{
		if((it->getType() == "file" || it->getType() == "filealbum")) itemList.append(it->text());
	}

	return itemList;
}

KURL::List
ImageListView::allItemsURL()
{
	KURL::List itemList;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if(it->isImage()) itemList.append(it->getURL());
	return itemList;
}

QStringList
ImageListView::selectedItems()
{
	QStringList itemList;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if (it->isSelected() && (it->getType() == "file" || it->getType() == "filealbum") )
			itemList.append(it->text());
	return itemList;
}


KURL::List
ImageListView::selectedURLs()
{
	KURL::List list;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if (it->isSelected())
			list.append(it->getURL());
	return list;
}

KURL::List
ImageListView::selectedImageURLs()
{
	KURL::List list;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if (it->isSelected() && it->isImage())
			list.append(it->getURL());
	return list;
}


QStringList
ImageListView::allItemsPath()
{
	QStringList itemList;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if((it->getType() == "file" || it->getType() == "filealbum"))
			itemList.append(it->fullName());
	return itemList;
}

QStringList
ImageListView::selectedItemsPath()
{
	QStringList itemList;
	for (FileIconItem *it = firstItem(); it; it = it->nextItem())
		if (it->isSelected())
			if((it->getType() == "file" || it->getType() == "filealbum")) itemList.append(it->fullName());
	return itemList;
}

void
ImageListView::refreshItems(const QStringList& )
{
	refresh();
}

void
ImageListView::reload()
{
		mw->iv->reload();
		mw->imageMetaInfo->reload();

}

void
ImageListView::load(FileIconItem* item)
{
	if(!item)
	{
		mw->iv->loadImage(QString::null);
		mw->imageMetaInfo->setURL(KURL(), QString::null);
		return;
	}
	if(item->isImage())
	{
		mw->iv->loadImage(item->fullName(), item->index());
		mw->imageMetaInfo->setURL(item->getURL(), item->mimetype());
	}
	else
	{
		mw->iv->loadImage(QString::null);
		if(item->getType() != "dir")
			mw->imageMetaInfo->setURL(item->getURL(), item->mimetype());
		else
			mw->imageMetaInfo->setURL(KURL(), QString::null);
	}
}

void
ImageListView::load(const QString& path)
{
	mw->iv->loadImage(path);
	KURL url; url.setPath(path);
	mw->imageMetaInfo->setURL(url, KMimeType::findByPath(path, 0, true )->name());
}


void
ImageListView::setgimpPath(const QString& gimp)
{
	gimpPath_ = gimp;
}
QString
ImageListView::getgimpPath()
{
	return gimpPath_;
}

void
ImageListView::slotDisplayExifInformation()
{
#ifdef HAVE_LIBKEXIF
#if LIBKEXIF_VERSION < 020
        KExif kexif(this);
#else
        KExifDialog kexif(this);
#endif
        if (kexif.loadFile(currentItem()->fullName()))
                kexif.exec();
        else
                KMessageBox::sorry(this, i18n("This item has no Exif Information."));
#else
#ifdef __GNUC__
#warning no HAVE_LIBKEXIF
#endif
#endif /* HAVE_LIBKEXIF */
}


KIO::Job*
ImageListView::removeThumbnails(bool allCurrentItems)
{
	KURL::List listIm = allCurrentItems?allItemsURL():selectedURLs();
	KURL::List listTh;
	KURL thURL;
	for(KURL::List::iterator it=listIm.begin(); it != listIm.end(); ++it)
	{
		if(QFileInfo(il->thumbnailPath((*it).path())).exists())
		{
			thURL.setPath(il->thumbnailPath((*it).path()));
			listTh.append(thURL);
		}
		if(QFileInfo(QDir::homeDirPath()+"/.showimg/cache/"+(*it).path()).exists())
		{
			thURL.setPath(QDir::homeDirPath()+"/.showimg/cache/"+(*it).path());
			listTh.append(thURL);
		}
	}
	return KIO::del( listTh );
}

void
ImageListView::forceGenerateThumbnails()
{
	KIO::Job *job = removeThumbnails();
	connect(job, SIGNAL(result( KIO::Job *)), this, SLOT(forceGenerateThumbnails__( KIO::Job *)));
}

void
ImageListView::forceGenerateThumbnails__(KIO::Job *job)
{
	if(job) if (job->error()==0)
		{
			stopLoading();
			slotLoadFirst(true);
		}
		else
			job->showErrorDialog();
}


void
ImageListView::generateEXIFThumbnails()
{
	KIO::Job *job = removeThumbnails();
	connect(job, SIGNAL(result( KIO::Job *)), this, SLOT(generateEXIFThumbnails__( KIO::Job *)));
}
void
ImageListView::generateEXIFThumbnails__(KIO::Job *job)
{
	if(job) if (job->error()==0)
		{
			stopLoading();
			slotLoadFirst(true, true);
		}
		else
			job->showErrorDialog();
}

bool
ImageListView::currentDragItemAreMovable()
{
	return m_currentDragItemAreMovable;
}

void
ImageListView::slotEXIFOrientation()
{
	ImageLoader::Orientation orient=ImageLoader::NOT_AVAILABLE;
	if(aEXIF_Orientation_normal->isChecked())
	{
		orient=ImageLoader::NORMAL;
		aEXIF_Orientation_normal->setChecked(false);
	}
	else
	if(aEXIF_Orientation_hflip->isChecked())
	{
		orient=ImageLoader::HFLIP;
		aEXIF_Orientation_hflip->setChecked(false);
	}
	else
	if(aEXIF_Orientation_vflip->isChecked())
	{
		orient=ImageLoader::VFLIP;
		aEXIF_Orientation_vflip->setChecked(false);
	}
	else
	if(aEXIF_Orientation_rot90->isChecked())
	{
		orient=ImageLoader::ROT_90;
		aEXIF_Orientation_rot90->setChecked(false);
	}
	else
	if(aEXIF_Orientation_rot270->isChecked())
	{
		orient=ImageLoader::ROT_270;
		aEXIF_Orientation_rot270->setChecked(false);
	}

	if (orient != ImageLoader::NOT_AVAILABLE)
		if (ImageLoader::setEXIFOrientation(currentItem()->fullName(), orient))
			reload();
}

#include "imagelistview.moc"
