/***************************************************************************
 *   Copyright (C) 2004 by David Sansome                                   *
 *   david@dave-linux                                                      *
 *                                                                         *
 *   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 <tqlayout.h>

#include <klocale.h>
#include <kglobal.h>
#include <kfontdialog.h>
#include <kiconloader.h>
#include <tqfile.h>
#include <tqtextstream.h>
#include <tqregexp.h>
#include <tqdir.h>
#include <tqcombobox.h>
#include <tqmap.h>
#include <tqbuttongroup.h>
#include <tqpushbutton.h>
#include <tqradiobutton.h>
#include <tqlabel.h>
#include <kurllabel.h>
#include <kapplication.h>
#include <kfontcombo.h>
#include <tqspinbox.h>
#include <ksqueezedtextlabel.h>
#include <stdlib.h>
#include <kmessagebox.h>
#include <kconfig.h>
#include <tqstyle.h>
#include <tqheader.h>
#include <klistview.h>
#include <tqmessagebox.h>
#include <tqcheckbox.h>
#include <kglobal.h>
#include <kstandarddirs.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "kcmgtk.h"
#include "mozillaprofile.h"

const TQString KcmGtk::GTK_RC_FILE(".gtkrc-2.0-kde-kde4");
const TQString KcmGtk::KDE_RC_DIR(KGlobal::dirs()->localtdedir() + "/env/");
const TQString KcmGtk::GTK_TQT_RC_FILE("gtk-qt-engine.rc.sh");

const TQString KcmGtk::GTK3_INI_DIR(TQDir::homeDirPath() + "/.config/gtk-3.0/");
const TQString KcmGtk::GTK3_INI_FILE("settings.ini");

/*typedef KGenericFactory<KcmGtk, TQWidget> KcmGtkFactory;
K_EXPORT_COMPONENT_FACTORY( kcm_gtk, KcmGtkFactory("gtk"))*/

extern "C"
{
	KCModule *create_kcmgtk( TQWidget * parent, const char * name )
	{
		KGlobal::locale()->insertCatalogue( "gtkqtengine" );
		return new KcmGtk( parent, "kcmgtk" );
	}
}

GtkRcParser::GtkRcParser()
 : emacs(false)
{
}

void GtkRcParser::parse(TQString fileName)
{
	TQFile file(fileName);
	file.open(IO_ReadOnly);
	TQTextStream stream(&file);
	
	TQRegExp includeRe("include\\s*\"([^\"]*)\"");
	TQRegExp fontRe("font_name\\s*=\\s*\"([^\"]*)\"");
	TQRegExp keyThemeRe("gtk-key-theme-name\\s*=\\s*\"([^\"]*)\"");
	
	TQStringList includes;
	
	while (1)
	{
		TQString line = stream.readLine();
		if (line.isNull())
			break;
		if (line.startsWith("#"))
			continue;
		
		line = line.stripWhiteSpace();
		
		if (line.startsWith("include"))
		{
			if (includeRe.search(line) == -1)
				continue;
			TQString themePath = includeRe.cap(1);
			if (themePath.endsWith("/gtk-2.0/gtkrc") && !themePath.startsWith("/etc"))
				style = includeRe.cap(1);
		}
		if (line.startsWith("font_name"))
		{
			if (fontRe.search(line) == -1)
				continue;
			// Assume there will only be one font line
			font = parseFont(fontRe.cap(1));
		}
		if (line.startsWith("gtk-key-theme-name"))
		{
			if (keyThemeRe.search(line) == -1)
				continue;
			if (TQString(keyThemeRe.cap(1)).lower() == "emacs")
				emacs = true;
		}
	}
	
	file.close();
}

TQFont GtkRcParser::parseFont(TQString fontString)
{
	TQFont ret;
	while (true)
	{
		int lastSpacePos = fontString.findRev(' ');
		if (lastSpacePos == -1)
			break;

		TQString lastWord = fontString.right(fontString.length() - lastSpacePos).stripWhiteSpace();

		if (lastWord.lower() == "bold")
			ret.setBold(true);
		else if (lastWord.lower() == "italic")
			ret.setItalic(true);
		else
		{
			bool ok;
			int fontSize = lastWord.toInt(&ok);
			if (!ok)
				break;
			ret.setPointSize(fontSize);
		}

		fontString = fontString.left(lastSpacePos);
	}
	ret.setFamily(fontString);
	return ret;
}

KcmGtk::KcmGtk(TQWidget *parent, const char *name, const TQStringList&)
    : KCModule(parent, name),
      myAboutData(0),
      emacsDetailsDialog(NULL),
      searchPathsDialog(NULL)
{
	KGlobal::locale()->insertCatalogue("gtkqtengine");
	
	config = new KConfig("kcmgtkrc");

	TQStringList gtkSearchPathsDefault;
	gtkSearchPathsDefault.append("/usr");
	gtkSearchPathsDefault.append("/usr/local");
	gtkSearchPathsDefault.append("/opt/gnome");
	gtkSearchPathsDefault.append(TQDir::homeDirPath() + "/.local");

	gtkSearchPaths = config->readListEntry("gtkSearchPaths", gtkSearchPathsDefault);

	
	// Add the widget to our layout
	TQBoxLayout* l = new TQVBoxLayout(this);
	widget = new KcmGtkWidget(this);
	l->addWidget(widget);
	
	// Load the icons
	KIconLoader iconLoader;
	widget->styleIcon->setPixmap(iconLoader.loadIcon("style", KIcon::Desktop));
	widget->styleIcon3->setPixmap(iconLoader.loadIcon("style", KIcon::Desktop));
	widget->fontIcon->setPixmap(iconLoader.loadIcon("fonts", KIcon::Desktop));
	widget->firefoxIcon->setPixmap(iconLoader.loadIcon("firefox", KIcon::Desktop));
	widget->keyboardIcon->setPixmap(iconLoader.loadIcon("keyboard", KIcon::Desktop));
	
	getInstalledThemes();
	load();
	
	// Connect some signals
	connect(widget->warning2, TQT_SIGNAL(leftClickedURL(const TQString&)), KApplication::kApplication(), TQT_SLOT(invokeBrowser(const TQString&)));
	connect(widget->styleGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(itemChanged()));
	connect(widget->warning5, TQT_SIGNAL(leftClickedURL(const TQString&)), KApplication::kApplication(), TQT_SLOT(invokeBrowser(const TQString&)));
	connect(widget->styleGroup3, TQT_SIGNAL(clicked(int)), TQT_SLOT(itemChanged()));
	connect(widget->fontGroup, TQT_SIGNAL(clicked(int)), TQT_SLOT(itemChanged()));
	connect(widget->styleBox, TQT_SIGNAL(activated(int)), TQT_SLOT(itemChanged()));
	connect(widget->styleBox, TQT_SIGNAL(activated(int)), TQT_SLOT(styleChanged()));
	connect(widget->styleBox3, TQT_SIGNAL(activated(int)), TQT_SLOT(itemChanged()));
	connect(widget->styleBox3, TQT_SIGNAL(activated(int)), TQT_SLOT(styleChanged()));
	connect(widget->emacsBox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(itemChanged()));
	connect(widget->fontChange, TQT_SIGNAL(clicked()), TQT_SLOT(fontChangeClicked()));
	connect(widget->firefoxFix, TQT_SIGNAL(clicked()), TQT_SLOT(firefoxFixClicked()));
	connect(widget->emacsDetails, TQT_SIGNAL(clicked()), TQT_SLOT(emacsDetailsClicked()));
	connect(widget->warning3, TQT_SIGNAL(clicked()), TQT_SLOT(searchPathsClicked()));
	connect(widget->warning6, TQT_SIGNAL(clicked()), TQT_SLOT(searchPathsClicked()));
}

void KcmGtk::getInstalledThemes()
{
	themes.clear();
	for ( TQStringList::Iterator it = gtkSearchPaths.begin(); it != gtkSearchPaths.end(); ++it )
	{
		TQString path = (*it) + "/share/themes/";
		TQDir dir(path);
		TQStringList entryList = dir.entryList(TQDir::Dirs, TQDir::Unsorted);
		for ( TQStringList::Iterator it2 = entryList.begin(); it2 != entryList.end(); ++it2 )
		{
			if ((*it2).startsWith("."))
				continue;
			if (themes.find(*it2) != themes.end())
				continue;
			if (!TQFile::exists(path + (*it2) + "/gtk-2.0/gtkrc"))
				continue;
			themes.insert((*it2), path + (*it2) + "/gtk-2.0/gtkrc");
		}
	}
	
	widget->styleBox->clear();
	TQStringList otherStyles = themes.keys();
	otherStyles.remove(otherStyles.find("Qt"));
	widget->styleBox->insertStringList(otherStyles);
	
	bool installed = (themes.find("Qt") != themes.end());
	widget->styleKde->setEnabled(installed);
	widget->warning1->setHidden(installed);
	widget->warning2->setHidden(installed);
	widget->warning3->setHidden(installed);

	gtk3Themes.clear();
	for ( TQStringList::Iterator it = gtkSearchPaths.begin(); it != gtkSearchPaths.end(); ++it )
	{
		TQString path = (*it) + "/share/themes/";
		TQDir dir(path);
		TQStringList entryList = dir.entryList(TQDir::Dirs, TQDir::Unsorted);
		for ( TQStringList::Iterator it2 = entryList.begin(); it2 != entryList.end(); ++it2 )
		{
			if ((*it2).startsWith("."))
				continue;
			if (gtk3Themes.find(*it2) != gtk3Themes.end())
				continue;
			if (!TQFile::exists(path + (*it2) + "/gtk-3.0/gtk.css"))
				continue;
			gtk3Themes.insert((*it2), path + (*it2) + "/gtk-3.0/gtk.css");
		}
	}
	
	widget->styleBox3->clear();
	TQStringList otherGtk3Styles = gtk3Themes.keys();
	otherGtk3Styles.remove(otherGtk3Styles.find("tdegtk"));
	widget->styleBox3->insertStringList(otherGtk3Styles);
	
	bool gtk3installed = (gtk3Themes.find("tdegtk") != gtk3Themes.end());
	widget->styleKde3->setEnabled(gtk3installed);
	widget->warning4->setHidden(gtk3installed);
	widget->warning5->setHidden(gtk3installed);
	widget->warning6->setHidden(gtk3installed);
}

void KcmGtk::itemChanged()
{
	// In KDE < 3.3 there is no changed() slot - only a signal.
	emit changed(true);
}

void KcmGtk::fontChangeClicked()
{
	if ( KFontDialog::getFont( font ) == KFontDialog::Accepted )
	{
		updateFontPreview();
		widget->fontGroup->setButton(widget->fontGroup->id(widget->fontOther));
		itemChanged();
	}
}

void KcmGtk::styleChanged()
{
	widget->styleGroup->setButton(widget->styleGroup->id(widget->styleOther));
	itemChanged();
}

TQString KcmGtk::env(TQString key)
{
	char* value = getenv(key.latin1());
	if (value == NULL)
		return TQString();
	else
		return TQString(value);
}

void KcmGtk::updateFontPreview()
{
	widget->fontPreview->setFont(font);
	widget->fontPreview->setText( 
		i18n("%1 (size %2)").arg(font.family()).arg(TQString::number(font.pointSize())));
	widget->fontPreview2->setFont(font);
}


KcmGtk::~KcmGtk()
{
	delete config;
}


void KcmGtk::load()
{
	parser.parse(TQDir::homeDirPath() + "/" + GTK_RC_FILE);
	
	bool usingQtEngine = false;
	if (!parser.style.isEmpty())
	{
		for ( TQMapIterator<TQString, TQString> it = themes.begin(); it != themes.end(); ++it )
		{
			if (it.data() != parser.style)
				continue;
			
			if (it.key() == "Qt")
				usingQtEngine = true;
			
			for (int i=0 ; i<widget->styleBox->count() ; ++i)
			{
				if (widget->styleBox->text(i) == it.key())
				{
					widget->styleBox->setCurrentItem(i);
					break;
				}
			}
			
			break;
		}
		
		if (usingQtEngine) {
			widget->styleGroup->setButton(widget->styleGroup->id(widget->styleKde));
		}
		else {
			widget->styleGroup->setButton(widget->styleGroup->id(widget->styleOther));
		}
	}

	font = parser.font;
	if (TQApplication::font().family() == font.family() &&
	    TQApplication::font().pointSize() == font.pointSize() &&
	    TQApplication::font().bold() == font.bold() &&
	    TQApplication::font().italic() == font.italic())
		widget->fontGroup->setButton(widget->fontGroup->id(widget->fontKde));
	else
		widget->fontGroup->setButton(widget->fontGroup->id(widget->fontOther));
	
	widget->emacsBox->setChecked(parser.emacs);
	
	updateFontPreview();

	bool usingGtk3TQtEngine = false;
	if (TQFile::exists(GTK3_INI_DIR + GTK3_INI_FILE)) {
		TQString activeGtk3Style;
		KConfig gtk3Config(GTK3_INI_DIR + GTK3_INI_FILE);
		gtk3Config.setGroup("Settings");
		activeGtk3Style = gtk3Config.readEntry("gtk-theme-name");
		if (activeGtk3Style == "tdegtk") {
			usingGtk3TQtEngine = true;
		}

		if (usingGtk3TQtEngine) {
			widget->styleGroup3->setButton(widget->styleGroup3->id(widget->styleKde3));
		}
		else {
			widget->styleGroup3->setButton(widget->styleGroup3->id(widget->styleOther3));
			for (int i=0; i<widget->styleBox3->count(); ++i) {
				if (widget->styleBox3->text(i) == activeGtk3Style) {
					widget->styleBox3->setCurrentItem(i);
					break;
				}
			}
		}
	}
}


void KcmGtk::save()
{
	// First write out the gtkrc file
	TQFile file(TQDir::homeDirPath() + "/" + GTK_RC_FILE);
	file.open(IO_WriteOnly);
	TQTextStream stream(&file);

	TQFont selectedFont(widget->fontKde->isChecked() ? TQApplication::font() : font);
	TQString fontName = selectedFont.family() + " " +
		TQString(selectedFont.bold() ? "Bold " : "") +
		TQString(selectedFont.italic() ? "Italic " : "") +
		TQString::number(selectedFont.pointSize());
	
	TQString themeName = widget->styleKde->isChecked() ? themes["Qt"] : themes[widget->styleBox->currentText()];
	TQString themeNameShort = widget->styleKde->isChecked() ? TQString("Qt") : widget->styleBox->currentText();

	TQString themeName3 = widget->styleKde3->isChecked() ? gtk3Themes["tdegtk"] : gtk3Themes[widget->styleBox3->currentText()];
	TQString themeNameShort3 = widget->styleKde3->isChecked() ? TQString("tdegtk") : widget->styleBox3->currentText();
	
	stream << "# This file was written by TDE\n";
	stream << "# You can edit it in the TDE control center, under \"GTK Styles and Fonts\"\n";
	stream << "\n";
	stream << "include \"" << themeName << "\"\n";
	if (TQFile::exists("/etc/gtk-2.0/gtkrc"))
		stream << "include \"/etc/gtk-2.0/gtkrc\"\n";
	stream << "\n";
	stream << "style \"user-font\"\n";
	stream << "{\n";
	stream << "\tfont_name=\"" << fontName << "\"\n";
	stream << "}\n";
	stream << "widget_class \"*\" style \"user-font\"\n";
	stream << "\n";
	stream << "gtk-theme-name=\"" << themeNameShort << "\"\n";
	stream << "gtk-font-name=\"" << fontName << "\"\n";
	
	if (widget->emacsBox->isChecked())
		stream << "gtk-key-theme-name=\"Emacs\"\n";
	
	file.close();
	
	// Now we check if that file is actually being loaded.
	TQDir kdeRcDir;
	if (!kdeRcDir.exists(KDE_RC_DIR))
	{
		// Make sure KDE's rc dir exists
		kdeRcDir.mkdir(KDE_RC_DIR);
	}
	file.setName(KDE_RC_DIR + "/" + GTK_TQT_RC_FILE);
	
	bool envFileDidNotExist = (!file.exists());
	
	file.open(IO_ReadWrite);
	stream.setDevice(TQT_TQIODEVICE(&file));
	bool found = false;
	for (;;)
	{
		TQString line = stream.readLine();
		if (line.isNull())
			break;
		
		if (line.stripWhiteSpace().startsWith("export GTK2_RC_FILES=$HOME/" + GTK_RC_FILE))
		{
			found = true;
			break;
		}
	}
	if (!found)
	{
		stream << "#!/bin/bash\n\n";
		stream << "# Make sure our customised gtkrc file is loaded.\n";
		stream << "export GTK2_RC_FILES=$HOME/" + GTK_RC_FILE + "\n";
	}
	file.close();
	
	// Make it executable
	if (!found)
		chmod(file.name().utf8(), 0755);
	
	// Tell the user to restart KDE if the environment file was created this time
	if (envFileDidNotExist)
		TQMessageBox::information(this, "Restart TDE", "Your changes have been saved, but you will have to restart TDE for them to take effect.", TQMessageBox::Ok);
	
	// Older versions of the Gtk-Qt theme engine wrote directly into ~/.gtkrc-2.0
	// If the user has upgraded, that file needs to be deleted so the old settings
	// won't override the new ones set now.
	file.setName(TQDir::homeDirPath() + "/.gtkrc-2.0");
	if (file.exists())
	{
		file.open(IO_ReadOnly);
		TQString firstLine;
		file.readLine(firstLine, 50);
		file.close();
		
		if (firstLine == "# This file was written by TDE")
			file.remove();
	}
	
	// Simarly, remove the line we added to ~/.bashrc to tell GTK to load ~/.gtkrc-2.0
	file.setName(TQDir::homeDirPath() + "/.bashrc");
	if (file.exists())
	{
		file.open(IO_ReadOnly);
		TQByteArray fileData = file.readAll();
		file.close();
		
		TQString rcLine = "export GTK2_RC_FILES=$HOME/.gtkrc-2.0";
		TQString fileDataString(fileData);
		fileDataString.replace("\n" + rcLine, "\n# (This is no longer needed from version 0.8 of the theme engine)\n# " + rcLine);
		
		file.open(IO_WriteOnly);
		stream.setDevice(TQT_TQIODEVICE(&file));
		stream << fileDataString;
		file.close();
	}

	TQDir gtk3IniDir;
	if (!gtk3IniDir.exists(GTK3_INI_DIR))
	{
		// Make sure the GTK INI dir exists
		gtk3IniDir.mkdir(GTK3_INI_DIR);
	}

	TQFile gtk3IniFile(GTK3_INI_DIR + GTK3_INI_FILE);
	gtk3IniFile.open(IO_WriteOnly);
	TQTextStream gtk3IniStream(&gtk3IniFile);
	gtk3IniStream << "# This file was written by TDE\n";
	gtk3IniStream << "# You can edit it in the TDE control center, under \"GTK Styles and Fonts\"\n";
	gtk3IniStream << "\n";
	gtk3IniStream << "[Settings]\n";
	gtk3IniStream << "gtk-theme-name = " << themeNameShort3 << "\n";
	gtk3IniFile.close();

	emit changed(true);
}


int KcmGtk::buttons()
{
	return KCModule::Apply;
}

TQString KcmGtk::quickHelp() const
{
	return i18n("");
}


void KcmGtk::firefoxFixClicked()
{
	profiles.clear();
	getProfiles(TQDir::homeDirPath() + "/.mozilla/firefox/", 0);
	getProfiles(TQDir::homeDirPath() + "/.thunderbird/", 1);
	
	TQString profilePath;
	if (profiles.count() == 0)
	{
		KMessageBox::error(this, i18n("No Mozilla profiles found"), i18n("Could not load Mozilla profiles"));
		return;
	}
	else if (profiles.count() == 1)
	{
		fixProfile(profiles.begin().data());
	}
	else
	{
		KDialogBase* dialog = new KDialogBase(this, "", true, i18n("Mozilla profile"), KDialogBase::Ok | KDialogBase::Cancel);
		MozillaProfileWidget* w = new MozillaProfileWidget(dialog);
		w->profilesList->header()->hide();
		w->profilesList->hideColumn(1);
		
		TQPixmap icon = KGlobal::iconLoader()->loadIcon("kuser", KIcon::Small);
		
		for ( TQMapIterator<TQString,TQString> it = profiles.begin(); it != profiles.end(); ++it )
		{
			KListViewItem* i = new KListViewItem(w->profilesList);
			i->setPixmap(0, icon);
			i->setText(0, it.key());
			i->setText(1, it.data());
		}
		
		dialog->setMainWidget(w);
		if (dialog->exec() == TQDialog::Rejected)
		{
			delete dialog;
			return;
		}
		
		TQListViewItemIterator it2(w->profilesList, TQListViewItemIterator::Selected);
		while (it2.current())
		{
			KListViewItem* i = (KListViewItem*) it2.current();
			++it2;
			
			fixProfile(i->text(1));
		}
		delete dialog;
	}
	
	KMessageBox::information(this, i18n("Your Mozilla profile was updated sucessfully.  You must close and restart all Firefox and Thunderbird windows for the changes to take effect"), i18n("Mozilla profile"));
}

void KcmGtk::getProfiles(const TQString& basePath, int type)
{
	TQString fileName = basePath + "/profiles.ini";
	if (TQFile::exists(fileName))
	{
		KConfig config(fileName, true, false);
		TQStringList groups = config.groupList();
		
		for ( TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it )
		{
			if (!(*it).lower().startsWith("profile"))
				continue;
			
			config.setGroup(*it);
			TQString name = (type ? i18n("Thunderbird") : i18n("Firefox")) + " - " + config.readEntry("Name");
			TQString path = config.readEntry("Path");
			if (!path.startsWith("/"))
				path = basePath + path;
			profiles.insert(name, path);
		}
	}
}

void KcmGtk::fixProfile(const TQString& path)
{
	if (!TQFile::exists(path + "/chrome"))
	{
		TQDir dir(path);
		dir.mkdir("chrome");
	}
	
	TQString data = scrollBarCSS();
	writeFirefoxCSS(path + "/chrome/userChrome.css", data);
	writeFirefoxCSS(path + "/chrome/userContent.css", data);
}

TQString KcmGtk::scrollBarCSS()
{
	// The following code determines how many buttons are on a scrollbar
	// It works by looking at each pixel of the scrollbar's area not taken up by the groove,
	// and asking the style which subcontrol is at that location.
	TQScrollBar sbar(NULL);
	sbar.setOrientation(Qt::Horizontal);
	sbar.setValue(1);
	sbar.resize(200,25);
	
	TQRect rect = tqApp->style().querySubControlMetrics(TQStyle::CC_ScrollBar, &sbar, TQStyle::SC_ScrollBarGroove);
	
	bool back1 = false;
	bool forward1 = false;
	bool back2 = false;
	bool forward2 = false;
	
	TQStyle::SubControl sc = TQStyle::SC_None;
	for (TQPoint pos(0,7) ; pos.x()<rect.x() ; pos.setX(pos.x()+1))
	{
		TQStyle::SubControl sc2 = tqApp->style().querySubControl(TQStyle::CC_ScrollBar, &sbar, pos);
		if (sc != sc2)
		{
			if (sc2 == TQStyle::SC_ScrollBarAddLine) forward1 = true;
			if (sc2 == TQStyle::SC_ScrollBarSubLine) back1 = true;
			sc = sc2;
		}
	}
	sc = TQStyle::SC_None;
	for (TQPoint pos(rect.x()+rect.width(),7) ; pos.x()<200 ; pos.setX(pos.x()+1))
	{
		TQStyle::SubControl sc2 = tqApp->style().querySubControl(TQStyle::CC_ScrollBar, &sbar, pos);
		if (sc != sc2)
		{
			if (sc2 == TQStyle::SC_ScrollBarAddLine) forward2 = true;
			if (sc2 == TQStyle::SC_ScrollBarSubLine) back2 = true;
			sc = sc2;
		}
	}
	
	TQString upTop = (back1 ? "-moz-box" : "none");
	TQString downTop = (forward1 ? "-moz-box" : "none");
	TQString upBottom = (back2 ? "-moz-box" : "none");
	TQString downBottom = (forward2 ? "-moz-box" : "none");
	
	TQString data;
	data += "/* The following four lines were added by TDE */\n";
	data += "scrollbarbutton[sbattr=\"scrollbar-up-top\"] { display: " + upTop + " !important; }\n";
	data += "scrollbarbutton[sbattr=\"scrollbar-down-top\"] { display: " + downTop + " !important; }\n";
	data += "scrollbarbutton[sbattr=\"scrollbar-up-bottom\"] { display: " + upBottom + " !important; }\n";
	data += "scrollbarbutton[sbattr=\"scrollbar-down-bottom\"] { display: " + downBottom + " !important; }\n";
	
	return data;
}

void KcmGtk::writeFirefoxCSS(const TQString& path, const TQString& data)
{
	TQString fileData;
	TQFile file(path);
	if (file.open(IO_ReadOnly))
	{
		TQTextStream stream(&file);
		for (;;)
		{
			TQString line = stream.readLine();
			if (line.isNull())
				break;
			
			if ((line == "# The following four lines were added by TDE") ||
			    (line == "/* The following four lines were added by TDE */"))
			{
				for (int i=0 ; i<4 ; i++)
					stream.readLine();
				continue;
			}
			
			fileData += line + "\n";
		}
		file.close();
	}
	
	if (!file.open(IO_WriteOnly | IO_Truncate))
	{
		KMessageBox::error(this, i18n("Could not write to %1").arg(path), i18n("Mozilla profile"));
		return;
	}
	TQTextStream stream(&file);
	stream << fileData << data;
	file.close();
	
	return;
}

void KcmGtk::emacsDetailsClicked()
{
	if (emacsDetailsDialog == NULL)
	{
		emacsDetailsDialog = new EmacsDetails(this);
		emacsDetailsDialog->list->header()->setStretchEnabled(true, 1);
	}
	
	emacsDetailsDialog->show();
}

void KcmGtk::searchPathsClicked()
{
	if (searchPathsDialog == NULL)
	{
		searchPathsDialog = new SearchPaths(this);
		connect(searchPathsDialog->okButton, TQT_SIGNAL(clicked()), TQT_SLOT(searchPathsOk()));
		connect(searchPathsDialog->pathBox, TQT_SIGNAL(textChanged(const TQString&)), TQT_SLOT(searchPathsTextChanged(const TQString&)));
		connect(searchPathsDialog->pathList, TQT_SIGNAL(currentChanged(TQListBoxItem*)), TQT_SLOT(searchPathsCurrentChanged(TQListBoxItem*)));
		connect(searchPathsDialog->addButton, TQT_SIGNAL(clicked()), TQT_SLOT(searchPathsAddClicked()));
		connect(searchPathsDialog->removeButton, TQT_SIGNAL(clicked()), TQT_SLOT(searchPathsRemoveClicked()));
	}

	searchPathsDialog->pathList->clear();
	for (TQStringList::Iterator it = gtkSearchPaths.begin(); it != gtkSearchPaths.end(); ++it )
		new TQListBoxText(searchPathsDialog->pathList, *it);

	searchPathsDialog->show();
}

void KcmGtk::searchPathsOk()
{
	gtkSearchPaths.clear();
	int i=0;
	TQListBoxItem* item = 0;
	while ((item = searchPathsDialog->pathList->item(i++)))
		gtkSearchPaths.append(item->text());
	
	config->writeEntry("gtkSearchPaths", gtkSearchPaths);
	getInstalledThemes();
}

void KcmGtk::searchPathsTextChanged(const TQString& text)
{
	searchPathsDialog->addButton->setDisabled(text.isEmpty());
}

void KcmGtk::searchPathsCurrentChanged(TQListBoxItem* item)
{
	searchPathsDialog->removeButton->setEnabled(item != NULL);
}

void KcmGtk::searchPathsAddClicked()
{
	new TQListBoxText(searchPathsDialog->pathList, searchPathsDialog->pathBox->text());
	searchPathsDialog->pathBox->clear();
}

void KcmGtk::searchPathsRemoveClicked()
{
	searchPathsDialog->pathList->removeItem(searchPathsDialog->pathList->currentItem());
}


#include "kcmgtk.moc"