Fix manual download links.
[kugel-rb.git] / rbutil / rbutilqt / themesinstallwindow.cpp
blob4c75d431fb74be5ae736d8209b9ec36433977bb2
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Riebeling
10 * $Id$
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <QtGui>
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"
30 ThemesInstallWindow::ThemesInstallWindow(QWidget *parent) : QDialog(parent)
32 ui.setupUi(this);
33 ui.listThemes->setAlternatingRowColors(true);
34 ui.listThemes->setSelectionMode(QAbstractItemView::ExtendedSelection);
35 ui.listThemes->setSortingEnabled(true);
36 ui.themePreview->clear();
37 ui.themePreview->setText(tr("no theme selected"));
38 ui.labelSize->setText(tr("no selection"));
39 ui.listThemes->setLayoutDirection(Qt::LeftToRight);
40 ui.themeDescription->setLayoutDirection(Qt::LeftToRight);
42 connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(close()));
43 connect(ui.buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
44 connect(ui.listThemes, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
45 this, SLOT(updateDetails(QListWidgetItem*, QListWidgetItem*)));
46 connect(ui.listThemes, SIGNAL(itemSelectionChanged()), this, SLOT(updateSize()));
47 connect(&igetter, SIGNAL(done(bool)), this, SLOT(updateImage(bool)));
50 ThemesInstallWindow::~ThemesInstallWindow()
52 if(infocachedir!="")
53 recRmdir(infocachedir);
57 void ThemesInstallWindow::downloadInfo()
59 // try to get the current build information
60 getter = new HttpGet(this);
62 themesInfo.open();
63 qDebug() << "[Themes] downloading info to" << themesInfo.fileName();
64 themesInfo.close();
66 QUrl url;
67 url = QUrl(SystemInfo::value(SystemInfo::ThemesUrl).toString()
68 + "/rbutilqt.php?target="
69 + SystemInfo::value(SystemInfo::CurConfigureModel).toString());
70 qDebug() << "[Themes] Info URL:" << url << "Query:" << url.queryItems();
71 if(RbSettings::value(RbSettings::CacheOffline).toBool())
72 getter->setCache(true);
73 getter->setFile(&themesInfo);
75 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
76 connect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
77 getter->getFile(url);
81 void ThemesInstallWindow::downloadDone(int id, bool error)
83 downloadDone(error);
84 qDebug() << "[Themes] Download" << id << "done, error:" << error;
88 void ThemesInstallWindow::downloadDone(bool error)
90 qDebug() << "[Themes] Download done, error:" << error;
92 disconnect(logger, SIGNAL(aborted()), getter, SLOT(abort()));
93 disconnect(logger, SIGNAL(aborted()), this, SLOT(close()));
94 themesInfo.open();
96 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
97 QStringList tl = iniDetails.childGroups();
98 qDebug() << "[Themes] Theme site result:"
99 << iniDetails.value("error/code").toString()
100 << iniDetails.value("error/description").toString()
101 << iniDetails.value("error/query").toString();
103 if(error) {
104 logger->addItem(tr("Network error: %1.\n"
105 "Please check your network and proxy settings.")
106 .arg(getter->errorString()), LOGERROR);
107 getter->abort();
108 logger->setFinished();
109 disconnect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
110 connect(logger, SIGNAL(closed()), this, SLOT(close()));
111 return;
113 // handle possible error codes
114 if(iniDetails.value("error/code").toInt() != 0 || !iniDetails.contains("error/code")) {
115 qDebug() << "[Themes] Theme site returned an error:"
116 << iniDetails.value("error/code");
117 logger->addItem(tr("the following error occured:\n%1")
118 .arg(iniDetails.value("error/description", "unknown error").toString()), LOGERROR);
119 logger->setFinished();
120 connect(logger, SIGNAL(closed()), this, SLOT(close()));
121 return;
123 logger->addItem(tr("done."), LOGOK);
124 logger->setFinished();
125 logger->close();
127 // setup list
128 for(int i = 0; i < tl.size(); i++) {
129 iniDetails.beginGroup(tl.at(i));
130 // skip all themes without name field set (i.e. error section)
131 if(iniDetails.value("name").toString().isEmpty()) {
132 iniDetails.endGroup();
133 continue;
135 qDebug() << "[Themes] adding to list:" << tl.at(i);
136 // convert to unicode and replace HTML-specific entities
137 QByteArray raw = iniDetails.value("name").toByteArray();
138 QTextCodec* codec = QTextCodec::codecForHtml(raw);
139 QString name = codec->toUnicode(raw);
140 name.replace("&quot;", "\"").replace("&amp;", "&");
141 name.replace("&lt;", "<").replace("&gt;", ">");
142 QListWidgetItem *w = new QListWidgetItem;
143 w->setData(Qt::DisplayRole, name.trimmed());
144 w->setData(Qt::UserRole, tl.at(i));
145 ui.listThemes->addItem(w);
147 iniDetails.endGroup();
149 // check if there's a themes "MOTD" available
150 if(iniDetails.contains("status/msg")) {
151 // check if there's a localized msg available
152 QString lang = RbSettings::value(RbSettings::Language).toString().split("_").at(0);
153 QString msg;
154 if(iniDetails.contains("status/msg." + lang))
155 msg = iniDetails.value("status/msg." + lang).toString();
156 else
157 msg = iniDetails.value("status/msg").toString();
158 qDebug() << "[Themes] MOTD" << msg;
159 if(!msg.isEmpty())
160 QMessageBox::information(this, tr("Information"), msg);
165 void ThemesInstallWindow::updateSize(void)
167 long size = 0;
168 // sum up size for all selected themes
169 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
170 int items = ui.listThemes->selectedItems().size();
171 for(int i = 0; i < items; i++) {
172 iniDetails.beginGroup(ui.listThemes->selectedItems()
173 .at(i)->data(Qt::UserRole).toString());
174 size += iniDetails.value("size").toInt();
175 iniDetails.endGroup();
177 ui.labelSize->setText(tr("Download size %L1 kiB (%n item(s))", "", items)
178 .arg((size + 512) / 1024));
182 void ThemesInstallWindow::updateDetails(QListWidgetItem* cur, QListWidgetItem* prev)
184 if(cur == prev)
185 return;
187 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
189 QCoreApplication::processEvents();
190 ui.themeDescription->setText(tr("fetching details for %1")
191 .arg(cur->data(Qt::DisplayRole).toString()));
192 ui.themePreview->clear();
193 ui.themePreview->setText(tr("fetching preview ..."));
194 imgData.clear();
196 iniDetails.beginGroup(cur->data(Qt::UserRole).toString());
198 QUrl img, txt;
199 txt = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
200 + iniDetails.value("descriptionfile").toString()));
201 img = QUrl(QString(SystemInfo::value(SystemInfo::ThemesUrl).toString() + "/"
202 + iniDetails.value("image").toString()));
204 QString text;
205 QTextCodec* codec = QTextCodec::codecForName("UTF-8");
206 text = tr("<b>Author:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
207 .value("author", tr("unknown")).toByteArray()));
208 text += tr("<b>Version:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
209 .value("version", tr("unknown")).toByteArray()));
210 text += tr("<b>Description:</b> %1<hr/>").arg(codec->toUnicode(iniDetails
211 .value("about", tr("no description")).toByteArray()));
213 text.trimmed();
214 text.replace("\n", "<br/>");
215 ui.themeDescription->setHtml(text);
216 iniDetails.endGroup();
218 igetter.abort();
219 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
220 igetter.setCache(true);
221 else
223 if(infocachedir=="")
225 infocachedir = QDir::tempPath() + "rbutil-themeinfo";
226 QDir d = QDir::temp();
227 d.mkdir("rbutil-themeinfo");
229 igetter.setCache(infocachedir);
232 igetter.getFile(img);
236 void ThemesInstallWindow::updateImage(bool error)
238 qDebug() << "[Themes] Updating image:"<< !error;
240 if(error) {
241 ui.themePreview->clear();
242 ui.themePreview->setText(tr("Retrieving theme preview failed.\n"
243 "HTTP response code: %1").arg(igetter.httpResponse()));
244 return;
247 QPixmap p;
248 if(!error) {
249 imgData = igetter.readAll();
250 if(imgData.isNull()) return;
251 p.loadFromData(imgData);
252 if(p.isNull()) {
253 ui.themePreview->clear();
254 ui.themePreview->setText(tr("no theme preview"));
256 else
257 ui.themePreview->setPixmap(p);
262 void ThemesInstallWindow::resizeEvent(QResizeEvent* e)
264 qDebug() << "[Themes]" << e;
266 QPixmap p, q;
267 QSize img;
268 img.setHeight(ui.themePreview->height());
269 img.setWidth(ui.themePreview->width());
271 p.loadFromData(imgData);
272 if(p.isNull()) return;
273 q = p.scaled(img, Qt::KeepAspectRatio, Qt::SmoothTransformation);
274 ui.themePreview->setScaledContents(false);
275 ui.themePreview->setPixmap(p);
280 void ThemesInstallWindow::show()
282 QDialog::show();
283 logger = new ProgressLoggerGui(this);
284 logger->show();
285 logger->addItem(tr("getting themes information ..."), LOGINFO);
287 connect(logger, SIGNAL(aborted()), this, SLOT(close()));
289 downloadInfo();
294 void ThemesInstallWindow::abort()
296 igetter.abort();
297 logger->setFinished();
298 this->close();
302 void ThemesInstallWindow::accept()
304 if(ui.listThemes->selectedItems().size() == 0) {
305 this->close();
306 return;
308 QStringList themes;
309 QStringList names;
310 QStringList version;
311 QString zip;
312 QSettings iniDetails(themesInfo.fileName(), QSettings::IniFormat, this);
313 for(int i = 0; i < ui.listThemes->selectedItems().size(); i++) {
314 iniDetails.beginGroup(ui.listThemes->selectedItems().at(i)->data(Qt::UserRole).toString());
315 zip = SystemInfo::value(SystemInfo::ThemesUrl).toString()
316 + "/" + iniDetails.value("archive").toString();
317 themes.append(zip);
318 names.append("Theme: " +
319 ui.listThemes->selectedItems().at(i)->data(Qt::DisplayRole).toString());
320 // if no version info is available use installation (current) date
321 version.append(iniDetails.value("version",
322 QDate().currentDate().toString("yyyyMMdd")).toString());
323 iniDetails.endGroup();
325 qDebug() << "[Themes] installing:" << themes;
327 logger = new ProgressLoggerGui(this);
328 logger->show();
329 QString mountPoint = RbSettings::value(RbSettings::Mountpoint).toString();
330 qDebug() << "[Themes] mountpoint:" << mountPoint;
331 // show dialog with error if mount point is wrong
332 if(!QFileInfo(mountPoint).isDir()) {
333 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
334 logger->setFinished();
335 return;
338 installer = new ZipInstaller(this);
339 installer->setUrl(themes);
340 installer->setLogSection(names);
341 installer->setLogVersion(version);
342 installer->setMountPoint(mountPoint);
343 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
344 installer->setCache(true);
346 connect(logger, SIGNAL(closed()), this, SLOT(close()));
347 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
348 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
349 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
350 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
351 installer->install();