rockbox/rbutil/rbutilqt/themesinstallwindow.cpp
Dominik Riebeling 1f1826e39c Remove Rockbox Utility Offline Mode.
Offline Mode was intended to allow performing an installation without network
access. However, to get the required files cached the same installation has to
be performed with network access, which is a rather strange prerequisite. A
better way would be a way to direct Rockbox Utility to some local "repository"
that holds the required files.

Furthermore, Offline Mode hasn't been tested since long and is likely to be
broken since the caching mechanism has been extended.

For now remove this functionality. As far as I know it's been rarely used (if
at all) anyway.

Change-Id: Ib2af4892708e0440bd0a7940c131f04182ddb39a
2013-01-13 19:45:29 +01:00

389 lines
13 KiB
C++

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2007 by Dominik Riebeling
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <QtGui>
#include "ui_themesinstallfrm.h"
#include "themesinstallwindow.h"
#include "zipinstaller.h"
#include "progressloggergui.h"
#include "utils.h"
#include "rbsettings.h"
#include "systeminfo.h"
#include "rockboxinfo.h"
#include "version.h"
ThemesInstallWindow::ThemesInstallWindow(QWidget *parent) : QDialog(parent)
{
ui.setupUi(this);
ui.listThemes->setAlternatingRowColors(true);
ui.listThemes->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui.listThemes->setSortingEnabled(true);
ui.themePreview->clear();
ui.themePreview->setText(tr("no theme selected"));
ui.labelSize->setText(tr("no selection"));
ui.listThemes->setLayoutDirection(Qt::LeftToRight);
ui.themeDescription->setLayoutDirection(Qt::LeftToRight);
connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
connect(ui.listThemes, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(updateDetails(QListWidgetItem*, QListWidgetItem*)));
connect(ui.listThemes, SIGNAL(itemSelectionChanged()), this, SLOT(updateSize()));
connect(&igetter, SIGNAL(done(bool)), this, SLOT(updateImage(bool)));
logger = NULL;
}
ThemesInstallWindow::~ThemesInstallWindow()
{
if(infocachedir!="")
Utils::recursiveRmdir(infocachedir);
}
void ThemesInstallWindow::downloadInfo()
{
// try to get the current build information
getter = new HttpGet(this);
RockboxInfo installInfo
= RockboxInfo(RbSettings::value(RbSettings::Mountpoint).toString());
themesInfo.open();
qDebug() << "[Themes] downloading info to" << themesInfo.fileName();
themesInfo.close();
QString infoUrl = SystemInfo::value(SystemInfo::ThemesInfoUrl).toString();
infoUrl.replace("%TARGET%",
SystemInfo::value(SystemInfo::CurConfigureModel).toString());
infoUrl.replace("%REVISION%", installInfo.revision());
infoUrl.replace("%RELEASE%", installInfo.release());
infoUrl.replace("%RBUTILVER%", VERSION);
QUrl url = QUrl(infoUrl);
qDebug() << "[Themes] Info URL:" << url << "Query:" << url.queryItems();
getter->setFile(&themesInfo);
connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
connect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
getter->getFile(url);
}
void ThemesInstallWindow::downloadDone(int id, bool error)
{
downloadDone(error);
qDebug() << "[Themes] Download" << id << "done, error:" << error;
}
void ThemesInstallWindow::downloadDone(bool error)
{
qDebug() << "[Themes] Download done, error:" << error;
disconnect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
disconnect(logger, SIGNAL(aborted()), this, SLOT(close()));
themesInfo.open();
QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
QStringList tl = iniDetails.childGroups();
qDebug() << "[Themes] Theme site result:"
<< iniDetails.value("error/code").toString()
<< iniDetails.value("error/description").toString()
<< iniDetails.value("error/query").toString();
if(error) {
logger->addItem(tr("Network error: %1.\n"
"Please check your network and proxy settings.")
.arg(getter->errorString()), LOGERROR);
getter->abort();
logger->setFinished();
disconnect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
connect(logger, SIGNAL(closed()), this, SLOT(close()));
return;
}
// handle possible error codes
if(iniDetails.value("error/code").toInt() != 0 || !iniDetails.contains("error/code")) {
qDebug() << "[Themes] Theme site returned an error:"
<< iniDetails.value("error/code");
logger->addItem(tr("the following error occured:\n%1")
.arg(iniDetails.value("error/description", "unknown error").toString()), LOGERROR);
logger->setFinished();
connect(logger, SIGNAL(closed()), this, SLOT(close()));
return;
}
logger->addItem(tr("done."), LOGOK);
logger->setFinished();
logger->close();
// setup list
for(int i = 0; i < tl.size(); i++) {
iniDetails.beginGroup(tl.at(i));
// skip all themes without name field set (i.e. error section)
if(iniDetails.value("name").toString().isEmpty()) {
iniDetails.endGroup();
continue;
}
qDebug() << "[Themes] adding to list:" << tl.at(i);
// convert to unicode and replace HTML-specific entities
QByteArray raw = iniDetails.value("name").toByteArray();
QTextCodec* codec = QTextCodec::codecForHtml(raw);
QString name = codec->toUnicode(raw);
name.replace("&quot;", "\"").replace("&amp;", "&");
name.replace("&lt;", "<").replace("&gt;", ">");
QListWidgetItem *w = new QListWidgetItem;
w->setData(Qt::DisplayRole, name.trimmed());
w->setData(Qt::UserRole, tl.at(i));
ui.listThemes->addItem(w);
iniDetails.endGroup();
}
// check if there's a themes "MOTD" available
if(iniDetails.contains("status/msg")) {
// check if there's a localized msg available
QString lang = RbSettings::value(RbSettings::Language).toString().split("_").at(0);
QString msg;
if(iniDetails.contains("status/msg." + lang))
msg = iniDetails.value("status/msg." + lang).toString();
else
msg = iniDetails.value("status/msg").toString();
qDebug() << "[Themes] MOTD" << msg;
if(!msg.isEmpty())
QMessageBox::information(this, tr("Information"), msg);
}
}
void ThemesInstallWindow::updateSize(void)
{
long size = 0;
// sum up size for all selected themes
QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
int items = ui.listThemes->selectedItems().size();
for(int i = 0; i < items; i++) {
iniDetails.beginGroup(ui.listThemes->selectedItems()
.at(i)->data(Qt::UserRole).toString());
size += iniDetails.value("size").toInt();
iniDetails.endGroup();
}
ui.labelSize->setText(tr("Download size %L1 kiB (%n item(s))", "", items)
.arg((size + 512) / 1024));
}
void ThemesInstallWindow::updateDetails(QListWidgetItem* cur, QListWidgetItem* prev)
{
if(cur == prev)
return;
QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
QCoreApplication::processEvents();
ui.themeDescription->setText(tr("fetching details for %1")
.arg(cur->data(Qt::DisplayRole).toString()));
ui.themePreview->clear();
ui.themePreview->setText(tr("fetching preview ..."));
imgData.clear();
iniDetails.beginGroup(cur->data(Qt::UserRole).toString());
QUrl img, txt;
txt = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
+ iniDetails.value("descriptionfile").toString()));
img = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
+ iniDetails.value("image").toString()));
QString text;
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
text = tr("<b>Author:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
.value("author", tr("unknown")).toByteArray()));
text += tr("<b>Version:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
.value("version", tr("unknown")).toByteArray()));
text += tr("<b>Description:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
.value("about", tr("no description")).toByteArray()));
text.replace("\n", "<br/>");
ui.themeDescription->setHtml(text);
iniDetails.endGroup();
igetter.abort();
if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
igetter.setCache(true);
else
{
if(infocachedir=="")
{
infocachedir = QDir::tempPath() + "rbutil-themeinfo";
QDir d = QDir::temp();
d.mkdir("rbutil-themeinfo");
}
igetter.setCache(infocachedir);
}
igetter.getFile(img);
}
void ThemesInstallWindow::updateImage(bool error)
{
qDebug() << "[Themes] Updating image:"<< !error;
if(error) {
ui.themePreview->clear();
ui.themePreview->setText(tr("Retrieving theme preview failed.\n"
"HTTP response code: %1").arg(igetter.httpResponse()));
return;
}
QPixmap p;
if(!error) {
imgData = igetter.readAll();
if(imgData.isNull()) return;
p.loadFromData(imgData);
if(p.isNull()) {
ui.themePreview->clear();
ui.themePreview->setText(tr("no theme preview"));
}
else
ui.themePreview->setPixmap(p);
}
}
void ThemesInstallWindow::resizeEvent(QResizeEvent* e)
{
qDebug() << "[Themes]" << e;
QPixmap p, q;
QSize img;
img.setHeight(ui.themePreview->height());
img.setWidth(ui.themePreview->width());
p.loadFromData(imgData);
if(p.isNull()) return;
q = p.scaled(img, Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui.themePreview->setScaledContents(false);
ui.themePreview->setPixmap(p);
}
void ThemesInstallWindow::show()
{
QDialog::show();
if(windowSelectOnly)
ui.buttonOk->setText(tr("Select"));
if(!logger)
logger = new ProgressLoggerGui(this);
if(ui.listThemes->count() == 0) {
logger->show();
logger->addItem(tr("getting themes information ..."), LOGINFO);
connect(logger, SIGNAL(aborted()), this, SLOT(close()));
downloadInfo();
}
}
void ThemesInstallWindow::abort()
{
igetter.abort();
logger->setFinished();
this->close();
}
void ThemesInstallWindow::accept(void)
{
if(!windowSelectOnly)
install();
else
close();
}
void ThemesInstallWindow::install()
{
if(ui.listThemes->selectedItems().size() == 0) {
logger->addItem(tr("No themes selected, skipping"), LOGINFO);
emit done(false);
return;
}
QStringList themes;
QStringList names;
QStringList version;
QString zip;
QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
for(int i = 0; i < ui.listThemes->selectedItems().size(); i++) {
iniDetails.beginGroup(ui.listThemes->selectedItems().at(i)->data(Qt::UserRole).toString());
zip = SystemInfo::value(SystemInfo::ThemesUrl).toString()
+ "/" + iniDetails.value("archive").toString();
themes.append(zip);
names.append("Theme: " +
ui.listThemes->selectedItems().at(i)->data(Qt::DisplayRole).toString());
// if no version info is available use installation (current) date
version.append(iniDetails.value("version",
QDate().currentDate().toString("yyyyMMdd")).toString());
iniDetails.endGroup();
}
qDebug() << "[Themes] installing:" << themes;
if(logger == NULL)
logger = new ProgressLoggerGui(this);
logger->show();
QString mountPoint = RbSettings::value(RbSettings::Mountpoint).toString();
qDebug() << "[Themes] mountpoint:" << mountPoint;
// show dialog with error if mount point is wrong
if(!QFileInfo(mountPoint).isDir()) {
logger->addItem(tr("Mount point is wrong!"),LOGERROR);
logger->setFinished();
return;
}
installer = new ZipInstaller(this);
installer->setUrl(themes);
installer->setLogSection(names);
installer->setLogVersion(version);
installer->setMountPoint(mountPoint);
if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
installer->setCache(true);
if(!windowSelectOnly) {
connect(logger, SIGNAL(closed()), this, SLOT(close()));
connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
}
connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
connect(installer, SIGNAL(done(bool)), this, SIGNAL(done(bool)));
connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
installer->install();
}
void ThemesInstallWindow::changeEvent(QEvent *e)
{
if(e->type() == QEvent::LanguageChange) {
ui.retranslateUi(this);
} else {
QWidget::changeEvent(e);
}
}