/***************************** LICENSE START ***********************************

 Copyright 2014 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

	
#include "MvQIconFolderView.h"

#include "Desktop.h"
#include "IconClass.h"
#include "IconObject.h"
#include "IconInfo.h"
#include "Folder.h"
#include "FolderSettings.h"

#include "MvQActionList.h"
#include "MvQContextMenu.h"
#include "MvQDesktopSettings.h"
#include "MvQDropTarget.h"
#include "MvQFolderViewDelegate.h"
#include "MvQFolderItemProperty.h"
#include "MvQFolderModel.h"
#include "MvQIconProvider.h"
#include "MvQIconMimeData.h"
#include "MvQTheme.h"

#include <QApplication>
#include <QClipboard>
#include <QDrag>
#include <QDropEvent>
#include <QLinearGradient>
#include <QLineEdit>
#include <QScrollBar>
#include <QShortcut>
#include <QTimer>


QPen MvQIconItem::editPen_=QColor(Qt::yellow);	
QBrush MvQIconItem::editBrush_;
QPen MvQIconItem::MvQIconItem::hoverPen_;
QBrush MvQIconItem::hoverBrush_;
QPen MvQIconItem::selectPen_;
QBrush MvQIconItem::selectBrush_;
int  MvQIconItem::cornerRad_=4;	
	
//================================================================
//
// MvQIconItemTimer
//
//================================================================

MvQIconItemTimer::MvQIconItemTimer(MvQIconItem *item,QObject *parent) : 
 QTimer(parent),
 item_(item),
 cnt_(0),
 maxCnt_(10)
{
	connect(this, SIGNAL(timeout()), 
		this, SLOT(slotTimeout()));		   
}  

void MvQIconItemTimer::setItem(MvQIconItem *item)
{
  	stop();
	if(item_)
		item->setBlinkState(MvQIconItem::NoBlink);  
	item_=item;
	cnt_=0;
}	

void MvQIconItemTimer::blink()
{
  	if(item_)
	{
		cnt_=0;  	
	  	start(150);
	}
}

void MvQIconItemTimer::slotTimeout()
{
  	if(item_ && cnt_ < maxCnt_)
	{
	  	item_->setBlinkState((cnt_%2 ==0)?MvQIconItem::BlinkOn:MvQIconItem::BlinkOff);
	  	//item_->update();
		cnt_++;
	}	
	else
	{
	  	stop();
		cnt_=0;
		if(item_)
			item_->setBlinkState(MvQIconItem::NoBlink);  
		item_=0;
	}
}	
		
//================================================================
//
// MvQEditorProxy
//
//================================================================

MvQEditorProxy::MvQEditorProxy(MvQIconItem *item,QGraphicsItem *parent) : 
  QGraphicsProxyWidget(parent),
  item_(item)
{
	QString text=item->text();
	QFont f=item->font();
	QFontMetrics fm(f);
	
	editor_=new QLineEdit(text);
	editor_->setFont(item->font());
	editor_->setMinimumWidth(fm.width(text)+16);
	editor_->setMaximumWidth(fm.width(text)+fm.width("AAAAAAA"));		
    editor_->selectAll();
    //editor_->setCursorPosition(0);
	//editor_->deselect();
	
  	setWidget(editor_);
}	

QLineEdit* MvQEditorProxy::editor()
{
  	return editor_;
}	

MvQIconItem* MvQEditorProxy::item()
{
	 return item_;
}  

void MvQEditorProxy::keyPressEvent(QKeyEvent *e)
{
    qDebug() << "ketPressEvent" << e->key() << Qt::Key_Return << Qt::Key_Enter;
    QGraphicsProxyWidget::keyPressEvent(e);
    if((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) &&
       editor_->selectedText() != editor_->text())
    {
        Q_EMIT finishedEditing();
    }
}


//================================================================
//
// MvQIconItem
//
//================================================================

MvQIconItem::MvQIconItem(const QModelIndex& index,MvQFolderItemProperty* itemProp,MvQIconFolderView* view,QGraphicsItem* parent) : 
  QGraphicsItem(parent),
  view_(view),
  itemProp_(itemProp),
  index_(index),
  hover_(false),
  dropTarget_(false),
  blinkState_(NoBlink)
{
  	//Setup colours - static memebers
	if(editPen_.color() == Qt::yellow)
	{  	
		QString group="itemview_main";	
  		editPen_=QPen(MvQTheme::colour(group,"edit_pen"));
		editBrush_=MvQTheme::brush(group,"edit_brush");
		hoverPen_=QPen(MvQTheme::colour(group,"hover_pen"));
		hoverBrush_=MvQTheme::brush(group,"hover_brush");
		selectPen_=QPen(MvQTheme::colour(group,"select_pen"));
		selectBrush_=MvQTheme::brush(group,"select_brush");
	}
	
	setAcceptHoverEvents(true); 
	
	setFlag(QGraphicsItem::ItemIsSelectable,true);
	
	index_=index;
  	
	adjust();
  	
}

QRectF MvQIconItem::boundingRect() const
{
   	return bRect_;
}

void MvQIconItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*,QWidget*)
{
	QPixmap pixmap=index_.data(Qt::DecorationRole).value<QPixmap>();
		
	//Save painter state
	painter->save();
	 	
	QString text=index_.data(Qt::DisplayRole).toString();		
		
	//Background	
	QRectF fillRect=bRect_;	
	
	if(blinkState_ == BlinkOn)
	{
		painter->fillRect(fillRect,Qt::black); 	  
	}	
	//If the icon editor is open we render a transparent rect above the item
	else if(index_.data(MvQFolderModel::EditorRole).toBool())
	{  			
		painter->setPen(editPen_);
		painter->setBrush(editBrush_);
		painter->drawRoundedRect(fillRect,cornerRad_,cornerRad_);
	}
	else if(isSelected())
	{			
		painter->setPen(selectPen_);
		painter->setBrush(selectBrush_);
		painter->drawRoundedRect(fillRect,cornerRad_,cornerRad_);
	}	
	else if(hover_)
	{	
		painter->setPen(hoverPen_);
		painter->setBrush(hoverBrush_);
		painter->drawRoundedRect(fillRect,cornerRad_,cornerRad_);
	}
	else if(dropTarget_)
	{	
		painter->setPen(hoverPen_);
		painter->setBrush(selectBrush_);
		painter->drawRoundedRect(fillRect,cornerRad_,cornerRad_);
	}
	
	painter->setBrush(QBrush());
	
 	//Render icon
	painter->drawPixmap(iconRect_.toRect(),pixmap);
	
	//Tender text	
	QFont font = index_.data(Qt::FontRole).value<QFont>();   
	painter->setFont(font);
	
	if(blinkState_ == BlinkOn)	  
	  	painter->setPen(Qt::white);
	else
		painter->setPen(index_.data(Qt::ForegroundRole).value<QColor>());
	
	painter->drawText(textRect_,Qt::AlignCenter,text);
	
	painter->restore();				
}

void MvQIconItem::adjust()
{
	prepareGeometryChange();
	
	QString name=index_.data(Qt::DisplayRole).toString();	
	bRect_=QRectF(QPointF(0,0),itemProp_->size(name));	
	QPoint refPos=index_.data(MvQFolderModel::PositionRole).toPoint();
	setPos(itemProp_->position(name,refPos));
	
	textRect_=itemProp_->textRect(name);
	iconRect_=itemProp_->iconRect(name);	
}  

bool MvQIconItem::textContains(QPointF pos)
{	
 	return textRect_.contains(pos);
}

QPointF MvQIconItem::textPos()
{
	return pos()+textRect_.topLeft();	
}	
	
QRect MvQIconItem::pixmapRect()
{
  	return iconRect_.toRect();
}	

const QModelIndex& MvQIconItem::index()
{
  	return index_;
}

QString  MvQIconItem::text()
{
  	return index_.data(Qt::DisplayRole).toString();	
}

QFont  MvQIconItem::font()
{
  	return index_.data(Qt::FontRole).value<QFont>();	
}

void MvQIconItem::hoverEnterEvent(QGraphicsSceneHoverEvent *)
{
 	 hover_=true;
	 update();
	 view_->itemEntered(this);
}  

void MvQIconItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
{
 	 hover_=false;
	 update();	 
	 view_->itemLeft(this);
}  

void MvQIconItem::setDropTarget(bool t)
{
  	 dropTarget_=t;
	 update();
} 

void MvQIconItem::setBlinkState(BlinkState b)
{
  	 blinkState_=b;
	 update();
}  

//=================================================================
//
//  MvQIconFolderView
// 
//=================================================================

MvQIconFolderView::MvQIconFolderView(MvQFolderModel *folderModel,
				     MvQActionList* iconActions,
				     MvQActionList* desktopActions,QWidget *parent) :  
	QGraphicsView(parent),	
	MvQFolderViewBase(folderModel,parent),   
	allowMoveAction_(true),
        enterFolders_(true),
        mousePos_(0,0),
        canDrag_(false),
        editor_(0),
        timer_(0),
        defaultShortCut_(0),
        appIconActions_(iconActions),
        appDesktopActions_(desktopActions)
{  			
  	//setBackgroundBrush(QColor(125,124,123));
	
	setAlignment(Qt::AlignLeft | Qt::AlignTop);
	setDragMode(QGraphicsView::RubberBandDrag);
	
	QGraphicsScene* scene_=new QGraphicsScene(this);
	setScene(scene_);
			
	qDebug() << maximumViewportSize() << items().count();	
	qDebug() << "scenerect" << sceneRect();
	
	setContextMenuPolicy(Qt::CustomContextMenu);
	
	//Context menu 
    	connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
                this, SLOT(slotContextMenu(const QPoint &)));
		
	//Set the style
	setProperty("mvStyle","IconFolderView");
	
	//We set up the shortcuts here!!
	setupShortCut(); 
	
	//We attach the model because by default the view is enabled. At this point the model is empty so
	//it is a cheap operation!!
	attachModel();	
}  

MvQIconFolderView::~MvQIconFolderView()
{	
}

//Connect the models signal to the view
void MvQIconFolderView::attachModel()
{
	//Standard signals from the model	
	
	connect(filterModel_,SIGNAL(modelReset()),
		this,SLOT(reset())); 
		
	connect(filterModel_,SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)),
		this,SLOT(slotDataChanged(const QModelIndex&,const QModelIndex&)));	
			
	//Custom signals from the model	
	connect(folderModel_,SIGNAL(iconSizeChanged()),
		this,SLOT(slotIconSizeChanged()));	
			
	connect(folderModel_,SIGNAL(objectRenamed(const QModelIndex&,QString)),	
		this,SLOT(slotObjectRenamed(const QModelIndex& ,QString)));
	
	//We need to call it to be sure that the view show the actual state of the model!!!	
	//doReset();			
}  

//Disconnect the model from the view
void MvQIconFolderView::detachModel()
{ 
	disconnect(filterModel_,0,this,0);  
	disconnect(folderModel_,0,this,0); 
}  

void MvQIconFolderView::doReset()
{
  	reset();
}	

QWidget* MvQIconFolderView::concreteWidget()
{
  	return this;
}	

//-----------------------------------------
// Event
//-----------------------------------------

bool MvQIconFolderView::event(QEvent* event) 
{
    //qDebug() << "TYPE" << event->type();
	return QGraphicsView::event(event);	
}

void MvQIconFolderView::changeEvent(QEvent* event) 
{
  	if(event->type() == QEvent::EnabledChange)
	{
	 	if(isEnabled())
		{
		  	attachModel();
			//Reset will be called by the handler!!!!			
			blockSignals(false);
		}
		//When the view is diabled we do not want to receive any signals from the model
		else
		{
		  	detachModel();
			clearContents();
			blockSignals(true);
		}
	}	
}

//-----------------------------------------
// Accessing indexes, objects or items
//-----------------------------------------

QModelIndex MvQIconFolderView::indexAt(QPointF scenePos)
{
	QGraphicsItem *item=scene()->itemAt(scenePos, QTransform());
	if(item)
	{	  
	  	MvQIconItem* icItem=static_cast<MvQIconItem*>(item);
		return icItem->index();  	
	}	
	return QModelIndex();
}

IconObject* MvQIconFolderView::iconObjectAt(QPointF scenePos)
{
	QGraphicsItem *item=scene()->itemAt(scenePos, QTransform());
	if(item)
	{	  
	  	MvQIconItem* icItem=static_cast<MvQIconItem*>(item);
		return folderModel_->objectFromIndex(icItem->index());  	
	}
	return 0;
}

MvQIconItem* MvQIconFolderView::objectToItem(IconObject* obj)
{
	QPersistentModelIndex idx(filterModel_->mapFromSource(folderModel_->indexFromObject(obj)));	
		
	QHash<QPersistentModelIndex,MvQIconItem*>::iterator it =items_.find(idx);
	return (it != items_.end())?it.value():0;
}			

MvQIconItem* MvQIconFolderView::indexToItem(const QModelIndex& index)
{ 
  	QPersistentModelIndex idx(index);		
	QHash<QPersistentModelIndex,MvQIconItem*>::iterator it =items_.find(idx);
	return (it != items_.end())?it.value():0;
}

QModelIndex MvQIconFolderView::itemToIndex(QGraphicsItem *item)
{ 
  	if(item)
	{	  
	  	MvQIconItem* icItem=static_cast<MvQIconItem*>(item);
		return icItem->index();  	
	}
	return QModelIndex();
}

IconObject* MvQIconFolderView::itemToObject(QGraphicsItem *item)
{ 
  	if(item)
	{	  
	  	MvQIconItem* icItem=static_cast<MvQIconItem*>(item);
		return folderModel_->objectFromIndex(icItem->index());  	
	}
	return 0;
}

QRect MvQIconFolderView::pixmapRect(QList<IconObject*> objLst)
{  
	QRect bbox;
	foreach(IconObject* obj,objLst)
	{
		QRect b=pixmapRect(obj);
	  	if(!b.isNull())
		  	bbox=bbox.united(b);
	}
				
  	return bbox;
}  

QRect MvQIconFolderView::pixmapRect(IconObject *obj)
{
  	if(MvQIconItem* item=objectToItem(obj))
	{
		return item->mapToScene(item->pixmapRect()).boundingRect().toRect();
	}
	
	return QRect();
}	


QRect MvQIconFolderView::itemRect(QList<IconObject*> objLst)
{  
	QRect bbox;
	foreach(IconObject* obj,objLst)
	{
		if(MvQIconItem* item=objectToItem(obj))
			bbox=bbox.united(itemRect(item).toRect());
	}
				
  	return bbox;
}  

QRect MvQIconFolderView::itemRect(IconObject *obj)
{
  	if(MvQIconItem* item=objectToItem(obj))
	{
		return item->mapToScene(item->boundingRect()).boundingRect().toRect();
	}
	
	return QRect();
}	

QRectF MvQIconFolderView::itemRect(QGraphicsItem*item)
{
  	if(item)
	{
		return item->mapToScene(item->boundingRect()).boundingRect();
	}
	
	return QRectF();
}	

QModelIndexList MvQIconFolderView::selectedIndexes()
{
	QModelIndexList lst;
	
  	foreach(QGraphicsItem* item,items())
	{
	  	if(item->isSelected())
		{
		  	QModelIndex index=itemToIndex(item);
			if(index.isValid())
			  	lst << index;
		}	
	}
	
	return lst;
}

void MvQIconFolderView::selectOnlyOneItem(QGraphicsItem *item)
{
	if(item)
	{
	  	if(!item->isSelected())
		{  	
			scene()->clearSelection();
			item->setSelected(true);
		}	
	}
}	
//-----------------------------------------
// Keypress, shortcut and context menu
//-----------------------------------------

void  MvQIconFolderView::itemEntered(MvQIconItem *item)
{  	
	emit itemEntered(itemInfo(item->index(),FilterModelIndex));
}

void  MvQIconFolderView::itemLeft(MvQIconItem */*item*/)
{  	
	emit itemEntered(QString());
}

MvQContextItemSet* MvQIconFolderView::cmSet()
{
	static MvQContextItemSet cmItems("IconFolderView");  
  	return &cmItems;
}

void MvQIconFolderView::slotContextMenu(const QPoint& position)
{	
    //QGraphicsItem *item=itemAt(position);
    //Relay the context menu event ot the editor!
    if(editor_)
    {
        QPointF scenePos=mapToScene(position);
        if(editor_->contains(editor_->mapFromScene(scenePos)))
        {
            QContextMenuEvent gme(QContextMenuEvent::Mouse,position,mapToGlobal(position));
            QApplication::sendEvent(editor_->editor(),&gme);
            return;
        }
    }

	QModelIndexList lst=selectedIndexes();
	qDebug() << "selected" << lst;
	
	QModelIndex index=indexAt(mapToScene(position));
	
	QPoint scrollOffset(horizontalScrollBar()->value(),verticalScrollBar()->value()); 
	handleContextMenu(index,lst,mapToGlobal(position),position+scrollOffset,this);	  
		  
	/*QModelIndexList lst=selectedIndexes();
	QPoint scrollOffset(horizontalScrollBar()->value(),verticalScrollBar()->value());
	handleContextMenu(indexAt(position),lst,mapToGlobal(position),position+scrollOffset,this);*/
	
  	/*if(lst.count() == 1)
	{ 
		QModelIndex index=indexAt(position);	
		QPoint scrollOffset(horizontalScrollBar()->value(),verticalScrollBar()->value());
	
		handleContextMenu(index,mapToGlobal(position),position+scrollOffset,this);
	}
	else if(lst.count() > 1)
	{
	  	handleContextMenu(lst,mapToGlobal(position),position+scrollOffset,this);
	} */ 	
}

void  MvQIconFolderView::mouseDoubleClickEvent(QMouseEvent* event)
{	 	
  	QModelIndexList lst=selectedIndexes();
	QModelIndex index=indexAt(mapToScene(event->pos()));	
	if(lst.count() == 1 && lst.at(0)  == index)
		 handleDoubleClick(index);
}


void  MvQIconFolderView::iconCommandFromMain(QString name)
{	 	
	handleIconCommand(selectedIndexes(),name);
}

//-------------------------
//
//-------------------------

void MvQIconFolderView::folderChanged()
{
  	emit currentFolderChanged(currentFolder());	
}

void MvQIconFolderView::iconCommand(QString name,IconObjectH obj)
{
	if(name == "rename")
	{
	  	
	}
	else
  		emit iconCommandRequested(name,obj);
}

void MvQIconFolderView::desktopCommand(QString name,QPoint pos)
{	     
  	emit desktopCommandRequested(name,pos);  
}

void MvQIconFolderView::initImportedHalfSizeItems()
{  
	if(filterModel_->rowCount() ==0)
		return;
	
	if(Folder *f=folderModel_->folder())
	{
		FolderSettings *fs=f->settings();
		if(fs->halfSizeImported() && 
		   itemProp_->viewMode() == Desktop::SimpleViewMode &&
	           itemProp_->iconSize() == 16)
		{			  	
			for(int i=0; i < filterModel_->rowCount(); i++)
			{	  	
				QModelIndex idx=filterModel_->index(i,0);
				QString name=filterModel_->data(idx,Qt::DisplayRole).toString();		
				
				//Get the original pos taken from MetviewUI (padding addded!). It is valid for 16px icon size!
		  		QPoint refPos=filterModel_->data(idx,MvQFolderModel::PositionRole).toPoint();	
				
				QPoint storedPos=itemProp_->storedPosition(refPos);
			
				//If the stored position is valid:
				//We need to scale it up to the reference position and set it as the real position!!
				if(IconInfo::validPos(storedPos.x(),storedPos.y()))
				{
					filterModel_->setData(idx,itemProp_->referencePosition(name,refPos),
						      MvQFolderModel::PositionRole);
				}		      
			}
			
			fs->halfSizeImportUsed();
	
		}
	}	
}		



//------------------------------------------
// Reflecting changes in the model
//------------------------------------------

void MvQIconFolderView::clearContents()
{
	removeEditor();
	removeDropTarget();
  	scene()->clear();
	items_.clear();	
}


void MvQIconFolderView::reset()
{  	
  	removeEditor();
	removeDropTarget();
  	scene()->clear();
	items_.clear();	
    
	initImportedHalfSizeItems();
	
	for(int i=0; i < filterModel_->rowCount(); i++)
	{	  	
		QModelIndex idx=filterModel_->index(i,0);
		
		MvQIconItem* item=new MvQIconItem(idx,itemProp_,this);
		scene()->addItem(item);
				
		QPersistentModelIndex idxP(idx);
		items_[idxP]=item;
	}

	//Checks if there are icons with (0,0) positions and layout them
	//nicely
	checkPositions();
	
	adjustSceneRect();
}

void MvQIconFolderView::slotDataChanged(const QModelIndex& from,const QModelIndex&)
{
 	if(from.isValid())
	{
		if(MvQIconItem *item=indexToItem(from))
		 	item->update(); 
	}
}  

void  MvQIconFolderView::slotObjectArrived(const QModelIndex&)
{
  	//showLastCreated();
}  

//===============================================
// Icon positions
//===============================================

void MvQIconFolderView::adjustSceneRect()
{
  	QRectF r=scene()->itemsBoundingRect();
	r.setTopLeft(QPointF(0,0));
	r.setBottom(r.bottom()+10);
	scene()->setSceneRect(r);
}

void MvQIconFolderView::adjustItems()
{
  	QHash<QPersistentModelIndex,MvQIconItem*>::const_iterator it = items_.constBegin();
	while(it != items_.constEnd())
	{
		it.value()->adjust();
		it++;
	}
}
	
void MvQIconFolderView::toGrid(Desktop::GridSortMode mode)
{			
  	computeGrid(mode);
	adjustSceneRect(); 
}  

void MvQIconFolderView::slotIconSizeChanged()
{ 
	adjustItems();
	adjustSceneRect();
}

QSize MvQIconFolderView::maxItemSize()
{	
	int h=0;	
	int w=itemProp_->iconSize();
		
  	foreach(QGraphicsItem *item,items())
	{	
	  	QSize s=item->boundingRect().size().toSize();
		if(s.width() > w) w=s.width();
		if(h==0) h=s.height();
	}
	
	return QSize(w,h);
}

void MvQIconFolderView::computeGrid(Desktop::GridSortMode sortMode)
{	 
  	if(!folderModel_->folder())
	  	return;
		
	QSize itemSize=maxItemSize();
	
  	int dx=itemSize.width()+2;
	int colNum=static_cast<int>(round(static_cast<float>(viewport()->size().width())/static_cast<float>(dx)));
	if(colNum==0) colNum=1;	
	int dy=itemSize.height()+3*itemProp_->scaling();
		
	//qDebug() << "DELTA" << itemSize.height() << itemProp_->scaling() << dy;
	
	int x=5;
	int y=5;
		
	std::multimap<QString,QModelIndex> items;
	
	if(sortMode == Desktop::GridSortByName)
	{
		for(int i=0; i < filterModel_->rowCount(); i++)
		{
		  	QModelIndex idx=filterModel_->index(i,0);		  		  
		 	items.insert(std::pair<QString,QModelIndex>(filterModel_->data(idx,Qt::DisplayRole).toString(),filterModel_->index(i,0)));
		}
	}			
	else if(sortMode == Desktop::GridSortByType)
	{
	  	for(int i=0; i < filterModel_->rowCount(); i++)
		{
		  	QModelIndex idx=filterModel_->index(i,1);		  		  
		 	items.insert(std::pair<QString,QModelIndex>(filterModel_->data(idx,Qt::DisplayRole).toString(),filterModel_->index(i,0)));
		}
	}	
	else if(sortMode == Desktop::GridSortBySize)
	{	
		std::multimap<qint64,QModelIndex> sizeItems;		
		for(int i=0; i < filterModel_->rowCount(); i++)
		{
		  	QModelIndex idx=filterModel_->index(i,2);
		  	sizeItems.insert(std::pair<qint64,QModelIndex>(filterModel_->data(idx,Qt::UserRole).toLongLong(),filterModel_->index(i,0)));
		}
		int cntS=0;
		for(std::multimap<qint64,QModelIndex>::const_iterator it=sizeItems.begin(); it != sizeItems.end(); it++, cntS++)
		{
			items.insert(std::pair<QString,QModelIndex>(QString::number(cntS),it->second));			
		}	
	}
	
	int cnt=0;
	for(std::multimap<QString,QModelIndex>::const_iterator it=items.begin(); it != items.end(); it++, cnt++)
	{
		MvQIconItem *item=indexToItem(it->second);
		
		QPoint pos;
		if(itemProp_->viewMode() == Desktop::IconViewMode)
		{			
			int w=item->boundingRect().width();	
			pos=QPoint(x+(dx-w)/2,y);
		}
		else
		{
		  	pos=QPoint(x,y);
		}  
		  
		QString name=filterModel_->data(it->second,Qt::DisplayRole).toString();				
		filterModel_->setData(it->second,itemProp_->referencePosition(name,pos),MvQFolderModel::PositionRole);
		item->adjust();
		
		x+=dx;
		if(cnt >0 && cnt%colNum == colNum-1)
		{  
			x=5;
			y+=dy;		
		}
	}
} 

void MvQIconFolderView::checkPositions()
{
   	if(!folderModel_->folder())
	  	return;

	QList<QModelIndex> needPos;
	MvQIconItem* bottomItem=0;
	
	int h=0;	
	int maxWidth=itemProp_->iconSize();
	int maxX=0;
	int maxY=0;
	
	QHash<QPersistentModelIndex,MvQIconItem*>::const_iterator it = items_.constBegin();
	while(it != items_.constEnd())
	{	
		//Reference pos
		QPoint refPos=it.key().data(MvQFolderModel::PositionRole).toPoint();
	  	
		//stored pos
		QPoint storedPos=itemProp_->storedPosition(refPos);
		
		//qDebug() << refPos;
		
		if(IconInfo::validPos(storedPos.x(),storedPos.y()))
		{  		  
			QPointF pos=it.value()->pos();
			if(pos.x() > maxX) maxX=pos.x();
			if(pos.y() > maxY) 
			{
			  	maxY=pos.y();
				bottomItem=it.value();
			}
		}
		else
		{			  	
		  	needPos << it.value()->index();
		}
		
		QSize s=it.value()->boundingRect().size().toSize();	
		if(s.width() > maxWidth) maxWidth=s.width();	  	
		if(h == 0) h=s.height();
		
		it++;
	}
	
  	if(needPos.count() ==0)
	  	return;
  	  	
	int dx=maxWidth+2;

	//Find out the available widthfor layouting
	int sceneWidth = sceneRect().size().width();	
	
	//The actual viewport can be bigger than the scenerect width.
	if(viewport()->size().width() > sceneWidth)
	  	sceneWidth=viewport()->size().width();
	
	//If the window is not yet visible the viewport and the scenerect do not have the correct size!!!! 
	//So we estimate the available size form the window size (it is "almost" correctly set although it is not visible)
	if(QWidget* win=window())
	{
		if(!win->isVisible())
		  	sceneWidth=win->size().width()-20;	
	}  
		 
	int dy=h+3*itemProp_->scaling();
	
	//Find the staring pos of the new items
	int x=5;
	int y=maxY+((maxY==0)?10:dy);
	//int sceneWidth = sceneRect().size().width();
	
	if(sceneWidth< 20)
	{
	  	sceneWidth = maxX+maxWidth+20;
	}	
	
	//Try to find a starting postion in the last "row" of the "old" items
	if(bottomItem)
	{
	  	//See if other items intersect the bottom item's row
		QRectF bottomRect=bottomItem->boundingRect();
		bottomRect.moveTo(bottomItem->pos());		
		
		//This is the rect at the right edge of the available area in the bottomItem's row.
		QRectF r(QPointF(sceneWidth-bottomRect.width(),bottomRect.y()),bottomRect.size());
		
		int rectStep=0;
		while(r.x() > 0 && r.width() >0)  
		{
		  	//r.translate(-r.width(), 0);
			//See if we have overlapping items with the rect!!
			QList<QGraphicsItem*>  intersectVector = scene()->items(r,Qt::IntersectsItemShape,Qt::AscendingOrder);
			if(!intersectVector.isEmpty())
			{
			  	//If the first rect overlaps we need to start a new row 
				//otherwise ...
				if(rectStep >0)
				{	
				  	//.. we need to find the rightmost overlapping rect
				  	QRectF endRect=intersectVector.at(0)->boundingRect();
					endRect.moveTo(intersectVector.at(0)->pos());
					
					for(int iv=1; iv < intersectVector.count(); iv++)
					{
					  	QRectF actRect=intersectVector.at(iv)->boundingRect();
						actRect.moveTo(intersectVector.at(iv)->pos());
						if(actRect.right() > endRect.right())
						  	endRect=actRect;
					}	
					
					if(intersectVector.count() == 1 && 
					   intersectVector.at(0)== bottomItem)
					{
						x=bottomRect.x()-(dx-bottomRect.width())/2+dx;
						y=bottomRect.y();  
					}
					else
					{
					  	x=endRect.x()-(dx-endRect.width())/2+dx;
						y=bottomRect.y();  
					}									  					  				
				}

				break;								
			}
			
			//We move the rect to the left
			r.translate(-r.width(), 0);
			
			rectStep++;
		}	
	}	
		
	for(int i=0; i < needPos.count(); i++)
	{
		MvQIconItem *item=indexToItem(needPos[i]);
		
		QPoint pos;
		int w=item->boundingRect().width();
		if(itemProp_->viewMode() == Desktop::IconViewMode)
		{						  
		  	pos=QPoint(x+(dx-w)/2,y);
			if(pos.x()+w > sceneWidth)
			{  
				x=5;
				y+=dy;		
			}
			pos=QPoint(x+(dx-w)/2,y);
		}
		else
		{
		  	pos=QPoint(x,y);
			if(pos.x()+w > sceneWidth)
			{  
				x=5;
				y+=dy;		
			}	
			pos=QPoint(x,y);
		}  
		
		QString name=filterModel_->data(needPos[i],Qt::DisplayRole).toString();				
		filterModel_->setData(needPos[i],itemProp_->referencePosition(name,pos),MvQFolderModel::PositionRole);		
		item->adjust();	
		
		//qDebug() << name << pos << w << sceneWidth;
		
		x+=dx;		
	}
}

//===========================
// Drag
//===========================

void MvQIconFolderView::mousePressEvent(QMouseEvent *event)
{
	canDrag_=false;	
	
	mousePos_=event->pos();
	
	QPointF scenePos=mapToScene(event->pos());
	
	if(editor_)
	{
        //This is the standard behaviour on various systems: when we click
        //outside the editor we finish editing and confirm the rename operation. However,
        //the editor can have a context menu open so we need to check if we click inside
        //the context menu. Unfortunately QWidget::childAt() and Qwidget::childrenRect() does not
        //work properly to decide if the position is inside the context menu. So we have to check the
        //children one by one.
        if(!editor_->contains(editor_->mapFromScene(scenePos)))
        {
            bool outside=true;
            foreach(QObject *chObj,editor_->editor()->children())
            {
                if(chObj->isWidgetType())
                {
                    if(QWidget* w=static_cast<QWidget*>(chObj))
                    {
                        QPoint posInW=w->mapFromGlobal(event->globalPos());
                        if(w->rect().contains(posInW))
                        {
                            outside=false;
                            break;
                        }
                    }
                }
            }

            if(outside)
            {
                qDebug() << "click outside editor";
                slotRename();
                return;
            }
        }

        QGraphicsView::mousePressEvent(event);
        return;
	}
	
	//At this point the item cannot be the editor!!!
	if(event->button() == Qt::LeftButton || event->button() == Qt::MidButton)
	{
	  	MvQIconItem *item=static_cast<MvQIconItem*>(itemAt(event->pos()));
		if(item)
		{			 				  		  		  		  
			//check if editor is needed
	  		if(item->textContains(item->mapFromScene(scenePos)))
			{
				if(IconObject* obj=itemToObject(item))
				{
				  	if(obj->renamable())
					{
			  			selectOnlyOneItem(item);
						edit(item);
					}
				}				
				return;
			}
				
			//Set startpos in Viewport coordinates and enable drag
			startPos_=event->pos();		
			canDrag_=true;
			
			if(event->button() == Qt::MidButton)
			{
			  	selectOnlyOneItem(item);
				event->accept();
				return;
			}	
		}			 	
	}	
	else if(event->button() == Qt::RightButton)
	{
	  	QGraphicsItem *item=itemAt(event->pos());	  	
	  	selectOnlyOneItem(item);		
	  	event->accept();
		return;
	}	
	
	QGraphicsView::mousePressEvent(event);
}

void MvQIconFolderView::mouseMoveEvent(QMouseEvent *event)
{  
  	if(canDrag_ && event->buttons() & (Qt::LeftButton | Qt::MidButton))
	{
	  	int distance = (event->pos() - startPos_).manhattanLength();
		if(distance >= QApplication::startDragDistance())
		{
			canDrag_=false;

			QPoint scenePos=mapToScene(startPos_).toPoint();
			
		  	if(allowMoveAction_)
			{  		  
				if(event->buttons() & Qt::LeftButton)		  
		  			performDrag(Qt::MoveAction,scenePos);
				else if(event->buttons() & Qt::MidButton)
			  		performDrag(Qt::CopyAction,scenePos);
			}
			else
			{
			  	performDrag(Qt::CopyAction,scenePos);
			}
		}	
		
		return;
	}
	
	QGraphicsView::mouseMoveEvent(event);
}

void MvQIconFolderView::performDrag(Qt::DropAction dropAction,QPoint scenePos)
{	
	//The object that was dragged
	//IconObject* dragObj=iconObjectAt(mapFromScene(scenePos));
	IconObject* dragObj=iconObjectAt(scenePos);
	
	
	//List of object to drag
	QList<IconObject*> objLst;
	foreach(QGraphicsItem* gt,scene()->selectedItems())
		objLst << itemToObject(gt);	
	
	//Need a solution!!!!!!!!!!!!!!!!!1		
	bool fromHelper=(!allowMoveAction_);
	
	QDrag *drag=buildDrag(dragObj,objLst,fromHelper,this,scenePos);	
	
	if(drag)
	{
	  	//We always initiate a copy or move  action
		drag->exec(Qt::CopyAction | Qt::MoveAction,dropAction);	
	}	
	else
	{
	  	qDebug() << "Could not build drag object!!!";
	}	
}	

//===========================
// Drop
//===========================

void MvQIconFolderView::checkDropTarget(QDropEvent *event)
{  
	IconObject* dragObj=0;
	if(event->mimeData()->hasFormat("metview/icon"))
	{	
		const MvQIconMimeData* mimeData=qobject_cast<const MvQIconMimeData*>(event->mimeData());
				
		if(mimeData)
			dragObj=mimeData->dragObject();
	}
	
	
	if(!dragObj)
	{  	
	  	removeDropTarget();
		return;
	}	
	
	QPointF scenePos=mapToScene(event->pos());
	Qt::DropAction dropAction=event->proposedAction();
	
	IconObject *obj=iconObjectAt(scenePos);	
  
	if(obj != dragObj && obj && obj->isFolder() && !obj->locked())
	{
	  	
	  	MvQDropTarget::Instance()->reset(QString::fromStdString(obj->name()),(dropAction == Qt::MoveAction));							
		if(window())
		{  
			MvQDropTarget::Instance()->move(mapToGlobal(event->pos())+QPoint(20,20));
		}
		return;
	}
	else
	{
		removeDropTarget();
	}	
}	  

void MvQIconFolderView::removeDropTarget()
{	
  	MvQDropTarget::Instance()->hide();
}

void MvQIconFolderView::dragEnterEvent(QDragEnterEvent *event)
{
	//qDebug() << event->mimeData()->formats();
	//qDebug() << event->mimeData()->text();
	//qDebug() << event->proposedAction();
	
	if(event->source() &&
	   (event->proposedAction() == Qt::CopyAction ||
	    event->proposedAction() == Qt::MoveAction))
	{
		event->accept();
	}
	else  
		event->ignore();
}

void MvQIconFolderView::dragMoveEvent(QDragMoveEvent *event)
{
	if(event->source() &&
	   (event->proposedAction() == Qt::CopyAction ||
	    event->proposedAction() == Qt::MoveAction))
	{		
		checkDropTarget(event);
		event->accept();
	}
	else
	{
	  	removeDropTarget();
	  	event->ignore();
	}	
}

void MvQIconFolderView::dragLeaveEvent(QDragLeaveEvent *event)
{
	removeDropTarget();
	event->accept();
}

void MvQIconFolderView::dropEvent(QDropEvent *event)
{
	removeDropTarget();
	
	if(!event->source())
	{
		event->ignore();
		return;
	}	
	
	if(event->proposedAction() != Qt::CopyAction &&
	   event->proposedAction() != Qt::MoveAction)
	{
		event->ignore();
		return;
	}	
	
	QPoint pos=mapToScene(event->pos()).toPoint();
	
	//--------------------------------------
	// Drag and drop from another Metview folder
	//--------------------------------------
	
	if(event->mimeData()->hasFormat("metview/icon"))
	{	
		const MvQIconMimeData* mimeData=qobject_cast<const MvQIconMimeData*>(event->mimeData());
				
		if(!mimeData)
		{
			event->ignore();
			return;
		}	
	
		IconObject* dragObj=mimeData->dragObject();
		MvQFolderModel *model=mimeData->model();		
	
		//We cannot drop icons into a locked folder!
  		if(model != folderModel_ && folderModel_->folder()->locked())
		{
			event->ignore();
			return;
		}
				
		if(model && dragObj)
		{			
			performDrop(event->proposedAction(),mimeData,pos,(model == folderModel_));						
			event->accept();
			return;
		}
	}
	else if(event->mimeData()->hasFormat("metview/new_icon"))
	{	
		//We cannot drop icons into a locked folder!
  		if(folderModel_->folder()->locked())
		{
			event->ignore();
			return;
		}
		
		const MvQNewIconMimeData* mimeData=qobject_cast<const MvQNewIconMimeData*>(event->mimeData());
				
		if(!mimeData)
		{
			event->ignore();
			return;
		}	
	
		if(mimeData->iconDefType() == MvQNewIconMimeData::UserDef)
		{
			const IconClass &kind=IconClass::find(mimeData->className().toStdString());
			
			QString cname=QString::fromStdString(kind.defaultName());
			
			QPoint bottomRight(1,1);
			QPoint newPos=itemProp_->positionFromHotSpot(cname,pos,bottomRight);									     									     
			QPoint refPos=itemProp_->referencePosition(cname,newPos);   
			kind.createOne(folderModel_->folder(),refPos.x(),refPos.y());						
	
			event->accept();
			return;
		}
	}
	
	
	event->ignore();
}

void MvQIconFolderView::performDrop(Qt::DropAction dropAction,const MvQIconMimeData* data,
				    QPoint cursorScenePos,bool fromSameView)
{ 
  	IconObject* dragObj=data->dragObject();
	
	//Find out the itemRect topleft point in scene (scaled)
  	QPoint scenePos=itemProp_->positionFromHotSpot(QString::fromStdString(dragObj->name()),
						       cursorScenePos,data->hotSpotInVisRect());
  
  	//The object position - ignoring the scaling 
	QPoint refPos=itemProp_->referencePosition(QString::fromStdString(dragObj->name()),scenePos);              	
	QPoint deltaPos=refPos-itemProp_->referencePosition(dragObj);
	
	bool toSameFolder=true;
	Folder *folder=folderModel_->folder();
	IconObject *objAt=iconObjectAt(cursorScenePos);
	
	//See if we drop the icons onto a folder icon. We do not allow dropping a folder into itself!!
	if(objAt && objAt->isFolder() && !data->objects().contains(objAt))
	{
		 folder=static_cast<Folder*>(objAt);
		 toSameFolder=false;
	}
	
	bool doAdjustScene=false;
	QRectF scRect=scene()->sceneRect();
	float rightEdge=scRect.left();
	float bottomEdge=scRect.bottom();
	
	QPoint bottomRight(1,1);	
	for(int i=0; i < data->objects().count(); i++)
	{					  
		IconObject *obj=data->objects().at(i);
		  
		if(!obj || !isAccepted(obj))
			continue;
	
		//If the drop target is a folder icon in the current folder we set the coordinates to
		//undef. This will instruct the view to find maningful new positions to the icons,
		if(toSameFolder == false && folder)
		{
			//Copy  
			if(dropAction == Qt::CopyAction)
			{			
				obj->clone(folder,false);
			}
			//Move
			else if(dropAction == Qt::MoveAction)
			{  				  	
				if(!obj->locked())
				{
					obj->position(IconInfo::undefX(),IconInfo::undefY());				
					folder->adopt(obj); 
				}	
			}	
		}	
		//Otherwise we compute the possible new positions according to the position of the drag object
		else
		{
		 	QPoint newPos;
			QPoint newRefPos;
		
			if(obj == dragObj)
			{
				newRefPos=refPos;
				newPos=scenePos;
			}
			else
			{  
				QPoint dp=data->pixDistances().at(i); 
				newPos=itemProp_->positionFromHotSpot(QString::fromStdString(obj->name()),
									     cursorScenePos+dp*getIconSize(),
									     bottomRight);		
			  		     					     
				newRefPos=itemProp_->referencePosition(QString::fromStdString(obj->name()),newPos);
			
				//Icons can be off screen vertically or horizontally so we need to 
				//adjust their positions
				if(newRefPos.y() < 0)
			  		newRefPos.setY(0);
				if(newRefPos.x() < 0)
			  		newRefPos.setX(0);
								
			}
			
			if(!doAdjustScene)
			{
			  	QSize objSize=itemProp_->size(QString::fromStdString(obj->name()));
				if(newPos.x()+objSize.width()+2 > rightEdge  || 
				   newPos.y()+objSize.height()+2 > bottomEdge) 
					doAdjustScene=true;
			}			
			
			//Copy  
			if(dropAction == Qt::CopyAction)
			{			
				obj->clone(folder,newRefPos.x(),newRefPos.y(),false);
			}
			//Move
			else if(dropAction == Qt::MoveAction)
			{  
				//Drag from the same view/model
				if(fromSameView)
				{		  	
			  		QString name=QString::fromStdString(obj->name());					
					QPoint oriPos=itemProp_->referencePosition(obj);
					QPoint newPos=oriPos+deltaPos;
				
					//Icons can be off screen vertically or horizontally so we need to 
					//adjust their positions
					if(newPos.y() < 0)
			  			newPos.setY(0);
					if(newPos.x() < 0)
			  			newPos.setX(0);				
					
					//We need to store the storedPos in the object!!!
					QPoint storedPos=itemProp_->storedPosition(newPos);
					obj->position(storedPos.x(),storedPos.y());
					
					if(MvQIconItem *item=objectToItem(obj))
					{
			  			item->setPos(itemProp_->position(name,newPos));
					}
				}
				
				//Drop from another view/model
				else
				{
					if(!obj->locked())
					{
						//We need to store the storedPos in the object!!!
						QPoint storedPos=itemProp_->storedPosition(newRefPos);
						obj->position(storedPos.x(),storedPos.y());					
						folder->adopt(obj);
					}	
				}
			}	
		}	
	}
	
	if(doAdjustScene)
		adjustSceneRect();
} 


//===============================================
// Renaming
//===============================================

void MvQIconFolderView::rename(IconObject *obj)
{
 	if(MvQIconItem *item=objectToItem(obj))
		edit(item);  
}  


void MvQIconFolderView::slotRename()
{
  	if(editor_)
	{	  	
        qDebug() << "slotRename()";

        folderModel_->setData(editor_->item()->index(),editor_->editor()->text(),Qt::EditRole);
		removeEditor();
	}
}

//Called from the source model when the item was renamed!
void MvQIconFolderView::slotObjectRenamed(const QModelIndex& sourceIndex,QString oriName)
{
	QModelIndex index=filterModel_->mapFromSource(sourceIndex);
  	MvQIconItem *item=indexToItem(index);
  	if(item)
	{
	  	if(itemProp_->viewMode() == Desktop::IconViewMode)
		{
			QString name=filterModel_->data(index,Qt::DisplayRole).toString();
			QPoint pos=filterModel_->data(index,MvQFolderModel::PositionRole).toPoint();	
			QPoint newPos=itemProp_->adjsutReferencePosition(name,oriName,pos);	
			filterModel_->setData(index,newPos,MvQFolderModel::PositionRole);
		}
		item->adjust();
	}	
}  


void MvQIconFolderView::edit(QGraphicsItem *item)
{
  	if(item && !editor_) 
	{  	
	  	qDebug() << "create editor";
		
	  	MvQIconItem *ic=static_cast<MvQIconItem*>(item);
		editor_=new MvQEditorProxy(ic);
		
        //Warning: editingFinished is emitted twice !!! It is a known qt bug!!
		//So we needed to use returnPressed here.
        //connect(editor_->editor(),SIGNAL(returnPressed()),
        connect(editor_,SIGNAL(finishedEditing()),
            this,SLOT(slotRename()));
			
		scene()->addItem(editor_);
		//editor_->setPos(item->pos().x(),item->pos().y()+getIconSize()+5);
		editor_->setPos(ic->textPos());
		scene()->setFocusItem(editor_,Qt::MouseFocusReason);	
		editor_->editor()->setFocus(Qt::MouseFocusReason);
		
		if(defaultShortCut_)
		  	defaultShortCut_->setEnabled(false);	
	}
}	

void MvQIconFolderView::removeEditor()
{
  	if(editor_)
	{
		scene()->removeItem(editor_);
		editor_->deleteLater();
		editor_=0;
		
		if(defaultShortCut_)
		  	defaultShortCut_->setEnabled(true);
	}
}

//==============================================================
//  Keys
//==============================================================

void MvQIconFolderView::setupShortCut()
{
	if(shortCutInit_)
	  	return;
	else
	  	shortCutInit_=true;
	
	if(MvQContextItemSet *cms=cmSet())
	{
		foreach(MvQContextItem *cm,cms->icon())
		{	  		
		  	if(!appIconActions_  ||  !appIconActions_->shortCutDefined(cm->shortCut()))
			{  
			  	if(QShortcut *sc=cm->makeShortCut(this))		
				{
					connect(sc,SIGNAL(activated()),
						this,SLOT(slotIconShortCut()));
				}
			}	
		}
		
		foreach(MvQContextItem *cm,cms->desktop())
		{	  
		  	if(!appDesktopActions_  ||  !appDesktopActions_->shortCutDefined(cm->shortCut()))
			{  
		  		if(QShortcut *sc=cm->makeShortCut(this))
				{
		  			connect(sc,SIGNAL(activated()),
						this,SLOT(slotDesktopShortCut()));
				}
			}
		}
		
		if(QShortcut* sc=cms->makeDefaultIconShortCut(this))
		{
			defaultShortCut_=sc;
		  	connect(defaultShortCut_,SIGNAL(activated()),
				this,SLOT(slotDefaultShortCut()));
		}
		
	}
}

void MvQIconFolderView::slotIconShortCut()
{
	QShortcut *sc=static_cast<QShortcut*>(QObject::sender());
  	if(sc)
	{	QModelIndexList lst=selectedIndexes();
		
		qDebug() << "shortcuts" << sc << lst;
		if(lst.count() > 0)
		  	handleIconShortCut(sc,lst);
	}	
}

void MvQIconFolderView::slotDefaultShortCut()
{
  	if(defaultShortCut_)
	{	QModelIndexList lst=selectedIndexes();
		
		qDebug() << "default shortcut" << lst;
		if(lst.count() == 1)
		  	handleDoubleClick(lst.at(0));
	}	
}

void MvQIconFolderView::slotDesktopShortCut()
{
	QShortcut *sc=static_cast<QShortcut*>(QObject::sender());
  	if(sc) 
	{
	  	QPoint scrollOffset(horizontalScrollBar()->value(),verticalScrollBar()->value()); 
		handleDesktopShortCut(sc,mousePos_+scrollOffset,this);
	}	
}


void MvQIconFolderView::keyPressEvent(QKeyEvent* event)
{
	QGraphicsItem *current=0;
	
	qDebug() << "KEY" <<  event->key();
	
	if(editor_)
	{
	  	QGraphicsView::keyPressEvent(event);
		return;
	}
	
   	switch(event->key())
	{
	case Qt::Key_Left:
	case Qt::Key_Right:  
	case Qt::Key_Up: 
	case Qt::Key_Down:
	case Qt::Key_Home:
	case Qt::Key_End:  
		{
	  	current=findByKey(event->key());
		if(current)
		{
	  		if(!current->isSelected())
			{  	
			  	scene()->clearSelection();
				current->setSelected(true);
				ensureVisible(current);
			}	
		}
		event->accept();
		}
		break;
	default:
		bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier));
        	if(!event->text().isEmpty() && !modified)
		{
        		current=findByText(event->text());
			if(current)
			{
	  			if(!current->isSelected())
				{  	
			  		scene()->clearSelection();
					current->setSelected(true);
					ensureVisible(current);
				}	
			}
			event->accept();
        	} 
        	else
		{
	  		event->ignore();
		}
		break;
	}	
	
  	//QGraphicsView::keyPressEvent(event);
}	


//---------------------------------
// Keypad navigation
//---------------------------------

QGraphicsItem *MvQIconFolderView::findByKey(int key)
{
  	if(items().count()==0) 
	  	return 0;
  
  	QGraphicsItem *current=items().at(0);
	QList<QGraphicsItem*> sLst=scene()->selectedItems();
  	if(sLst.size()>0) current=sLst.at(0);
	 
	QRectF rect=current->boundingRect();
	rect.moveTo(current->pos());

	QSizeF contents = sceneRect().size();
    	QList<QGraphicsItem*> intersectVector;
    	
  	switch(key)
   	{  
   	case Qt::Key_Left:     		
	  	while (intersectVector.isEmpty()) 
		{
            		rect.translate(-rect.width(), 0);
            		if (rect.right() <= 0)
			{
			  	rect.moveTo(contents.width()-rect.width(),rect.y()-rect.height());
				if (rect.bottom() <= 0) 			
                			return current;
				if (rect.top() < 0)
                			rect.setTop(0);
			}
            		if (rect.left() < 0)
                		rect.setLeft(0);
			
            		intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
        	}
        	return intersectVector.at(0);		
	case  Qt::Key_Right:
	  	while (intersectVector.isEmpty()) 
		{
            		rect.translate(rect.width(), 0);
			if (rect.left() >= contents.width())
			{
			  	rect.moveTo(0,rect.y()+rect.height());
				if (rect.top() >= contents.height())
			  		return current;
				if (rect.bottom() > contents.height())
                			rect.setBottom(contents.height());
			}
			if (rect.right() > contents.width())
                		rect.setRight(contents.width());	   
            		
			intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
        	}
        	return intersectVector.at(0);		
	  
	 case Qt::Key_Up:
        	while (intersectVector.isEmpty()) 
		{
            		rect.translate(0, -rect.height());
            		if (rect.bottom() <= 0) 			
                		return current;
			if (rect.top() < 0)
                		rect.setTop(0);
			
			intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
		}	
		return intersectVector.at(0);	
	 
	 case Qt::Key_Down:
        	while (intersectVector.isEmpty()) 
		{
            		rect.translate(0, rect.height());
           		if (rect.top() >= contents.height())
			  	return current;
			 if (rect.bottom() > contents.height())
                		rect.setBottom(contents.height());
			intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
		}	
		return intersectVector.at(0);				
           
	case Qt::Key_Home:		
		rect.moveTo(-rect.width(),0);
		while (intersectVector.isEmpty()) 
		{
            		rect.translate(rect.width(), 0);
			if (rect.left() >= contents.width())
			{
			  	rect.moveTo(0,rect.y()+rect.height());
				if (rect.top() >= contents.height())
			  		return current;
				if (rect.bottom() > contents.height())
                			rect.setBottom(contents.height());
			}
			if (rect.right() > contents.width())
                		rect.setRight(contents.width());	   
            		
			intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
        	}
        	return intersectVector.at(0);	
		
	case Qt::Key_End:
		rect.moveTo(contents.width()-1,contents.height()-rect.height());
	  	while (intersectVector.isEmpty()) 
		{
            		rect.translate(-rect.width(), 0);
            		if (rect.right() <= 0)
			{
			  	rect.moveTo(contents.width()-rect.width(),rect.y()-rect.height());
				if (rect.bottom() <= 0) 			
                			return current;
				if (rect.top() < 0)
                			rect.setTop(0);
			}
            		if (rect.left() < 0)
                		rect.setLeft(0);
			
            		intersectVector = scene()->items(rect,Qt::IntersectsItemShape,Qt::AscendingOrder);
            		intersectVector.removeAll(current);
        	}
		return intersectVector.at(0);
	
	default:
	  	return current;
	}	
}    

QGraphicsItem* MvQIconFolderView::findByText(QString search)
{   
    	if(!folderModel_->folder() || items().count()==0) 
	  	return 0;
  
	//Get current item and index
  	QGraphicsItem *currentItem=items().at(0);
	QList<QGraphicsItem*> sLst=scene()->selectedItems();
  	if(sLst.size()>0) currentItem=sLst.at(0);			
	QModelIndex current =  itemToIndex(currentItem); 
   
	QTime now(QTime::currentTime());
	if (search.isEmpty()
        	|| (keyboardInputTime_.msecsTo(now) > QApplication::keyboardInputInterval())) 
	{
        	keyboardInput_ = search; 
    	}
    	else 
	{
        	keyboardInput_ += search;
    	}
    	keyboardInputTime_ = now;
	
  
    	bool sameKey = false;
   	if(keyboardInput_.length() > 1) 
	{
        	int c = keyboardInput_.count(keyboardInput_.at(keyboardInput_.length() - 1));
        	sameKey = (c == keyboardInput_.length());
  
	}
	
    	const QString searchString = sameKey ? QString(keyboardInput_.at(0)) : keyboardInput_;
	QModelIndexList match = filterModel_->match(current, Qt::DisplayRole, searchString,-1,
						    Qt::MatchStartsWith | Qt::MatchWrap);
	
	match.removeOne(current);	
	return (match.count() > 0)?indexToItem(match.at(0)):currentItem;
}   

//==============================================
// Effects
//==============================================

void MvQIconFolderView::blink(const QModelIndex& index)
{
  	if(MvQIconItem *item=indexToItem(index))
	{
	  	ensureVisible(item);
  		if(!timer_)
		{
		  	timer_=new MvQIconItemTimer(item,this);
		}
		else
		{
		  	timer_->setItem(item);
		}
		
		timer_->blink();
	}	
}	

void MvQIconFolderView::showIcon(const QModelIndex& index)
{
	if(MvQIconItem *item=indexToItem(index))
	{
		ensureVisible(item);
		selectOnlyOneItem(item);
	}	
}
