From d8913d5d3aad1f21a35af6b132d998ddb56273d7 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 27 Aug 2018 23:29:44 -0400 Subject: [PATCH] Qt: add right-click for playlists to download thumbnails for the current entries --- Makefile.common | 3 +- griffin/griffin_cpp.cpp | 1 + intl/msg_hash_ja.h | 6 + intl/msg_hash_us.h | 6 + msg_hash.h | 3 + ui/drivers/qt/playlist.cpp | 30 +- ui/drivers/qt/playlistthumbnaildownload.cpp | 332 ++++++++++++++++++++ ui/drivers/qt/thumbnaildownload.cpp | 2 +- ui/drivers/qt/thumbnailpackdownload.cpp | 1 + ui/drivers/qt/ui_qt_window.cpp | 25 ++ ui/drivers/ui_qt.h | 18 ++ 11 files changed, 418 insertions(+), 9 deletions(-) create mode 100644 ui/drivers/qt/playlistthumbnaildownload.cpp diff --git a/Makefile.common b/Makefile.common index 93a2856104..d32bea96df 100644 --- a/Makefile.common +++ b/Makefile.common @@ -353,7 +353,8 @@ OBJ += ui/drivers/ui_qt.o \ ui/drivers/qt/playlist.o \ ui/drivers/qt/updateretroarch.o \ ui/drivers/qt/thumbnaildownload.o \ - ui/drivers/qt/thumbnailpackdownload.o + ui/drivers/qt/thumbnailpackdownload.o \ + ui/drivers/qt/playlistthumbnaildownload.o MOC_HEADERS += ui/drivers/ui_qt.h \ ui/drivers/qt/ui_qt_load_core_window.h \ diff --git a/griffin/griffin_cpp.cpp b/griffin/griffin_cpp.cpp index 47f25ab447..56f15070f7 100644 --- a/griffin/griffin_cpp.cpp +++ b/griffin/griffin_cpp.cpp @@ -51,6 +51,7 @@ UI #include "../ui/drivers/qt/updateretroarch.cpp" #include "../ui/drivers/qt/thumbnaildownload.cpp" #include "../ui/drivers/qt/thumbnailpackdownload.cpp" +#include "../ui/drivers/qt/playlistthumbnaildownload.cpp" #endif /*============================================================ diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index d71ea6ff28..ed2daaa004 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3796,5 +3796,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, "起動時に表示するプレイリスト:") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, "すべてのサムネイルをダウンロード") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "システムのすべて") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "このプレイリスト") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, "サムネイルのダウンロードが成功しました。") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "成功した数: %1 失敗した数: %2") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index b0c9290fa0..38f6bade70 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -7394,5 +7394,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST, "Start on playlist:") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, "Download All Thumbnails") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + "Entire System") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, + "This Playlist") MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, "Thumbnails downloaded successfully.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, + "Succeeded: %1 Failed: %2") diff --git a/msg_hash.h b/msg_hash.h index 3e1cd59d77..10661c8675 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2008,7 +2008,10 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_THUMBNAIL, MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALREADY_IN_PROGRESS, MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST, MENU_ENUM_LABEL_VALUE_QT_THUMBNAIL_PACK_DOWNLOADED_SUCCESSFULLY, + MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS, MENU_LABEL(MIDI_INPUT), MENU_LABEL(MIDI_OUTPUT), diff --git a/ui/drivers/qt/playlist.cpp b/ui/drivers/qt/playlist.cpp index af8bf6bc31..0e2099fb71 100644 --- a/ui/drivers/qt/playlist.cpp +++ b/ui/drivers/qt/playlist.cpp @@ -374,10 +374,12 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) QScopedPointer menu; QScopedPointer associateMenu; QScopedPointer hiddenPlaylistsMenu; + QScopedPointer downloadAllThumbnailsMenu; QScopedPointer hideAction; QScopedPointer newPlaylistAction; QScopedPointer deletePlaylistAction; - QScopedPointer downloadAllThumbnailsAction; + QScopedPointer downloadAllThumbnailsEntireSystemAction; + QScopedPointer downloadAllThumbnailsThisPlaylistAction; QPointer selectedAction; QPoint cursorPos = QCursor::pos(); QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos)); @@ -530,9 +532,16 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) if (!specialPlaylist) { - downloadAllThumbnailsAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS), this)); + downloadAllThumbnailsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS), this)); + downloadAllThumbnailsMenu->setObjectName("downloadAllThumbnailsMenu"); - menu->addAction(downloadAllThumbnailsAction.data()); + downloadAllThumbnailsThisPlaylistAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_THIS_PLAYLIST), downloadAllThumbnailsMenu.data())); + downloadAllThumbnailsEntireSystemAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_ALL_THUMBNAILS_ENTIRE_SYSTEM), downloadAllThumbnailsMenu.data())); + + downloadAllThumbnailsMenu->addAction(downloadAllThumbnailsThisPlaylistAction.data()); + downloadAllThumbnailsMenu->addAction(downloadAllThumbnailsEntireSystemAction.data()); + + menu->addMenu(downloadAllThumbnailsMenu.data()); } selectedAction = menu->exec(cursorPos); @@ -633,12 +642,19 @@ void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) } } } - else if (selectedItem && !specialPlaylist && selectedAction == downloadAllThumbnailsAction.data()) + else if (selectedItem && !specialPlaylist && selectedAction->parent() == downloadAllThumbnailsMenu.data()) { - int row = m_listWidget->row(selectedItem); + if (selectedAction == downloadAllThumbnailsEntireSystemAction.data()) + { + int row = m_listWidget->row(selectedItem); - if (row >= 0) - downloadAllThumbnails(currentPlaylistFileInfo.completeBaseName()); + if (row >= 0) + downloadAllThumbnails(currentPlaylistFileInfo.completeBaseName()); + } + else if (selectedAction == downloadAllThumbnailsThisPlaylistAction.data()) + { + downloadPlaylistThumbnails(currentPlaylistPath); + } } setCoreActions(); diff --git a/ui/drivers/qt/playlistthumbnaildownload.cpp b/ui/drivers/qt/playlistthumbnaildownload.cpp new file mode 100644 index 0000000000..985e7bb283 --- /dev/null +++ b/ui/drivers/qt/playlistthumbnaildownload.cpp @@ -0,0 +1,332 @@ +#include +#include +#include + +#include "../ui_qt.h" + +extern "C" { +#include +#include +#include +#include "../../../tasks/tasks_internal.h" +#include "../../../verbosity.h" +#include "../../../config.def.h" +#include "../../../configuration.h" +#include "../../../version.h" +} + +#define USER_AGENT "RetroArch-WIMP/" PACKAGE_VERSION +#define PARTIAL_EXTENSION ".partial" +#define THUMBNAIL_URL_HEADER "https://github.com/libretro-thumbnails/" +#define THUMBNAIL_URL_BRANCH "/blob/master/" +#define THUMBNAIL_IMAGE_EXTENSION ".png" +#define THUMBNAIL_URL_FOOTER THUMBNAIL_IMAGE_EXTENSION "?raw=true" + +void MainWindow::onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError /*code*/) +{ +} + +void MainWindow::onPlaylistThumbnailDownloadNetworkSslErrors(const QList &errors) +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + int i; + + if (!reply) + return; + + for (i = 0; i < errors.count(); i++) + { + const QSslError &error = errors.at(i); + QString string = QString("Ignoring SSL error code ") + QString::number(error.error()) + ": " + error.errorString(); + QByteArray stringArray = string.toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: %s\n", stringData); + } + + /* ignore all SSL errors for now, like self-signed, expired etc. */ + reply->ignoreSslErrors(); +} + +void MainWindow::onPlaylistThumbnailDownloadCanceled() +{ + m_playlistThumbnailDownloadProgressDialog->cancel(); +} + +void MainWindow::onPlaylistThumbnailDownloadFinished() +{ + QString playlistPath; + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + QNetworkReply::NetworkError error; + int code; + + if (!reply) + return; + + playlistPath = reply->property("playlist").toString(); + + error = reply->error(); + code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_playlistThumbnailDownloadFile.isOpen()) + m_playlistThumbnailDownloadFile.close(); + + if (code != 200) + { + QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + + if (!redirectUrl.isEmpty()) + { + QByteArray redirectUrlArray = redirectUrl.toString().toUtf8(); + const char *redirectUrlData = redirectUrlArray.constData(); + + /*RARCH_LOG("[Qt]: Thumbnail download got redirect with HTTP code %d: %s\n", code, redirectUrlData);*/ + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + downloadNextPlaylistThumbnail(reply->property("system").toString(), reply->property("title").toString(), reply->property("type").toString(), redirectUrl); + + return; + } + else + { + m_playlistThumbnailDownloadFile.remove(); + + m_failedThumbnails++; + + /*emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": HTTP Code " + QString::number(code)); + + RARCH_ERR("[Qt]: Thumbnail download failed with HTTP status code: %d\n", code); + + reply->disconnect(); + reply->abort(); + reply->deleteLater(); + + return;*/ + } + } + + if (error == QNetworkReply::NoError) + { + int index = m_playlistThumbnailDownloadFile.fileName().lastIndexOf(PARTIAL_EXTENSION); + QString newFileName = m_playlistThumbnailDownloadFile.fileName().left(index); + QFile newFile(newFileName); + + /* rename() requires the old file to be deleted first if it exists */ + if (newFile.exists() && !newFile.remove()) + { + m_failedThumbnails++; + RARCH_ERR("[Qt]: Thumbnail download finished, but old file could not be deleted.\n"); + } + else + { + if (m_playlistThumbnailDownloadFile.rename(newFileName)) + { + /*RARCH_LOG("[Qt]: Thumbnail download finished successfully.\n");*/ + m_downloadedThumbnails++; + } + else + { + /*RARCH_ERR("[Qt]: Thumbnail download finished, but temp file could not be renamed.\n"); + emit showErrorMessageDeferred(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_RENAME_FILE));*/ + m_failedThumbnails++; + } + } + } + else + { + /*QByteArray errorArray = reply->errorString().toUtf8(); + const char *errorData = errorArray.constData();*/ + + m_playlistThumbnailDownloadFile.remove(); + + m_failedThumbnails++; + + /*RARCH_ERR("[Qt]: Thumbnail download ended prematurely: %s\n", errorData); + emit showErrorMessageDeferred(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NETWORK_ERROR)) + ": Code " + QString::number(code) + ": " + errorData);*/ + } + + if (m_pendingPlaylistThumbnails.count() > 0) + { + QHash nextThumbnail = m_pendingPlaylistThumbnails.takeAt(0); + ViewType viewType = getCurrentViewType(); + + if (viewType == VIEW_TYPE_ICONS) + emit gridItemChanged(reply->property("title").toString()); + + downloadNextPlaylistThumbnail(nextThumbnail.value("db_name"), nextThumbnail.value("label_noext"), nextThumbnail.value("type")); + } + else + { + RARCH_LOG("[Qt]: Playlist thumbnails finished downloading.\n"); + /* update thumbnail */ + emit itemChanged(); + } + + reply->disconnect(); + reply->close(); + reply->deleteLater(); +} + +void MainWindow::onPlaylistThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + int progress = (bytesReceived / (float)bytesTotal) * 100.0f; + + if (!reply) + return; +} + +void MainWindow::onPlaylistThumbnailDownloadReadyRead() +{ + QNetworkReply *reply = m_playlistThumbnailDownloadReply.data(); + + if (!reply) + return; + + m_playlistThumbnailDownloadFile.write(reply->readAll()); +} + +void MainWindow::downloadNextPlaylistThumbnail(QString system, QString title, QString type, QUrl url) +{ + QString systemUnderscore = system; + QString urlString; + QNetworkReply *reply = NULL; + QNetworkRequest request; + settings_t *settings = config_get_ptr(); + + if (!settings) + return; + + systemUnderscore = systemUnderscore.replace(" ", "_"); + + urlString = QString(THUMBNAIL_URL_HEADER) + systemUnderscore + THUMBNAIL_URL_BRANCH + type + "/" + title + THUMBNAIL_URL_FOOTER; + + if (url.isEmpty()) + url = urlString; + + request.setUrl(url); + + if (m_playlistThumbnailDownloadFile.isOpen()) + { + RARCH_ERR("[Qt]: File is already open.\n"); + return; + } + else + { + QString dirString = QString(settings->paths.directory_thumbnails); + QString fileName = dirString + "/" + system + "/" + type + "/" + title + THUMBNAIL_IMAGE_EXTENSION + PARTIAL_EXTENSION; + QByteArray fileNameArray = fileName.toUtf8(); + QDir dir; + const char *fileNameData = fileNameArray.constData(); + + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_BOXART); + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_SCREENSHOT); + dir.mkpath(dirString + "/" + system + "/" + THUMBNAIL_TITLE); + + m_playlistThumbnailDownloadFile.setFileName(fileName); + + if (!m_playlistThumbnailDownloadFile.open(QIODevice::WriteOnly)) + { + m_playlistThumbnailDownloadProgressDialog->cancel(); + showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); + RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); + return; + } + } + + /*RARCH_LOG("[Qt]: Starting thumbnail download...\n"); + RARCH_LOG("[Qt]: Downloading URL %s\n", urlData);*/ + + request.setHeader(QNetworkRequest::UserAgentHeader, USER_AGENT); + + m_playlistThumbnailDownloadReply = m_networkManager->get(request); + + reply = m_playlistThumbnailDownloadReply.data(); + reply->setProperty("system", system); + reply->setProperty("title", title); + reply->setProperty("type", type); + + /* make sure any previous connection is removed first */ + disconnect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + disconnect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), m_playlistThumbnailDownloadProgressDialog, SLOT(cancel())); + connect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), reply, SLOT(abort())); + connect(m_playlistThumbnailDownloadProgressDialog, SIGNAL(canceled()), m_playlistThumbnailDownloadProgressDialog, SLOT(cancel())); + + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError))); + connect(reply, SIGNAL(sslErrors(const QList&)), this, SLOT(onPlaylistThumbnailDownloadNetworkSslErrors(const QList&))); + connect(reply, SIGNAL(finished()), this, SLOT(onPlaylistThumbnailDownloadFinished())); + connect(reply, SIGNAL(readyRead()), this, SLOT(onPlaylistThumbnailDownloadReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onPlaylistThumbnailDownloadProgress(qint64, qint64))); + + m_playlistThumbnailDownloadProgressDialog->setValue(m_playlistThumbnailDownloadProgressDialog->maximum() - m_pendingPlaylistThumbnails.count()); + + { + QString labelText = QString(msg_hash_to_str(MSG_DOWNLOADING)) + "...\n"; + + labelText += QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DOWNLOAD_PLAYLIST_THUMBNAIL_PROGRESS)).arg(m_downloadedThumbnails).arg(m_failedThumbnails); + + m_playlistThumbnailDownloadProgressDialog->setLabelText(labelText); + } +} + +void MainWindow::downloadPlaylistThumbnails(QString playlistPath) +{ + QFile playlistFile(playlistPath); + QString system; + QString title; + QString type; + QVector > playlistItems = getPlaylistItems(playlistPath); + settings_t *settings = config_get_ptr(); + int i; + + if (!settings || !playlistFile.exists()) + return; + + m_pendingPlaylistThumbnails.clear(); + m_downloadedThumbnails = 0; + m_failedThumbnails = 0; + + if (playlistItems.count() == 0) + return; + + for (i = 0; i < playlistItems.count(); i++) + { + const QHash &itemHash = playlistItems.at(i); + QHash hash; + QHash hash2; + QHash hash3; + + hash["db_name"] = itemHash.value("db_name"); + hash["label_noext"] = itemHash.value("label_noext"); + hash["type"] = THUMBNAIL_BOXART; + + hash2 = hash; + hash3 = hash; + + hash2["type"] = THUMBNAIL_SCREENSHOT; + hash3["type"] = THUMBNAIL_TITLE; + + m_pendingPlaylistThumbnails.append(hash); + m_pendingPlaylistThumbnails.append(hash2); + m_pendingPlaylistThumbnails.append(hash3); + } + + m_playlistThumbnailDownloadProgressDialog->setWindowModality(Qt::NonModal); + m_playlistThumbnailDownloadProgressDialog->setMinimumDuration(0); + m_playlistThumbnailDownloadProgressDialog->setRange(0, m_pendingPlaylistThumbnails.count()); + m_playlistThumbnailDownloadProgressDialog->setAutoClose(true); + m_playlistThumbnailDownloadProgressDialog->setAutoReset(true); + m_playlistThumbnailDownloadProgressDialog->setValue(0); + m_playlistThumbnailDownloadProgressDialog->setLabelText(QString(msg_hash_to_str(MSG_DOWNLOADING)) + "..."); + m_playlistThumbnailDownloadProgressDialog->setCancelButtonText(tr("Cancel")); + m_playlistThumbnailDownloadProgressDialog->show(); + + { + QHash firstThumbnail = m_pendingPlaylistThumbnails.takeAt(0); + + /* Start downloading the first thumbnail, the rest will download as each one finishes. */ + downloadNextPlaylistThumbnail(firstThumbnail.value("db_name"), firstThumbnail.value("label_noext"), firstThumbnail.value("type")); + } +} diff --git a/ui/drivers/qt/thumbnaildownload.cpp b/ui/drivers/qt/thumbnaildownload.cpp index ea4ea48839..f70ffcd13a 100644 --- a/ui/drivers/qt/thumbnaildownload.cpp +++ b/ui/drivers/qt/thumbnaildownload.cpp @@ -17,7 +17,6 @@ extern "C" { #define USER_AGENT "RetroArch-WIMP/" PACKAGE_VERSION #define PARTIAL_EXTENSION ".partial" -#define TEMP_EXTENSION ".tmp" #define THUMBNAIL_URL_HEADER "https://github.com/libretro-thumbnails/" #define THUMBNAIL_URL_BRANCH "/blob/master/" #define THUMBNAIL_IMAGE_EXTENSION ".png" @@ -255,6 +254,7 @@ void MainWindow::downloadThumbnail(QString system, QString title, QUrl url) if (!m_thumbnailDownloadFile.open(QIODevice::WriteOnly)) { + m_thumbnailDownloadProgressDialog->cancel(); showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); return; diff --git a/ui/drivers/qt/thumbnailpackdownload.cpp b/ui/drivers/qt/thumbnailpackdownload.cpp index 75de1a6016..8fad5548f9 100644 --- a/ui/drivers/qt/thumbnailpackdownload.cpp +++ b/ui/drivers/qt/thumbnailpackdownload.cpp @@ -255,6 +255,7 @@ void MainWindow::downloadAllThumbnails(QString system, QUrl url) if (!m_thumbnailPackDownloadFile.open(QIODevice::WriteOnly)) { + m_thumbnailPackDownloadProgressDialog->cancel(); showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_WRITE_OPEN_FAILED), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); RARCH_ERR("[Qt]: Could not open file for writing: %s\n", fileNameData); return; diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index c84ae8f878..b0bbc26cce 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -327,6 +327,12 @@ MainWindow::MainWindow(QWidget *parent) : ,m_thumbnailPackDownloadProgressDialog(new QProgressDialog()) ,m_thumbnailPackDownloadFile() ,m_thumbnailPackDownloadReply() + ,m_playlistThumbnailDownloadProgressDialog(new QProgressDialog()) + ,m_playlistThumbnailDownloadFile() + ,m_playlistThumbnailDownloadReply() + ,m_pendingPlaylistThumbnails() + ,m_downloadedThumbnails(0) + ,m_failedThumbnails(0) { settings_t *settings = config_get_ptr(); QDir playlistDir(settings->paths.directory_playlist); @@ -351,6 +357,7 @@ MainWindow::MainWindow(QWidget *parent) : m_updateProgressDialog->cancel(); m_thumbnailDownloadProgressDialog->cancel(); m_thumbnailPackDownloadProgressDialog->cancel(); + m_playlistThumbnailDownloadProgressDialog->cancel(); m_gridProgressWidget = new QWidget(); gridProgressLabel = new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PROGRESS), m_gridProgressWidget); @@ -549,6 +556,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_gridLayoutWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onFileDropWidgetContextMenuRequested(const QPoint&))); connect(this, SIGNAL(itemChanged()), this, SLOT(onItemChanged())); + connect(this, SIGNAL(gridItemChanged(QString)), this, SLOT(onGridItemChanged(QString))); connect(this, SIGNAL(gotThumbnailDownload(QString,QString)), this, SLOT(onDownloadThumbnail(QString,QString))); /* make sure these use an auto connection so it will be queued if called from a different thread (some facilities in RA log messages from other threads) */ @@ -639,6 +647,23 @@ QVector > MainWindow::getPlaylists() return playlists; } +void MainWindow::onGridItemChanged(QString title) +{ + int i; + + for (i = 0; i < m_gridItems.count(); i++) + { + const QPointer &item = m_gridItems.at(i); + const QHash &hash = item->hash; + + if (hash.value("label_noext") == title) + { + loadImageDeferred(item.data(), item->widget->property("image_path").toString()); + break; + } + } +} + void MainWindow::onItemChanged() { ViewType viewType = getCurrentViewType(); diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index 656d5bd967..fd9375ffe6 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -300,6 +300,7 @@ signals: void showInfoMessageDeferred(QString msg); void extractArchiveDeferred(QString path, QString extractionDir, QString tempExtension, retro_task_callback_t cb); void itemChanged(); + void gridItemChanged(QString title); void gotThumbnailDownload(QString system, QString title); public slots: @@ -342,6 +343,8 @@ public slots: void deferReloadShaderParams(); void downloadThumbnail(QString system, QString title, QUrl url = QUrl()); void downloadAllThumbnails(QString system, QUrl url = QUrl()); + void downloadPlaylistThumbnails(QString playlistPath); + void downloadNextPlaylistThumbnail(QString system, QString title, QString type, QUrl url = QUrl()); private slots: void onLoadCoreClicked(const QStringList &extensionFilters = QStringList()); @@ -378,6 +381,7 @@ private slots: void onShowInfoMessage(QString msg); void onContributorsClicked(); void onItemChanged(); + void onGridItemChanged(QString title); int onExtractArchive(QString path, QString extractionDir, QString tempExtension, retro_task_callback_t cb); void onUpdateNetworkError(QNetworkReply::NetworkError code); @@ -402,6 +406,13 @@ private slots: void onThumbnailPackDownloadReadyRead(); void onThumbnailPackDownloadCanceled(); + void onPlaylistThumbnailDownloadNetworkError(QNetworkReply::NetworkError code); + void onPlaylistThumbnailDownloadNetworkSslErrors(const QList &errors); + void onPlaylistThumbnailDownloadFinished(); + void onPlaylistThumbnailDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void onPlaylistThumbnailDownloadReadyRead(); + void onPlaylistThumbnailDownloadCanceled(); + private: void setCurrentCoreLabel(); void getPlaylistFiles(); @@ -489,6 +500,13 @@ private: QFile m_thumbnailPackDownloadFile; QPointer m_thumbnailPackDownloadReply; + QProgressDialog *m_playlistThumbnailDownloadProgressDialog; + QFile m_playlistThumbnailDownloadFile; + QPointer m_playlistThumbnailDownloadReply; + QVector > m_pendingPlaylistThumbnails; + unsigned m_downloadedThumbnails; + unsigned m_failedThumbnails; + protected: void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event);