From 2b4bbc91a707b1a13932f1d44859e7be0dfc6573 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Tue, 9 Feb 2021 14:19:09 +0800 Subject: [PATCH] fix: should now be able to show property dialog for all supported files --- CMakeLists.txt | 2 + app/graphicsview.cpp | 9 +-- app/graphicsview.h | 2 +- app/main.cpp | 11 ++- app/mainwindow.cpp | 94 +++++++++--------------- app/mainwindow.h | 9 +-- app/playlistmanager.cpp | 153 ++++++++++++++++++++++++++++++++++++++++ app/playlistmanager.h | 44 ++++++++++++ 8 files changed, 243 insertions(+), 81 deletions(-) create mode 100644 app/playlistmanager.cpp create mode 100644 app/playlistmanager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 69a3605..2a0e9ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set (PPIC_CPP_FILES app/metadatamodel.cpp app/metadatadialog.cpp app/exiv2wrapper.cpp + app/playlistmanager.cpp ) set (PPIC_HEADER_FILES @@ -61,6 +62,7 @@ set (PPIC_HEADER_FILES app/metadatamodel.h app/metadatadialog.h app/exiv2wrapper.h + app/playlistmanager.h ) set (PPIC_QRC_FILES diff --git a/app/graphicsview.cpp b/app/graphicsview.cpp index c61dc04..f47cf06 100644 --- a/app/graphicsview.cpp +++ b/app/graphicsview.cpp @@ -25,12 +25,10 @@ GraphicsView::GraphicsView(QWidget *parent) connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &GraphicsView::viewportRectChanged); } -void GraphicsView::showFileFromUrl(const QUrl &url, bool doRequestGallery) +void GraphicsView::showFileFromPath(const QString &filePath, bool doRequestGallery) { emit navigatorViewRequired(false, 0); - QString filePath(url.toLocalFile()); - if (filePath.endsWith(".svg")) { showSvg(filePath); } else if (filePath.endsWith(".gif")) { @@ -43,12 +41,15 @@ void GraphicsView::showFileFromUrl(const QUrl &url, bool doRequestGallery) // So we cannot use imageFormat() and check if it returns QImage::Format_Invalid to detect if we support the file. // QImage::Format imageFormat = imageReader.imageFormat(); if (imageReader.format().isEmpty()) { + doRequestGallery = false; showText(tr("File is not a valid image")); } else if (!imageReader.supportsAnimation() && !imageReader.canRead()) { + doRequestGallery = false; showText(tr("Image data is invalid or currently unsupported")); } else { const QPixmap & pixmap = QPixmap::fromImageReader(&imageReader); if (pixmap.isNull()) { + doRequestGallery = false; showText(tr("Image data is invalid or currently unsupported")); } else { showImage(pixmap); @@ -253,7 +254,7 @@ void GraphicsView::dropEvent(QDropEvent *event) if (urls.isEmpty()) { showText(tr("File url list is empty")); } else { - showFileFromUrl(urls.first(), true); + showFileFromPath(urls.first().toLocalFile(), true); } } else if (mimeData->hasImage()) { QImage img = qvariant_cast(mimeData->imageData()); diff --git a/app/graphicsview.h b/app/graphicsview.h index f942562..b3234e6 100644 --- a/app/graphicsview.h +++ b/app/graphicsview.h @@ -11,7 +11,7 @@ class GraphicsView : public QGraphicsView public: GraphicsView(QWidget *parent = nullptr); - void showFileFromUrl(const QUrl &url, bool requestGallery = false); + void showFileFromPath(const QString &filePath, bool requestGallery = false); void showImage(const QPixmap &pixmap); void showImage(const QImage &image); diff --git a/app/main.cpp b/app/main.cpp index 73c19dc..be7be91 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,4 +1,7 @@ #include "mainwindow.h" + +#include "playlistmanager.h" + #include #include #include @@ -35,13 +38,7 @@ int main(int argc, char *argv[]) parser.process(a); QStringList urlStrList = parser.positionalArguments(); - QList urlList; - for (const QString & str : qAsConst(urlStrList)) { - QUrl url = QUrl::fromLocalFile(str); - if (url.isValid()) { - urlList.append(url); - } - } + QList && urlList = PlaylistManager::convertToUrlList(urlStrList); MainWindow w; w.show(); diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 60331ad..e84774c 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -11,6 +11,7 @@ #include "metadatamodel.h" #include "metadatadialog.h" #include "actionmanager.h" +#include "playlistmanager.h" #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +31,7 @@ MainWindow::MainWindow(QWidget *parent) : FramelessWindow(parent) , m_am(new ActionManager) + , m_pm(new PlaylistManager(PlaylistManager::PL_SAMEFOLDER, this)) { if (Settings::instance()->stayOnTop()) { this->setWindowFlag(Qt::WindowStaysOnTopHint); @@ -128,9 +129,9 @@ MainWindow::MainWindow(QWidget *parent) m_gv->setOpacity(0, false); m_closeButton->setOpacity(0, false); - connect(this, &MainWindow::galleryLoaded, this, [this]() { - m_prevButton->setVisible(isGalleryAvailable()); - m_nextButton->setVisible(isGalleryAvailable()); + connect(m_pm, &PlaylistManager::loaded, this, [this](int galleryFileCount) { + m_prevButton->setVisible(galleryFileCount > 1); + m_nextButton->setVisible(galleryFileCount > 1); }); QShortcut * prevPictureShorucut = new QShortcut(QKeySequence(Qt::Key_PageUp), this); @@ -163,11 +164,11 @@ void MainWindow::showUrls(const QList &urls) { if (!urls.isEmpty()) { if (urls.count() == 1) { - m_graphicsView->showFileFromUrl(urls.first(), true); + m_graphicsView->showFileFromPath(urls.first().toLocalFile(), true); } else { - m_graphicsView->showFileFromUrl(urls.first(), false); - m_files = urls; - m_currentFileIndex = 0; + m_graphicsView->showFileFromPath(urls.first().toLocalFile(), false); + m_pm->setPlaylist(urls); + m_pm->setCurrentIndex(0); } } else { m_graphicsView->showText(tr("File url list is empty")); @@ -208,77 +209,44 @@ void MainWindow::adjustWindowSizeBySceneRect() // can be empty if it is NOT from a local file. QUrl MainWindow::currentImageFileUrl() const { - if (m_currentFileIndex != -1) { - return m_files.value(m_currentFileIndex); - } + QUrl url; + std::tie(std::ignore, url) = m_pm->currentFileUrl(); - return QUrl(); + return url; } void MainWindow::clearGallery() { - m_currentFileIndex = -1; - m_files.clear(); + m_pm->clear(); } void MainWindow::loadGalleryBySingleLocalFile(const QString &path) { - QFileInfo info(path); - QDir dir(info.path()); - QString currentFileName = info.fileName(); - QStringList entryList = dir.entryList({"*.jpg", "*.jpeg", "*.jfif", "*.png", "*.gif", "*.svg", "*.bmp"}, - QDir::Files | QDir::NoSymLinks, QDir::NoSort); - - QCollator collator; - collator.setNumericMode(true); - - std::sort(entryList.begin(), entryList.end(), collator); - - clearGallery(); - - for (int i = 0; i < entryList.count(); i++) { - const QString & fileName = entryList.at(i); - const QString & oneEntry = dir.absoluteFilePath(fileName); - const QUrl & url = QUrl::fromLocalFile(oneEntry); - m_files.append(url); - if (fileName == currentFileName) { - m_currentFileIndex = i; - } - } - - emit galleryLoaded(); + m_pm->setCurrentFile(path); } void MainWindow::galleryPrev() { - int count = m_files.count(); - if (!isGalleryAvailable()) { - return; + int index; + QString filePath; + std::tie(index, filePath) = m_pm->previousFile(); + + if (index >= 0) { + m_graphicsView->showFileFromPath(filePath, false); + m_pm->setCurrentIndex(index); } - - m_currentFileIndex = m_currentFileIndex - 1 < 0 ? count - 1 : m_currentFileIndex - 1; - - m_graphicsView->showFileFromUrl(m_files.at(m_currentFileIndex), false); } void MainWindow::galleryNext() { - int count = m_files.count(); - if (!isGalleryAvailable()) { - return; + int index; + QString filePath; + std::tie(index, filePath) = m_pm->nextFile(); + + if (index >= 0) { + m_graphicsView->showFileFromPath(filePath, false); + m_pm->setCurrentIndex(index); } - - m_currentFileIndex = m_currentFileIndex + 1 == count ? 0 : m_currentFileIndex + 1; - - m_graphicsView->showFileFromUrl(m_files.at(m_currentFileIndex), false); -} - -bool MainWindow::isGalleryAvailable() -{ - if (m_currentFileIndex < 0 || m_files.isEmpty() || m_currentFileIndex >= m_files.count()) { - return false; - } - return true; } void MainWindow::showEvent(QShowEvent *event) @@ -601,10 +569,12 @@ void MainWindow::on_actionPaste_triggered() } if (!clipboardImage.isNull()) { - clearGallery(); m_graphicsView->showImage(clipboardImage); + clearGallery(); } else if (clipboardFileUrl.isValid()) { - m_graphicsView->showFileFromUrl(clipboardFileUrl, true); + QString localFile(clipboardFileUrl.toLocalFile()); + m_graphicsView->showFileFromPath(localFile, true); + m_pm->setCurrentFile(localFile); } } diff --git a/app/mainwindow.h b/app/mainwindow.h index b32be48..73d9eff 100644 --- a/app/mainwindow.h +++ b/app/mainwindow.h @@ -13,6 +13,7 @@ class QGraphicsView; QT_END_NAMESPACE class ActionManager; +class PlaylistManager; class ToolButton; class GraphicsView; class NavigatorView; @@ -33,10 +34,6 @@ public: void loadGalleryBySingleLocalFile(const QString &path); void galleryPrev(); void galleryNext(); - bool isGalleryAvailable(); - -signals: - void galleryLoaded(); protected slots: void showEvent(QShowEvent *event) override; @@ -77,6 +74,7 @@ private slots: private: ActionManager *m_am; + PlaylistManager *m_pm; QPoint m_oldMousePos; QPropertyAnimation *m_fadeOutAnimation; @@ -90,9 +88,6 @@ private: BottomButtonGroup *m_bottomButtonGroup; bool m_protectedMode = false; bool m_clickedOnWindow = false; - - QList m_files; - int m_currentFileIndex = -1; }; #endif // MAINWINDOW_H diff --git a/app/playlistmanager.cpp b/app/playlistmanager.cpp new file mode 100644 index 0000000..6afbcbf --- /dev/null +++ b/app/playlistmanager.cpp @@ -0,0 +1,153 @@ +#include "playlistmanager.h" + +#include +#include +#include +#include + +PlaylistManager::PlaylistManager(PlaylistType type, QObject *parent) + : QObject(parent) + , m_type(type) +{ + +} + +PlaylistManager::~PlaylistManager() +{ + +} + +void PlaylistManager::setPlaylistType(PlaylistManager::PlaylistType type) +{ + m_type = type; +} + +PlaylistManager::PlaylistType PlaylistManager::playlistType() const +{ + return m_type; +} + +void PlaylistManager::clear() +{ + m_currentIndex = -1; + m_playlist.clear(); +} + +void PlaylistManager::setPlaylist(const QList &urls) +{ + m_playlist = urls; +} + +void PlaylistManager::setCurrentFile(const QString & filePath) +{ + QFileInfo info(filePath); + QDir dir(info.path()); + QString && currentFileName = info.fileName(); + + switch (playlistType()) { + case PL_SAMEFOLDER: { + if (dir.path() == m_currentDir) { + int index = indexOf(filePath); + m_currentIndex = index == -1 ? appendFile(filePath) : index; + } else { + QStringList entryList = dir.entryList({"*.jpg", "*.jpeg", "*.jfif", "*.png", "*.gif", "*.svg", "*.bmp"}, + QDir::Files | QDir::NoSymLinks, QDir::NoSort); + + QCollator collator; + collator.setNumericMode(true); + + std::sort(entryList.begin(), entryList.end(), collator); + + clear(); + + int index = -1; + for (int i = 0; i < entryList.count(); i++) { + const QString & fileName = entryList.at(i); + const QString & oneEntry = dir.absoluteFilePath(fileName); + const QUrl & url = QUrl::fromLocalFile(oneEntry); + m_playlist.append(url); + if (fileName == currentFileName) { + index = i; + } + } + m_currentIndex = index == -1 ? appendFile(filePath) : index; + m_currentDir = dir.path(); + } + break; + } + case PL_USERPLAYLIST:{ + int index = indexOf(filePath); + m_currentIndex = index == -1 ? appendFile(filePath) : index; + break; + } + default: + break; + } + + emit loaded(m_playlist.count()); +} + +void PlaylistManager::setCurrentIndex(int index) +{ + if (index < 0 || index >= m_playlist.count()) return; + m_currentIndex = index; +} + +int PlaylistManager::appendFile(const QString &filePath) +{ + int index = m_playlist.length(); + m_playlist.append(QUrl::fromLocalFile(filePath)); + + return index; +} + +int PlaylistManager::indexOf(const QString &filePath) +{ + const QUrl & url = QUrl::fromLocalFile(filePath); + return m_playlist.indexOf(url); +} + +std::tuple PlaylistManager::previousFile() const +{ + int count = m_playlist.count(); + if (count == 0) return std::make_tuple(-1, QString()); + + int index = m_currentIndex - 1 < 0 ? count - 1 : m_currentIndex - 1; + return std::make_tuple(index, m_playlist.at(index).toLocalFile()); +} + +std::tuple PlaylistManager::nextFile() const +{ + int count = m_playlist.count(); + if (count == 0) return std::make_tuple(-1, QString()); + + int index = m_currentIndex + 1 == count ? 0 : m_currentIndex + 1; + return std::make_tuple(index, m_playlist.at(index).toLocalFile()); +} + +std::tuple PlaylistManager::currentFile() const +{ + if (m_playlist.count() == 0) return std::make_tuple(-1, QString()); + + return std::make_tuple(m_currentIndex, m_playlist.at(m_currentIndex).toLocalFile()); +} + +std::tuple PlaylistManager::currentFileUrl() const +{ + if (m_playlist.count() == 0) return std::make_tuple(-1, QUrl()); + + return std::make_tuple(m_currentIndex, m_playlist.at(m_currentIndex)); +} + +QList PlaylistManager::convertToUrlList(const QStringList &files) +{ + QList urlList; + for (const QString & str : qAsConst(files)) { + QUrl url = QUrl::fromLocalFile(str); + if (url.isValid()) { + urlList.append(url); + } + } + + return urlList; +} diff --git a/app/playlistmanager.h b/app/playlistmanager.h new file mode 100644 index 0000000..4d72690 --- /dev/null +++ b/app/playlistmanager.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +class PlaylistManager : public QObject +{ + Q_OBJECT +public: + enum PlaylistType { + PL_USERPLAYLIST, // Regular playlist, managed by user. + PL_SAMEFOLDER // PlaylistManager managed playlist, loaded from files from same folder. + }; + + explicit PlaylistManager(PlaylistType type = PL_USERPLAYLIST, QObject *parent = nullptr); + ~PlaylistManager(); + + void setPlaylistType(PlaylistType type); + PlaylistType playlistType() const; + + void clear(); + + void setPlaylist(const QList & urls); + void setCurrentFile(const QString & filePath); + void setCurrentIndex(int index); + int appendFile(const QString & filePath); + int indexOf(const QString & filePath); + + std::tuple previousFile() const; + std::tuple nextFile() const; + std::tuple currentFile() const; + std::tuple currentFileUrl() const; + + static QList convertToUrlList(const QStringList & files); + +signals: + void loaded(int length); + +private: + QList m_playlist; + PlaylistType m_type; + QString m_currentDir; + int m_currentIndex = -1; +}; +