/***************************************************************************
 *   Copyright (C) 2005 by Nicolas Ternisien                               *
 *   nicolas.ternisien@gmail.com                                           *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/
 
#include "fileList.h"

#include <tqlayout.h>
#include <tqvgroupbox.h>
#include <tqbuttongroup.h>
#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqvbox.h>
#include <tqhbox.h>
#include <tqwhatsthis.h>
#include <tqtooltip.h>

// KDE includes
#include <klocale.h>
#include <kactioncollection.h>
#include <kbuttonbox.h>
#include <klistbox.h>
#include <kfiledialog.h>
#include <kurl.h>
#include <kmessagebox.h>
#include <kiconloader.h>

FileList::FileList(TQWidget *parent, TQString description) : 
	TQWidget(parent) 
	{

	TQHBoxLayout *layout = new TQHBoxLayout(this);
	layout->setAutoAdd(true);
	
	
	TQVGroupBox* dirBox = new TQVGroupBox(i18n( "Files" ), this);
	
	TQLabel *defaultPathLabel = new TQLabel(description, dirBox);
	defaultPathLabel->setTextFormat(RichText);

	TQHBox* center= new TQHBox(dirBox);
	center->setSpacing(10);
		
	fileList=new KListBox(center);
	buttons=new TQVBox(center);
	
	fileList->setSelectionMode(TQListBox::Extended);
	
	TQToolTip::add(fileList, i18n("List of files used by this log type"));
	TQWhatsThis::add(fileList, i18n("<qt>Here is a list of every files that will be read by KSystemLog to display the current log lines.</qt>"));
	

	add=new TQPushButton(SmallIcon("fileopen"), i18n("&Add File..."), buttons);
	connect(add, TQT_SIGNAL(clicked()), this, TQT_SLOT(addItem()));
	TQToolTip::add(add, i18n("Choose a new file"));
	TQWhatsThis::add(add, i18n("Opens a dialog box to choose a new file to be added to the list."));

	
	remove=new TQPushButton(SmallIconSet("edit_remove"), i18n("&Remove"), buttons);
	connect(remove, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeSelectedItem()));
	TQToolTip::add(remove, i18n("Delete the current file(s)"));
	TQWhatsThis::add(remove, i18n("Deletes the selected files of the list."));
	
	up=new TQPushButton(SmallIconSet("up"), i18n("Move &Up"), buttons);
	connect(up, TQT_SIGNAL(clicked()), this, TQT_SLOT(moveUpItem()));
	TQToolTip::add(up, i18n("Move up the current file(s)"));
	TQWhatsThis::add(up, i18n("<qt>Moves up the selected files in the list. This option allows the files to be read <b>in first</b> by KSystemLog.</qt>"));
	
	down=new TQPushButton(SmallIconSet("down"), i18n("Move &Down"), buttons);
	connect(down, TQT_SIGNAL(clicked()), this, TQT_SLOT(moveDownItem()));
	TQToolTip::add(down, i18n("Move down the current file(s)"));
	TQWhatsThis::add(down, i18n("<qt>Moves down the selected files in the list. This option allows the files to be read <b>at last</b> by KSystemLog.</qt>"));

	removeAll=new TQPushButton(SmallIconSet("cancel"), i18n("Re&move All"), buttons);
	connect(removeAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeAllItem()));
	TQToolTip::add(removeAll, i18n("Remove all files"));
	TQWhatsThis::add(removeAll, i18n("<qt>Remove all files of the list, even if they are not selected.</qt>"));

	fileListMenu=new KPopupMenu(this);
	fileListMenu->insertTitle(i18n("File List"));
	fileListMenu->insertItem(SmallIcon("fileopen"), i18n("&Add File..."), this, TQT_SLOT(addItem()), 0, ADD_FILE_MENU_ID);
	fileListMenu->insertItem(SmallIcon("edit_remove"), i18n("&Remove"), this, TQT_SLOT(removeSelectedItem()), 0, REMOVE_MENU_ID);
	fileListMenu->insertSeparator();
	fileListMenu->insertItem(SmallIcon("up"), i18n("Move &Up"), this, TQT_SLOT(moveUpItem()), 0, MOVE_UP_MENU_ID);
	fileListMenu->insertItem(SmallIcon("down"), i18n("Move &Down"), this, TQT_SLOT(moveDownItem()), 0, MOVE_DOWN_MENU_ID);
	fileListMenu->insertSeparator();
	fileListMenu->insertItem(SmallIcon("cancel"), i18n("Re&move All"), this, TQT_SLOT(removeAllItem()), 0, REMOVE_ALL_MENU_ID);
	
	connect(fileList, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(updateButtons()));
	
	connect(this, TQT_SIGNAL(fileListChanged(int)), this, TQT_SLOT(updateButtons()));
	
	connect(fileList, TQT_SIGNAL(rightButtonClicked(TQListBoxItem*, const TQPoint &)), this, TQT_SLOT(displayPopupMenu(TQListBoxItem*, const TQPoint&)));
	
	updateButtons();

}

FileList::~FileList() {

}

TQString FileList::getText(int i) {
	return(fileList->text(i));
}



void FileList::insertItem(TQString& item) {
	fileList->insertItem(item);
}

int FileList::count() {
	return(fileList->count());
}

void FileList::displayPopupMenu(TQListBoxItem*, const TQPoint& point) {
	fileListMenu->popup(point);
}

void FileList::addItem() {
	//Open a standard Filedialog
	KURL::List urlList;
	urlList=KFileDialog::getOpenURLs(DEFAULT_FOLDER, "*|" + i18n("All Files (*)") + "\n*.log|" + i18n("Log Files (*.log)"), this, i18n("Choose Log File"));
	
	KURL url;
	KURL::List::iterator it;
	
	for(it=urlList.begin(); it!=urlList.end(); ++it) {
		url=*it;
		if (isValidFile(url)) {
			fileList->insertItem(url.path());
		}
	}
	
	emit fileListChanged(fileList->count());
}

bool FileList::isValidFile(KURL url) {
	TQString message;
	
	//If it is not valid
	if (!url.isValid()) {
		message=i18n("'%1' is not valid.").arg(url.path());
		KMessageBox::error(this, message, i18n("File selection failed"), KMessageBox::Notify);
		return(false);
	}

	//If it is not a local file
	if (!url.isLocalFile()) {
		message=i18n("'%1' is not a local file.").arg(url.path());
		KMessageBox::error(this, message, i18n("File selection failed"), KMessageBox::Notify);
		return(false);
	}
	
	//If it's a directory, it's not valid
	if (TQDir(url.path()).exists()) {
		message=i18n("'%1' is a folder.").arg(url.path());
		KMessageBox::error(this, message, i18n("File selection failed"), KMessageBox::Notify);
		return(false);
	}
		
	return(true);
}

void FileList::removeItem(int id) {
	fileList->removeItem(id);
}

void FileList::removeSelectedItem() {
	
	for (int i=0; i<(int) fileList->count(); i++) {
		if (fileList->isSelected(i)==true) {
			this->removeItem(i);
			i--;
		}
	}
	
	fileList->setSelected(fileList->count()-1, true);
	fileList->setCurrentItem(fileList->count()-1);
	
	emit fileListChanged(fileList->count());
}

void FileList::moveUpItem() {
	int count=fileList->count();
	
	TQListBoxItem* item;
	int index;
	for (int i=1; i<count; i++) {
		if (fileList->isSelected(i)==true && fileList->isSelected(i-1)==false) {
			item=fileList->item(i);
			fileList->takeItem(item);
			fileList->insertItem(item, i-1);
			
			index=fileList->index(item);
			fileList->setSelected(index, true);
			fileList->setCurrentItem(index);
		}
	}
	
	emit fileListChanged(count);
}

void FileList::moveDownItem() {
	int count=fileList->count();
	
	TQListBoxItem* item;
	int index;
	for (int i=count-2; i>=0; i--) {
		if (fileList->isSelected(i)==true && fileList->isSelected(i+1)==false) {
			item=fileList->item(i);
			fileList->takeItem(item);
			fileList->insertItem(item, i+1);
			
			index=fileList->index(item);
			fileList->setSelected(index, true);
			fileList->setCurrentItem(index);
		}
	}
	
	emit fileListChanged(count);

}

void FileList::removeAllItem() {
	int count=fileList->count();
	
	for (int i=0; i<count; i++) {
		this->removeItem(0);
	}
	
	emit fileListChanged(0);
}


bool FileList::updateButtons() {
	int count=fileList->count();
	
	if (count==0)
		removeAll->setEnabled(false);
	else
		removeAll->setEnabled(true);
	
	bool selection=false;
	
	for (int i=0; i<count; i++) {
		if (fileList->isSelected(i)==true) {
			selection=true;
		}
	}

	//If nothing is selected, disabled special buttons
	remove->setEnabled(selection);
	up->setEnabled(selection);
	down->setEnabled(selection);
	
	return(selection);
}


#include "fileList.moc"
