diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index b6618adec9..bf64fd5614 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -1266,6 +1266,109 @@ void MainWindow::changeThumbnailType(ThumbnailType type) m_gridView->viewport()->update(); } +QString MainWindow::changeThumbnail(const QImage &image, QString type) +{ + QHash hash = getCurrentContentHash(); + QString label = hash["label_noext"]; + QString dirString = QDir::cleanPath(QString(config_get_ptr()->paths.directory_thumbnails)) + "/" + hash["db_name"] + "/" + type; + QString thumbPath = dirString + "/" + label.replace(m_fileSanitizerRegex, "_") + ".png"; + QByteArray dirArray = QDir::toNativeSeparators(dirString).toUtf8(); + const char *dirData = dirArray.constData(); + QByteArray thumbArray = QDir::toNativeSeparators(thumbPath).toUtf8(); + const char *thumbData = thumbArray.constData(); + QDir dir(dirString); + int quality = -1; + QImage scaledImage(image); + + if (!dir.exists()) + { + if (dir.mkpath(".")) + RARCH_LOG("[Qt]: Created directory: %s\n", dirData); + else + { + RARCH_ERR("[Qt]: Could not create directory: %s\n", dirData); + return QString(); + } + } + + if (m_settings->contains("thumbnail_max_size")) + { + int size = m_settings->value("thumbnail_max_size", 512).toInt(); + + if (size != 0) + scaledImage = image.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + + if (m_settings->contains("thumbnail_quality")) + quality = m_settings->value("thumbnail_quality", -1).toInt(); + + if (scaledImage.save(thumbPath, "png", quality)) + { + RARCH_LOG("[Qt]: Saved image: %s\n", thumbData); + m_playlistModel->reloadThumbnailPath(thumbPath); + updateVisibleItems(); + + return thumbPath; + } + + RARCH_ERR("[Qt]: Could not save image: %s\n", thumbData); + return QString(); +} + +void MainWindow::onThumbnailDropped(const QImage &image, ThumbnailType thumbnailType) +{ + switch (thumbnailType) + { + case THUMBNAIL_TYPE_BOXART: + { + QString path = changeThumbnail(image, THUMBNAIL_BOXART); + + if (path.isNull()) + return; + + if (m_thumbnailPixmap) + delete m_thumbnailPixmap; + + m_thumbnailPixmap = new QPixmap(path); + + onResizeThumbnailOne(); + break; + } + + case THUMBNAIL_TYPE_TITLE_SCREEN: + { + QString path = changeThumbnail(image, THUMBNAIL_TITLE); + + if (path.isNull()) + return; + + if (m_thumbnailPixmap2) + delete m_thumbnailPixmap2; + + m_thumbnailPixmap2 = new QPixmap(path); + + onResizeThumbnailTwo(); + break; + } + + case THUMBNAIL_TYPE_SCREENSHOT: + { + QString path = changeThumbnail(image, THUMBNAIL_SCREENSHOT); + + if (path.isNull()) + return; + + if (m_thumbnailPixmap3) + delete m_thumbnailPixmap3; + + m_thumbnailPixmap3 = new QPixmap(path); + + onResizeThumbnailThree(); + break; + } + } +} + QVector > MainWindow::getCoreInfo() { QVector > infoList; @@ -2108,6 +2211,22 @@ void MainWindow::setCoreActions() } } +void MainWindow::setThumbnailsAcceptDrops(bool accept) +{ + ThumbnailWidget *thumbnail = findChild("thumbnail1Widget"); + ThumbnailWidget *thumbnail2 = findChild("thumbnail2Widget"); + ThumbnailWidget *thumbnail3 = findChild("thumbnail3Widget"); + + if (thumbnail) + thumbnail->setAcceptDrops(accept); + + if (thumbnail2) + thumbnail2->setAcceptDrops(accept); + + if (thumbnail3) + thumbnail3->setAcceptDrops(accept); +} + void MainWindow::onTabWidgetIndexChanged(int index) { if (m_browserAndPlaylistTabWidget->tabText(index) == msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_TAB_FILE_BROWSER)) @@ -2432,12 +2551,22 @@ void MainWindow::onCurrentItemChanged(const QHash &hash) m_thumbnailPixmap = new QPixmap(hash["path"]); m_thumbnailPixmap2 = new QPixmap(*m_thumbnailPixmap); m_thumbnailPixmap3 = new QPixmap(*m_thumbnailPixmap); + + setThumbnailsAcceptDrops(false); } else { m_thumbnailPixmap = new QPixmap(QString(settings->paths.directory_thumbnails) + "/" + playlist_name + "/" + THUMBNAIL_BOXART + "/" + label + ".png"); m_thumbnailPixmap2 = new QPixmap(QString(settings->paths.directory_thumbnails) + "/" + playlist_name + "/" + THUMBNAIL_TITLE + "/" + label + ".png"); m_thumbnailPixmap3 = new QPixmap(QString(settings->paths.directory_thumbnails) + "/" + playlist_name + "/" + THUMBNAIL_SCREENSHOT + "/" + label + ".png"); + + if (m_currentBrowser == BROWSER_TYPE_PLAYLISTS) + { + if (currentPlaylistIsSpecial()) + setThumbnailsAcceptDrops(false); + else + setThumbnailsAcceptDrops(true); + } } resizeThumbnails(true, true, true); diff --git a/ui/drivers/ui_qt.cpp b/ui/drivers/ui_qt.cpp index 9cf8e0ed45..e499a43ddb 100644 --- a/ui/drivers/ui_qt.cpp +++ b/ui/drivers/ui_qt.cpp @@ -63,9 +63,10 @@ typedef struct ui_companion_qt ui_window_qt_t *window; } ui_companion_qt_t; -ThumbnailWidget::ThumbnailWidget(QWidget *parent) : +ThumbnailWidget::ThumbnailWidget(ThumbnailType type, QWidget *parent) : QFrame(parent) ,m_sizeHint(QSize(256, 256)) + ,m_thumbnailType(type) { } @@ -111,6 +112,40 @@ void ThumbnailWidget::setSizeHint(QSize size) m_sizeHint = size; } +void ThumbnailWidget::dragEnterEvent(QDragEnterEvent *event) +{ + const QMimeData *data = event->mimeData(); + + if (data->hasUrls()) + event->acceptProposedAction(); +} + +/* Workaround for QTBUG-72844. Without it, you can't drop on this if you first drag over another widget that doesn't accept drops. */ +void ThumbnailWidget::dragMoveEvent(QDragMoveEvent *event) +{ + event->acceptProposedAction(); +} + +void ThumbnailWidget::dropEvent(QDropEvent *event) +{ + const QMimeData *data = event->mimeData(); + + if (data->hasUrls()) + { + const QString imageString = data->urls().at(0).toLocalFile(); + const QImage image(imageString); + + if (!image.isNull()) + emit(filesDropped(image, m_thumbnailType)); + else + { + QByteArray stringArray = QDir::toNativeSeparators(imageString).toUtf8(); + const char *stringData = stringArray.constData(); + RARCH_ERR("[Qt]: Could not read image: %s\n", stringData); + } + } +} + ThumbnailLabel::ThumbnailLabel(QWidget *parent) : QWidget(parent) ,m_pixmap(NULL) @@ -403,9 +438,14 @@ static void* ui_companion_qt_init(void) browserButtonsHBoxLayout->addItem(new QSpacerItem(browserAndPlaylistTabWidget->tabBar()->width(), 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); - thumbnailWidget = new ThumbnailWidget(); - thumbnail2Widget = new ThumbnailWidget(); - thumbnail3Widget = new ThumbnailWidget(); + thumbnailWidget = new ThumbnailWidget(THUMBNAIL_TYPE_BOXART); + thumbnailWidget->setObjectName("thumbnail1Widget"); + + thumbnail2Widget = new ThumbnailWidget(THUMBNAIL_TYPE_TITLE_SCREEN); + thumbnail2Widget->setObjectName("thumbnail2Widget"); + + thumbnail3Widget = new ThumbnailWidget(THUMBNAIL_TYPE_SCREENSHOT); + thumbnail3Widget->setObjectName("thumbnail3Widget"); thumbnailWidget->setLayout(new QVBoxLayout()); thumbnail2Widget->setLayout(new QVBoxLayout()); @@ -415,6 +455,10 @@ static void* ui_companion_qt_init(void) thumbnail2Widget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); thumbnail3Widget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + QObject::connect(thumbnailWidget, SIGNAL(filesDropped(const QImage&, ThumbnailType)), mainwindow, SLOT(onThumbnailDropped(const QImage&, ThumbnailType))); + QObject::connect(thumbnail2Widget, SIGNAL(filesDropped(const QImage&, ThumbnailType)), mainwindow, SLOT(onThumbnailDropped(const QImage&, ThumbnailType))); + QObject::connect(thumbnail3Widget, SIGNAL(filesDropped(const QImage&, ThumbnailType)), mainwindow, SLOT(onThumbnailDropped(const QImage&, ThumbnailType))); + thumbnail = new ThumbnailLabel(); thumbnail->setObjectName("thumbnail"); diff --git a/ui/drivers/ui_qt.h b/ui/drivers/ui_qt.h index cad3009d9e..36ab03b338 100644 --- a/ui/drivers/ui_qt.h +++ b/ui/drivers/ui_qt.h @@ -42,7 +42,6 @@ #include #include #include -#include #include "qt/filedropwidget.h" @@ -168,6 +167,7 @@ class ThumbnailWidget : public QFrame Q_OBJECT public: ThumbnailWidget(QWidget *parent = 0); + ThumbnailWidget(ThumbnailType type, QWidget *parent = 0); ThumbnailWidget(const ThumbnailWidget& other) { retro_assert(false && "DONT EVER USE THIS"); } QSize sizeHint() const; @@ -175,13 +175,18 @@ public: signals: void mouseDoubleClicked(); void mousePressed(); + void filesDropped(const QImage& image, ThumbnailType type); private: QSize m_sizeHint; + ThumbnailType m_thumbnailType; protected: void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); }; class ThumbnailLabel : public QWidget @@ -457,6 +462,7 @@ public slots: void downloadPlaylistThumbnails(QString playlistPath); void downloadNextPlaylistThumbnail(QString system, QString title, QString type, QUrl url = QUrl()); void changeThumbnailType(ThumbnailType type); + void onThumbnailDropped(const QImage &image, ThumbnailType type); private slots: void onLoadCoreClicked(const QStringList &extensionFilters = QStringList()); @@ -540,6 +546,8 @@ private: bool currentPlaylistIsAll(); void applySearch(); void updateItemsCount(); + void setThumbnailsAcceptDrops(bool accept); + QString changeThumbnail(const QImage &image, QString type); PlaylistModel *m_playlistModel; QSortFilterProxyModel *m_proxyModel;