diff --git a/CHANGELOG.md b/CHANGELOG.md
index c899522a..b2eb03cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
Version counting is based on semantic versioning (Major.Feature.Patch)
-## WIP (9.15.1)
+## WIP (9.16.0)
### YACReader
* Don't use scroll animations on macos by default, it where hdpi scroll is most likely to be used.
* New toolbar on macos.
@@ -21,6 +21,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
* 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.
+* Support for storing the new image filters from iOS and Android apps.
### YACReaderLibraryServer
* Log libraries validation when the app starts.
diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp
index f64f4c50..0aea4457 100644
--- a/YACReaderLibrary/db/data_base_management.cpp
+++ b/YACReaderLibrary/db/data_base_management.cpp
@@ -81,7 +81,13 @@ static QString fields = "title,"
"seriesGroup,"
"mainCharacterOrTeam,"
"review,"
- "tags";
+ "tags,"
+ // new 9.16 fields
+ "imageFiltersJson,"
+ "lastTimeImageFiltersSet,"
+ "lastTimeCoverSet,"
+ "usesExternalCover,"
+ "lastTimeMetadataSet";
DataBaseManagement::DataBaseManagement()
: QObject(), dataBasesList()
@@ -284,7 +290,13 @@ bool DataBaseManagement::createComicInfoTable(QSqlDatabase &database, QString ta
"seriesGroup TEXT,"
"mainCharacterOrTeam TEXT,"
"review TEXT,"
- "tags TEXT"
+ "tags TEXT,"
+ // new 9.16 fields
+ "imageFiltersJson TEXT,"
+ "lastTimeImageFiltersSet INTEGER DEFAULT 0,"
+ "lastTimeCoverSet INTEGER DEFAULT 0,"
+ "usesExternalCover BOOLEAN DEFAULT 0,"
+ "lastTimeMetadataSet INTEGER DEFAULT 0"
")");
return queryComicInfo.exec();
@@ -862,6 +874,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
bool pre9_8 = false;
bool pre9_13 = false;
bool pre9_14 = false;
+ bool pre9_16 = false;
QString libraryDatabasePath = LibraryPaths::libraryDatabasePath(libraryPath);
@@ -879,6 +892,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
pre9_13 = true;
if (compareVersions(DataBaseManagement::checkValidDB(libraryDatabasePath), "9.14.0") < 0)
pre9_14 = true;
+ if (compareVersions(DataBaseManagement::checkValidDB(libraryDatabasePath), "9.16.0") < 0)
+ pre9_16 = true;
QString connectionName = "";
bool returnValue = true;
@@ -1080,6 +1095,22 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
}
}
+ if (pre9_16) {
+ { // comic_info
+ QStringList columnDefs;
+ columnDefs << "imageFiltersJson TEXT";
+ columnDefs << "lastTimeImageFiltersSet INTEGER DEFAULT 0";
+
+ columnDefs << "lastTimeCoverSet INTEGER DEFAULT 0";
+ columnDefs << "usesExternalCover BOOLEAN DEFAULT 0";
+
+ columnDefs << "lastTimeMetadataSet INTEGER DEFAULT 0";
+
+ bool successAddingColumns = addColumns("comic_info", columnDefs, db);
+ returnValue = returnValue && successAddingColumns;
+ }
+ }
+
if (returnValue) {
QSqlQuery updateVersion(db);
updateVersion.prepare("UPDATE db_info SET "
diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp
index e0e2f5c4..c2963004 100644
--- a/YACReaderLibrary/db_helper.cpp
+++ b/YACReaderLibrary/db_helper.cpp
@@ -712,7 +712,14 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db)
"seriesGroup = :seriesGroup,"
"mainCharacterOrTeam = :mainCharacterOrTeam,"
"review = :review,"
- "tags = :tags"
+ "tags = :tags,"
+
+ // new 9.16 fields
+ "imageFiltersJson = :imageFiltersJson,"
+ "lastTimeImageFiltersSet = :lastTimeImageFiltersSet,"
+ "lastTimeCoverSet = :lastTimeCoverSet,"
+ "usesExternalCover = :usesExternalCover,"
+ "lastTimeMetadataSet = :lastTimeMetadataSet"
//--
" WHERE id = :id");
@@ -790,6 +797,12 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db)
updateComicInfo.bindValue(":review", comicInfo->review);
updateComicInfo.bindValue(":tags", comicInfo->tags);
+ updateComicInfo.bindValue(":imageFiltersJson", comicInfo->imageFiltersJson);
+ updateComicInfo.bindValue(":lastTimeImageFiltersSet", comicInfo->lastTimeImageFiltersSet);
+ updateComicInfo.bindValue(":lastTimeCoverSet", comicInfo->lastTimeCoverSet);
+ updateComicInfo.bindValue(":usesExternalCover", comicInfo->usesExternalCover);
+ updateComicInfo.bindValue(":lastTimeMetadataSet", comicInfo->lastTimeMetadataSet);
+
updateComicInfo.exec();
QLOG_INFO() << updateComicInfo.lastError().databaseText();
@@ -962,6 +975,41 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
QSqlDatabase::removeDatabase(connectionName);
}
+void DBHelper::updateImageFilters(qulonglong libraryId, const ComicInfo &comicInfo)
+{
+ QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
+ QString connectionName = "";
+ {
+ QSqlDatabase db = DataBaseManagement::loadDatabase(LibraryPaths::libraryDataPath(libraryPath));
+
+ bool found;
+ ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
+
+ if (found && comic.info.lastTimeImageFiltersSet.toULongLong() < comicInfo.lastTimeImageFiltersSet.toULongLong()) {
+ QSqlQuery updateComicInfo(db);
+ updateComicInfo.prepare("UPDATE comic_info SET "
+ "lastTimeImageFiltersSet = :lastTimeImageFiltersSet, "
+ "imageFiltersJson = :imageFiltersJson "
+ " WHERE id = :id ");
+
+ updateComicInfo.bindValue(":lastTimeImageFiltersSet", comicInfo.lastTimeImageFiltersSet.toULongLong());
+ updateComicInfo.bindValue(":imageFiltersJson", comicInfo.imageFiltersJson);
+ updateComicInfo.bindValue(":id", comic.info.id);
+
+ auto ret = updateComicInfo.exec();
+ if (!ret) {
+ QLOG_ERROR() << "Error updating image filters for comic ID:" << comicInfo.id;
+ QLOG_ERROR() << updateComicInfo.lastError().databaseText();
+ QLOG_ERROR() << updateComicInfo.lastError().text();
+ }
+ }
+
+ connectionName = db.connectionName();
+ }
+
+ QSqlDatabase::removeDatabase(connectionName);
+}
+
void DBHelper::setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo)
{
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
@@ -1944,6 +1992,12 @@ ComicInfo DBHelper::getComicInfoFromQuery(QSqlQuery &query, const QString &idKey
int review = record.indexOf("review");
int tags = record.indexOf("tags");
+ int imageFiltersJson = record.indexOf("imageFiltersJson");
+ int lastTimeImageFiltersSet = record.indexOf("lastTimeImageFiltersSet");
+ int lastTimeCoverSet = record.indexOf("lastTimeCoverSet");
+ int usesExternalCover = record.indexOf("usesExternalCover");
+ int lastTimeMetadataSet = record.indexOf("lastTimeMetadataSet");
+
ComicInfo comicInfo;
comicInfo.hash = query.value(hash).toString();
@@ -2026,6 +2080,14 @@ ComicInfo DBHelper::getComicInfoFromQuery(QSqlQuery &query, const QString &idKey
comicInfo.tags = query.value(tags);
//--
+ // new 9.16 fields
+ comicInfo.imageFiltersJson = query.value(imageFiltersJson);
+ comicInfo.lastTimeImageFiltersSet = query.value(lastTimeImageFiltersSet);
+ comicInfo.lastTimeCoverSet = query.value(lastTimeCoverSet);
+ comicInfo.usesExternalCover = query.value(usesExternalCover).toBool();
+ comicInfo.lastTimeMetadataSet = query.value(lastTimeMetadataSet);
+ //--
+
comicInfo.existOnDb = true;
return comicInfo;
diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h
index 66d3981d..37d80250 100644
--- a/YACReaderLibrary/db_helper.h
+++ b/YACReaderLibrary/db_helper.h
@@ -72,6 +72,7 @@ public:
static Folder updateChildrenInfo(qulonglong folderId, QSqlDatabase &db);
static void updateChildrenInfo(QSqlDatabase &db);
static void updateProgress(qulonglong libraryId, const ComicInfo &comicInfo);
+ static void updateImageFilters(qulonglong libraryId, const ComicInfo &comicInfo);
static void setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo);
[[deprecated("Server v1")]] static void updateFromRemoteClient(qulonglong libraryId, const ComicInfo &comicInfo);
static void updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db);
diff --git a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp
index d11ce4b6..94324838 100644
--- a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp
+++ b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp
@@ -34,7 +34,6 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon
ComicInfo info;
info.currentPage = currentPage;
info.id = comicId;
- DBHelper::updateProgress(libraryId, info);
if (data.length() > 1) {
if (data.at(1).isEmpty() == false) {
@@ -43,8 +42,23 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon
info.id = nextComicId.toULongLong();
DBHelper::setComicAsReading(libraryId, info);
}
+
+ if (data.length() > 2) {
+ QStringList imageFiltersData = data.at(2).split("\t");
+ auto epoch = imageFiltersData.at(0).toULongLong();
+ QString imageFiltersJson = imageFiltersData.at(1);
+
+ ComicInfo imageFiltersInfo;
+ imageFiltersInfo.id = comicId;
+ imageFiltersInfo.lastTimeImageFiltersSet = epoch;
+ imageFiltersInfo.imageFiltersJson = imageFiltersJson.isEmpty() ? QVariant() : imageFiltersJson;
+
+ DBHelper::updateImageFilters(libraryId, imageFiltersInfo);
+ }
}
+ DBHelper::updateProgress(libraryId, info);
+
error = false;
updatedLibraryId = libraryId;
updatedComicId = comicId;
diff --git a/YACReaderLibrary/server/yacreader_server_data_helper.cpp b/YACReaderLibrary/server/yacreader_server_data_helper.cpp
index d43e0c51..7fafe7ab 100644
--- a/YACReaderLibrary/server/yacreader_server_data_helper.cpp
+++ b/YACReaderLibrary/server/yacreader_server_data_helper.cpp
@@ -170,6 +170,12 @@ QJsonObject YACReaderServerDataHelper::fullComicToJSON(const qulonglong libraryI
json["brightness"] = comic.info.brightness;
json["contrast"] = comic.info.contrast;
json["gamma"] = comic.info.gamma;
+ // 9.16
+ variantToJson("image_filters_json", QMetaType::QString, comic.info.imageFiltersJson, json);
+ variantToJson("last_time_image_filters_set", QMetaType::LongLong, comic.info.lastTimeImageFiltersSet, json);
+ variantToJson("last_time_cover_set", QMetaType::LongLong, comic.info.lastTimeCoverSet, json);
+ variantToJson("uses_external_cover", QMetaType::Bool, comic.info.usesExternalCover, json);
+ variantToJson("last_time_metadata_set", QMetaType::LongLong, comic.info.lastTimeMetadataSet, json);
return json;
}
diff --git a/common/comic_db.cpp b/common/comic_db.cpp
index 3b57650b..9fa6edb3 100644
--- a/common/comic_db.cpp
+++ b/common/comic_db.cpp
@@ -166,6 +166,23 @@ QString ComicDB::toTXT()
if (!info.tags.isNull())
txt.append(QString("tags:%1\r\n").arg(info.tags.toString()));
+ // 9.16
+
+ if (!info.imageFiltersJson.isNull())
+ txt.append(QString("imageFiltersJson:%1\r\n").arg(info.imageFiltersJson.toString()));
+
+ if (!info.lastTimeImageFiltersSet.isNull())
+ txt.append(QString("lastTimeImageFiltersSet:%1\r\n").arg(info.lastTimeImageFiltersSet.toULongLong()));
+
+ if (!info.lastTimeCoverSet.isNull())
+ txt.append(QString("lastTimeCoverSet:%1\r\n").arg(info.lastTimeCoverSet.toULongLong()));
+
+ if (!info.usesExternalCover.isNull())
+ txt.append(QString("usesExternalCover:%1\r\n").arg(info.usesExternalCover.toBool() ? "1" : "0"));
+
+ if (!info.lastTimeMetadataSet.isNull())
+ txt.append(QString("lastTimeMetadataSet:%1\r\n").arg(info.lastTimeMetadataSet.toULongLong()));
+
return txt;
}
@@ -399,6 +416,12 @@ ComicInfo &ComicInfo::operator=(const ComicInfo &comicInfo)
review = comicInfo.review;
tags = comicInfo.tags;
+ imageFiltersJson = comicInfo.imageFiltersJson;
+ lastTimeImageFiltersSet = comicInfo.lastTimeImageFiltersSet;
+ lastTimeCoverSet = comicInfo.lastTimeCoverSet;
+ usesExternalCover = comicInfo.usesExternalCover;
+ lastTimeMetadataSet = comicInfo.lastTimeMetadataSet;
+
return *this;
}
@@ -691,6 +714,12 @@ QDataStream &operator<<(QDataStream &stream, const ComicInfo &comicInfo)
stream << comicInfo.review;
stream << comicInfo.tags;
+ stream << comicInfo.imageFiltersJson;
+ stream << comicInfo.lastTimeImageFiltersSet;
+ stream << comicInfo.lastTimeCoverSet;
+ stream << comicInfo.usesExternalCover;
+ stream << comicInfo.lastTimeMetadataSet;
+
return stream;
}
@@ -770,5 +799,11 @@ QDataStream &operator>>(QDataStream &stream, ComicInfo &comicInfo)
stream >> comicInfo.review;
stream >> comicInfo.tags;
+ stream >> comicInfo.imageFiltersJson;
+ stream >> comicInfo.lastTimeImageFiltersSet;
+ stream >> comicInfo.lastTimeCoverSet;
+ stream >> comicInfo.usesExternalCover;
+ stream >> comicInfo.lastTimeMetadataSet;
+
return stream;
}
diff --git a/common/comic_db.h b/common/comic_db.h
index 77554c45..9f3b70d6 100644
--- a/common/comic_db.h
+++ b/common/comic_db.h
@@ -39,9 +39,9 @@ public:
int bookmark1;
int bookmark2;
int bookmark3;
- int brightness;
- int contrast;
- int gamma;
+ [[deprecated("Use imageFiltersJson")]] int brightness;
+ [[deprecated("Use imageFiltersJson")]] int contrast;
+ [[deprecated("Use imageFiltersJson")]] int gamma;
//-----------------
QVariant title; // string
@@ -104,6 +104,12 @@ public:
QVariant review; // string
QVariant tags; // string/list
+ QVariant imageFiltersJson; // string, JSON with image filters
+ QVariant lastTimeImageFiltersSet; // integer/date, last time image filters were set
+ QVariant lastTimeCoverSet; // integer/date, last time cover was set
+ QVariant usesExternalCover; // bool, whether the cover is external or not
+ QVariant lastTimeMetadataSet; // integer/date, last time metadata was set
+
QPixmap getCover(const QString &basePath);
Q_INVOKABLE QStringList getWriters();
@@ -208,6 +214,12 @@ public:
Q_PROPERTY(QVariant review MEMBER review CONSTANT)
Q_PROPERTY(QVariant tags MEMBER tags CONSTANT)
+ Q_PROPERTY(QVariant imageFiltersJson MEMBER imageFiltersJson CONSTANT)
+ Q_PROPERTY(QVariant lastTimeImageFiltersSet MEMBER lastTimeImageFiltersSet CONSTANT)
+ Q_PROPERTY(QVariant lastTimeCoverSet MEMBER lastTimeCoverSet CONSTANT)
+ Q_PROPERTY(QVariant usesExternalCover MEMBER usesExternalCover CONSTANT)
+ Q_PROPERTY(QVariant lastTimeMetadataSet MEMBER lastTimeMetadataSet CONSTANT)
+
//-new properties, not loaded from the DB automatically
bool isFavorite;
Q_PROPERTY(bool isFavorite MEMBER isFavorite WRITE setFavorite NOTIFY favoriteChanged)
diff --git a/common/yacreader_global.h b/common/yacreader_global.h
index 3508bfcb..57828611 100644
--- a/common/yacreader_global.h
+++ b/common/yacreader_global.h
@@ -9,11 +9,11 @@
class QLibrary;
-#define VERSION "9.15.1"
+#define VERSION "9.16.0"
// Used to check if the database needs to be updated, the version is stored in the database.
// This value is only incremented when the database structure changes.
-#define DB_VERSION "9.14.0"
+#define DB_VERSION "9.16.0"
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"
#define COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES "COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES"
diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp
index c0947291..d9a09861 100644
--- a/custom_widgets/whats_new_dialog.cpp
+++ b/custom_widgets/whats_new_dialog.cpp
@@ -43,42 +43,31 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
versionLabel->setAlignment(Qt::AlignCenter);
versionLabel->setStyleSheet("padding:0 0 0 0;"
"background-color:transparent;"
- "color:#858585;");
-
- auto text = new QLabel();
- text->setText("This version brings new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
"
+ "color:#858585;"); auto text = new QLabel();
+ text->setText("This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
"
"
"
"YACReader
"
- " • Save magnifying glass size and zoom level
"
- " • Add shortcut to reset the magnifying glass to its defaults (size and zoom), it is `slash` by default but it can be reassigned
"
- " • Bump PDF render size
"
- " • Fix trackpad scrolling, it makes using trackpads more responsive and natural
"
- " • Added more info to Help -> System info
"
- " • Don't use scroll animations on macos by default, it where hdpi scroll is most likely to be used and it causes scroll issues. (new 9.15.1)
"
+ " • Don't use scroll animations on macOS by default, where hdpi scroll is most likely to be used
"
+ " • New toolbar on macOS
"
+ " • New mouse modes to turn pages - you can setup the app to use the left/right buttons to turn pages directly or click on the left/right part of the screen to turn pages
"
"
"
"YACReaderLibrary
"
- " • Fix headers in the table view getting stuck in a non-movable state
"
- " • Add option to set the type of a library. It will convert all the content to the desired type (comic, manga, etc.) and set that type as the default for the library. Available in the library context menu
"
- " • Added more info to Help -> System info
"
- " • New setting to open comics in third-party reader apps by entering a command that launches the app, e.g., \"/path/to/the/app {comic_file_path}\". Use `{comic_file_path}` as a placeholder where `YACReaderLibrary` places the path to the comic file
"
- " • Purge covers and metadata not being used after a full library update
"
- " • Fix crash when updating the current folder content after a library update
"
- " • Fix crash when current folder is empty after an update
"
- " • Enable dropping content on the FolderContentView
"
- " • Fix `open containing folder...` shortcut for comics
"
- " • Add a dialog to show information about a library, including the number of folders, comics, and read comics
"
- " • Fix occasional crashes when using automatic library updates
"
- " • Add setting to hide the \"Continue Reading...\" banner from the home view
"
- " • Improve Grid and Flow Info comics view scroll performance
"
- " • Improve flexibility of the open comic in third party app setting so more complex commands can be used. e.g. `open -a \"/Applications/My Reader.app"
- "{comic_file_path}\"` (new 9.15.1)
"
+ " • Improve flexibility of the open comic in third party app setting so more complex commands can be used, e.g. `open -a \"/Applications/My Reader.app\" \"{comic_file_path}\"`
"
+ " • Fix setting the comic rating in the table view
"
+ " • Log libraries validation when the app starts
"
+ " • New toolbar on macOS
"
+ " • 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 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
"
+ " • Support for storing the new image filters from iOS and Android apps
"
"
"
"YACReaderLibraryServer
"
- " • New command --system-info to print information about the execution environment and available resources (including what image formats are supported and what libraries are used by the app).
"
- " • Fix automatic libraries updates not being triggered.
"
- "
"
- "All apps
"
- " • Sorting heuristic to try to find spreads in the content of a comic is now only used for files with less than 1000 pages to avoid false positives.
"
+ " • Log libraries validation when the app starts
"
"
"
"I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon "
"or donate some money using Pay-Pal and help keeping the project alive. "