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

 Copyright 2013 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 <QAction>
#include <QApplication>
#include <QDebug>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QMap>

#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QPainter>
#include <QPair>
#include <QPlainTextEdit>
#include <QToolButton>
#include <QVBoxLayout>

#include "MvQBookmarks.h"

#include "MvQ.h"
#include "MvQContextMenu.h"
#include "MvQDropTarget.h"
#include "MvQFileBrowser.h"
#include "MvQFolderViewBase.h"
#include "MvQKeyManager.h"
#include "MvQKeyModel.h"
#include "MvQIconProvider.h"

#include "Folder.h"
#include "IconClass.h"
#include "IconFactory.h"
#include "IconObject.h"
#include "MvKeyProfile.h"
#include "Path.h"
 
MvQKeyManager* MvQBookmarks::manager_=0;
MvQBookmarksModel* MvQBookmarks::model_=0;
MvKeyProfile* MvQBookmarks::prof_=0;

//==============================
//
// MvQBookmarksDelegate
//
//==============================

MvQBookmarksDelegate::MvQBookmarksDelegate(QWidget *parent) : QStyledItemDelegate(parent)
{
}
 
void MvQBookmarksDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,
		           const QModelIndex& index) const
{
	if(index.column() == 0)
	{
		QStyleOptionViewItemV4 vopt(option);
   		initStyleOption(&vopt, index);
   
    		const QStyle *style = vopt.widget ? vopt.widget->style() : QApplication::style();
    		const QWidget* widget = vopt.widget;

		//painter->fillRect(option.rect,QColor(238,238,238));
		
		//We render everything with the default method
  		style->drawControl(QStyle::CE_ItemViewItem, &vopt, painter, widget);
	
		//Draw separator line
		painter->save();
		painter->setPen(QColor(200,200,200));
		painter->drawLine(option.rect.x(),option.rect.bottom()+1,
				  option.rect.right(),option.rect.bottom()+1);
		painter->restore();		
	}
	else
	 	QStyledItemDelegate::paint(painter,option,index);
}		

//=============================================
// 
// MvQBookmarksModel
//
//=============================================

QVariant MvQBookmarksModel::data( const QModelIndex& index, int role ) const
{
	if( !index.isValid() || index.column() !=0 ||  
	    (role != Qt::DisplayRole && role != Qt::ToolTipRole  && 
	     role != Qt::DecorationRole && role != Qt::UserRole))
        {			
		return QVariant();
	}
	
	MvKey  *key=profile_->at(index.row());	
	if(role == Qt::DisplayRole)
	{
		 return QString::fromStdString(key->shortName()); 
	}
	else if(role == Qt::ToolTipRole)
	{	  
	  	string cntStr=key->metaData("path_count");
		if(!cntStr.empty())
			return "Bookmark for a <b>group of folders</b>";
		else				  
		{
		  	//Check if path exist
		 	Path p=Folder::top()->path();
			if(p.add(key->name()).exists())
		  		return QString::fromStdString(key->name());
			else
			  	return "<b>Folder does not exsist!</b><br>" + QString::fromStdString(key->name());
		}	
			
	}
	else if(role == Qt::DecorationRole)
	{	
		return MvQIconProvider::bookmarkPixmap(key->name(),18);
	}
	else if(role == Qt::UserRole)
	{
	  	string cntStr=key->metaData("path_count");
		if(!cntStr.empty())
			return QVariant();
		else				  
			return QString::fromStdString(key->name());
	}

	return  QVariant();
}

//================================================
// 
//  MvQBookmarks
//
//================================================

MvQBookmarks::MvQBookmarks(QWidget *parent) : QObject(parent)
{
} 

//Static
void MvQBookmarks::init()
{	
	if(manager_)
	  	return;
  
  	manager_=new MvQKeyManager(MvQKeyManager::BookmarkType);
	manager_->loadProfiles();
	
	prof_=0;
	if(manager_->data().size() > 0)
	{  
		prof_=manager_->data().at(0);
	}
	else
	{
	  	prof_=new MvKeyProfile("custom");
		manager_->addProfile(prof_);
	}	

	model_=new MvQBookmarksModel(prof_);

}

//Static
MvQContextItemSet* MvQBookmarks::cmSet()
{
	static MvQContextItemSet cm("Bookmarks");
	return &cm;
}

//Static
void MvQBookmarks::save()
{
	manager_->saveProfiles();
}

bool MvQBookmarks::isBookmark(QString path)
{
  	MvKeyProfile *prof=model_->profile();
	if(!prof)
	  	return false;
	
	string p=path.toStdString();
	
	for(unsigned int i=0; i < prof->size(); i++)
	{  	  
	  	if(prof->at(i)->name() == p)
	  		return true;
	}
	return false;
}

void MvQBookmarks::defaultCommand(const QModelIndex &index)
{
 	MvKeyProfile *prof=model_->profile();
	MvKey *key=0;
	if(prof && index.row() <= static_cast<int>(prof->size()-1))
	{
	  	key=prof->at(index.row());
	}
	else 
	  	return;
	
	if(!key)
	  	return;
	
	QString fullName=QString::fromStdString(key->name());
	if(!isFolderGroup(key))
		emit openInBrowser(fullName);
	else
	  	emit openGroupInTabs(getPathsFromKey(key));
}	

void MvQBookmarks::command(QString name,const QModelIndex &index)
{
	if(!index.isValid())
		return;
	
	MvKeyProfile *prof=model_->profile();
	MvKey *key=0;
	if(prof && index.row() <= static_cast<int>(prof->size()-1))
	{
	  	key=prof->at(index.row());
	}
	else 
	  	return;
	
	if(!key)
	  	return;
	
	QString fullName=QString::fromStdString(key->name());
		
	if(name == "open" && !isFolderGroup(key))
	{
	  	emit openInBrowser(fullName);
	}
	else if(name == "openInTab" && !isFolderGroup(key))
	{
	  	emit openInTab(fullName);
	}
	else if(name == "openInWin" && !isFolderGroup(key))
	{
	  	emit openInWin(fullName);
	}
	else if(name == "editEntry")
	{
	  	if(editItem(index))
			MvQBookmarks::save();
	}
	else if(name == "duplicateEntry")
	{
	  	if(duplicateItem(index))
			MvQBookmarks::save();
	}
	else if(name == "removeEntry")
	{
	  	if(deleteItem(index))
			MvQBookmarks::save();
	}
	else if(name == "openGroup")
	{
	  	emit openGroupInTabs(getPathsFromKey(key));
	}
	else if (name == "openGroupInWin")
	{	  
		emit openGroupInWin(getPathsFromKey(key));
	}
	else if (name == "empty")
	{	  	
	  	MvQ::emptyWasteBasket();	
	}
}

void MvQBookmarks::command(QString name)
{
	if(name == "addEntry")
	{
	  	emit bookmarkFolder();
	
	}	
	else if(name == "addTabs")
	{
	  	emit  bookmarkTabs();
	}
	else if(name == "addBookmark")
	{
		MvKey *key=new MvKey;
		addItem(key);
	}		
}

//Static 
bool MvQBookmarks::addItem(MvKey *key)
{
  	if(!key)
	  	return false;

	QDialog *dialog;
	
	if(!MvQBookmarks::isFolderGroup(key))
		dialog=new MvQBookmarksDialog(key,tr("Add bookmark")); 
	else
		dialog=new MvQBookmarksGroupDialog(key,tr("Add new bookmark group"));

	bool retVal=false;
	if(dialog->exec() == QDialog::Accepted)
	{
		model_->profileIsAboutToChange();
		prof_->addKey(key);
		model_->setKeyProfile(prof_);
		MvQBookmarks::save();
			
		retVal=true;
	}
	else
	{
	  	delete key;
		retVal=false;
	}
	
	dialog->deleteLater();
	return retVal;
}


//Static
bool MvQBookmarks::addItem(IconObject *obj)
{
	if(obj && !obj->isFolder())  	
  		return false;
	
	MvKey *key=new MvKey;		
  	if(obj)
	{
	  	key->setName(obj->fullName());
		key->setShortName(obj->name());
	}
		
	return MvQBookmarks::addItem(key);	
}  

//Static
bool MvQBookmarks::addItem(QString path)
{
	if(path.isEmpty())
	  	return false;
	
	Path p=Folder::top()->path();
	Path realPath=p.add(path.toStdString());
	
	if(!realPath.exists())
		return false;
	
	MvKey *key=new MvKey;		
	key->setName(path.toStdString());
	key->setShortName(realPath.name());
			
	return MvQBookmarks::addItem(key);
}  

//Static
bool MvQBookmarks::addItem(QList<Folder*> folderLst)
{
	MvKey *key=new MvKey;	
	//Foldergroup bookmarks' name maust be FOLDERGROUP !!!
  	key->setName("FOLDERGROUP");
	key->setShortName("Tabs");
	
	//Set data for the paths
	key->setMetaData("path_count",QString::number(folderLst.count()).toStdString());	
	for(int i=0; i < folderLst.count(); i++)
	{
	  	QString id;
                id.sprintf("path_%02d",i);
	  	key->setMetaData(id.toStdString(),folderLst.at(i)->fullName());
	}	
	
	return MvQBookmarks::addItem(key);
}

//static
bool MvQBookmarks::editItem(QString path)
{
  	bool retVal=false;
  	MvKeyProfile *prof=model_->profile();
	if(!prof)
	  	return false;
	
	string p=path.toStdString();
	QModelIndex index;

	for(unsigned int i=0; i < prof->size(); i++)
	{  	  
	  	if(prof->at(i)->name() == p)
		{
		  	retVal=editItem(prof->at(i));			
		}	
	}
	
	return retVal;
}  

//static
bool MvQBookmarks::editItem(MvKey *key)
{
	if(!key)
  		return false;

	bool accepted=false; 
	if(key->name() == "FOLDERGROUP" && !key->metaData("path_count").empty())
	{
		MvQBookmarksGroupDialog dialog(key,tr("Edit bookmark group"));
		if(dialog.exec()  == QDialog::Accepted)
		{
			accepted=true;	
		}
	}
	else
	{  
		MvQBookmarksDialog dialog(key,tr("Edit bookmark"));
		if(dialog.exec()  == QDialog::Accepted)	
		{
			 accepted=true;
		}
	}	
			
	if(accepted)	
	{
		//Not too efficient
		model_->profileIsAboutToChange();
		model_->setKeyProfile(prof_);
	}
	
	return accepted;
}  


bool MvQBookmarks::editItem(const QModelIndex& index)
{
	MvKeyProfile *prof=model_->profile();
	MvKey *key=0;
	if(prof && index.isValid() && index.row() <= static_cast<int>(prof->size()-1))
	{
	  	key=prof->at(index.row());	
	}
	else
	  	return false;
		
	return MvQBookmarks::editItem(key);
}  

bool MvQBookmarks::duplicateItem(const QModelIndex& index)
{
	MvKeyProfile *prof=model_->profile();
	MvKey *key=0;
	if(prof && index.isValid() && index.row() <= static_cast<int>(prof->size()-1))
	{
	  	key=prof->at(index.row());	
	}
	else
	  	return false;
		
	MvKey *dupKey=key->clone();		
	if(!dupKey->shortName().empty())
	{
		model_->profileIsAboutToChange();
		prof->addKey(dupKey);
		model_->setKeyProfile(prof);
		return true;
	}
	
	return false;
}  

bool MvQBookmarks::deleteItem(const QModelIndex& index)
{
	MvKeyProfile *prof=model_->profile();
	if(prof==0 || !index.isValid() )
		return false;	
	
	MvKey *key=prof->at(index.row());
	
	QString str=tr("Are you sure that you want to delete entry <b>");
	str+=QString::fromStdString(key->shortName());
	str+="</b>?";

 	QMessageBox msgBox;
	msgBox.setWindowTitle(tr("Delete bookmark"));
	msgBox.setText(str);
 	msgBox.setIcon(QMessageBox::Warning);
	msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
	msgBox.setDefaultButton(QMessageBox::Cancel);
	
	int ret=msgBox.exec();

	switch (ret) 
	{
   	case QMessageBox::Yes:
       	{	
		model_->profileIsAboutToChange();
		prof->deleteKey(index.row());
		model_->setKeyProfile(prof);
		return true;
	}
      	break;
   	case QMessageBox::Cancel:
       	// Cancel was clicked
       	break;
   	default:
       	// should never be reached
      	 break;
	}	
	
	return false;
}

MvKey* MvQBookmarks::getKey(const QModelIndex& index)
{
	if(index.row() >=0)
	{		
		MvKeyProfile *prof=model_->profile();
		if(prof && index.row() <= static_cast<int>(prof->size()-1))
		{
	  		return prof->at(index.row());	
		}
	}
	
	return 0;
}  

QString  MvQBookmarks::getPath(const QModelIndex& index)
{
	MvKey *key=getKey(index);
	return (key)?QString::fromStdString(key->name()):QString();
}	
	
QStringList MvQBookmarks::getPathsFromKey(MvKey* key)
{
	QStringList lst;
	
	if(!key)
		return lst;
	
	string cntStr=key->metaData("path_count");
	if(!cntStr.empty())
	{			  	
	  	int cnt=QString::fromStdString(cntStr).toInt();	  	
	  	for(int i=0; i < cnt; i++)
		{
		  	QString id;
                	id.sprintf("path_%02d",i);
	  		string val=key->metaData(id.toStdString()); 
	  		if(!val.empty())
				lst << QString::fromStdString(val);							
		}
	}
	
	return lst;
}

//Static
bool MvQBookmarks::isFolderGroup(MvKey *key)
{
  	if(!key)
	  	return false;
		
	return (key->name() == "FOLDERGROUP" && key->metaData("path_count").empty() == false);
}	


//================================================
// 
//  MvQBookmarksMenu
//
//================================================

MvQBookmarksMenu::MvQBookmarksMenu(QWidget *parent,QMenu *menu) : 
	MvQBookmarks(parent),
	menu_(menu)
{
	actionFolder_ = new QAction(menu_);
	actionFolder_->setIcon(QPixmap(":/desktop/add_bookmark.svg")); 
	actionFolder_->setText(tr("Bookmark current &folder"));
        //actionFolder_->setShortcut(tr("Ctrl+D"));
	menu_->addAction(actionFolder_);

	actionTabs_ = new QAction(menu_);
	actionTabs_->setIcon(QPixmap(":/desktop/add_bookmark_group.svg")); 
	actionTabs_->setText(tr("Bookmark current &tabs"));
        //actionTabs_->setShortcut(tr("Ctrl+T"));
	menu_->addAction(actionTabs_);

	QAction *sep1=new QAction(this);
	sep1->setSeparator(true);
	menu_->addAction(sep1);
	
	actionAdd_ = new QAction(menu_);
	actionAdd_->setIcon(QPixmap(":/desktop/add.svg")); 
	actionAdd_->setText(tr("New bookmark"));
        //addAction->setShortcut(tr("Ctrl+T"));
	menu_->addAction(actionAdd_);

	QAction *sep=new QAction(this);
	sep->setSeparator(true);
	menu_->addAction(sep);
	
	//Populate
	slotUpdate();
	
  	connect(model_,SIGNAL(modelReset()),
		this,SLOT(slotUpdate()));

	connect(menu_,SIGNAL(triggered(QAction*)),
		this,SLOT(slotMenu(QAction*))); 
		
	//Context menu 
    	menu_->setContextMenuPolicy(Qt::CustomContextMenu);
	
	connect(menu_,SIGNAL(customContextMenuRequested(const QPoint &)),
                this, SLOT(slotContextMenu(const QPoint &)));	  			
}  
			
void MvQBookmarksMenu::slotContextMenu(const QPoint& pos)
{
	MvQContextItemSet *cms=cmSet();
	if(!cms) return;
	
	QAction *ac=menu_->actionAt(pos);
	QString path="path=" + getPath(ac);

	if(!path.isEmpty())
	{
		QString selection=MvQContextMenu::instance()->exec(cms->icon(),menu_->mapToGlobal(pos),menu_,
								   path);  		
		if(!selection.isEmpty()) 
		{
		  	QModelIndex index=getIndex(ac);
			command(selection,index);
		}	
	}	
}	
void MvQBookmarksMenu::slotUpdate()
{
	QList<QAction*> lst=menu_->actions();
	
	int cnt=model_->rowCount();
	
	for(int i=0; i < cnt; i++)
	{
	  	QAction *action;
		if(lst.count() <= i+5)
		{  
			action=new QAction(menu_);
			menu_->addAction(action);
		}
		else
		{
		  	action=lst.at(i+5);
		}		
			
  		QModelIndex index=model_->index(i,0);
	  	QString name=model_->data(index,Qt::DisplayRole).toString();
	  	QString tooltip=model_->data(index,Qt::ToolTipRole).toString();
	  	QPixmap pix=model_->data(index,Qt::DecorationRole).value<QPixmap>();
		
		action->setText(name);
		action->setToolTip(tooltip);
		action->setIcon(pix);
		action->setData(i+1);
	}
	
	while(lst.count() > cnt+5)
	{
	  	QAction *action=lst.takeLast();	
		qDebug() << action->text();
	  	menu_->removeAction(action);		
		delete action;
	}	  
}  

void MvQBookmarksMenu::slotMenu(QAction* ac)
{	 
	if(ac == actionFolder_)
	  	command("addEntry");	
  	else if(ac == actionTabs_)
	  	command("addTabs");
	else if( ac == actionAdd_)
	  	command("addBookmark");
  	else
	  	defaultCommand(getIndex(ac));
}  
  
QString  MvQBookmarksMenu::getPath(QAction* ac)
{
	if(ac && !ac->isSeparator())
	{
		QModelIndex index=getIndex(ac);
		return MvQBookmarks::getPath(index);
	}
	
	return QString();
}  
  
MvKey* MvQBookmarksMenu::getKey(QAction* ac)
{
	if(ac && !ac->isSeparator())
	{
		QModelIndex index=getIndex(ac);
		return MvQBookmarks::getKey(index);
	}
	
	return 0;
}  
  
QModelIndex MvQBookmarksMenu::getIndex(QAction *ac)
{
 	if(ac && !ac->isSeparator())
	{
		int  i=ac->data().toInt()-1;
		return model_->index(i,0);
	} 
	
	return QModelIndex();
}  
  
//================================================
// 
//  MvQBookmarksView
//
//================================================

MvQBookmarksView::MvQBookmarksView(QWidget *parent) : 
 QListView(parent)
{ 
	//view_->setModel(model_);	
	setDragEnabled(true);
 	setAcceptDrops(true);
		
	setSpacing(0); 
	setProperty("sidebarView","true");
}	
  
  
void MvQBookmarksView::checkDropTarget(QDropEvent *event)
{  
	if(!event->mimeData()->hasFormat("metview/icon"))
	{	
		removeDropTarget();			
	}
	
	QModelIndex index=indexAt(event->pos());
	QString s=model()->data(index,Qt::UserRole).toString();
	
	if(!s.isEmpty())
	{	
		Folder *f=Folder::folder(s.toStdString(),false);  		
		if(f && !f->locked())
		{
	  		Qt::DropAction dropAction=event->proposedAction();
			MvQDropTarget::Instance()->reset(QString::fromStdString(f->name()),
							 (dropAction == Qt::MoveAction),"folder");	
		
			if(window())
			{  
				MvQDropTarget::Instance()->move(mapToGlobal(event->pos())+QPoint(20,20));
			}
			return;
		}
	}
	
	removeDropTarget();	
}	  

void MvQBookmarksView::removeDropTarget() 
{  
  	MvQDropTarget::Instance()->hide();
}  
  
void MvQBookmarksView::dragEnterEvent(QDragEnterEvent *event)
{
	if(event->source() != this)
	{
	  	if(event->source() &&
	   	  (event->proposedAction() == Qt::CopyAction ||
	           event->proposedAction() == Qt::MoveAction))
		{
			event->accept();
			
		}
		else  
			event->ignore();
	}
	else
	  	QListView::dragEnterEvent(event);
}

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

void MvQBookmarksView::dragLeaveEvent(QDragLeaveEvent *event)
{	
	removeDropTarget();
	event->accept();
}	
	  
void MvQBookmarksView::dropEvent(QDropEvent *event)
{
	if(event->source() != this)
	{  
	  	removeDropTarget();
		
		if(!event->source())
		{
			event->ignore();
			return;
		}	
	
		if(event->proposedAction() != Qt::CopyAction &&
	  	   event->proposedAction() != Qt::MoveAction)
		{
			event->ignore();
			return;
		}	
	
		QModelIndex index=indexAt(event->pos());
		QString s=model()->data(index,Qt::UserRole).toString();
		
		if(!s.isEmpty())
		{	
			Folder *f=Folder::folder(s.toStdString(),false);
			MvQFolderViewBase::dropToFolder(f,event);
		}	
			
	}
	
	else
	  	QListView::dropEvent(event);
} 
  
void MvQBookmarksView::paintEvent(QPaintEvent *event)
{
	QListView::paintEvent(event);
	
	//QPainter painter(viewport());
	//painter.setRenderHint(QPainter::Antialiasing);

    	//Render ring pixmap
    	//painter.drawPixmap(15,50,MvQIconProvider::dropTargetPixmap("Defaults",true));
	
}


//================================================
// 
//  MvQBookmarksPanel
//
//================================================

MvQBookmarksPanel::MvQBookmarksPanel(QWidget *parent) : 
      MvQBookmarks(parent)
{
	widget_=new QWidget(parent);
  	widget_->setProperty("sidebar","true");	
  
  	QVBoxLayout *vb=new QVBoxLayout;
	vb->setSpacing(0); 
	vb->setContentsMargins(0,0,0,0);
	widget_->setLayout(vb);
	
	QHBoxLayout *hb=new QHBoxLayout;
	vb->addLayout(hb);
	
	hb->addSpacing(4);
	
	QLabel *label=new QLabel("<b>" + tr("Bookmarks") + "</b>",widget_);
	hb->addWidget(label);
	
	//QToolButton *addTb=new QToolButton(widget_);
	//addTb->setAutoRaise(true);	
	//addTb->setIcon(QPixmap(":/desktop/add_bookmark.svg")); 
	//addTb->setToolTip(tr("Add current folder to bookmarks"));
	//hb->addWidget(addTb);
	
	//connect(addTb,SIGNAL(clicked(bool)),
	//	this,SLOT(slotAddItem(bool)));

	QToolButton *closeTb=new QToolButton(widget_);
	closeTb->setAutoRaise(true);	
	closeTb->setIcon(QPixmap(":/desktop/remove.svg")); 
	closeTb->setToolTip(tr("Close sidebar"));
	hb->addWidget(closeTb);
	
	connect(closeTb,SIGNAL(clicked(bool)),
		this,SIGNAL(closePanel(bool)));
	
	view_=new MvQBookmarksView(widget_);
	vb->addWidget(view_);
	
	view_->setModel(model_);	
	//view_->setDragEnabled(true);
 	//view_->setAcceptDrops(true);
		
	//view_->setSpacing(0); 
	//view_->setProperty("mvStyle","bookmarks");
	
	view_->setContextMenuPolicy(Qt::CustomContextMenu);
	
	//MvQBookmarksDelegate* delegate=new MvQBookmarksDelegate(view_);
	//view_->setItemDelegate(delegate);
	

	connect(view_,SIGNAL(doubleClicked(const QModelIndex&)),
		this,SLOT(slotDoubleClickItem(const QModelIndex&)));
	
	//Context menu 
    	connect(view_,SIGNAL(customContextMenuRequested(const QPoint &)),
                this, SLOT(slotContextMenu(const QPoint &))); 
}

void MvQBookmarksPanel::slotDoubleClickItem(const QModelIndex& index)
{
	defaultCommand(index);
}  

void MvQBookmarksPanel::slotContextMenu(const QPoint& pos)
{
	MvQContextItemSet* cms=cmSet();
	if(!cms) return;
	
	QModelIndex index=view_->indexAt(pos);
  
	//Desktop action
	if(!index.isValid())
	{  
		QString selection=MvQContextMenu::instance()->exec(cms->desktop(),view_->mapToGlobal(pos),view_);   	
		if(!selection.isEmpty()) 
		  	command(selection);  
	}
	
	//Icon Actions
	else if(model_->profile() && index.isValid())
	{		
	  	QString path="path=" + getPath(index);
	  	QString selection=MvQContextMenu::instance()->exec(cms->icon(),view_->mapToGlobal(pos),view_,
				    path);  
		
		if(!selection.isEmpty()) 
		  	command(selection,index);
	}	
}	

void MvQBookmarksPanel::slotAddItem(bool)
{
  	command("addEntry");
}




//================================================
// 
//  MvQBookmarksDialog
//
//================================================

MvQBookmarksDialog::MvQBookmarksDialog(MvKey* key,QString title,QWidget *parent) : 
    QDialog(parent), 
    key_(key)
{
	setWindowTitle(title);
  	
  	QVBoxLayout* vb=new QVBoxLayout;
	setLayout(vb);
		
	QGridLayout* grid=new QGridLayout;
	vb->addLayout(grid);
	
	QLabel *label;
	
	label=new QLabel(tr("&Label:"));
	labelEdit_=new QLineEdit;
	label->setBuddy(labelEdit_);
	if(key_)
	{
		labelEdit_->setText(QString::fromStdString(key_->shortName()));
	}
	
	grid->addWidget(label,0,0);
	grid->addWidget(labelEdit_,0,1);
	
	label=new QLabel(tr("&Path:"));
	pathEdit_=new QLineEdit;
	label->setBuddy(pathEdit_);
	if(key_)
	{
	  	pathEdit_->setText(QString::fromStdString(key_->name()));
	}
	grid->addWidget(label,1,0);
	grid->addWidget(pathEdit_,1,1);
	
	// Buttonbox
	QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                      | QDialogButtonBox::Cancel);
 
	connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
		
	//Try to find the optimal dialog width
	QFont font;
	QFontMetrics fm(font);
	setMinimumWidth(fm.width(tr("Label"))+fm.width(pathEdit_->text())+100);
	
	vb->addWidget(buttonBox);
}  

void MvQBookmarksDialog::accept()
{
  	QString path=pathEdit_->text();
	QString label=labelEdit_->text();
  		
  	QString errTxt=tr("Failed to create bookmark!");
  	
  	if(path.isEmpty())
	{  
		QMessageBox::critical(this,tr("Create bookmark"),errTxt + tr("<b> Path</b> cannot be empty!"));
		return;
	}
	else if(label.isEmpty())
	{
		QMessageBox::critical(this,tr("Create bookmark"),errTxt+ tr(" <b>Label</b> cannot be empty!"));
		return;
	} 
  	 
  	if(key_)
	{
	  	key_->setName(path.toStdString());
		key_->setShortName(label.toStdString());
	}
	
	QDialog::accept();
}	

//================================================
// 
//  MvQBookmarksGroupDialog
//
//================================================

MvQBookmarksGroupDialog::MvQBookmarksGroupDialog(MvKey* key,QString title,QWidget *parent) : 
    QDialog(parent), 
    key_(key)
{
	setWindowTitle(title);
  	
  	QVBoxLayout* vb=new QVBoxLayout;
	setLayout(vb);
		
	QGridLayout* grid=new QGridLayout;
	vb->addLayout(grid);
	
	QLabel *label;
	
	label=new QLabel(tr("&Label:"));
	labelEdit_=new QLineEdit;
	label->setBuddy(labelEdit_);
	if(key_)
	{
		labelEdit_->setText(QString::fromStdString(key_->shortName()));
	}
	
	grid->addWidget(label,0,0);
	grid->addWidget(labelEdit_,0,1);
	
	label=new QLabel(tr("&Paths:"));
	pathEdit_=new QPlainTextEdit;
	label->setBuddy(pathEdit_);
	pathEdit_->setPlainText(getPathsFromKey());
	 
	grid->addWidget(label,1,0);
	grid->addWidget(pathEdit_,1,1);
	
	// Buttonbox
	QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                      | QDialogButtonBox::Cancel);
 
	connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
		
	//Try to find the optimal dialog width
	QFont font;
	QFontMetrics fm(font);
	//setMinimumWidth(fm.width(tr("Label"))+fm.width(pathEdit_->text())+100);
	
	vb->addWidget(buttonBox);
}  

QString MvQBookmarksGroupDialog::getPathsFromKey()
{
	QString str;
	
	if(!key_)
		return str;
	
	string cntStr=key_->metaData("path_count");
	if(!cntStr.empty())
	{			  	
	  	int cnt=QString::fromStdString(cntStr).toInt();	  	
	  	for(int i=0; i < cnt; i++)
		{
		  	QString id;
                	id.sprintf("path_%02d",i);
	  		string val=key_->metaData(id.toStdString()); 
	  		if(!val.empty())
				str+=QString::fromStdString(val)+"\n";							
		}
	}
	
	return str;
}

void MvQBookmarksGroupDialog::accept()
{  	
  	QString path=pathEdit_->toPlainText();
	QString label=labelEdit_->text();
  		
  	QString errTxt=tr("Failed to create bookmark!");
  	
  	if(path.isEmpty())
	{  
		QMessageBox::critical(this,tr("Create bookmark"),errTxt + tr(" <b>Path</b> cannot be empty!"));
		return;
	}
	else if(label.isEmpty())
	{
		QMessageBox::critical(this,tr("Create bookmark"),errTxt+ tr(" <b>Label</b> cannot be empty!"));
		return;
	} 
  
 	if(key_)
	{
	  	//key_->setName(labelEdit_->text().toStdString());
		key_->setShortName(label.toStdString());
		
		//Figure out paths and add it to the key's metadata
		key_->clearMetaData();		
		QStringList lst=path.split("\n");
		int cnt=0;
		foreach(QString s,lst)
		{
		  	QString p=s.simplified();
			if(!p.isEmpty())
			{
				QString id;
                		id.sprintf("path_%02d",cnt);
				key_->setMetaData(id.toStdString(),p.toStdString());
				cnt++;
			}
		}
		key_->setMetaData("path_count",QString::number(cnt).toStdString());
				
	}
	QDialog::accept();
}	
