From 280c0256db2378c9f33775b270f211660e5bf868 Mon Sep 17 00:00:00 2001 From: Nils Schwabe Date: Fri, 14 Mar 2014 14:50:24 +0100 Subject: - Added IconHolder to cache items - Added FileDownloader for icon downloads --- src/FileDownloader.cpp | 37 +++++++++++++++++++ src/FileDownloader.h | 45 +++++++++++++++++++++++ src/main.cpp | 3 +- src/sessionsiconholder.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++++ src/sessionsiconholder.h | 40 +++++++++++++++++++++ src/sessiontreemodel.cpp | 28 ++++++++------- src/sessiontreemodel.h | 3 ++ 7 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 src/FileDownloader.cpp create mode 100644 src/FileDownloader.h create mode 100644 src/sessionsiconholder.cpp create mode 100644 src/sessionsiconholder.h diff --git a/src/FileDownloader.cpp b/src/FileDownloader.cpp new file mode 100644 index 0000000..d72fdd8 --- /dev/null +++ b/src/FileDownloader.cpp @@ -0,0 +1,37 @@ +/* + * FileDownloader.cpp + * + * Created on: Mar 7, 2014 + * Author: nils + */ + +#include + +#include "FileDownloader.h" + +FileDownloader::FileDownloader(QObject *parent) : + QObject(parent) { + connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), + SLOT(fileDownloaded(QNetworkReply*))); +} + +FileDownloader::~FileDownloader() { + +} + +void FileDownloader::connectSlot(QObject* obj, const char* slot) { + QObject::connect(this, SIGNAL(downloaded(QString& fileName, QByteArray downloadedData)), + obj, slot); +} + +void FileDownloader::fileDownloaded(QNetworkReply* pReply) { + QByteArray downloadedData = pReply->readAll(); + //emit a signal + pReply->deleteLater(); + emit downloaded(this->fileName, downloadedData); +} + +void FileDownloader::downloadFile(const QUrl& fileUrl) { + this->fileName = QFileInfo(fileUrl.toLocalFile()).fileName(); + m_WebCtrl.get(QNetworkRequest(fileUrl)); +} diff --git a/src/FileDownloader.h b/src/FileDownloader.h new file mode 100644 index 0000000..fccfa7a --- /dev/null +++ b/src/FileDownloader.h @@ -0,0 +1,45 @@ +/* + * FileDownloader.h + * + * Created on: Mar 7, 2014 + * Author: nils + */ + +#ifndef FILEDOWNLOADER_H_ +#define FILEDOWNLOADER_H_ + +#include +#include +#include +#include +#include + +class FileDownloader : public QObject +{ + Q_OBJECT +public: + explicit FileDownloader(QObject *parent = 0); + + virtual ~FileDownloader(); + + void downloadFile(const QUrl& fileUrl); + + void connectSlot(QObject* obj, const char* slot); + + QByteArray downloadedData() const; + +signals: + void downloaded(QString& fileName, QByteArray downloadedData); + +private slots: + + void fileDownloaded(QNetworkReply* pReply); + +private: + + QNetworkAccessManager m_WebCtrl; + QString fileName; + +}; + +#endif /* FILEDOWNLOADER_H_ */ diff --git a/src/main.cpp b/src/main.cpp index e9e8328..a682a06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -223,9 +223,8 @@ int main(int argc, char *argv[]) { w.addItems(xsessions, a.translate("Dialog", "X Sessions")); } - w.addLabelItem(a.translate("Dialog", "Loading..."), a.translate("Dialog", "Virtual Sessions")); - if (vsessions.size()) { + w.addLabelItem(a.translate("Dialog", "Loading..."), a.translate("Dialog", "Virtual Sessions")); if (!(QFile::permissions(runVmScript) & QFile::ExeUser)) { std::cerr << a.translate( "Console", diff --git a/src/sessionsiconholder.cpp b/src/sessionsiconholder.cpp new file mode 100644 index 0000000..b0feb66 --- /dev/null +++ b/src/sessionsiconholder.cpp @@ -0,0 +1,90 @@ +/* + * sessionsiconholder.cpp + * + * Created on: Mar 7, 2014 + * Author: nils + */ + +#include +#include +#include +#include +#include +#include + +#include "globals.h" +#include "sessionsiconholder.h" +#include "FileDownloader.h" + +SessionsIconHolder::SessionsIconHolder() { +} + +void SessionsIconHolder::afterDownload(QString& iconName, QByteArray downloadedData) { + // save the data to disk + QString filePath = "/tmp/vmchooser2/icons/" + iconName; + QFile file(filePath); + if (!file.open(QFile::WriteOnly)) { + if (debugMode) { + qDebug() << "Could not write file: " << filePath; + } + return; + } + file.write(downloadedData); + + if (file.write(downloadedData) != downloadedData.length()) { + if (debugMode) { + qDebug() << "Could not write file: " << filePath; + } + return; + } + + file.close(); + QIcon icon(filePath); + iconsURL.insert(iconName, icon); + // TODO: trigger sessionstree to update the icons +} + +QIcon SessionsIconHolder::getIconFromResource(const QString& name) { + if (iconsResource.contains(name)) { + return iconsResource[name]; + } + + QIcon icon; + if (QResource(":" + name.toLower() + ".svg").isValid()) { + icon = QIcon(":" + name.toLower() + ".svg"); + } else if (QResource(":" + name.toLower()).isValid()) { + icon = QIcon(":" + name.toLower()); + } else { + icon = QIcon(":none"); + } + + iconsResource.insert(name, icon); + return icon; +} + +QIcon SessionsIconHolder::getIconFromFile(const QString& filename) { + if (iconsFile.contains(filename)) { + return iconsFile[filename]; + } + + QFile iconFile(filename); + if (iconFile.exists()) { + return QIcon(filename); + } + + return QIcon(":none"); +} + +QIcon SessionsIconHolder::getIconFromURL(const QUrl& fileUrl) { + QString iconName = QFileInfo(fileUrl.toLocalFile()).fileName(); + if (iconsURL.contains(iconName)) { + return iconsURL[iconName]; + } + + FileDownloader fileDownloader(this); + fileDownloader.connectSlot(this, + SLOT(afterDownload(QString& iconName, QByteArray downloadedData))); + fileDownloader.downloadFile(fileUrl); + + return QIcon(":none"); +} diff --git a/src/sessionsiconholder.h b/src/sessionsiconholder.h new file mode 100644 index 0000000..336ce40 --- /dev/null +++ b/src/sessionsiconholder.h @@ -0,0 +1,40 @@ +/* + * sessionsiconholder.h + * + * Created on: Mar 7, 2014 + * Author: nils + */ + +#ifndef SESSIONSICONHOLDER_H_ +#define SESSIONSICONHOLDER_H_ + +#include +#include +#include +#include +#include +#include + +#include "globals.h" +#include "sessionsiconholder.h" +#include "FileDownloader.h" + + +class SessionsIconHolder : QObject { + Q_OBJECT + +private: + QHash iconsResource; + QHash iconsFile; + QHash iconsURL; +public: + SessionsIconHolder(); + + QIcon getIconFromResource(const QString& name); + QIcon getIconFromFile(const QString& filename); + QIcon getIconFromURL(const QUrl& url); +public slots: + void afterDownload(QString& iconName, QByteArray downloadedData); +}; + +#endif /* SESSIONSICONHOLDER_H_ */ diff --git a/src/sessiontreemodel.cpp b/src/sessiontreemodel.cpp index d0fc79e..9bc13f6 100644 --- a/src/sessiontreemodel.cpp +++ b/src/sessiontreemodel.cpp @@ -8,10 +8,12 @@ #include "sessiontreeitem.h" #include "vsession.h" +#include "sessionsiconholder.h" SessionTreeModel::SessionTreeModel(QObject *parent) : QAbstractItemModel(parent) { root_ = new SessionTreeItem("dummy"); + iconHolder = new SessionsIconHolder(); } SessionTreeModel::~SessionTreeModel() { @@ -52,35 +54,35 @@ QVariant SessionTreeModel::data(const QModelIndex &index, int role) const { if (role == Qt::ToolTipRole) return s->description(); if (role == Qt::DecorationRole) { - // TODO: use cache for icons if (index.column() == 0) { // TODO: is this line needed? QString icon(s->icon()); if (QFileInfo(icon).isAbsolute()) { // try to load icon from file - QFile iconFile(icon); - if (iconFile.exists()) { - return QIcon(icon); + QIcon file_icon = iconHolder->getIconFromFile(icon); + if (!file_icon.name().isEmpty()) { + return file_icon; + } + + // try to load icon from url + QIcon url_icon = iconHolder->getIconFromURL(icon); + if (!url_icon.name().isEmpty()) { + return url_icon; } // fallback to os icon if (s->type() == Session::VSESSION) { const VSession* vs = (VSession*) s; if (vs->getAttribute("os", "param").toLower().startsWith("win")) { - return QIcon(":windows"); + return iconHolder->getIconFromResource("windows"); } else { - return QIcon(":linux"); + return iconHolder->getIconFromResource("linux"); } } } else { // try to load icon from QResource - if (QResource(":" + icon.toLower() + ".svg").isValid()) { - return QIcon(":" + icon.toLower() + ".svg"); - } else if (QResource(":" + icon.toLower()).isValid()) { - return QIcon(":" + icon.toLower()); - } else { - return QIcon(":none"); - } + qDebug() << icon; + return iconHolder->getIconFromResource(icon); } } } diff --git a/src/sessiontreemodel.h b/src/sessiontreemodel.h index a768bf1..e4edcba 100644 --- a/src/sessiontreemodel.h +++ b/src/sessiontreemodel.h @@ -5,6 +5,8 @@ #include #include +#include "sessionsiconholder.h" + class SessionTreeItem; class Session; @@ -32,6 +34,7 @@ class SessionTreeModel : public QAbstractItemModel { private: SessionTreeItem* root_; + SessionsIconHolder* iconHolder; }; #endif // VMCHOOSER_SESSIONTREEMODEL_H -- cgit v1.2.3-55-g7522