You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yakuake/yakuake/src/skin_settings.cpp

432 lines
12 KiB

/*
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 <kapplication.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kio/global.h>
#include <kio/job.h>
#include <kio/netaccess.h>
#include <kfiledialog.h>
#include <ktar.h>
#include <klineedit.h>
#include <kcolorbutton.h>
#include <unistd.h> // unlink()
SkinSettings::SkinSettings(TQWidget* tqparent, const char* name, bool translucency)
: SkinSettingsUI(tqparent, name)
{
kcfg_skin->hide();
skinbgcolor_label->setEnabled(!translucency);
skinbgcolor_label->setHidden(translucency);
kcfg_skinbgcolor->setEnabled(!translucency);
kcfg_skinbgcolor->setHidden(translucency);
skinbgtqlayout->setEnabled(!translucency);
skinbgtqlayout->tqinvalidate();
skins_list->header()->hide();
skins_list->setSelectionModeExt(KListView::Single);
skins_list->setResizeMode(KListView::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 = KGlobal::dirs()->findAllResources("data","yakuake/*/title.skin");
TQStringList tabs_dirs = KGlobal::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");
KConfig 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");
KConfig 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 (!KIO::NetAccess::download(skin_url, install_skin_file, NULL))
{
KMessageBox::error(0L,
KIO::NetAccess::lastErrorString(),
i18n("Failed to Download Skin"),
KMessageBox::Notify
);
return;
}
TQDir skin_dir(install_skin_file);
if (!skin_dir.exists())
{
KIO::ListJob* job = KIO::listRecursive("tar:" + install_skin_file, false, false);
connect(job, TQT_SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList&)),
this, TQT_SLOT(slotListSkinArchive(KIO::Job*, const KIO::UDSEntryList&)));
connect(job, TQT_SIGNAL(result(KIO::Job*)),
this, TQT_SLOT(slotValidateSkinArchive(KIO::Job*)));
}
else
failInstall(i18n("The installer was given a directory, not a file."));
}
void SkinSettings::slotListSkinArchive(KIO::Job* /* job */, const KIO::UDSEntryList& list)
{
KIO::UDSEntryList::const_iterator it = list.begin();
for(; it != list.end(); ++it)
{
KIO::UDSEntry::const_iterator itUSDEntry = (*it).begin();
for (; itUSDEntry != (*it).end(); ++itUSDEntry )
{
if((*itUSDEntry).m_uds == KIO::UDS_NAME)
{
install_skin_file_list.append((*itUSDEntry).m_str);
}
}
}
}
void SkinSettings::slotValidateSkinArchive(KIO::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").tqarg(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()));
KIO::DeleteJob* job = KIO::del(KURL(item->dir()), false, false);
connect(job, TQT_SIGNAL(result(KIO::Job*)), this, TQT_SLOT(slotInstallSkinArchive(KIO::Job*)));
}
else
cleanupAfterInstall();
}
}
else
slotInstallSkinArchive();
}
void SkinSettings::slotInstallSkinArchive(KIO::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()
{
KIO::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?").tqarg(selected_item->text(0)).tqarg(selected_item->author()),
i18n("Remove Skin"),
KStdGuiItem::del());
if (remove == KMessageBox::Continue)
{
unlink(TQFile::encodeName(selected_item->dir()));
KIO::DeleteJob* job = KIO::del(KURL(selected_item->dir()), false, false);
connect(job, TQT_SIGNAL(result(KIO::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;
}
}