Fix advanced EQ menu
[maemo-rb.git] / rbutil / rbutilqt / themesinstallwindow.cpp
blob2003b41c02863ba4b5adda87e6ed2390c8eef8e8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Riebeling
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
19 #include <QDialog>
20 #include <QMessageBox>
22 #include "ui_themesinstallfrm.h"
23 #include "themesinstallwindow.h"
24 #include "zipinstaller.h"
25 #include "progressloggergui.h"
26 #include "utils.h"
27 #include "rbsettings.h"
28 #include "systeminfo.h"
29 #include "rockboxinfo.h"
30 #include "version.h"
32 ThemesInstallWindow::ThemesInstallWindow(QWidget *parent) : QDialog(parent)
34 ui.setupUi(this);
35 ui.listThemes->setAlternatingRowColors(true);
36 ui.listThemes->setSelectionMode(QAbstractItemView::ExtendedSelection);
37 ui.listThemes->setSortingEnabled(true);
38 ui.themePreview->clear();
39 ui.themePreview->setText(tr("no theme selected"));
40 ui.labelSize->setText(tr("no selection"));
41 ui.listThemes->setLayoutDirection(Qt::LeftToRight);
42 ui.themeDescription->setLayoutDirection(Qt::LeftToRight);
44 connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
45 connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
46 connect(ui.listThemes, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
47 this, SLOT(updateDetails(QListWidgetItem*, QListWidgetItem*)));
48 connect(ui.listThemes, SIGNAL(itemSelectionChanged()), this, SLOT(updateSize()));
49 connect(&igetter, SIGNAL(done(bool)), this, SLOT(updateImage(bool)));
51 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
52 igetter.setCache(true);
53 else
55 if(infocachedir.isEmpty())
57 infocachedir = QDir::tempPath() + "rbutil-themeinfo";
58 QDir d = QDir::temp();
59 d.mkdir("rbutil-themeinfo");
61 igetter.setCache(infocachedir);
64 logger = NULL;
67 ThemesInstallWindow::~ThemesInstallWindow()
69 if(!infocachedir.isEmpty())
70 Utils::recursiveRmdir(infocachedir);
74 void ThemesInstallWindow::downloadInfo()
76 // try to get the current build information
77 getter = new HttpGet(this);
78 RockboxInfo installInfo
79 = RockboxInfo(RbSettings::value(RbSettings::Mountpoint).toString());
81 themesInfo.open();
82 qDebug() << "[Themes] downloading info to" << themesInfo.fileName();
83 themesInfo.close();
85 QString infoUrl = SystemInfo::value(SystemInfo::ThemesInfoUrl).toString();
86 infoUrl.replace("%TARGET%",
87 SystemInfo::value(SystemInfo::CurConfigureModel).toString());
88 infoUrl.replace("%REVISION%", installInfo.revision());
89 infoUrl.replace("%RELEASE%", installInfo.release());
90 infoUrl.replace("%RBUTILVER%", VERSION);
91 QUrl url = QUrl(infoUrl);
92 qDebug() << "[Themes] Info URL:" << url;
93 getter->setFile(&themesInfo);
95 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
96 connect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
97 getter->getFile(url);
101 void ThemesInstallWindow::downloadDone(int id, bool error)
103 downloadDone(error);
104 qDebug() << "[Themes] Download" << id << "done, error:" << error;
108 void ThemesInstallWindow::downloadDone(bool error)
110 qDebug() << "[Themes] Download done, error:" << error;
112 disconnect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
113 disconnect(logger, SIGNAL(aborted()), this, SLOT(close()));
114 themesInfo.open();
116 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
117 QStringList tl = iniDetails.childGroups();
118 qDebug() << "[Themes] Theme site result:"
119 << iniDetails.value("error/code").toString()
120 << iniDetails.value("error/description").toString()
121 << iniDetails.value("error/query").toString();
123 if(error) {
124 logger->addItem(tr("Network error: %1.\n"
125 "Please check your network and proxy settings.")
126 .arg(getter->errorString()), LOGERROR);
127 getter->abort();
128 logger->setFinished();
129 disconnect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
130 connect(logger, SIGNAL(closed()), this, SLOT(close()));
131 return;
133 // handle possible error codes
134 if(iniDetails.value("error/code").toInt() != 0 || !iniDetails.contains("error/code")) {
135 qDebug() << "[Themes] Theme site returned an error:"
136 << iniDetails.value("error/code");
137 logger->addItem(tr("the following error occured:\n%1")
138 .arg(iniDetails.value("error/description", "unknown error").toString()), LOGERROR);
139 logger->setFinished();
140 connect(logger, SIGNAL(closed()), this, SLOT(close()));
141 return;
143 logger->addItem(tr("done."), LOGOK);
144 logger->setFinished();
145 logger->close();
147 // setup list
148 for(int i = 0; i < tl.size(); i++) {
149 iniDetails.beginGroup(tl.at(i));
150 // skip all themes without name field set (i.e. error section)
151 if(iniDetails.value("name").toString().isEmpty()) {
152 iniDetails.endGroup();
153 continue;
155 qDebug() << "[Themes] adding to list:" << tl.at(i);
156 // convert to unicode and replace HTML-specific entities
157 QByteArray raw = iniDetails.value("name").toByteArray();
158 QTextCodec* codec = QTextCodec::codecForHtml(raw);
159 QString name = codec->toUnicode(raw);
160 name.replace("&quot;", "\"").replace("&amp;", "&");
161 name.replace("&lt;", "<").replace("&gt;", ">");
162 QListWidgetItem *w = new QListWidgetItem;
163 w->setData(Qt::DisplayRole, name.trimmed());
164 w->setData(Qt::UserRole, tl.at(i));
165 ui.listThemes->addItem(w);
167 iniDetails.endGroup();
169 // check if there's a themes "MOTD" available
170 if(iniDetails.contains("status/msg")) {
171 // check if there's a localized msg available
172 QString lang = RbSettings::value(RbSettings::Language).toString().split("_").at(0);
173 QString msg;
174 if(iniDetails.contains("status/msg." + lang))
175 msg = iniDetails.value("status/msg." + lang).toString();
176 else
177 msg = iniDetails.value("status/msg").toString();
178 qDebug() << "[Themes] MOTD" << msg;
179 if(!msg.isEmpty())
180 QMessageBox::information(this, tr("Information"), msg);
185 void ThemesInstallWindow::updateSize(void)
187 long size = 0;
188 // sum up size for all selected themes
189 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
190 int items = ui.listThemes->selectedItems().size();
191 for(int i = 0; i < items; i++) {
192 iniDetails.beginGroup(ui.listThemes->selectedItems()
193 .at(i)->data(Qt::UserRole).toString());
194 size += iniDetails.value("size").toInt();
195 iniDetails.endGroup();
197 ui.labelSize->setText(tr("Download size %L1 kiB (%n item(s))", "", items)
198 .arg((size + 512) / 1024));
202 void ThemesInstallWindow::updateDetails(QListWidgetItem* cur, QListWidgetItem* prev)
204 if(cur == prev)
205 return;
207 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
209 QCoreApplication::processEvents();
210 ui.themeDescription->setText(tr("fetching details for %1")
211 .arg(cur->data(Qt::DisplayRole).toString()));
212 ui.themePreview->clear();
213 ui.themePreview->setText(tr("fetching preview ..."));
214 imgData.clear();
216 iniDetails.beginGroup(cur->data(Qt::UserRole).toString());
218 QUrl img, txt;
219 txt = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
220 + iniDetails.value("descriptionfile").toString()));
221 img = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
222 + iniDetails.value("image").toString()));
224 QString text;
225 QTextCodec* codec = QTextCodec::codecForName("UTF-8");
226 text = tr("<b>Author:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
227 .value("author", tr("unknown")).toByteArray()));
228 text += tr("<b>Version:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
229 .value("version", tr("unknown")).toByteArray()));
230 text += tr("<b>Description:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
231 .value("about", tr("no description")).toByteArray()));
233 text.replace("\n", "<br/>");
234 ui.themeDescription->setHtml(text);
235 iniDetails.endGroup();
236 igetter.abort();
237 igetter.getFile(img);
241 void ThemesInstallWindow::updateImage(bool error)
243 qDebug() << "[Themes] Updating image:"<< !error;
245 if(error) {
246 ui.themePreview->clear();
247 ui.themePreview->setText(tr("Retrieving theme preview failed.\n"
248 "HTTP response code: %1").arg(igetter.httpResponse()));
249 return;
252 QPixmap p;
253 if(!error) {
254 imgData = igetter.readAll();
255 if(imgData.isNull()) return;
256 p.loadFromData(imgData);
257 if(p.isNull()) {
258 ui.themePreview->clear();
259 ui.themePreview->setText(tr("no theme preview"));
261 else
262 ui.themePreview->setPixmap(p);
267 void ThemesInstallWindow::resizeEvent(QResizeEvent* e)
269 qDebug() << "[Themes]" << e;
271 QPixmap p, q;
272 QSize img;
273 img.setHeight(ui.themePreview->height());
274 img.setWidth(ui.themePreview->width());
276 p.loadFromData(imgData);
277 if(p.isNull()) return;
278 q = p.scaled(img, Qt::KeepAspectRatio, Qt::SmoothTransformation);
279 ui.themePreview->setScaledContents(false);
280 ui.themePreview->setPixmap(p);
285 void ThemesInstallWindow::show()
287 QDialog::show();
288 if(windowSelectOnly)
289 ui.buttonOk->setText(tr("Select"));
291 if(!logger)
292 logger = new ProgressLoggerGui(this);
294 if(ui.listThemes->count() == 0) {
295 logger->show();
296 logger->addItem(tr("getting themes information ..."), LOGINFO);
298 connect(logger, SIGNAL(aborted()), this, SLOT(close()));
300 downloadInfo();
306 void ThemesInstallWindow::abort()
308 igetter.abort();
309 logger->setFinished();
310 this->close();
314 void ThemesInstallWindow::accept(void)
316 if(!windowSelectOnly)
317 install();
318 else
319 close();
323 void ThemesInstallWindow::install()
325 if(ui.listThemes->selectedItems().size() == 0) {
326 logger->addItem(tr("No themes selected, skipping"), LOGINFO);
327 emit done(false);
328 return;
330 QStringList themes;
331 QStringList names;
332 QStringList version;
333 QString zip;
334 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
335 for(int i = 0; i < ui.listThemes->selectedItems().size(); i++) {
336 iniDetails.beginGroup(ui.listThemes->selectedItems().at(i)->data(Qt::UserRole).toString());
337 zip = SystemInfo::value(SystemInfo::ThemesUrl).toString()
338 + "/" + iniDetails.value("archive").toString();
339 themes.append(zip);
340 names.append("Theme: " +
341 ui.listThemes->selectedItems().at(i)->data(Qt::DisplayRole).toString());
342 // if no version info is available use installation (current) date
343 version.append(iniDetails.value("version",
344 QDate().currentDate().toString("yyyyMMdd")).toString());
345 iniDetails.endGroup();
347 qDebug() << "[Themes] installing:" << themes;
349 if(logger == NULL)
350 logger = new ProgressLoggerGui(this);
351 logger->show();
352 QString mountPoint = RbSettings::value(RbSettings::Mountpoint).toString();
353 qDebug() << "[Themes] mountpoint:" << mountPoint;
354 // show dialog with error if mount point is wrong
355 if(!QFileInfo(mountPoint).isDir()) {
356 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
357 logger->setFinished();
358 return;
361 installer = new ZipInstaller(this);
362 installer->setUrl(themes);
363 installer->setLogSection(names);
364 installer->setLogVersion(version);
365 installer->setMountPoint(mountPoint);
366 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
367 installer->setCache(true);
369 if(!windowSelectOnly) {
370 connect(logger, SIGNAL(closed()), this, SLOT(close()));
371 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
373 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
374 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
375 connect(installer, SIGNAL(done(bool)), this, SIGNAL(done(bool)));
376 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
377 installer->install();
381 void ThemesInstallWindow::changeEvent(QEvent *e)
383 if(e->type() == QEvent::LanguageChange) {
384 ui.retranslateUi(this);
385 } else {
386 QWidget::changeEvent(e);