|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright (C) 2007 Eike Hein <hein@kde.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "skin_settings.h"
|
|
|
|
#include "skin_settings.moc"
|
|
|
|
#include "skin_list_item.h"
|
|
|
|
#include "settings.h"
|
|
|
|
|
|
|
|
#include <tqurl.h>
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <tdeio/global.h>
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include <tdefiledialog.h>
|
|
|
|
#include <ktar.h>
|
|
|
|
#include <klineedit.h>
|
|
|
|
#include <kcolorbutton.h>
|
|
|
|
|
|
|
|
#include <unistd.h> // unlink()
|
|
|
|
|
|
|
|
|
|
|
|
SkinSettings::SkinSettings(TQWidget* parent, const char* name, bool translucency)
|
|
|
|
: SkinSettingsUI(parent, name)
|
|
|
|
{
|
|
|
|
kcfg_skin->hide();
|
|
|
|
|
|
|
|
skinbgcolor_label->setEnabled(!translucency);
|
|
|
|
skinbgcolor_label->setHidden(translucency);
|
|
|
|
|
|
|
|
kcfg_skinbgcolor->setEnabled(!translucency);
|
|
|
|
kcfg_skinbgcolor->setHidden(translucency);
|
|
|
|
|
|
|
|
skinbglayout->setEnabled(!translucency);
|
|
|
|
skinbglayout->invalidate();
|
|
|
|
|
|
|
|
skins_list->header()->hide();
|
|
|
|
skins_list->setSelectionModeExt(TDEListView::Single);
|
|
|
|
skins_list->setResizeMode(TDEListView::LastColumn);
|
|
|
|
skins_list->setRootIsDecorated(false);
|
|
|
|
skins_list->setDragEnabled(false);
|
|
|
|
skins_list->setAcceptDrops(false);
|
|
|
|
skins_list->setDropVisualizer(false);
|
|
|
|
skins_list->setSortColumn(0);
|
|
|
|
|
|
|
|
connect(skins_list, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotUpdateRemoveButton()));
|
|
|
|
connect(skins_list, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotUpdateSkinSetting()));
|
|
|
|
connect(kcfg_skin, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(slotUpdateSelection(const TQString&)));
|
|
|
|
connect(install_button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotInstallSkin()));
|
|
|
|
connect(remove_button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotRemoveSkin()));
|
|
|
|
|
|
|
|
skins_dir = locateLocal("data", "yakuake/");
|
|
|
|
|
|
|
|
selected = Settings::skin();
|
|
|
|
|
|
|
|
slotPopulate();
|
|
|
|
}
|
|
|
|
|
|
|
|
SkinSettings::~SkinSettings()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::showEvent(TQShowEvent* e)
|
|
|
|
{
|
|
|
|
slotPopulate();
|
|
|
|
SkinSettingsUI::showEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotPopulate()
|
|
|
|
{
|
|
|
|
TQStringList skins_dirs;
|
|
|
|
TQStringList titles_dirs = TDEGlobal::dirs()->findAllResources("data","yakuake/*/title.skin");
|
|
|
|
TQStringList tabs_dirs = TDEGlobal::dirs()->findAllResources("data","yakuake/*/tabs.skin");
|
|
|
|
|
|
|
|
for (TQStringList::Iterator it = titles_dirs.begin(); it != titles_dirs.end(); ++it)
|
|
|
|
{
|
|
|
|
if (tabs_dirs.contains((*it).section('/', 0, -2) + "/tabs.skin"))
|
|
|
|
skins_dirs << (*it).section('/', 0, -2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (skins_dirs.count() > 0)
|
|
|
|
{
|
|
|
|
skins_list->clear();
|
|
|
|
|
|
|
|
for (TQStringList::Iterator it = skins_dirs.begin(); it != skins_dirs.end(); ++it)
|
|
|
|
{
|
|
|
|
TQUrl titles_url = locate("appdata", (*it) + "/title.skin");
|
|
|
|
TDEConfig titles_config(titles_url.path());
|
|
|
|
titles_config.setGroup("Description");
|
|
|
|
|
|
|
|
TQString titles_name(titles_config.readEntry("Skin", ""));
|
|
|
|
TQString titles_author(titles_config.readEntry("Author", ""));
|
|
|
|
TQString titles_icon_name(titles_config.readEntry("Icon", ""));
|
|
|
|
|
|
|
|
TQUrl tabs_url = locate("appdata", (*it) + "/tabs.skin");
|
|
|
|
TDEConfig tabs_config(tabs_url.path());
|
|
|
|
tabs_config.setGroup("Description");
|
|
|
|
|
|
|
|
TQString tabs_name(tabs_config.readEntry("Skin", ""));
|
|
|
|
TQString tabs_author(tabs_config.readEntry("Author", ""));
|
|
|
|
TQString tabs_icon_name(tabs_config.readEntry("Icon", ""));
|
|
|
|
|
|
|
|
TQString skin_name = (*it).section('/', -1, -1);
|
|
|
|
TQString skin_fancy_name = i18n("Unnamed");
|
|
|
|
TQString skin_author = i18n("Unknown");
|
|
|
|
TQString skin_icon_name;
|
|
|
|
TQUrl skin_icon_url;
|
|
|
|
TQPixmap skin_icon;
|
|
|
|
|
|
|
|
if (!titles_name.isEmpty())
|
|
|
|
skin_fancy_name = titles_name;
|
|
|
|
else if (!tabs_name.isEmpty())
|
|
|
|
skin_fancy_name = tabs_name;
|
|
|
|
|
|
|
|
if (!titles_author.isEmpty())
|
|
|
|
skin_author = titles_author;
|
|
|
|
else if (!tabs_author.isEmpty())
|
|
|
|
skin_author = tabs_author;
|
|
|
|
|
|
|
|
if (!titles_icon_name.isEmpty())
|
|
|
|
skin_icon_name = titles_icon_name;
|
|
|
|
else if (!tabs_icon_name.isEmpty())
|
|
|
|
skin_icon_name = tabs_icon_name;
|
|
|
|
|
|
|
|
skin_icon_url = locate("appdata", (*it) + skin_icon_name);
|
|
|
|
|
|
|
|
if (skin_icon_url.isValid())
|
|
|
|
skin_icon.load(skin_icon_url.path());
|
|
|
|
|
|
|
|
bool exists = false;
|
|
|
|
SkinListItem* item = 0;
|
|
|
|
|
|
|
|
TQListViewItemIterator it2(skins_list);
|
|
|
|
|
|
|
|
while (it2.current())
|
|
|
|
{
|
|
|
|
item = static_cast<SkinListItem*>(it2.current());
|
|
|
|
if (item && item->name() == skin_name) exists = true;
|
|
|
|
++it2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!exists)
|
|
|
|
{
|
|
|
|
SkinListItem* skin = new SkinListItem(skins_list, skin_fancy_name, skin_author, skin_icon, skin_name, (*it));
|
|
|
|
|
|
|
|
if (skin_name == selected) skins_list->setSelected(skin, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
slotUpdateRemoveButton();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotInstallSkin()
|
|
|
|
{
|
|
|
|
KURL skin_url = KFileDialog::getOpenURL(TQString(),
|
|
|
|
i18n("*.tar.gz *.tar.bz2 *.tar *.zip|Yakuake Skins"),
|
|
|
|
NULL, i18n("Select Skin Archive"));
|
|
|
|
|
|
|
|
if (skin_url.isEmpty()) return;
|
|
|
|
|
|
|
|
if (!TDEIO::NetAccess::download(skin_url, install_skin_file, NULL))
|
|
|
|
{
|
|
|
|
KMessageBox::error(0L,
|
|
|
|
TDEIO::NetAccess::lastErrorString(),
|
|
|
|
i18n("Failed to Download Skin"),
|
|
|
|
KMessageBox::Notify
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDir skin_dir(install_skin_file);
|
|
|
|
|
|
|
|
if (!skin_dir.exists())
|
|
|
|
{
|
|
|
|
TDEIO::ListJob* job = TDEIO::listRecursive("tar:" + install_skin_file, false, false);
|
|
|
|
|
|
|
|
connect(job, TQT_SIGNAL(entries(TDEIO::Job*, const TDEIO::UDSEntryList&)),
|
|
|
|
this, TQT_SLOT(slotListSkinArchive(TDEIO::Job*, const TDEIO::UDSEntryList&)));
|
|
|
|
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotValidateSkinArchive(TDEIO::Job*)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
failInstall(i18n("The installer was given a directory, not a file."));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotListSkinArchive(TDEIO::Job* /* job */, const TDEIO::UDSEntryList& list)
|
|
|
|
{
|
|
|
|
TDEIO::UDSEntryList::const_iterator it = list.begin();
|
|
|
|
|
|
|
|
for(; it != list.end(); ++it)
|
|
|
|
{
|
|
|
|
TDEIO::UDSEntry::const_iterator itUSDEntry = (*it).begin();
|
|
|
|
|
|
|
|
for (; itUSDEntry != (*it).end(); ++itUSDEntry )
|
|
|
|
{
|
|
|
|
if((*itUSDEntry).m_uds == TDEIO::UDS_NAME)
|
|
|
|
{
|
|
|
|
install_skin_file_list.append((*itUSDEntry).m_str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotValidateSkinArchive(TDEIO::Job* job)
|
|
|
|
{
|
|
|
|
if (!job->error())
|
|
|
|
{
|
|
|
|
install_skin_name = install_skin_file_list.first();
|
|
|
|
|
|
|
|
if (install_skin_file_list.contains(TQString(install_skin_name + "/title.skin"))
|
|
|
|
&& install_skin_file_list.contains(TQString(install_skin_name + "/tabs.skin")))
|
|
|
|
{
|
|
|
|
checkForExistingSkin();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
failInstall(i18n("Unable to locate required files in the skin archive.\n\n The archive appears to be invalid."));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
failInstall(i18n("Unable to list the skin archive contents.") + TQString("\n\n %1").arg(job->errorString()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::checkForExistingSkin()
|
|
|
|
{
|
|
|
|
bool exists = false;
|
|
|
|
SkinListItem* item = 0;
|
|
|
|
|
|
|
|
TQListViewItemIterator it(skins_list);
|
|
|
|
|
|
|
|
while (it.current())
|
|
|
|
{
|
|
|
|
item = static_cast<SkinListItem*>(it.current());
|
|
|
|
if (item && item->name() == install_skin_name) exists = true;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exists)
|
|
|
|
{
|
|
|
|
TQFile skin(item->dir() + "/titles.skin");
|
|
|
|
|
|
|
|
if (!skin.open(IO_ReadOnly | IO_WriteOnly))
|
|
|
|
{
|
|
|
|
failInstall(i18n("This skin appears to be already installed and you lack the required permissions to overwrite it."));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skin.close();
|
|
|
|
|
|
|
|
int remove = KMessageBox::warningContinueCancel(0L,
|
|
|
|
i18n("This skin appears to be already installed. Do you want to overwrite it?"),
|
|
|
|
i18n("Skin Already Exists"),
|
|
|
|
i18n("Reinstall Skin"));
|
|
|
|
|
|
|
|
if (remove == KMessageBox::Continue)
|
|
|
|
{
|
|
|
|
unlink(TQFile::encodeName(item->dir()));
|
|
|
|
TDEIO::DeleteJob* job = TDEIO::del(KURL(item->dir()), false, false);
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job*)), this, TQT_SLOT(slotInstallSkinArchive(TDEIO::Job*)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
cleanupAfterInstall();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
slotInstallSkinArchive();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotInstallSkinArchive(TDEIO::Job* delete_job)
|
|
|
|
{
|
|
|
|
if (delete_job && delete_job->error())
|
|
|
|
{
|
|
|
|
KMessageBox::error(0L,
|
|
|
|
delete_job->errorString(),
|
|
|
|
i18n("Could Not Delete Skin"),
|
|
|
|
KMessageBox::Notify
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
KTar skin_archive(install_skin_file);
|
|
|
|
|
|
|
|
if (skin_archive.open(IO_ReadOnly))
|
|
|
|
{
|
|
|
|
const KArchiveDirectory* skin_dir = skin_archive.directory();
|
|
|
|
skin_dir->copyTo(skins_dir);
|
|
|
|
skin_archive.close();
|
|
|
|
|
|
|
|
slotPopulate();
|
|
|
|
|
|
|
|
if (Settings::skin() == install_skin_name)
|
|
|
|
emit settingsChanged();
|
|
|
|
|
|
|
|
cleanupAfterInstall();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
failInstall(i18n("The skin archive file could not be opened."));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::failInstall(const TQString& error)
|
|
|
|
{
|
|
|
|
KMessageBox::error(0L, error,
|
|
|
|
i18n("Cannot Install Skin"),
|
|
|
|
KMessageBox::Notify
|
|
|
|
);
|
|
|
|
|
|
|
|
cleanupAfterInstall();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::cleanupAfterInstall()
|
|
|
|
{
|
|
|
|
TDEIO::NetAccess::removeTempFile(install_skin_file);
|
|
|
|
install_skin_file = TQString();
|
|
|
|
install_skin_name = TQString();
|
|
|
|
install_skin_file_list.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotRemoveSkin()
|
|
|
|
{
|
|
|
|
if (skins_list->childCount() <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
SkinListItem* selected_item = static_cast<SkinListItem*>(skins_list->selectedItem());
|
|
|
|
|
|
|
|
if (!selected_item) return;
|
|
|
|
|
|
|
|
int remove = KMessageBox::warningContinueCancel(0L,
|
|
|
|
i18n("Do you want to remove \"%1\" by %2?").arg(selected_item->text(0)).arg(selected_item->author()),
|
|
|
|
i18n("Remove Skin"),
|
|
|
|
KStdGuiItem::del());
|
|
|
|
|
|
|
|
if (remove == KMessageBox::Continue)
|
|
|
|
{
|
|
|
|
unlink(TQFile::encodeName(selected_item->dir()));
|
|
|
|
TDEIO::DeleteJob* job = TDEIO::del(KURL(selected_item->dir()), false, false);
|
|
|
|
connect(job, TQT_SIGNAL(result(TDEIO::Job *)), this, TQT_SLOT(slotPopulate()));
|
|
|
|
|
|
|
|
if (selected_item->name() == Settings::skin())
|
|
|
|
{
|
|
|
|
Settings::setSkin("default");
|
|
|
|
Settings::writeConfig();
|
|
|
|
emit settingsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
slotResetSelection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotUpdateRemoveButton()
|
|
|
|
{
|
|
|
|
if (skins_list->childCount() <= 1)
|
|
|
|
{
|
|
|
|
remove_button->setEnabled(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkinListItem* selected_item = static_cast<SkinListItem*>(skins_list->selectedItem());
|
|
|
|
|
|
|
|
if (!selected_item) return;
|
|
|
|
|
|
|
|
if (selected_item->name() == "default")
|
|
|
|
{
|
|
|
|
remove_button->setEnabled(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQFile skin(selected_item->dir() + "/title.skin");
|
|
|
|
|
|
|
|
if (!skin.open(IO_ReadOnly | IO_WriteOnly))
|
|
|
|
remove_button->setEnabled(false);
|
|
|
|
else
|
|
|
|
remove_button->setEnabled(true);
|
|
|
|
|
|
|
|
skin.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotUpdateSkinSetting()
|
|
|
|
{
|
|
|
|
SkinListItem* selected_item = static_cast<SkinListItem*>(skins_list->selectedItem());
|
|
|
|
|
|
|
|
if (selected_item)
|
|
|
|
{
|
|
|
|
selected = selected_item->name();
|
|
|
|
kcfg_skin->setText(selected_item->name());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotResetSelection()
|
|
|
|
{
|
|
|
|
selected = Settings::skin();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkinSettings::slotUpdateSelection(const TQString& selection)
|
|
|
|
{
|
|
|
|
selected = selection;
|
|
|
|
SkinListItem* skin = 0;
|
|
|
|
|
|
|
|
TQListViewItemIterator it(skins_list);
|
|
|
|
|
|
|
|
while (it.current())
|
|
|
|
{
|
|
|
|
skin = static_cast<SkinListItem*>(it.current());
|
|
|
|
|
|
|
|
if (skin && skin->name() == selected)
|
|
|
|
skins_list->setSelected(skin, true);
|
|
|
|
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|