diff --git a/CHANGELOG.md b/CHANGELOG.md index 472ea6d7..c899522a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,11 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * New setting in Comic Vine scraper to force exact volume matches. * Better default search query in the Comic Vine scraper. * Improved navigation in Comic Vine scraper, including keeping the current query around to make edits and refined searches easier. -* Add support for adding custom covers for folders using the context menu. +* Add support for custom covers for any folder using the context menu. +* The edit cover buttons now support looping through pages, going forward from the last returns to the first, and going backward from the first jumps to the last. +* Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog. +* Covers can be set in bulk for various comics at once. +* New button to reset to the default cover of a comic. ### YACReaderLibraryServer * Log libraries validation when the app starts. diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 8ae9df1c..56e90257 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -43,6 +43,7 @@ ../images/flow4.png ../images/flow5.png ../images/glowLine.png + ../images/loadCustomCover.svg ../images/hiddenCovers.png ../images/icon-new.svg ../images/iconLibrary.png @@ -70,6 +71,7 @@ ../images/previousCoverPage.png ../images/readingRibbon.png ../images/readRibbon.png + ../images/resetCover.svg ../images/searching_icon.png ../images/serverConfigBackground.png ../images/shortcuts_group_comics.svg diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 48ef18ef..5ed2f4fc 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -1,6 +1,7 @@ #include "library_window.h" #include "yacreader_global.h" +#include "yacreader_global_gui.h" #include #include @@ -2313,12 +2314,7 @@ void LibraryWindow::setFolderCover() void LibraryWindow::setCustomFolderCover(Folder folder) { - QString supportedImageFormatsString; - for (const QByteArray &format : QImageReader::supportedImageFormats()) { - supportedImageFormatsString += QString("*.%1 ").arg(QString(format)); - } - - QString customCoverPath = QFileDialog::getOpenFileName(this, tr("Select custom cover"), QDir::homePath(), tr("Images (%1)").arg(supportedImageFormatsString)); + auto customCoverPath = YACReader::imageFileLoader(this); if (!customCoverPath.isEmpty()) { QImage cover(customCoverPath); if (cover.isNull()) { diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index e33c7cdd..55b66c9d 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -1,10 +1,14 @@ #include "properties_dialog.h" +#include "yacreader_global_gui.h" + +#include "cover_utils.h" #include "data_base_management.h" #include "initial_comic_info_extractor.h" #include "yacreader_field_edit.h" #include "yacreader_field_plain_text_edit.h" #include "db_helper.h" +#include "yacreader_cover_label.h" #include #include @@ -36,7 +40,8 @@ PropertiesDialog::PropertiesDialog(QWidget *parent) createTabBar(); auto rootLayout = new QGridLayout; - cover = new QLabel(); + cover = new YACReader::CoverLabel(); + connect(cover, &YACReader::CoverLabel::imageDropped, this, &PropertiesDialog::loadCustomCoverImageFromPath); mainLayout = new QGridLayout; mainLayout->addWidget(tabBar, 0, 0); @@ -102,11 +107,23 @@ void PropertiesDialog::createCoverBox() showPreviousCoverPageButton = new QToolButton(); showPreviousCoverPageButton->setIcon(QIcon(":/images/previousCoverPage.png")); + showPreviousCoverPageButton->setToolTip(tr("Load previous page as cover")); showPreviousCoverPageButton->setStyleSheet("QToolButton {border:none;}"); showNextCoverPageButton = new QToolButton(); showNextCoverPageButton->setIcon(QIcon(":/images/nextCoverPage.png")); + showNextCoverPageButton->setToolTip(tr("Load next page as cover")); showNextCoverPageButton->setStyleSheet("QToolButton {border:none;}"); + resetCoverButton = new QToolButton(); + resetCoverButton->setIcon(QIcon(":/images/resetCover.svg")); + resetCoverButton->setToolTip(tr("Reset cover to the default image")); + resetCoverButton->setStyleSheet("QToolButton {border:none;}"); + + loadCustomCoverImageButton = new QToolButton(); + loadCustomCoverImageButton->setIcon(QIcon(":/images/loadCustomCover.svg")); + loadCustomCoverImageButton->setToolTip(tr("Load custom cover image")); + loadCustomCoverImageButton->setStyleSheet("QToolButton {border:none;}"); + coverPageNumberLabel = new QLabel("-"); coverPageNumberLabel->setStyleSheet("QLabel {color: white; font-weight:bold; font-size:14px;}"); @@ -116,6 +133,10 @@ void PropertiesDialog::createCoverBox() layout->addWidget(coverPageNumberLabel, 0, Qt::AlignVCenter); layout->addSpacing(5); layout->addWidget(showNextCoverPageButton, 0, Qt::AlignVCenter); + layout->addSpacing(5); + layout->addWidget(resetCoverButton, 0, Qt::AlignVCenter); + layout->addSpacing(5); + layout->addWidget(loadCustomCoverImageButton, 0, Qt::AlignVCenter); coverPageEdit->setStyleSheet("QLineEdit {border:none;}"); layout->setSpacing(0); @@ -132,6 +153,8 @@ void PropertiesDialog::createCoverBox() connect(showPreviousCoverPageButton, &QAbstractButton::clicked, this, &PropertiesDialog::loadPreviousCover); connect(showNextCoverPageButton, &QAbstractButton::clicked, this, &PropertiesDialog::loadNextCover); + connect(resetCoverButton, &QAbstractButton::clicked, this, &PropertiesDialog::resetCover); + connect(loadCustomCoverImageButton, &QAbstractButton::clicked, this, &PropertiesDialog::loadCustomCoverImage); } void PropertiesDialog::createGeneralInfoBox() @@ -434,6 +457,8 @@ QImage blurred(const QImage &image, const QRect &rect, int radius, bool alphaOnl void PropertiesDialog::loadComic(ComicDB &comic) { + customCover = QImage(); + if (!comic.info.series.isNull()) series->setText(comic.info.series.toString()); if (!comic.info.title.isNull()) @@ -456,22 +481,17 @@ void PropertiesDialog::loadComic(ComicDB &comic) showPreviousCoverPageButton->setEnabled(true); showNextCoverPageButton->setEnabled(true); - if (coverPage == 1) - showPreviousCoverPageButton->setDisabled(true); - if (coverPage == comic.info.numPages.toInt()) - showNextCoverPageButton->setDisabled(true); - coverChanged = false; - coverBox->show(); + updateCoverBoxForSingleComic(); if (!QFileInfo(basePath + comic.path).exists()) { QMessageBox::warning(this, tr("Not found"), tr("Comic not found. You should update your library.")); showPreviousCoverPageButton->setDisabled(true); showNextCoverPageButton->setDisabled(true); } + } else { + coverPageNumberLabel->setText("1"); } - /*if(comic.info.numPages != NULL) - numPagesEdit->setText(QString::number(*comic.info.numPages));*/ if (!comic.info.number.isNull()) numberEdit->setText(comic.info.number.toString()); @@ -581,9 +601,13 @@ void PropertiesDialog::updateButtons() void PropertiesDialog::setComics(QList comics) { - updated = false; sequentialEditing = false; + updated = false; + currentComicIndex = 0; + coverChanged = false; + customCover = QImage(); + this->comics = comics; ComicDB comic = comics[0]; @@ -593,7 +617,7 @@ void PropertiesDialog::setComics(QList comics) updateButtons(); if (comics.length() > 1) { - coverBox->hide(); + updateCoverBoxForMultipleComics(); setDisableUniqueValues(true); this->setWindowTitle(tr("Edit selected comics information")); @@ -700,9 +724,12 @@ void PropertiesDialog::setComics(QList comics) void PropertiesDialog::setComicsForSequentialEditing(int currentComicIndex, QList comics) { - updated = false; sequentialEditing = true; + updated = false; + coverChanged = false; + customCover = QImage(); + this->comics = comics; this->currentComicIndex = currentComicIndex; @@ -726,6 +753,40 @@ void PropertiesDialog::updateComics() DBHelper::update(&(itr->info), db); updated = true; } + + if (!sequentialEditing && coverChanged) { + auto coverPath = LibraryPaths::coverPath(basePath, itr->info.hash); + + if (customCover.isNull()) { // reseted, we need to restore the default cover + itr->info.coverPage = QVariant(); + + InitialComicInfoExtractor ie(basePath + itr->path, coverPath, 1); + ie.extract(); + + if (ie.getOriginalCoverSize().second > 0) { + itr->info.originalCoverSize = QString("%1x%2").arg(ie.getOriginalCoverSize().first).arg(ie.getOriginalCoverSize().second); + itr->info.coverSizeRatio = static_cast(ie.getOriginalCoverSize().first) / ie.getOriginalCoverSize().second; + } + + emit coverChangedSignal(*itr); + + DBHelper::update(&(itr->info), db); + updated = true; + } else { + itr->info.coverPage = QVariant(); + YACReader::saveCover(coverPath, customCover); + + auto width = customCover.width(); + auto height = customCover.height(); + itr->info.originalCoverSize = QString("%1x%2").arg(width).arg(height); + itr->info.coverSizeRatio = static_cast(width) / height; + + DBHelper::update(&(itr->info), db); + updated = true; + + emit coverChangedSignal(*itr); + } + } } db.commit(); connectionName = db.connectionName(); @@ -739,14 +800,14 @@ void PropertiesDialog::setMultipleCover() QPixmap last = lastComic.info.getCover(basePath); last = last.scaledToHeight(575, Qt::SmoothTransformation); - coverImage = QPixmap::fromImage(blurred(last.toImage(), QRect(0, 0, last.width(), last.height()), 15)); + auto coverImage = QPixmap::fromImage(blurred(last.toImage(), QRect(0, 0, last.width(), last.height()), 15)); cover->setPixmap(coverImage); } void PropertiesDialog::setCover(const QPixmap &coverI) { - coverImage = coverI.scaledToHeight(575, Qt::SmoothTransformation); + auto coverImage = coverI.scaledToHeight(575, Qt::SmoothTransformation); cover->setPixmap(coverImage); } @@ -755,13 +816,14 @@ void PropertiesDialog::setFilename(const QString &nameString) { title->setText(nameString); } + void PropertiesDialog::setNumpages(int pagesNum) { numPagesEdit->setText(QString::number(pagesNum)); } + void PropertiesDialog::setSize(float sizeFloat) { - size->setText(QString::number(sizeFloat, 'f', 2) + " MB"); } @@ -787,7 +849,11 @@ void PropertiesDialog::save() if (sequentialEditing) if (coverChanged) { - itr->info.coverPage = coverPageNumberLabel->text().toInt(); + if (customCover.isNull()) { + itr->info.coverPage = coverPageNumberLabel->text().toInt(); + } else { + itr->info.coverPage = QVariant(); + } edited = true; } @@ -955,15 +1021,31 @@ void PropertiesDialog::save() if (sequentialEditing) { if (coverChanged) { auto coverPath = LibraryPaths::coverPath(basePath, comics[currentComicIndex].info.hash); - InitialComicInfoExtractor ie(basePath + comics[currentComicIndex].path, coverPath, comics[currentComicIndex].info.coverPage.toInt()); - ie.extract(); - if (ie.getOriginalCoverSize().second > 0) { - comics[currentComicIndex].info.originalCoverSize = QString("%1x%2").arg(ie.getOriginalCoverSize().first).arg(ie.getOriginalCoverSize().second); - comics[currentComicIndex].info.coverSizeRatio = static_cast(ie.getOriginalCoverSize().first) / ie.getOriginalCoverSize().second; + if (customCover.isNull()) { + InitialComicInfoExtractor ie(basePath + comics[currentComicIndex].path, coverPath, comics[currentComicIndex].info.coverPage.toInt()); + ie.extract(); + + if (ie.getOriginalCoverSize().second > 0) { + comics[currentComicIndex].info.originalCoverSize = QString("%1x%2").arg(ie.getOriginalCoverSize().first).arg(ie.getOriginalCoverSize().second); + comics[currentComicIndex].info.coverSizeRatio = static_cast(ie.getOriginalCoverSize().first) / ie.getOriginalCoverSize().second; + } + + comics[currentComicIndex].info.edited = true; + + emit coverChangedSignal(comics[currentComicIndex]); + } else { + auto width = customCover.width(); + auto height = customCover.height(); + + comics[currentComicIndex].info.originalCoverSize = QString("%1x%2").arg(width).arg(height); + comics[currentComicIndex].info.coverSizeRatio = static_cast(width) / height; + + comics[currentComicIndex].info.edited = true; + + YACReader::saveCover(coverPath, customCover); + emit coverChangedSignal(comics[currentComicIndex]); } - - emit coverChangedSignal(comics[currentComicIndex]); } } } @@ -1093,48 +1175,87 @@ void PropertiesDialog::updateCoverPageNumberLabel(int n) void PropertiesDialog::loadNextCover() { int current = coverPageNumberLabel->text().toInt(); - if (current < comics[currentComicIndex].info.numPages.toInt()) { - updateCoverPageNumberLabel(current + 1); + int next; - InitialComicInfoExtractor ie(basePath + comics[currentComicIndex].path, "", current + 1); - ie.extract(); - setCover(ie.getCover()); - repaint(); + if (current == comics[currentComicIndex].info.numPages.toInt()) + next = 1; + else + next = current + 1; - if ((current + 1) == comics[currentComicIndex].info.numPages.toInt()) { - showNextCoverPageButton->setDisabled(true); - } + setCoverPage(next); - showPreviousCoverPageButton->setEnabled(true); - if (current + 1 != comics[currentComicIndex].info.coverPage) - coverChanged = true; - else - coverChanged = false; - } + coverChanged = next != comics[currentComicIndex].info.coverPage; } void PropertiesDialog::loadPreviousCover() { int current = coverPageNumberLabel->text().toInt(); - if (current != 1) { - updateCoverPageNumberLabel(current - 1); - InitialComicInfoExtractor ie(basePath + comics[currentComicIndex].path, "", current - 1); + int previous; + + if (current == 1) + previous = comics[currentComicIndex].info.numPages.toInt(); + else + previous = current - 1; + + setCoverPage(previous); + + coverChanged = previous != comics[currentComicIndex].info.coverPage.toInt(); +} + +void PropertiesDialog::resetCover() +{ + if (sequentialEditing) { + setCoverPage(1); + coverChanged = true; // it could be that the cover is a custom cover, so we need to always update it + } else { + InitialComicInfoExtractor ie(basePath + comics.last().path, "", 1); ie.extract(); - setCover(ie.getCover()); - repaint(); + auto cover = ie.getCover(); + cover = cover.scaledToHeight(575, Qt::SmoothTransformation); - if ((current - 1) == 1) { - showPreviousCoverPageButton->setDisabled(true); - } + auto coverImage = QPixmap::fromImage(blurred(cover.toImage(), QRect(0, 0, cover.width(), cover.height()), 15)); - showNextCoverPageButton->setEnabled(true); - if (current - 1 != comics[currentComicIndex].info.coverPage.toInt()) - coverChanged = true; - else - coverChanged = false; + this->cover->setPixmap(coverImage); + + customCover = QImage(); + coverChanged = true; } } +void PropertiesDialog::loadCustomCoverImage() +{ + auto path = YACReader::imageFileLoader(this); + loadCustomCoverImageFromPath(path); +} + +void PropertiesDialog::loadCustomCoverImageFromPath(const QString &path) +{ + if (path.isEmpty()) { + return; + } + + customCover = QImage(path); + coverChanged = true; + + if (customCover.isNull()) { + QMessageBox::warning(this, tr("Invalid cover"), tr("The image is invalid.")); + return; + } + + setCover(QPixmap::fromImage(customCover)); +} + +void PropertiesDialog::setCoverPage(int pageNumber) +{ + customCover = QImage(); + + updateCoverPageNumberLabel(pageNumber); + InitialComicInfoExtractor ie(basePath + comics[currentComicIndex].path, "", pageNumber); + ie.extract(); + setCover(ie.getCover()); + repaint(); +} + bool PropertiesDialog::close() { if (updated) { @@ -1143,3 +1264,17 @@ bool PropertiesDialog::close() return QDialog::close(); } + +void PropertiesDialog::updateCoverBoxForMultipleComics() +{ + showPreviousCoverPageButton->hide(); + showNextCoverPageButton->hide(); + coverPageNumberLabel->hide(); +} + +void PropertiesDialog::updateCoverBoxForSingleComic() +{ + showPreviousCoverPageButton->show(); + showNextCoverPageButton->show(); + coverPageNumberLabel->show(); +} diff --git a/YACReaderLibrary/properties_dialog.h b/YACReaderLibrary/properties_dialog.h index 7485656a..f4dcdd96 100644 --- a/YACReaderLibrary/properties_dialog.h +++ b/YACReaderLibrary/properties_dialog.h @@ -19,6 +19,10 @@ class QComboBox; // class YACReaderBusyWidget; class QToolButton; +namespace YACReader { +class CoverLabel; +} + #include "comic_db.h" class PropertiesDialog : public QDialog @@ -33,7 +37,7 @@ private: QTabWidget *tabBar; QWidget *coverBox; - QLabel *cover; + YACReader::CoverLabel *cover; QScrollArea *sa; QWidget *generalInfoBox; @@ -113,12 +117,13 @@ private: QPushButton *previousButton; QPushButton *restoreButton; //?? - QPixmap coverImage; - QToolButton *showPreviousCoverPageButton; QToolButton *showNextCoverPageButton; QLabel *coverPageNumberLabel; + QToolButton *resetCoverButton; + QToolButton *loadCustomCoverImageButton; + void createTabBar(); void createCoverBox(); void createGeneralInfoBox(); @@ -144,6 +149,8 @@ private: bool updated; QString originalCoverSize; + QImage customCover; + public: PropertiesDialog(QWidget *parent = nullptr); QString databasePath; @@ -170,7 +177,13 @@ public slots: void setSize(float size); void loadNextCover(); void loadPreviousCover(); + void resetCover(); + void loadCustomCoverImage(); + void loadCustomCoverImageFromPath(const QString &path); + void setCoverPage(int pageNumber); bool close(); + void updateCoverBoxForMultipleComics(); + void updateCoverBoxForSingleComic(); signals: void coverChangedSignal(const ComicDB &comic); diff --git a/common/comic_db.cpp b/common/comic_db.cpp index 1d1c3dc1..3b57650b 100644 --- a/common/comic_db.cpp +++ b/common/comic_db.cpp @@ -404,12 +404,7 @@ ComicInfo &ComicInfo::operator=(const ComicInfo &comicInfo) QPixmap ComicInfo::getCover(const QString &basePath) { - if (cover.isNull()) { - cover.load(YACReader::LibraryPaths::coverPath(basePath, hash)); - } - QPixmap c; - c.convertFromImage(cover); - return c; + return QPixmap(YACReader::LibraryPaths::coverPath(basePath, hash)); } QStringList ComicInfo::getWriters() diff --git a/common/comic_db.h b/common/comic_db.h index 6c6dac09..77554c45 100644 --- a/common/comic_db.h +++ b/common/comic_db.h @@ -84,8 +84,6 @@ public: QVariant comicVineID; // string - QImage cover; - QVariant lastTimeOpened; // integer/date QVariant coverSizeRatio; // h/w QVariant originalCoverSize; // string "WxH" @@ -189,8 +187,6 @@ public: Q_PROPERTY(QVariant comicVineID MEMBER comicVineID CONSTANT) - Q_PROPERTY(QImage cover MEMBER cover CONSTANT) - Q_PROPERTY(QVariant lastTimeOpened MEMBER lastTimeOpened CONSTANT) Q_PROPERTY(QVariant coverSizeRatio MEMBER coverSizeRatio CONSTANT) diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index e9589490..7ad76dfa 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -2,6 +2,8 @@ #include #include +#include +#include using namespace YACReader; @@ -99,3 +101,47 @@ QPixmap YACReader::hdpiPixmap(const QString &file, QSize size) { return QIcon(file).pixmap(size); } + +QString YACReader::imageFileLoader(QWidget *parent) +{ + QString supportedImageFormatsString; + for (const QByteArray &format : QImageReader::supportedImageFormats()) { + supportedImageFormatsString += QString("*.%1 ").arg(QString(format)); + } + + return QFileDialog::getOpenFileName(parent, QObject::tr("Select custom cover"), QDir::homePath(), QObject::tr("Images (%1)").arg(supportedImageFormatsString)); +} + +QString YACReader::imagePathFromMimeData(const QMimeData *mimeData) +{ + QString filePath; + + if (mimeData->hasUrls()) { + QList urlList = mimeData->urls(); + + if (!urlList.isEmpty()) { + QUrl url = urlList.first(); + if (url.isLocalFile()) { + filePath = url.toLocalFile(); + + QFileInfo fileInfo(filePath); + QString extension = fileInfo.suffix().toLower(); + QList supportedFormats = QImageReader::supportedImageFormats(); + bool isSupported = false; + + for (const QByteArray &format : supportedFormats) { + if (extension == QString(format).toLower()) { + isSupported = true; + break; + } + } + + if (!isSupported) { + filePath.clear(); + } + } + } + } + + return filePath; +} diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 0b61d42f..b6bedfd4 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -112,6 +112,7 @@ QString addExtensionToIconPath(const QString &path); QString addExtensionToIconPathInToolbar(const QString &path); QAction *actionWithCustomIcon(const QIcon &icon, QAction *action); QPixmap hdpiPixmap(const QString &file, QSize size); - +QString imageFileLoader(QWidget *parent); +QString imagePathFromMimeData(const QMimeData *mimeData); } #endif diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri index 0ea43ca6..1b218b77 100644 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ b/custom_widgets/custom_widgets_yacreaderlibrary.pri @@ -21,7 +21,8 @@ HEADERS += \ $$PWD/yacreader_library_list_widget.h \ $$PWD/yacreader_library_item_widget.h \ $$PWD/yacreader_treeview.h \ - $$PWD/yacreader_busy_widget.h + $$PWD/yacreader_busy_widget.h \ + $$PWD/yacreader_cover_label.h !CONFIG(no_opengl){ HEADERS += $$PWD/yacreader_gl_flow_config_widget.h } @@ -50,8 +51,8 @@ SOURCES += \ $$PWD/yacreader_library_list_widget.cpp \ $$PWD/yacreader_library_item_widget.cpp \ $$PWD/yacreader_treeview.cpp \ - $$PWD/yacreader_busy_widget.cpp - + $$PWD/yacreader_busy_widget.cpp \ + $$PWD/yacreader_cover_label.cpp !CONFIG(no_opengl){ SOURCES += $$PWD/yacreader_gl_flow_config_widget.cpp } diff --git a/custom_widgets/yacreader_cover_label.cpp b/custom_widgets/yacreader_cover_label.cpp new file mode 100644 index 00000000..63a2db7a --- /dev/null +++ b/custom_widgets/yacreader_cover_label.cpp @@ -0,0 +1,31 @@ +#include "yacreader_cover_label.h" +#include "yacreader_global_gui.h" + +YACReader::CoverLabel::CoverLabel(QWidget *parent) + : QLabel(parent) +{ + setAcceptDrops(true); +} + +void YACReader::CoverLabel::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasUrls() && !YACReader::imagePathFromMimeData(event->mimeData()).isEmpty()) { + event->acceptProposedAction(); + } +} + +void YACReader::CoverLabel::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } +} + +void YACReader::CoverLabel::dropEvent(QDropEvent *event) +{ + QString path = YACReader::imagePathFromMimeData(event->mimeData()); + if (!path.isEmpty()) { + emit imageDropped(path); + event->acceptProposedAction(); + } +} diff --git a/custom_widgets/yacreader_cover_label.h b/custom_widgets/yacreader_cover_label.h new file mode 100644 index 00000000..8d570c9f --- /dev/null +++ b/custom_widgets/yacreader_cover_label.h @@ -0,0 +1,29 @@ +#ifndef DROP_LABEL_H +#define DROP_LABEL_H + +#include +#include +#include +#include + +namespace YACReader { + +class CoverLabel : public QLabel +{ + Q_OBJECT + +public: + explicit CoverLabel(QWidget *parent = nullptr); + +protected: + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + +signals: + void imageDropped(const QString &path); +}; + +} + +#endif // DROP_LABEL_H diff --git a/images/loadCustomCover.svg b/images/loadCustomCover.svg new file mode 100644 index 00000000..08ff06b1 --- /dev/null +++ b/images/loadCustomCover.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/resetCover.svg b/images/resetCover.svg new file mode 100644 index 00000000..2790627b --- /dev/null +++ b/images/resetCover.svg @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file