From b3d970fdf4ef11c30ff1a8327b4c268cf8363f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 08:36:30 +0200 Subject: [PATCH 01/81] Remove unused dialog --- YACReader/YACReader.pro | 2 -- YACReader/shortcuts_dialog.cpp | 64 ---------------------------------- YACReader/shortcuts_dialog.h | 20 ----------- 3 files changed, 86 deletions(-) delete mode 100644 YACReader/shortcuts_dialog.cpp delete mode 100644 YACReader/shortcuts_dialog.h diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 64c639d88..08502677b 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -86,7 +86,6 @@ HEADERS += ../common/comic.h \ ../common/bookmarks.h \ bookmarks_dialog.h \ render.h \ - shortcuts_dialog.h \ translator.h \ goto_flow_widget.h \ page_label_widget.h \ @@ -125,7 +124,6 @@ SOURCES += ../common/comic.cpp \ ../common/bookmarks.cpp \ bookmarks_dialog.cpp \ render.cpp \ - shortcuts_dialog.cpp \ translator.cpp \ goto_flow_widget.cpp \ page_label_widget.cpp \ diff --git a/YACReader/shortcuts_dialog.cpp b/YACReader/shortcuts_dialog.cpp deleted file mode 100644 index 3994656d6..000000000 --- a/YACReader/shortcuts_dialog.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "shortcuts_dialog.h" -#include -#include -#include -#include -#include -#include -#include - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#endif - -ShortcutsDialog::ShortcutsDialog(QWidget *parent) - : QDialog(parent) //,Qt::FramelessWindowHint) -{ - setModal(true); - setWindowIcon(QIcon(":/images/shortcuts.png")); - setWindowTitle(tr("YACReader keyboard shortcuts")); - - auto mainLayout = new QVBoxLayout; - - close = new QPushButton(tr("Close")); - connect(close, &QAbstractButton::clicked, this, &QWidget::close); - - auto bottomLayout = new QHBoxLayout; - bottomLayout->addStretch(); - bottomLayout->addWidget(close); - - auto shortcutsLayout = new QHBoxLayout; - - shortcuts = new QTextEdit(); - shortcuts->setFrameStyle(QFrame::NoFrame); - - //"

General functions:


O : Open comic
Esc : Exit

" - shortcuts->setReadOnly(true); - shortcutsLayout->addWidget(shortcuts); - // shortcutsLayout->addWidget(shortcuts2); - shortcutsLayout->setSpacing(0); - mainLayout->addLayout(shortcutsLayout); - mainLayout->addLayout(bottomLayout); - - setLayout(mainLayout); - - setFixedSize(QSize(700, 500)); - - QFile f(":/files/shortcuts.html"); - f.open(QIODevice::ReadOnly); - QTextStream txtS(&f); - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - txtS.setEncoding(QStringConverter::Utf8); -#else - txtS.setCodec(QTextCodec::codecForName("UTF-8")); -#endif - - QString content = txtS.readAll(); - - f.close(); - - shortcuts->setHtml(content); - - setWindowTitle(tr("Keyboard Shortcuts")); -} diff --git a/YACReader/shortcuts_dialog.h b/YACReader/shortcuts_dialog.h deleted file mode 100644 index cf985c398..000000000 --- a/YACReader/shortcuts_dialog.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SHORTCUTS_DIALOG_H -#define SHORTCUTS_DIALOG_H - -#include -#include -#include - -class ShortcutsDialog : public QDialog -{ - Q_OBJECT -public: - ShortcutsDialog(QWidget *parent = nullptr); - -private: - QTextEdit *shortcuts; - QPushButton *close; -public slots: -}; - -#endif // SHORTCUTS_DIALOG_H From 9b196a655a1e3036486197a036736ccd3da410e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 08:54:31 +0200 Subject: [PATCH 02/81] Remove obsolete setting that doesn't have any effect --- .../controllers/v1/foldercontroller.cpp | 16 +++++--------- YACReaderLibrary/server_config_dialog.cpp | 21 ------------------- YACReaderLibrary/server_config_dialog.h | 2 -- common/yacreader_global.h | 1 - 4 files changed, 5 insertions(+), 35 deletions(-) diff --git a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp index 0ba2ff78d..4c791f3ae 100644 --- a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp +++ b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp @@ -30,8 +30,6 @@ void FolderController::service(HttpRequest &request, HttpResponse &response) QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("libraryConfig"); - bool showlessInfoPerFolder = settings->value(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false).toBool(); - HttpSession session = Static::sessionStore->getSession(request, response, false); YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); @@ -170,16 +168,12 @@ void FolderController::service(HttpRequest &request, HttpResponse &response) if (item->isDir()) { t.setVariable(QString("element%1.class").arg(i), "folder"); - if (showlessInfoPerFolder) { + QList children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id); + if (children.length() > 0) { + const ComicDB *comic = static_cast(children.at(0)); + t.setVariable(QString("element%1.image.url").arg(i), QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash)); + } else t.setVariable(QString("element%1.image.url").arg(i), "/images/f.png"); - } else { - QList children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id); - if (children.length() > 0) { - const ComicDB *comic = static_cast(children.at(0)); - t.setVariable(QString("element%1.image.url").arg(i), QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash)); - } else - t.setVariable(QString("element%1.image.url").arg(i), "/images/f.png"); - } t.setVariable(QString("element%1.browse").arg(i), QString("BROWSE").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id))); t.setVariable(QString("element%1.cover.browse").arg(i), QString("").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id))); diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index 4a11b4be4..4c7fdbcb1 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -85,11 +85,6 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) check->setText(tr("enable the server")); check->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); - performanceWorkaroundCheck = new QCheckBox(this); - performanceWorkaroundCheck->move(332, 354); - performanceWorkaroundCheck->setText(tr("display less information about folders in the browser\nto improve the performance")); - performanceWorkaroundCheck->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); - // set black background QPalette palette; QImage image(":/images/serverConfigBackground.png"); @@ -113,12 +108,9 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) check->setChecked(false); } - performanceWorkaroundCheck->setChecked(settings->value(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false).toBool()); - settings->endGroup(); connect(check, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableServer); - connect(performanceWorkaroundCheck, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableperformanceWorkaround); } void ServerConfigDialog::enableServer(int status) @@ -144,19 +136,6 @@ void ServerConfigDialog::enableServer(int status) settings->endGroup(); } -void ServerConfigDialog::enableperformanceWorkaround(int status) -{ - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor - settings->beginGroup("libraryConfig"); - - if (status == Qt::Checked) { - settings->setValue(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, true); - } else { - settings->setValue(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false); - } - settings->endGroup(); -} - void ServerConfigDialog::generateQR() { ip->clear(); diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index 8ab8dd830..34e51c769 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -19,7 +19,6 @@ class ServerConfigDialog : public QDialog QLineEdit *port; QCheckBox *check; - QCheckBox *performanceWorkaroundCheck; QPushButton *close; QPushButton *accept; @@ -30,7 +29,6 @@ public slots: void generateQR(const QString &serverAddress); void regenerateQR(const QString &ip); void enableServer(int status); - void enableperformanceWorkaround(int status); void updatePort(); signals: void portChanged(QString port); diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 5dd34d3bf..43a72a130 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -8,7 +8,6 @@ #define VERSION "9.12.0" -#define REMOTE_BROWSE_PERFORMANCE_WORKAROUND "REMOTE_BROWSE_PERFORMANCE_WORKAROUND" #define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA" #define NUM_DAYS_BETWEEN_VERSION_CHECKS "NUM_DAYS_BETWEEN_VERSION_CHECKS" From 76347060c76bd3e40aeb84ff9c01710358787f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 09:06:13 +0200 Subject: [PATCH 03/81] Update dialog info when it is shown --- YACReaderLibrary/server_config_dialog.cpp | 7 +++++++ YACReaderLibrary/server_config_dialog.h | 1 + 2 files changed, 8 insertions(+) diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index 4c7fdbcb1..fba9aa9e0 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -113,6 +113,13 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) connect(check, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableServer); } +void ServerConfigDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + + generateQR(); +} + void ServerConfigDialog::enableServer(int status) { QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index 34e51c769..7d0e9cfab 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -13,6 +13,7 @@ class ServerConfigDialog : public QDialog Q_OBJECT public: ServerConfigDialog(QWidget *parent = 0); + void showEvent(QShowEvent *event) override; private: QComboBox *ip; From 37f1b49164dff2e07b855e27274c3344346e2239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 09:22:41 +0200 Subject: [PATCH 04/81] Remove commented code --- YACReaderLibrary/server_config_dialog.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index fba9aa9e0..0298d4959 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -36,8 +36,6 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) QLabel *propaganda = new QLabel(tr("YACReader is available for iOS devices. Discover it! "), this); propaganda->move(332, 505); propaganda->setStyleSheet("QLabel {color:#4D4D4D; font-size:13px; font-family: Arial; font-style: italic;}"); - /*propaganda->setWordWrap(true); - propaganda->setFixedWidth(590);*/ propaganda->setOpenExternalLinks(true); // FORM--------------------------------------------------------------------- @@ -62,10 +60,7 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) connect(port, &QLineEdit::textChanged, this, [=](const QString &portValue) { accept->setEnabled(!portValue.isEmpty()); }); - // port->setFixedWidth(100); - // port->move(332, 244); - // port->move(520,110); QValidator *validator = new QIntValidator(1024, 65535, this); port->setValidator(validator); @@ -76,7 +71,6 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) portWidgetLayout->setContentsMargins(0, 0, 0, 0); portWidget->setLayout(portWidgetLayout); portWidget->move(332, 244); - // accept->move(514,149); connect(accept, &QAbstractButton::pressed, this, &ServerConfigDialog::updatePort); // END FORM----------------------------------------------------------------- @@ -85,7 +79,6 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) check->setText(tr("enable the server")); check->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); - // set black background QPalette palette; QImage image(":/images/serverConfigBackground.png"); palette.setBrush(this->backgroundRole(), QBrush(image)); @@ -193,7 +186,6 @@ void ServerConfigDialog::regenerateQR(const QString &ip) void ServerConfigDialog::updatePort() { - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("listener"); settings->setValue("port", port->text().toInt()); From 579281aacc3168e2e9b1f97dc69da0cbe09f18d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 09:23:30 +0200 Subject: [PATCH 05/81] Add an Android link to the server dialog info --- YACReaderLibrary/server_config_dialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index 0298d4959..dd852e419 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -33,7 +33,7 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) qrMessage->setWordWrap(true); qrMessage->setFixedWidth(200); - QLabel *propaganda = new QLabel(tr("YACReader is available for iOS devices. Discover it! "), this); + QLabel *propaganda = new QLabel(tr("YACReader is available for iOS and Android devices.
Discover it for iOS or Android."), this); propaganda->move(332, 505); propaganda->setStyleSheet("QLabel {color:#4D4D4D; font-size:13px; font-family: Arial; font-style: italic;}"); propaganda->setOpenExternalLinks(true); @@ -72,6 +72,7 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) portWidget->setLayout(portWidgetLayout); portWidget->move(332, 244); connect(accept, &QAbstractButton::pressed, this, &ServerConfigDialog::updatePort); + // END FORM----------------------------------------------------------------- check = new QCheckBox(this); From 215261424322be7f897050eb5eb5cf7399984551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 09:25:29 +0200 Subject: [PATCH 06/81] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2864d4ad..be96ea5f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ## WIP +### YACReaderLibrary +* Avoid showing stale information in the server config dialog by updating the connection information when the dialog is opened. + ## 9.12 ### YACReaderLibrary From 3355f2137cee68eff0bd85bab26ebe0ca3c403f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 29 Apr 2023 10:45:57 +0200 Subject: [PATCH 07/81] Remove include --- YACReader/main_window_viewer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index e2f06df9a..b5df07494 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -7,7 +7,6 @@ #include "check_new_version.h" #include "comic.h" #include "bookmarks_dialog.h" -#include "shortcuts_dialog.h" #include "width_slider.h" #include "qnaturalsorting.h" #include "help_about_dialog.h" From a47b706e296c465dc4ade903a7bd0317a6d776ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 30 Apr 2023 14:00:09 +0200 Subject: [PATCH 08/81] Fix a bunch of warnings --- YACReaderLibrary/add_library_dialog.cpp | 3 +-- YACReaderLibrary/comic_flow.cpp | 2 +- YACReaderLibrary/comic_vine/search_volume.h | 1 - YACReaderLibrary/comic_vine/select_volume.cpp | 2 +- YACReaderLibrary/comics_view.cpp | 2 +- YACReaderLibrary/create_library_dialog.cpp | 4 ++-- YACReaderLibrary/folder_content_view.cpp | 2 +- .../import_comics_info_dialog.cpp | 2 +- YACReaderLibrary/import_library_dialog.cpp | 4 ++-- YACReaderLibrary/library_creator.cpp | 4 ++-- YACReaderLibrary/rename_library_dialog.cpp | 2 +- YACReaderLibrary/trayicon_controller.cpp | 2 +- .../yacreader_history_controller.cpp | 20 +++++++++---------- 13 files changed, 24 insertions(+), 26 deletions(-) diff --git a/YACReaderLibrary/add_library_dialog.cpp b/YACReaderLibrary/add_library_dialog.cpp index 13e106946..80c2e8a1b 100644 --- a/YACReaderLibrary/add_library_dialog.cpp +++ b/YACReaderLibrary/add_library_dialog.cpp @@ -68,8 +68,7 @@ void AddLibraryDialog::setupUI() void AddLibraryDialog::add() { - // accept->setEnabled(false); - emit(addLibrary(QDir::cleanPath(path->text()), nameEdit->text())); + emit addLibrary(QDir::cleanPath(path->text()), nameEdit->text()); } void AddLibraryDialog::nameSetted(const QString &text) diff --git a/YACReaderLibrary/comic_flow.cpp b/YACReaderLibrary/comic_flow.cpp index 931aae938..2cc4dbd24 100644 --- a/YACReaderLibrary/comic_flow.cpp +++ b/YACReaderLibrary/comic_flow.cpp @@ -36,7 +36,7 @@ void ComicFlow::setImagePaths(const QStringList &paths) addSlide(img); s = imageFiles.at(i); s.remove(s.size() - 4, 4); - if (QFileInfo(s + ".r").exists()) + if (QFileInfo::exists(s + ".r")) markSlide(i); } diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 49cc0f38c..6a9f1ee79 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -12,7 +12,6 @@ class SearchVolume : public QWidget SearchVolume(QWidget *parent = nullptr); void clean(); void setVolumeInfo(const QString &volume); -public slots: QString getVolumeInfo() const; private: diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index d62e38ebe..3a745ba87 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -59,7 +59,7 @@ SelectVolume::SelectVolume(QWidget *parent) connect(filterEdit, &QLineEdit::textChanged, proxyModel, &QSortFilterProxyModel::setFilterFixedString); - connect(tableVolumes->horizontalHeader(), &QHeaderView::sectionClicked, + connect(tableVolumes->horizontalHeader(), &QHeaderView::sectionClicked, this, [=](int index) { tableVolumes->horizontalHeader()->sortIndicatorSection() == index ? tableVolumes->sortByColumn(index, tableVolumes->horizontalHeader()->sortIndicatorOrder() == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder) : tableVolumes->sortByColumn(index, Qt::AscendingOrder); }); // connections diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index 4d9525d1a..64ab0cf4c 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -24,7 +24,7 @@ ComicsView::ComicsView(QWidget *parent) view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( - view, &QQuickWidget::statusChanged, + view, &QQuickWidget::statusChanged, this, [=](QQuickWidget::Status status) { if (status == QQuickWidget::Error) { QLOG_ERROR() << view->errors(); diff --git a/YACReaderLibrary/create_library_dialog.cpp b/YACReaderLibrary/create_library_dialog.cpp index 2c49d2726..397ae6369 100644 --- a/YACReaderLibrary/create_library_dialog.cpp +++ b/YACReaderLibrary/create_library_dialog.cpp @@ -87,10 +87,10 @@ void CreateLibraryDialog::create() QFileInfo f(path->text()); if (f.exists() && f.isDir() && f.isWritable()) { if (!libraries.contains(nameEdit->text())) { - emit(createLibrary(QDir::cleanPath(path->text()), QDir::cleanPath(path->text()) + "/.yacreaderlibrary", nameEdit->text())); + emit createLibrary(QDir::cleanPath(path->text()), QDir::cleanPath(path->text()) + "/.yacreaderlibrary", nameEdit->text()); close(); } else - emit(libraryExists(nameEdit->text())); + emit libraryExists(nameEdit->text()); } else QMessageBox::critical(NULL, tr("Path not found"), tr("The selected path does not exist or is not a valid path. Be sure that you have write access to this folder")); } diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 33ca36c41..db8eb4602 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -30,7 +30,7 @@ FolderContentView::FolderContentView(QWidget *parent) view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( - view, &QQuickWidget::statusChanged, + view, &QQuickWidget::statusChanged, this, [=](QQuickWidget::Status status) { if (status == QQuickWidget::Error) { QLOG_ERROR() << view->errors(); diff --git a/YACReaderLibrary/import_comics_info_dialog.cpp b/YACReaderLibrary/import_comics_info_dialog.cpp index de635e526..2ed5fd569 100644 --- a/YACReaderLibrary/import_comics_info_dialog.cpp +++ b/YACReaderLibrary/import_comics_info_dialog.cpp @@ -96,7 +96,7 @@ void ImportComicsInfoDialog::close() progressBar->hide(); accept->setDisabled(true); QDialog::close(); - emit(finished(0)); + emit finished(0); } void Importer::run() diff --git a/YACReaderLibrary/import_library_dialog.cpp b/YACReaderLibrary/import_library_dialog.cpp index c288f5eb9..2a065bd61 100644 --- a/YACReaderLibrary/import_library_dialog.cpp +++ b/YACReaderLibrary/import_library_dialog.cpp @@ -97,9 +97,9 @@ void ImportLibraryDialog::add() if (!libraries.contains(nameEdit->text())) { accept->setEnabled(false); progressBar->show(); - emit(unpackCLC(QDir::cleanPath(path->text()), QDir::cleanPath(destPath->text()), nameEdit->text())); + emit unpackCLC(QDir::cleanPath(path->text()), QDir::cleanPath(destPath->text()), nameEdit->text()); } else { - emit(libraryExists(nameEdit->text())); + emit libraryExists(nameEdit->text()); } } diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 6d843cfe0..d9b2e898b 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -154,7 +154,7 @@ void LibraryCreator::run() _database.close(); } QSqlDatabase::removeDatabase(_databaseConnection); - emit(created()); + emit created(); QLOG_INFO() << "Create library END"; } else { QLOG_INFO() << "Starting to update folder" << _sourceFolder << "in library ( " << _source << "," << _target << ")"; @@ -308,7 +308,7 @@ void LibraryCreator::insertComic(const QString &relativePath, const QFileInfo &f numPages = ie.getNumPages(); originalCoverSize = ie.getOriginalCoverSize(); if (numPages > 0) { - emit(comicAdded(relativePath, _target + "/covers/" + hash + ".jpg")); + emit comicAdded(relativePath, _target + "/covers/" + hash + ".jpg"); } } diff --git a/YACReaderLibrary/rename_library_dialog.cpp b/YACReaderLibrary/rename_library_dialog.cpp index 683bb8b13..b249a22c9 100644 --- a/YACReaderLibrary/rename_library_dialog.cpp +++ b/YACReaderLibrary/rename_library_dialog.cpp @@ -54,7 +54,7 @@ void RenameLibraryDialog::setupUI() void RenameLibraryDialog::rename() { // accept->setEnabled(false); - emit(renameLibrary(newNameEdit->text())); + emit renameLibrary(newNameEdit->text()); } void RenameLibraryDialog::nameSetted(const QString &text) diff --git a/YACReaderLibrary/trayicon_controller.cpp b/YACReaderLibrary/trayicon_controller.cpp index d1ca2faa6..79b121d40 100644 --- a/YACReaderLibrary/trayicon_controller.cpp +++ b/YACReaderLibrary/trayicon_controller.cpp @@ -36,7 +36,7 @@ TrayIconController::TrayIconController(QSettings *settings, LibraryWindow *windo #endif } - connect(&trayIcon, &QSystemTrayIcon::activated, + connect(&trayIcon, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) { #ifdef Q_OS_LINUX auto expectedReason = QSystemTrayIcon::Trigger; diff --git a/YACReaderLibrary/yacreader_history_controller.cpp b/YACReaderLibrary/yacreader_history_controller.cpp index 26af82a95..9ac7d4017 100644 --- a/YACReaderLibrary/yacreader_history_controller.cpp +++ b/YACReaderLibrary/yacreader_history_controller.cpp @@ -11,32 +11,32 @@ void YACReaderHistoryController::clear() history.clear(); history.append(YACReaderLibrarySourceContainer(QModelIndex(), YACReaderLibrarySourceContainer::Folder)); // root folder is always the first item - emit(enabledBackward(false)); - emit(enabledForward(false)); + emit enabledBackward(false); + emit enabledForward(false); } void YACReaderHistoryController::backward() { if (currentFolderNavigation > 0) { currentFolderNavigation--; - emit(modelIndexSelected(history.at(currentFolderNavigation))); - emit(enabledForward(true)); + emit modelIndexSelected(history.at(currentFolderNavigation)); + emit enabledForward(true); } if (currentFolderNavigation == 0) - emit(enabledBackward(false)); + emit enabledBackward(false); } void YACReaderHistoryController::forward() { if (currentFolderNavigation < history.count() - 1) { currentFolderNavigation++; - emit(modelIndexSelected(history.at(currentFolderNavigation))); - emit(enabledBackward(true)); + emit modelIndexSelected(history.at(currentFolderNavigation)); + emit enabledBackward(true); } if (currentFolderNavigation == history.count() - 1) - emit(enabledForward(false)); + emit enabledForward(false); } void YACReaderHistoryController::updateHistory(const YACReaderLibrarySourceContainer &source) @@ -54,11 +54,11 @@ void YACReaderHistoryController::updateHistory(const YACReaderLibrarySourceConta if (source != history.at(currentFolderNavigation)) { history.append(source); - emit(enabledBackward(true)); + emit enabledBackward(true); currentFolderNavigation++; } - emit(enabledForward(false)); + emit enabledForward(false); } YACReaderLibrarySourceContainer YACReaderHistoryController::lastSourceContainer() From 6593f03740ecc479be8234db740360d1e842a310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 30 Apr 2023 14:07:35 +0200 Subject: [PATCH 09/81] Remove some unused includes --- YACReader/configuration.cpp | 1 - YACReader/goto_flow.cpp | 1 - YACReader/magnifying_glass.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/YACReader/configuration.cpp b/YACReader/configuration.cpp index 68a9d1731..0217a1229 100644 --- a/YACReader/configuration.cpp +++ b/YACReader/configuration.cpp @@ -7,7 +7,6 @@ #include #include -#include "yacreader_global.h" Configuration::Configuration() { diff --git a/YACReader/goto_flow.cpp b/YACReader/goto_flow.cpp index 7bbc8eae0..ae6b0aa0d 100644 --- a/YACReader/goto_flow.cpp +++ b/YACReader/goto_flow.cpp @@ -1,6 +1,5 @@ #include "goto_flow.h" #include "configuration.h" -#include "comic.h" #include #include diff --git a/YACReader/magnifying_glass.cpp b/YACReader/magnifying_glass.cpp index c6c2d688b..38d8e6296 100644 --- a/YACReader/magnifying_glass.cpp +++ b/YACReader/magnifying_glass.cpp @@ -1,7 +1,6 @@ #include "magnifying_glass.h" #include "viewer.h" #include "configuration.h" -#include "shortcuts_manager.h" #include From 2a1f3febeaa0d66cd02b54976552df1297b87a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 30 Apr 2023 14:17:26 +0200 Subject: [PATCH 10/81] Format --- YACReader/configuration.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReader/configuration.cpp b/YACReader/configuration.cpp index 0217a1229..9e7f64559 100644 --- a/YACReader/configuration.cpp +++ b/YACReader/configuration.cpp @@ -7,7 +7,6 @@ #include #include - Configuration::Configuration() { } From 686e91af574625daaf11e1c91e0f8f9d96bbddec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 30 Apr 2023 14:28:40 +0200 Subject: [PATCH 11/81] Fix missing include --- YACReader/goto_flow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/YACReader/goto_flow.cpp b/YACReader/goto_flow.cpp index ae6b0aa0d..96e42e84f 100644 --- a/YACReader/goto_flow.cpp +++ b/YACReader/goto_flow.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "yacreader_flow.h" From 830d8d911fdacffe920cb0edaeb5aac11ffde022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Wed, 3 May 2023 18:58:32 +0200 Subject: [PATCH 12/81] Fix type It is used as a string, and because how sqlite3 works internally the field can actually store a string, so no need for data migration. --- YACReaderLibrary/db/data_base_management.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index b22a7c739..0e1d0196b 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -178,7 +178,7 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "publisher TEXT," "format TEXT," "color BOOLEAN," - "ageRating BOOLEAN," // this is actually a string (TEXT), funny thing is that the current implementation works + "ageRating TEXT," "synopsis TEXT," "characters TEXT," From f2bf53ce5bbfd89b284e117fff3711c8de4b6b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Fri, 12 May 2023 16:59:23 +0200 Subject: [PATCH 13/81] Add new fields to the DB and make then available to be used in the apps --- YACReader/main_window_viewer.cpp | 2 +- YACReaderLibrary/db/comic_model.cpp | 23 +- YACReaderLibrary/db/comic_model.h | 8 +- YACReaderLibrary/db/data_base_management.cpp | 183 ++++++++++-- YACReaderLibrary/db/data_base_management.h | 1 - YACReaderLibrary/db/folder_model.cpp | 196 +++++-------- YACReaderLibrary/db/folder_model.h | 34 +-- YACReaderLibrary/db/query_parser.cpp | 34 ++- YACReaderLibrary/db/query_parser.h | 3 +- YACReaderLibrary/db_helper.cpp | 239 +++++++++++----- YACReaderLibrary/db_helper.h | 5 +- YACReaderLibrary/library_creator.cpp | 32 ++- YACReaderLibrary/library_window.cpp | 210 ++++++++++---- YACReaderLibrary/library_window.h | 13 +- YACReaderLibrary/properties_dialog.cpp | 8 +- .../server/yacreader_server_data_helper.cpp | 56 +++- common/comic_db.cpp | 266 +++++++++--------- common/comic_db.h | 78 ++--- common/folder.cpp | 23 +- common/folder.h | 96 ++----- common/qnaturalsorting.cpp | 1 + common/yacreader_global.h | 11 +- shortcuts_management/shortcuts_manager.h | 6 + 23 files changed, 947 insertions(+), 581 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index b5df07494..179540e4e 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -1575,7 +1575,7 @@ void MainWindowViewer::sendComic() auto client = new YACReaderLocalClient; connect(client, &YACReaderLocalClient::finished, client, &YACReaderLocalClient::deleteLater); - currentComicDB.info.lastTimeOpened = QDateTime::currentMSecsSinceEpoch() / 1000; + currentComicDB.info.lastTimeOpened = QDateTime::currentSecsSinceEpoch(); viewer->updateComic(currentComicDB); diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index e5fcce180..34f6c1ebf 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -239,6 +239,7 @@ QHash ComicModel::roleNames() const roles[CoverPathRole] = "cover_path"; roles[PublicationDate] = "date"; roles[ReadableTitle] = "readable_title"; + roles[Added] = "added_date"; return roles; } @@ -301,6 +302,10 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const return item->data(Id); else if (role == PublicationDateRole) return QVariant(localizedDate(item->data(PublicationDate).toString())); + else if (role == AddedRole) + return item->data(Added); + else if (role == TypeRole) + return item->data(Type); if (role != Qt::DisplayRole) return QVariant(); @@ -443,6 +448,8 @@ QStringList ComicModel::getPaths(const QString &_source) return paths; } +#define COMIC_MODEL_QUERY_FIELDS "ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date,ci.added,ci.type" + void ComicModel::setupFolderModelData(unsigned long long int folderId, const QString &databasePath) { enableResorting = false; @@ -458,7 +465,7 @@ void ComicModel::setupFolderModelData(unsigned long long int folderId, const QSt { QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date " + selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " "WHERE c.parentId = :parentId"); selectQuery.bindValue(":parentId", folderId); @@ -485,7 +492,7 @@ void ComicModel::setupLabelModelData(unsigned long long parentLabel, const QStri { QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date " + selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " "INNER JOIN comic_label cl ON (c.id == cl.comic_id) " "WHERE cl.label_id = :parentLabelId " @@ -529,7 +536,7 @@ void ComicModel::setupReadingListModelData(unsigned long long parentReadingList, foreach (qulonglong id, ids) { QSqlQuery selectQuery(db); - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date " + selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " "INNER JOIN comic_reading_list crl ON (c.id == crl.comic_id) " "WHERE crl.reading_list_id = :parentReadingList " @@ -566,7 +573,7 @@ void ComicModel::setupFavoritesModelData(const QString &databasePath) { QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date " + selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " "INNER JOIN comic_default_reading_list cdrl ON (c.id == cdrl.comic_id) " "WHERE cdrl.default_reading_list_id = :parentDefaultListId " @@ -595,7 +602,7 @@ void ComicModel::setupReadingModelData(const QString &databasePath) { QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date " + selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " "WHERE ci.hasBeenOpened = 1 AND ci.read = 0 " "ORDER BY ci.lastTimeOpened DESC"); @@ -652,7 +659,7 @@ void ComicModel::setupModelData(QSqlQuery &sqlquery) return naturalSortLessThanCI(c1->data(ComicModel::FileName).toString(), c2->data(ComicModel::FileName).toString()); } else { if (c1->data(ComicModel::Number).isNull() == false && c2->data(ComicModel::Number).isNull() == false) { - return c1->data(ComicModel::Number).toInt() < c2->data(ComicModel::Number).toInt(); + return naturalSortLessThanCI(c1->data(ComicModel::Number).toString(), c2->data(ComicModel::Number).toString()); } else { return c2->data(ComicModel::Number).isNull(); } @@ -794,7 +801,7 @@ QVector ComicModel::setComicsRead(QList l return getReadList(); } -void ComicModel::setComicsManga(QList list, bool isManga) +void ComicModel::setComicsType(QList list, FileType type) { QString connectionName = ""; { @@ -803,7 +810,7 @@ void ComicModel::setComicsManga(QList list, bool isManga) foreach (QModelIndex mi, list) { bool found; ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found); - c.info.manga = isManga; + c.info.type = QVariant::fromValue(type); DBHelper::update(&(c.info), db); } db.commit(); diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index af6e05bd8..b4b5eeda4 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -31,11 +31,13 @@ class ComicModel : public QAbstractItemModel Path = 6, Hash = 7, ReadColumn = 8, - IsBis = 9, + IsBis = 9, // TODO_METADATA: Remove this column CurrentPage = 10, Rating = 11, HasBeenOpened = 12, PublicationDate = 13, + Added = 14, + Type = 15, }; enum Roles { @@ -55,6 +57,8 @@ class ComicModel : public QAbstractItemModel CoverPathRole, PublicationDateRole, ReadableTitle, + AddedRole, + TypeRole, }; enum Mode { @@ -107,7 +111,7 @@ class ComicModel : public QAbstractItemModel // setComicInfoForAllComics(); --> inserta la información común a todos los cómics de una sola vez. // setComicInfoForSelectedComis(QList list); -->inserta la información común para los comics seleccionados QVector setComicsRead(QList list, YACReaderComicReadStatus read); - void setComicsManga(QList list, bool isManga); + void setComicsType(QList list, FileType type); qint64 asignNumbers(QList list, int startingNumber); // void remove(ComicDB * comic, int row); void removeInTransaction(int row); diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 0e1d0196b..0aa71b9e4 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -64,23 +64,29 @@ static QString fields = "title," //"coverSizeRatio," cover may have changed since the info was exported... //"originalCoverSize," // h/w // new 9.8 fields - "manga"; + "manga," + // new 9.13 fields + "added," + "type," + "editor," + "imprint," + "teams," + "locations," + "series," + "alternateSeries," + "alternateNumber," + "alternateCount," + "languageISO," + "seriesGroup," + "mainCharacterOrTeam," + "review," + "tags"; DataBaseManagement::DataBaseManagement() : QObject(), dataBasesList() { } -/*TreeModel * DataBaseManagement::newTreeModel(QString path) -{ - //la consulta se ejecuta... - QSqlQuery selectQuery(loadDatabase(path)); - selectQuery.setForwardOnly(true); - selectQuery.exec("select * from folder order by parentId,name"); - //selectQuery.finish(); - return new TreeModel(selectQuery); -}*/ - QSqlDatabase DataBaseManagement::createDatabase(QString name, QString path) { return createDatabase(QDir::cleanPath(path) + "/" + name + ".ydb"); @@ -106,8 +112,6 @@ QSqlDatabase DataBaseManagement::createDatabase(QString dest) "VALUES (1,'root', '/')", db); } - // query.finish(); - // db.close(); return db; } @@ -156,13 +160,13 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "coverPage INTEGER DEFAULT 1," "numPages INTEGER," - "number INTEGER," + "number TEXT," // changed to text from INTEGER (9.13) "isBis BOOLEAN," "count INTEGER," "volume TEXT," "storyArc TEXT," - "arcNumber INTEGER," + "arcNumber TEXT," // changed to text from INTEGER (9.13) "arcCount INTEGER," "genere TEXT," @@ -174,7 +178,7 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "letterer TEXT," "coverArtist TEXT," - "date TEXT," // dd/mm/yyyy --> se mostrará en 3 campos diferentes + "date TEXT," // publication date dd/mm/yyyy --> se mostrará en 3 campos diferentes "publisher TEXT," "format TEXT," "color BOOLEAN," @@ -190,7 +194,7 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) // new 7.0 fields "hasBeenOpened BOOLEAN DEFAULT 0," - "rating INTEGER DEFAULT 0," + "rating INTEGER DEFAULT 0," // TODO_METADATA change type to REAL with two decimals "currentPage INTEGER DEFAULT 1, " "bookmark1 INTEGER DEFAULT -1, " "bookmark2 INTEGER DEFAULT -1, " @@ -205,8 +209,23 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "coverSizeRatio REAL," "originalCoverSize STRING," // h/w // new 9.8 fields - "manga BOOLEAN DEFAULT 0" - + "manga BOOLEAN DEFAULT 0," // deprecated 9.13 + // new 9.13 fields + "added INTEGER," + "type INTEGER DEFAULT 0," // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, 4 = 4koma + "editor TEXT," + "imprint TEXT," + "teams TEXT," + "locations TEXT," + "series TEXT," + "alternateSeries TEXT," + "alternateNumber TEXT," + "alternateCount INTEGER," + "languageISO TEXT," + "seriesGroup TEXT," + "mainCharacterOrTeam TEXT," + "review TEXT," + "tags TEXT" ")"); success = success && queryComicInfo.exec(); // queryComicInfo.finish(); @@ -226,7 +245,11 @@ bool DataBaseManagement::createTables(QSqlDatabase &database) "firstChildHash TEXT," "customImage TEXT," // new 9.8 fields - "manga BOOLEAN DEFAULT 0," + "manga BOOLEAN DEFAULT 0," // deprecated 9.13 + // new 9.13 fields + "type INTEGER DEFAULT 0," // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, 4 = 4koma + "added INTEGER," + "updated INTEGER," // updated when the folder gets new content "FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)"); success = success && queryFolder.exec(); @@ -460,7 +483,25 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) //-- // new 9.8 fields - "manga = :manga" + "manga = :manga," + + // new 9.13 fields + "added = :added," + "type = :type," // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, + "editor = :editor," + "imprint = :imprint," + "teams = :teams," + "locations = :locations," + "series = :series," + "alternateSeries = :alternateSeries," + "alternateNumber = :alternateNumber," + "alternateCount = :alternateCount," + "languageISO = :languageISO," + "seriesGroup = :seriesGroup," + "mainCharacterOrTeam = :mainCharacterOrTeam," + "review = :review," + "tags = :tags" + //-- " WHERE hash = :hash "); @@ -496,6 +537,21 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) "comicVineID," "lastTimeOpened," "coverSizeRatio," + "manga," + "added," + "type," + "editor," + "imprint," + "teams," + "locations," + "series," + "alternateSeries," + "alternateNumber," + "alternateCount," + "languageISO," + "seriesGroup," + "mainCharacterOrTeam," + "review," "hash)" "VALUES (:title," @@ -539,6 +595,23 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) ":coverSizeRatio," ":originalCoverSize," + ":manga," + ":added," + ":type," + ":editor," + ":imprint," + ":teams," + ":locations," + ":series," + ":alternateSeries," + ":alternateNumber," + ":alternateCount," + ":languageISO," + ":seriesGroup," + ":mainCharacterOrTeam," + ":review," + ":tags," + ":hash )"); QSqlRecord record = newInfo.record(); @@ -596,6 +669,8 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) return b; } + +// TODO: update fields // TODO fix these bindings void DataBaseManagement::bindValuesFromRecord(const QSqlRecord &record, QSqlQuery &query) { @@ -654,6 +729,22 @@ void DataBaseManagement::bindValuesFromRecord(const QSqlRecord &record, QSqlQuer bindValue("coverSizeRatio", record, query); bindValue("originalCoverSize", record, query); + bindValue("added", record, query); + bindValue("type", record, query); + bindValue("editor", record, query); + bindValue("imprint", record, query); + bindValue("teams", record, query); + bindValue("locations", record, query); + bindValue("series", record, query); + bindValue("alternateSeries", record, query); + bindValue("alternateNumber", record, query); + bindValue("alternateCount", record, query); + bindValue("languageISO", record, query); + bindValue("seriesGroup", record, query); + bindValue("mainCharacterOrTeam", record, query); + bindValue("review", record, query); + bindValue("tags", record, query); + bindValue("hash", record, query); } @@ -757,6 +848,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) bool pre8 = false; bool pre9_5 = false; bool pre9_8 = false; + bool pre9_13 = false; QString fullPath = path + "/library.ydb"; @@ -770,6 +862,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) pre9_5 = true; if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.8.0") < 0) pre9_8 = true; + if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.13.0") < 0) + pre9_13 = true; QString connectionName = ""; bool returnValue = false; @@ -895,6 +989,53 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path) returnValue = returnValue && successAddingColumns; } } + + if (pre9_13) { + { // comic_info + QStringList columnDefs; + columnDefs << "added INTEGER"; + columnDefs << "type INTEGER DEFAULT 0"; // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, + columnDefs << "editor TEXT"; + columnDefs << "imprint TEXT"; + columnDefs << "teams TEXT"; + columnDefs << "locations TEXT"; + columnDefs << "series TEXT"; + columnDefs << "alternateSeries TEXT"; + columnDefs << "alternateNumber TEXT"; + columnDefs << "alternateCount INTEGER"; + columnDefs << "languageISO TEXT"; + columnDefs << "seriesGroup TEXT"; + columnDefs << "mainCharacterOrTeam TEXT"; + columnDefs << "review TEXT"; + columnDefs << "tags TEXT"; + bool successAddingColumns = addColumns("comic_info", columnDefs, db); + returnValue = returnValue && successAddingColumns; + + QSqlQuery updateTypeQueryToManga(db); + updateTypeQueryToManga.prepare("UPDATE comic_info SET type = manga"); + bool successMigratingManga = updateTypeQueryToManga.exec(); + returnValue = returnValue && successMigratingManga; + + QSqlQuery updateNumberQueryToBis(db); + updateNumberQueryToBis.prepare("UPDATE comic_info SET number = number + 0.5 WHERE isBis = 1"); + bool successMigratingBis = updateNumberQueryToBis.exec(); + returnValue = returnValue && successMigratingBis; + } + { // folder + QStringList columnDefs; + columnDefs << "added INTEGER"; + columnDefs << "updated INTEGER"; + columnDefs << "type INTEGER DEFAULT 0"; + + bool successAddingColumns = addColumns("folder", columnDefs, db); + returnValue = returnValue && successAddingColumns; + + QSqlQuery updateTypeQueryToManga(db); + updateTypeQueryToManga.prepare("UPDATE folder SET type = manga"); + bool successMigratingManga = updateTypeQueryToManga.exec(); + returnValue = returnValue && successMigratingManga; + } + } } connectionName = db.connectionName(); } diff --git a/YACReaderLibrary/db/data_base_management.h b/YACReaderLibrary/db/data_base_management.h index 2c269e2ed..293021622 100644 --- a/YACReaderLibrary/db/data_base_management.h +++ b/YACReaderLibrary/db/data_base_management.h @@ -42,7 +42,6 @@ class DataBaseManagement : public QObject public: DataBaseManagement(); - // TreeModel * newTreeModel(QString path); // crea una base de datos y todas sus tablas static QSqlDatabase createDatabase(QString name, QString path); static QSqlDatabase createDatabase(QString dest); diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 97a617604..e2db89120 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -6,8 +6,6 @@ #include "db_helper.h" #include "qnaturalsorting.h" #include "yacreader_global_gui.h" -#include "QsLog.h" -#include "query_parser.h" #include @@ -61,14 +59,12 @@ FolderModel::FolderModel(QObject *parent) FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent) : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr) { - // lo m�s probable es que el nodo ra�z no necesite tener informaci�n QList rootData; - rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) + rootData << "root"; // id 1, parent 1, title "root" rootItem = new FolderItem(rootData); rootItem->id = ROOT; rootItem->parentItem = nullptr; setupModelData(sqlquery, rootItem); - // sqlquery.finish(); } FolderModel::~FolderModel() @@ -98,7 +94,11 @@ QHash FolderModel::roleNames() const roles[IdRole] = "id"; roles[MangaRole] = "is_manga"; roles[CoverPathRole] = "cover_path"; - roles[FolderName] = "name"; + roles[FolderNameRole] = "name"; + roles[NumChildrenRole] = "num_children"; + roles[TypeRole] = "type"; + roles[AddedRole] = "added"; + roles[UpdatedRole] = "type"; return roles; } @@ -150,7 +150,7 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const #endif } - if (role == FolderModel::FolderName) { + if (role == FolderModel::FolderNameRole) { return item->data(FolderModel::Name); } @@ -169,6 +169,18 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const if (role == FolderModel::CoverPathRole) return getCoverUrlPathForComicHash(item->data(FirstChildHash).toString()); + if (role == FolderModel::NumChildrenRole) + return item->data(NumChildren); + + if (role == FolderModel::TypeRole) + return item->data(Type); + + if (role == FolderModel::AddedRole) + return item->data(Added); + + if (role == FolderModel::UpdatedRole) + return item->data(Updated); + if (role != Qt::DisplayRole) return QVariant(); @@ -323,60 +335,34 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent) int manga = record.indexOf("manga"); int id = record.indexOf("id"); int parentId = record.indexOf("parentId"); + int numChildren = record.indexOf("numChildren"); int firstChildHash = record.indexOf("firstChildHash"); + int customImage = record.indexOf("customImage"); + int type = record.indexOf("type"); + int added = record.indexOf("added"); + int updated = record.indexOf("updated"); while (sqlquery.next()) { QList data; - data << sqlquery.value(name).toString(); - data << sqlquery.value(path).toString(); - data << sqlquery.value(finished).toBool(); - data << sqlquery.value(completed).toBool(); - data << sqlquery.value(manga).toBool(); - data << sqlquery.value(firstChildHash).toString(); - auto item = new FolderItem(data); - - item->id = sqlquery.value(id).toULongLong(); - // la inserci�n de hijos se hace de forma ordenada - FolderItem *parent = items.value(sqlquery.value(parentId).toULongLong()); - // if(parent !=0) //TODO if parent==0 the parent of item was removed from the DB and delete on cascade didn't work, ERROR. - parent->appendChild(item); - // se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones - items.insert(item->id, item); - } -} - -void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent) -{ - Q_UNUSED(parent); + data << sqlquery.value(name); + data << sqlquery.value(path); + data << sqlquery.value(finished); + data << sqlquery.value(completed); + data << sqlquery.value(manga); + data << sqlquery.value(numChildren); + data << sqlquery.value(firstChildHash); + data << sqlquery.value(customImage); + data << sqlquery.value(type); + data << sqlquery.value(added); + data << sqlquery.value(updated); - QSqlRecord record = sqlquery.record(); - - int name = record.indexOf("name"); - int path = record.indexOf("path"); - int finished = record.indexOf("finished"); - int completed = record.indexOf("completed"); - int manga = record.indexOf("manga"); - int id = record.indexOf("id"); - int parentId = record.indexOf("parentId"); - int firstChildHash = record.indexOf("firstChildHash"); - - while (sqlquery.next()) { - QList data; - - data << sqlquery.value(name).toString(); - data << sqlquery.value(path).toString(); - data << sqlquery.value(finished).toBool(); - data << sqlquery.value(completed).toBool(); - data << sqlquery.value(manga).toBool(); - data << sqlquery.value(firstChildHash).toString(); auto item = new FolderItem(data); item->id = sqlquery.value(id).toULongLong(); // la inserci�n de hijos se hace de forma ordenada FolderItem *parent = items.value(sqlquery.value(parentId).toULongLong()); - if (parent != 0) // TODO if parent==0 the parent of item was removed from the DB and delete on cascade didn't work, ERROR. - parent->appendChild(item); + parent->appendChild(item); // se a�ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones items.insert(item->id, item); } @@ -406,7 +392,7 @@ void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool if (!isSubfolder) { Folder f = DBHelper::loadFolder(item->id, db); - f.setCompleted(status); + f.completed = status; DBHelper::update(f, db); } } @@ -430,7 +416,7 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s if (!isSubfolder) { Folder f = DBHelper::loadFolder(item->id, db); - f.setFinished(status); + f.finished = status; DBHelper::update(f, db); } } @@ -439,10 +425,10 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s } QSqlDatabase::removeDatabase(connectionName); - emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash)); + emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Updated)); } -void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga) +void FolderModel::updateFolderType(const QModelIndexList &list, YACReader::FileType type) { QString connectionName = ""; { @@ -451,19 +437,19 @@ void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga) foreach (QModelIndex mi, list) { auto item = static_cast(mi.internalPointer()); - std::function setManga; - setManga = [&setManga](FolderItem *item, bool manga) -> void { - item->setData(FolderModel::Manga, manga); + std::function setType; + setType = [&setType](FolderItem *item, YACReader::FileType type) -> void { + item->setData(FolderModel::Type, QVariant::fromValue(type)); for (auto child : item->children()) { - setManga(child, manga); + setType(child, type); } }; - setManga(item, manga); + setType(item, type); if (!isSubfolder) { - DBHelper::updateFolderTreeManga(item->id, db, manga); + DBHelper::updateFolderTreeType(item->id, db, type); } } db.commit(); @@ -471,7 +457,7 @@ void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga) } QSqlDatabase::removeDatabase(connectionName); - emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash)); + emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Updated)); } QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi) @@ -552,7 +538,13 @@ Folder FolderModel::getFolder(const QModelIndex &mi) folderItem->parent()->data(Columns::Path).toString() + "/" + name, folderItem->data(Columns::Completed).toBool(), folderItem->data(Columns::Finished).toBool(), - folderItem->data(Columns::Manga).toBool()); + folderItem->data(Columns::Manga).toBool(), + folderItem->data(Columns::NumChildren).toInt(), + folderItem->data(Columns::FirstChildHash).toString(), + folderItem->data(Columns::CustomImage).toString(), + folderItem->data(Columns::Type).value(), + folderItem->data(Columns::Added).toLongLong(), + folderItem->data(Columns::Updated).toLongLong()); return folder; } @@ -589,74 +581,6 @@ QModelIndex FolderModel::getIndexFromFolder(const Folder &folder, const QModelIn return QModelIndex(); } -void FolderModel::fetchMoreFromDB(const QModelIndex &parent) -{ - FolderItem *item; - if (parent.isValid()) - item = static_cast(parent.internalPointer()); - else - item = rootItem; - - // Remove all children - if (item->childCount() > 0) { - beginRemoveRows(parent, 0, item->childCount() - 1); - item->clearChildren(); - endRemoveRows(); - } - - QString connectionName = ""; - { - QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); - - QList items; - QList nextLevelItems; - - QSqlQuery selectQuery(db); - selectQuery.prepare("select * from folder where id <> 1 and parentId = :parentId order by parentId,name"); - - items << item; - bool firstLevelUpdated = false; - while (items.size() > 0) { - nextLevelItems.clear(); - foreach (FolderItem *item, items) { - QLOG_DEBUG() << "ID " << item->id; - selectQuery.bindValue(":parentId", item->id); - - selectQuery.exec(); - - if (!firstLevelUpdated) { - // NO size support - int numResults = 0; - while (selectQuery.next()) - numResults++; - - if (!selectQuery.seek(-1)) - selectQuery.exec(); - // END no size support - - beginInsertRows(parent, 0, numResults - 1); - } - - updateFolderModelData(selectQuery, item); - - if (!firstLevelUpdated) { - endInsertRows(); - firstLevelUpdated = true; - } - - nextLevelItems << item->children(); - } - - items.clear(); - items = nextLevelItems; - } - connectionName = db.connectionName(); - } - QLOG_DEBUG() << "item->childCount()-1" << item->childCount() - 1; - - QSqlDatabase::removeDatabase(connectionName); -} - QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QModelIndex &parent) { FolderItem *parentItem; @@ -670,7 +594,9 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod newFolder.name = folderName; newFolder.parentId = parentItem->id; newFolder.path = parentItem->data(Columns::Path).toString() + "/" + folderName; - newFolder.setManga(parentItem->data(Columns::Manga).toBool()); + newFolder.manga = parentItem->data(Columns::Manga).toBool(); + newFolder.type = parentItem->data(Columns::Type).value(); + QString connectionName = ""; { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); @@ -687,7 +613,13 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod data << newFolder.path; data << false; // finished data << true; // completed - data << newFolder.isManga(); + data << newFolder.manga; + data << 0; // numChildren + data << QVariant(); // first child hash, new folder is empty + data << QVariant(); // custom cover + data << QVariant::fromValue(newFolder.type); + data << newFolder.added; + data << newFolder.updated; auto item = new FolderItem(data); item->id = newFolder.id; diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index cae4de9ed..6dae78c54 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -66,13 +66,10 @@ class FolderModel : public QAbstractItemModel void setupModelData(QString path); QString getDatabase(); QString getFolderPath(const QModelIndex &folder); - // QModelIndex indexFromItem(FolderItem * item, int column); - - // bool isFilterEnabled(){return filterEnabled;}; void updateFolderCompletedStatus(const QModelIndexList &list, bool status); void updateFolderFinishedStatus(const QModelIndexList &list, bool status); - void updateFolderManga(const QModelIndexList &list, bool manga); + void updateFolderType(const QModelIndexList &list, YACReader::FileType type); QStringList getSubfoldersNames(const QModelIndex &mi); FolderModel *getSubfoldersModel(const QModelIndex &mi); @@ -80,28 +77,35 @@ class FolderModel : public QAbstractItemModel Folder getFolder(const QModelIndex &mi); QModelIndex getIndexFromFolder(const Folder &folder, const QModelIndex &parent = QModelIndex()); - void fetchMoreFromDB(const QModelIndex &parent); - QModelIndex addFolderAtParent(const QString &folderName, const QModelIndex &parent); Q_INVOKABLE QUrl getCoverUrlPathForComicHash(const QString &hash) const; enum Columns { Name = 0, - Path = 1, - Finished = 2, - Completed = 3, - Manga = 4, - FirstChildHash = 5 - }; // id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL + Path, + Finished, + Completed, + Manga, // deprecated + NumChildren, + FirstChildHash, + CustomImage, + Type, // FileType + Added, + Updated, + }; enum Roles { FinishedRole = Qt::UserRole + 1, CompletedRole, IdRole, - MangaRole, + MangaRole, // deprecated CoverPathRole, - FolderName, + FolderNameRole, + NumChildrenRole, + TypeRole, + AddedRole, + UpdatedRole, }; bool isSubfolder; @@ -112,9 +116,7 @@ public slots: private: void fullSetup(QSqlQuery &sqlquery, FolderItem *parent); - void setupModelData(QSqlQuery &sqlquery, FolderItem *parent); - void updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent); FolderItem *rootItem; // el árbol QMap items; // relación entre folders diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 2015fd73a..f9d19e003 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -5,14 +5,17 @@ #include #include +#include + const std::map> QueryParser::fieldNames { - { FieldType::numeric, { "numpages", "number", "count", "arcnumber", "arccount" } }, - { FieldType::text, { "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes" } }, - { FieldType::boolean, { "isbis", "color", "read", "manga" } }, - { FieldType::date, { "date" } }, + { FieldType::numeric, { "numpages", "count", "arccount", "alternateCount" } }, + { FieldType::text, { "number", "arcnumber", "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes", "editor", "imprint", "teams", "locations", "series", "alternateSeries", "alternateNumber", "languageISO", "seriesGroup", "mainCharacterOrTeam", "review", "tags" } }, + { FieldType::boolean, { "isbis", "color", "read" } }, + { FieldType::date, { "date", "added", "lastTimeOpened" } }, { FieldType::filename, { "filename" } }, { FieldType::folder, { "folder" } }, - { FieldType::booleanFolder, { "completed", "finished" } }, + { FieldType::booleanFolder, { "completed", "finished" } }, // TODO_METADTA include new folder fields, e.g. type + { FieldType::enumField, { "type" } } }; int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPosition) const @@ -26,7 +29,7 @@ int QueryParser::TreeNode::buildSqlString(std::string &sqlString, int bindPositi } sqlString += "UPPER(c.filename) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ") OR "; sqlString += "UPPER(f.name) LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; - } else if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean })) { + } else if (isIn(fieldType(children[0].t), { FieldType::numeric, FieldType::boolean, FieldType::enumField })) { sqlString += "ci." + children[0].t + " = :bindPosition" + std::to_string(bindPosition) + " "; } else if (fieldType(children[0].t) == FieldType::filename) { sqlString += "(UPPER(c." + children[0].t + ") LIKE UPPER(:bindPosition" + std::to_string(bindPosition) + ")) "; @@ -67,6 +70,24 @@ int QueryParser::TreeNode::bindValues(QSqlQuery &selectQuery, int bindPosition) } else { selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(value)); } + } else if ((isIn(fieldType(children[0].t), { FieldType::enumField }))) { + auto enumType = children[0].t; + auto value = toLower(children[1].t); + if (enumType == "type") { + if (value == "comic") { + selectQuery.bindValue(QString::fromStdString(bind_string), 0); + } else if (value == "manga") { + selectQuery.bindValue(QString::fromStdString(bind_string), 1); + } else if (value == "westernmanga") { + selectQuery.bindValue(QString::fromStdString(bind_string), 2); + } else if (value == "webcomic" || value == "web") { + selectQuery.bindValue(QString::fromStdString(bind_string), 3); + } else if (value == "4koma" || value == "yonkoma") { + selectQuery.bindValue(QString::fromStdString(bind_string), 4); + } + } else { + selectQuery.bindValue(QString::fromStdString(bind_string), std::stoi(children[1].t)); + } } else { selectQuery.bindValue(QString::fromStdString(bind_string), QString::fromStdString("%%" + children[1].t + "%%")); } @@ -232,6 +253,7 @@ QueryParser::TreeNode QueryParser::baseToken() return TreeNode("token", { TreeNode("all", {}), TreeNode(token(true), {}) }); } + // TODO ":" should come from the lexer as a token auto words(split(token(true), ':')); if (words.size() > 1 && fieldType(words[0].toStdString()) != FieldType::unknown) { diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 69a5a3156..427723c27 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -85,7 +85,8 @@ class QueryParser date, folder, booleanFolder, - filename }; + filename, + enumField }; static FieldType fieldType(const std::string &str); static std::string join(const QStringList &strings, const std::string &delim); diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 7d2bb8f1b..98f774247 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -66,7 +66,7 @@ QList DBHelper::getFolderComicsFromLibraryForReading(qulonglong l return naturalSortLessThanCI(c1->name, c2->name); } else { if (c1->info.number.isNull() == false && c2->info.number.isNull() == false) { - return c1->info.number.toInt() < c2->info.number.toInt(); + return naturalSortLessThanCI(c1->info.number.toString(), c2->info.number.toString()); } else { return c2->info.number.isNull(); } @@ -637,9 +637,28 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db) //-- // new 9.8 fields - "manga = :manga" + "manga = :manga," //-- - " WHERE id = :id "); + + // new 9.13 fields + "added = :added," + "type = :type," + "editor = :editor," + "imprint = :imprint," + "teams = :teams," + "locations = :locations," + "series = :series," + "alternateSeries = :alternateSeries," + "alternateNumber = :alternateNumber," + "alternateCount = :alternateCount," + "languageISO = :languageISO," + "seriesGroup = :seriesGroup," + "mainCharacterOrTeam = :mainCharacterOrTeam," + "review = :review," + "tags = :tags" + + //-- + " WHERE id = :id"); updateComicInfo.bindValue(":title", comicInfo->title); @@ -698,7 +717,28 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db) updateComicInfo.bindValue(":coverSizeRatio", comicInfo->coverSizeRatio); updateComicInfo.bindValue(":originalCoverSize", comicInfo->originalCoverSize); + updateComicInfo.bindValue(":added", comicInfo->added); + auto intType = static_cast(comicInfo->type.value()); + updateComicInfo.bindValue(":type", intType); + updateComicInfo.bindValue(":editor", comicInfo->editor); + updateComicInfo.bindValue(":imprint", comicInfo->imprint); + updateComicInfo.bindValue(":teams", comicInfo->teams); + updateComicInfo.bindValue(":locations", comicInfo->locations); + updateComicInfo.bindValue(":series", comicInfo->series); + updateComicInfo.bindValue(":alternateSeries", comicInfo->alternateSeries); + updateComicInfo.bindValue(":alternateNumber", comicInfo->alternateNumber); + updateComicInfo.bindValue(":alternateCount", comicInfo->alternateCount); + updateComicInfo.bindValue(":languageISO", comicInfo->languageISO); + updateComicInfo.bindValue(":seriesGroup", comicInfo->seriesGroup); + updateComicInfo.bindValue(":mainCharacterOrTeam", comicInfo->mainCharacterOrTeam); + updateComicInfo.bindValue(":review", comicInfo->review); + updateComicInfo.bindValue(":tags", comicInfo->tags); + updateComicInfo.exec(); + + QLOG_INFO() << updateComicInfo.lastError().databaseText(); + QLOG_INFO() << updateComicInfo.lastError().text(); + QLOG_INFO() << updateComicInfo.lastQuery(); } void DBHelper::updateRead(ComicInfo *comicInfo, QSqlDatabase &db) @@ -718,12 +758,10 @@ void DBHelper::update(const Folder &folder, QSqlDatabase &db) QSqlQuery updateFolderInfo(db); updateFolderInfo.prepare("UPDATE folder SET " "finished = :finished, " - "completed = :completed, " - "manga = :manga " + "completed = :completed " "WHERE id = :id "); - updateFolderInfo.bindValue(":finished", folder.isFinished() ? 1 : 0); - updateFolderInfo.bindValue(":completed", folder.isCompleted() ? 1 : 0); - updateFolderInfo.bindValue(":manga", folder.isManga() ? 1 : 0); + updateFolderInfo.bindValue(":finished", folder.finished ? 1 : 0); + updateFolderInfo.bindValue(":completed", folder.completed ? 1 : 0); updateFolderInfo.bindValue(":id", folder.id); updateFolderInfo.exec(); } @@ -762,7 +800,7 @@ Folder DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase &db) } else { for (auto item : updatedSubfolders) { auto f = static_cast(item); - auto firstChildHash = f->getFirstChildHash(); + auto firstChildHash = f->firstChildHash; if (!firstChildHash.isEmpty()) { coverHash = firstChildHash; break; @@ -770,16 +808,16 @@ Folder DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase &db) } } - folder.setNumChildren(subfolders.count() + comics.count()); - folder.setFirstChildHash(coverHash); + folder.numChildren = subfolders.count() + comics.count(); + folder.firstChildHash = coverHash; QSqlQuery updateFolderInfo(db); updateFolderInfo.prepare("UPDATE folder SET " "numChildren = :numChildren, " "firstChildHash = :firstChildHash " "WHERE id = :id "); - updateFolderInfo.bindValue(":numChildren", folder.getNumChildren()); - updateFolderInfo.bindValue(":firstChildHash", folder.getFirstChildHash()); + updateFolderInfo.bindValue(":numChildren", folder.numChildren); + updateFolderInfo.bindValue(":firstChildHash", folder.firstChildHash); updateFolderInfo.bindValue(":id", folderId); updateFolderInfo.exec(); @@ -854,7 +892,7 @@ void DBHelper::updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatab updateComicInfo.bindValue(":read", comicInfo.read ? 1 : 0); updateComicInfo.bindValue(":currentPage", comicInfo.currentPage); updateComicInfo.bindValue(":hasBeenOpened", comicInfo.hasBeenOpened ? 1 : 0); - updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentMSecsSinceEpoch() / 1000); + updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentSecsSinceEpoch()); updateComicInfo.bindValue(":id", comicInfo.id); updateComicInfo.bindValue(":rating", comicInfo.rating); updateComicInfo.exec(); @@ -1067,7 +1105,7 @@ void DBHelper::updateFromRemoteClientWithHash(const QList &comics) updateComicInfo.bindValue(":read", info.read ? 1 : 0); updateComicInfo.bindValue(":currentPage", info.currentPage); updateComicInfo.bindValue(":hasBeenOpened", info.hasBeenOpened ? 1 : 0); - updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentMSecsSinceEpoch() / 1000); + updateComicInfo.bindValue(":lastTimeOpened", QDateTime::currentSecsSinceEpoch()); updateComicInfo.bindValue(":id", info.id); updateComicInfo.bindValue(":rating", info.rating); updateComicInfo.exec(); @@ -1195,11 +1233,12 @@ void DBHelper::updateComicsInfo(QList &comics, const QString &databaseP qulonglong DBHelper::insert(Folder *folder, QSqlDatabase &db) { QSqlQuery query(db); - query.prepare("INSERT INTO folder (parentId, name, path) " - "VALUES (:parentId, :name, :path)"); + query.prepare("INSERT INTO folder (parentId, name, path, added) " + "VALUES (:parentId, :name, :path, :added)"); query.bindValue(":parentId", folder->parentId); query.bindValue(":name", folder->name); query.bindValue(":path", folder->path); + query.bindValue(":added", QDateTime::currentSecsSinceEpoch()); query.exec(); return query.lastInsertId().toULongLong(); @@ -1207,16 +1246,21 @@ qulonglong DBHelper::insert(Folder *folder, QSqlDatabase &db) qulonglong DBHelper::insert(ComicDB *comic, QSqlDatabase &db, bool insertAllInfo) { + auto added = QDateTime::currentSecsSinceEpoch(); + if (!comic->info.existOnDb) { QSqlQuery comicInfoInsert(db); - comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages,coverSizeRatio,originalCoverSize) " - "VALUES (:hash,:numPages,:coverSizeRatio,:originalCoverSize)"); + + comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages,coverSizeRatio,originalCoverSize,added) " + "VALUES (:hash,:numPages,:coverSizeRatio,:originalCoverSize,:added)"); comicInfoInsert.bindValue(":hash", comic->info.hash); comicInfoInsert.bindValue(":numPages", comic->info.numPages); comicInfoInsert.bindValue(":coverSizeRatio", comic->info.coverSizeRatio); comicInfoInsert.bindValue(":originalCoverSize", comic->info.originalCoverSize); + comicInfoInsert.bindValue(":added", added); comicInfoInsert.exec(); comic->info.id = comicInfoInsert.lastInsertId().toULongLong(); + comic->info.added = added; comic->_hasCover = false; if (insertAllInfo) { @@ -1234,6 +1278,14 @@ qulonglong DBHelper::insert(ComicDB *comic, QSqlDatabase &db, bool insertAllInfo query.bindValue(":path", comic->path); query.exec(); + QSqlQuery updateFolder(db); + updateFolder.prepare("UPDATE folder SET " + "updated = :updated " + "WHERE id = :id "); + updateFolder.bindValue(":updated", added); + updateFolder.bindValue(":id", comic->parentId); + updateFolder.exec(); + return query.lastInsertId().toULongLong(); } @@ -1342,6 +1394,7 @@ void DBHelper::insertComicsInReadingList(const QList &comicsList, qulon db.commit(); } + // queries QList DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDatabase &db, bool sort) { @@ -1356,20 +1409,33 @@ QList DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDat int name = record.indexOf("name"); int path = record.indexOf("path"); + int finished = record.indexOf("finished"); + int completed = record.indexOf("completed"); + int manga = record.indexOf("manga"); int id = record.indexOf("id"); int numChildren = record.indexOf("numChildren"); int firstChildHash = record.indexOf("firstChildHash"); int customImage = record.indexOf("customImage"); + int type = record.indexOf("type"); + int added = record.indexOf("added"); + int updated = record.indexOf("updated"); Folder *currentItem; while (selectQuery.next()) { // TODO sort by sort indicator and name currentItem = new Folder(selectQuery.value(id).toULongLong(), parentId, selectQuery.value(name).toString(), selectQuery.value(path).toString()); - if (!selectQuery.value(numChildren).isNull() && selectQuery.value(numChildren).isValid()) - currentItem->setNumChildren(selectQuery.value(numChildren).toInt()); - currentItem->setFirstChildHash(selectQuery.value(firstChildHash).toString()); - currentItem->setCustomImage(selectQuery.value(customImage).toString()); + currentItem->finished = selectQuery.value(finished).toBool(); + currentItem->completed = selectQuery.value(completed).toBool(); + if (!selectQuery.value(numChildren).isNull() && selectQuery.value(numChildren).isValid()) { + currentItem->numChildren = selectQuery.value(numChildren).toInt(); + } + currentItem->firstChildHash = selectQuery.value(firstChildHash).toString(); + currentItem->customImage = selectQuery.value(customImage).toString(); + currentItem->manga = selectQuery.value(manga).toBool(); + currentItem->type = selectQuery.value(type).value(); + currentItem->added = selectQuery.value(added).toLongLong(); + currentItem->updated = selectQuery.value(updated).toLongLong(); int lessThan = 0; @@ -1524,21 +1590,21 @@ QList