diff --git a/Qt5-DROP.md b/Qt5-DROP.md new file mode 100644 index 00000000..658c4c28 --- /dev/null +++ b/Qt5-DROP.md @@ -0,0 +1,208 @@ +# Qt5 Drop - Cleanup Checklist + +Inventory of all Qt5 compatibility code and version branching across the project. +Goal: support only Qt6, remove all Qt5 conditionals and dead branches. + +--- + +## 1. Build System (.pro / .pri files) + +### core5compat module additions +These add `QT += core5compat` for Qt6 builds. Needed by third-party QtWebApp (QTextCodec, QRegExp). + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 51 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReader/YACReader.pro` | 53 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 20 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 40 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` (duplicate) | + +**Action**: Replace conditionals with unconditional `QT += core5compat` (still needed for QtWebApp). Remove the duplicate in YACReaderLibraryServer. + +### macextras module (Qt5-only, removed in Qt6) + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 44 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | +| `YACReader/YACReader.pro` | 48 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | + +**Action**: Remove these lines entirely. + +### gui-private module (Qt 6.7+) + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 53-55 | `greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private }` | +| `YACReader/YACReader.pro` | 55-57 | Same | + +**Action**: Simplify to `greaterThan(QT_MINOR_VERSION, 6): QT += gui-private` (drop the Qt5 guard). + +### Poppler backend version branching + +| File | Lines | What | +|------|-------|------| +| `dependencies/pdf_backend.pri` | 60-84 | Qt5 uses poppler-qt5, Qt6 uses poppler-qt6 (pkg-config, include paths, link flags) | + +**Action**: Keep only the Qt6 (poppler-qt6) branch, remove poppler-qt5 paths. + +### Minimum version check + +| File | Lines | What | +|------|-------|------| +| `config.pri` | 18-41 | `minQtVersion()` function, enforces minimum Qt 5.15.0 | + +**Action**: Update minimum to Qt 6.x. + +### QML resource branching (DONE) + +| File | Lines | What | +|------|-------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 317-321 | Was `greaterThan(QT_MAJOR_VERSION, 5) { qml6.qrc } else { qml.qrc }` | + +**Action**: Already cleaned up - now unconditional `RESOURCES += qml.qrc`. + +### Qt4 compatibility in third-party + +| File | Line | Code | +|------|------|------| +| `third_party/QsLog/QsLog.pri` | 11 | `greaterThan(QT_MAJOR_VERSION, 4): QT += widgets` | + +**Action**: Replace with unconditional `QT += widgets`. + +--- + +## 2. C++ Source Code (#if QT_VERSION checks) + +### Qt5 vs Qt6 API changes (own code) + +| File | Line(s) | Qt5 branch | Qt6 branch | API change | +|------|---------|------------|------------|------------| +| `common/pdf_comic.h` | 49 | `#include "poppler-qt5.h"` | `#include ` | Poppler header | +| `common/pdf_comic.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | +| `common/comic.cpp` | 812 | `auto _pdfComic = Poppler::Document::load()` | `pdfComic = Poppler::Document::load()` | Poppler return type | +| `YACReaderLibrary/initial_comic_info_extractor.cpp` | 44 | Same Poppler pattern | Same | Poppler return type | +| `YACReader/mouse_handler.cpp` | 22, 56, 107 | `QPointF(event->x(), event->y())` | `event->position()` | QMouseEvent API | +| `YACReader/viewer.cpp` | 762 | `pixmap(Qt::ReturnByValue)` | `pixmap()` | QPixmap return semantics | +| `custom_widgets/help_about_dialog.cpp` | 14, 88 | `QTextCodec` / `setCodec()` | `QStringConverter` / `setEncoding()` | Text encoding API | +| `YACReader/translator.cpp` | 291 | `player->setMedia()` | `player->setSource()` | QMediaPlayer API | +| `YACReaderLibrary/comic_vine/comic_vine_dialog.cpp` | 149, 160 | `QtConcurrent::run(this, &fn, args)` | `QtConcurrent::run(&fn, this, args)` | Argument order | +| `YACReaderLibrary/library_window.cpp` | 173 | Different key handling | `keySequence[0]` (QKeyCombination) | Key event API | +| `YACReaderLibrary/library_window.cpp` | 790-793 | Qt5 toolbar connections | Qt6 toolbar connections | macOS toolbar | +| `YACReader/main_window_viewer.cpp` | 483, 1357 | Qt5 toolbar/slider | Qt6 toolbar/slider | macOS toolbar | +| `YACReaderLibrary/trayhandler.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | +| `YACReader/main.cpp` | 102 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | +| `YACReaderLibraryServer/main.cpp` | 53 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | + +**Action**: For each, keep only the Qt6 branch, remove the `#if`/`#else`/`#endif` and the Qt5 code. + +### Qt4 vs Qt5 leftovers (very old) + +| File | Line(s) | What | +|------|---------|------| +| `custom_widgets/yacreader_table_view.cpp` | 31, 39, 46 | `#if QT_VERSION >= 0x050000` — `setResizeMode` vs `setSectionResizeMode` | +| `YACReaderLibrary/comic_vine/scraper_tableview.cpp` | 9, 16, 23 | Same Qt4 vs Qt5 header API | +| `YACReader/translator.cpp` | 3, 164 | `#if QT_VERSION >= 0x050000` — Phonon vs QMediaPlayer | +| `YACReader/main.cpp` | 135 | `#if QT_VERSION >= 0x050800` — QCommandLineOption::HiddenFromHelp | + +**Action**: Remove the `#if` guards entirely, keep only the Qt5+ code (which is also valid Qt6). + +### Qt 6.7+ specific (RHI widget) + +| File | Lines | What | +|------|-------|------| +| `common/rhi/yacreader_flow_rhi.h` | 8-302 | `#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)` — entire QRhiWidget implementation | + +**Action**: Keep this conditional (gates on Qt 6.7 minor version, not Qt5 vs Qt6). + +### Qt 6.9+ specific (test code) + +| File | Line | What | +|------|------|------| +| `tests/concurrent_queue_test/concurrent_queue_test.cpp` | 212 | `#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)` — QDebug for std::array | + +**Action**: Keep this conditional (Qt6 minor version gate). + +--- + +## 3. Third-Party Libraries + +### QtWebApp (`third_party/QtWebApp/`) + +| File | Lines | What | +|------|-------|------| +| `templateengine/templateengine.pri` | 5 | `QT += core5compat` | +| `templateengine/templateloader.cpp` | 13, 77, 86, 107 | QRegExp→QRegularExpression, QString::split flag | +| `httpserver/httpconnectionhandler.h` | 23 | `tSocketDescriptor` typedef (Qt4 vs Qt5) | +| `httpserver/httpconnectionhandlerpool.cpp` | 152 | SSL cert handling (Qt <5.15 vs 5.15+) | + +**Action**: Decide whether to update QtWebApp or replace it. If updating: remove Qt4/Qt5 branches, keep Qt6 code, potentially drop core5compat dependency by migrating QTextCodec→QStringConverter and QRegExp→QRegularExpression. + +### QsLog (`third_party/QsLog/`) + +| File | Lines | What | +|------|-------|------| +| `QsLog.pri` | 11 | Qt4 widgets guard | +| `QsLogDestFile.cpp` | 32, 157, 179 | QTextCodec vs QStringConverter | +| `QsLogWindow.cpp` | 129 | Qt4 header resize API | + +**Action**: Same approach — remove Qt4/Qt5 branches, keep Qt6 code. + +--- + +## 4. CI/CD and Build Scripts + +### GitHub Actions (`.github/workflows/build.yml`) + +**Qt5 build targets to remove:** +- Ubuntu Linux Qt5 build (~line 63) +- Windows x64 Qt5 build (~line 346) +- Windows x86 Qt5 build (~line 798) +- macOS Qt5 build (~line 201) + +**Qt6 build targets to keep (and simplify):** +- Linux Qt6 builds (~lines 90, 116) +- macOS Qt6 Universal (~line 145) — still installs `qt5compat` module (needed for QtWebApp) +- Windows x64 Qt6 (~line 408) — same +- Windows ARM64 Qt6 (~line 574) — same + +### Build scripts + +| File | What | +|------|------| +| `build_scripts/ubuntu_24.04/build.sh` | Qt6 — installs `libqt6core5compat6-dev`, `qml6-module-qt5compat-graphicaleffects` | +| `build_scripts/ubuntu_22.04/build.sh` | Qt5 — entire script is Qt5-only | + +**Action**: Remove `ubuntu_22.04` build script. In `ubuntu_24.04`, remove `qml6-module-qt5compat-graphicaleffects` (no longer used in QML). Keep `libqt6core5compat6-dev` (needed for QtWebApp). + +### Docker + +| File | What | +|------|------| +| `docker/Dockerfile` | Ubuntu x64 Qt6 — installs `libqt6core5compat6-dev` (build) and `libqt6core5compat6` (runtime) | +| `docker/Dockerfile.aarch64` | Ubuntu ARM64 Qt5-only build | + +**Action**: Remove or convert `Dockerfile.aarch64` to Qt6. Keep core5compat packages in main Dockerfile (QtWebApp). + +--- + +## 5. Summary + +### Safe to remove now (no dependencies) +- All `lessThan(QT_MAJOR_VERSION, 6)` lines (macextras) +- All `#if QT_VERSION >= 0x050000` / `0x050800` guards (Qt4 leftovers) +- All Qt5 CI build targets +- `build_scripts/ubuntu_22.04/` (Qt5-only) +- `qml6-module-qt5compat-graphicaleffects` from build scripts (QML migration done) + +### Requires code changes (keep Qt6 branch only) +- ~15 `#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)` blocks in own code +- Poppler backend selection in `pdf_backend.pri` +- `config.pri` minimum version bump + +### Keep as-is (Qt6 minor version gates) +- `QT_VERSION_CHECK(6, 7, 0)` — RHI widget +- `QT_VERSION_CHECK(6, 9, 0)` — test code +- `gui-private` for Qt 6.7+ (simplify guard only) + +### Depends on third-party decisions +- `core5compat` — still needed unless QtWebApp and QsLog are updated to drop QTextCodec/QRegExp diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index 6456463a..7d5c73a2 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -18,8 +18,6 @@ class QKeyEvent; class GoToFlowWidget : public QWidget, protected Themable { Q_OBJECT -protected: - void applyTheme(const Theme &theme) override; public: GoToFlowWidget(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); @@ -42,6 +40,7 @@ signals: protected: void keyPressEvent(QKeyEvent *event) override; void resizeEvent(QResizeEvent *event) override; + void applyTheme(const Theme &theme) override; private: QVBoxLayout *mainLayout; diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 67f545e5..4c671ca1 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -18,6 +18,7 @@ #include "yacreader_global.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" +#include "theme_manager.h" #include "whats_new_controller.h" @@ -186,7 +187,7 @@ void MainWindowViewer::setupUI() void MainWindowViewer::createActions() { openAction = new QAction(tr("&Open"), this); - openAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/open"))); + openAction->setIcon(QIcon(":/images/viewer_toolbar/open.svg")); openAction->setToolTip(tr("Open a comic")); openAction->setData(OPEN_ACTION_Y); openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y)); @@ -213,7 +214,7 @@ void MainWindowViewer::createActions() #endif openFolderAction = new QAction(tr("Open Folder"), this); - openFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openFolder"))); + openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.svg")); openFolderAction->setToolTip(tr("Open image folder")); openFolderAction->setData(OPEN_FOLDER_ACTION_Y); openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y)); @@ -237,28 +238,28 @@ void MainWindowViewer::createActions() connect(clearRecentFilesAction, &QAction::triggered, this, &MainWindowViewer::clearRecentFiles); saveImageAction = new QAction(tr("Save"), this); - saveImageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/save"))); + saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.svg")); saveImageAction->setToolTip(tr("Save current page")); saveImageAction->setData(SAVE_IMAGE_ACTION_Y); saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); connect(saveImageAction, &QAction::triggered, this, &MainWindowViewer::saveImage); openComicOnTheLeftAction = new QAction(tr("Previous Comic"), this); - openComicOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openPrevious"))); + openComicOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.svg")); openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); openComicOnTheLeftAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); openComicOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); connect(openComicOnTheLeftAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); openComicOnTheRightAction = new QAction(tr("Next Comic"), this); - openComicOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openNext"))); + openComicOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.svg")); openComicOnTheRightAction->setToolTip(tr("Open next comic")); openComicOnTheRightAction->setData(OPEN_NEXT_COMIC_ACTION_Y); openComicOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); connect(openComicOnTheRightAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); goToPageOnTheLeftAction = new QAction(tr("&Previous"), this); - goToPageOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/previous"))); + goToPageOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/previous.svg")); goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); goToPageOnTheLeftAction->setData(PREV_ACTION_Y); @@ -266,7 +267,7 @@ void MainWindowViewer::createActions() connect(goToPageOnTheLeftAction, &QAction::triggered, viewer, &Viewer::left); goToPageOnTheRightAction = new QAction(tr("&Next"), this); - goToPageOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/next"))); + goToPageOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/next.svg")); goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheRightAction->setToolTip(tr("Go to next page")); goToPageOnTheRightAction->setData(NEXT_ACTION_Y); @@ -274,7 +275,7 @@ void MainWindowViewer::createActions() connect(goToPageOnTheRightAction, &QAction::triggered, viewer, &Viewer::right); adjustHeightAction = new QAction(tr("Fit Height"), this); - adjustHeightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toHeight"))); + adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.svg")); // adjustWidth->setCheckable(true); adjustHeightAction->setToolTip(tr("Fit image to height")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); @@ -284,7 +285,7 @@ void MainWindowViewer::createActions() connect(adjustHeightAction, &QAction::triggered, this, &MainWindowViewer::fitToHeight); adjustWidthAction = new QAction(tr("Fit Width"), this); - adjustWidthAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toWidth"))); + adjustWidthAction->setIcon(QIcon(":/images/viewer_toolbar/toWidth.svg")); // adjustWidth->setCheckable(true); adjustWidthAction->setToolTip(tr("Fit image to width")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); @@ -294,7 +295,7 @@ void MainWindowViewer::createActions() connect(adjustWidthAction, &QAction::triggered, this, &MainWindowViewer::fitToWidth); adjustToFullSizeAction = new QAction(tr("Show full size"), this); - adjustToFullSizeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/full"))); + adjustToFullSizeAction->setIcon(QIcon(":/images/viewer_toolbar/full.svg")); adjustToFullSizeAction->setCheckable(false); adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y); adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y)); @@ -302,7 +303,7 @@ void MainWindowViewer::createActions() connect(adjustToFullSizeAction, &QAction::triggered, this, &MainWindowViewer::adjustToFullSizeSwitch); fitToPageAction = new QAction(tr("Fit to page"), this); - fitToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/fitToPage"))); + fitToPageAction->setIcon(QIcon(":/images/viewer_toolbar/fitToPage.svg")); fitToPageAction->setData(FIT_TO_PAGE_ACTION_Y); fitToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FIT_TO_PAGE_ACTION_Y)); fitToPageAction->setCheckable(true); @@ -338,7 +339,7 @@ void MainWindowViewer::createActions() connect(resetZoomAction, &QAction::triggered, this, &MainWindowViewer::resetZoomLevel); showZoomSliderlAction = new QAction(tr("Show zoom slider"), this); - showZoomSliderlAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/zoom"))); + showZoomSliderlAction->setIcon(QIcon(":/images/viewer_toolbar/zoom.svg")); increasePageZoomAction = new QAction(tr("Zoom+"), this); increasePageZoomAction->setData(ZOOM_PLUS_ACTION_Y); @@ -351,20 +352,20 @@ void MainWindowViewer::createActions() connect(decreasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::decreasePageZoomLevel); leftRotationAction = new QAction(tr("Rotate image to the left"), this); - leftRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateL"))); + leftRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateL.svg")); leftRotationAction->setData(LEFT_ROTATION_ACTION_Y); leftRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(LEFT_ROTATION_ACTION_Y)); connect(leftRotationAction, &QAction::triggered, viewer, &Viewer::rotateLeft); rightRotationAction = new QAction(tr("Rotate image to the right"), this); - rightRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateR"))); + rightRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateR.svg")); rightRotationAction->setData(RIGHT_ROTATION_ACTION_Y); rightRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RIGHT_ROTATION_ACTION_Y)); connect(rightRotationAction, &QAction::triggered, viewer, &Viewer::rotateRight); doublePageAction = new QAction(tr("Double page mode"), this); doublePageAction->setToolTip(tr("Switch to double page mode")); - doublePageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doublePage"))); + doublePageAction->setIcon(QIcon(":/images/viewer_toolbar/doublePage.svg")); doublePageAction->setCheckable(true); doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage()); doublePageAction->setData(DOUBLE_PAGE_ACTION_Y); @@ -374,7 +375,7 @@ void MainWindowViewer::createActions() // inversed pictures mode doubleMangaPageAction = new QAction(tr("Double page manga mode"), this); doubleMangaPageAction->setToolTip(tr("Reverse reading order in double page mode")); - doubleMangaPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doubleMangaPage"))); + doubleMangaPageAction->setIcon(QIcon(":/images/viewer_toolbar/doubleMangaPage.svg")); doubleMangaPageAction->setCheckable(true); doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y); @@ -383,7 +384,7 @@ void MainWindowViewer::createActions() connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch); goToPageAction = new QAction(tr("Go To"), this); - goToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/goto"))); + goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.svg")); goToPageAction->setToolTip(tr("Go to page ...")); goToPageAction->setData(GO_TO_PAGE_ACTION_Y); goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y)); @@ -393,20 +394,20 @@ void MainWindowViewer::createActions() optionsAction->setToolTip(tr("YACReader options")); optionsAction->setData(OPTIONS_ACTION_Y); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_Y)); - optionsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/options"))); + optionsAction->setIcon(QIcon(":/images/viewer_toolbar/options.svg")); connect(optionsAction, &QAction::triggered, optionsDialog, &OptionsDialog::show); helpAboutAction = new QAction(tr("Help"), this); helpAboutAction->setToolTip(tr("Help, About YACReader")); - helpAboutAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/help"))); + helpAboutAction->setIcon(QIcon(":/images/viewer_toolbar/help.svg")); helpAboutAction->setData(HELP_ABOUT_ACTION_Y); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_Y)); connect(helpAboutAction, &QAction::triggered, had, &QWidget::show); showMagnifyingGlassAction = new QAction(tr("Magnifying glass"), this); showMagnifyingGlassAction->setToolTip(tr("Switch Magnifying glass")); - showMagnifyingGlassAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/magnifyingGlass"))); + showMagnifyingGlassAction->setIcon(QIcon(":/images/viewer_toolbar/magnifyingGlass.svg")); showMagnifyingGlassAction->setCheckable(true); showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y); showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y)); @@ -414,7 +415,7 @@ void MainWindowViewer::createActions() setBookmarkAction = new QAction(tr("Set bookmark"), this); setBookmarkAction->setToolTip(tr("Set a bookmark on the current page")); - setBookmarkAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/bookmark"))); + setBookmarkAction->setIcon(QIcon(":/images/viewer_toolbar/bookmark.svg")); setBookmarkAction->setCheckable(true); setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y); setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y)); @@ -424,38 +425,38 @@ void MainWindowViewer::createActions() showBookmarksAction = new QAction(tr("Show bookmarks"), this); showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic")); - showBookmarksAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/showBookmarks"))); + showBookmarksAction->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.svg")); showBookmarksAction->setData(SHOW_BOOKMARKS_ACTION_Y); showBookmarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_BOOKMARKS_ACTION_Y)); connect(showBookmarksAction, &QAction::triggered, viewer->getBookmarksDialog(), &QWidget::show); showShorcutsAction = new QAction(tr("Show keyboard shortcuts"), this); - showShorcutsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/shortcuts"))); + showShorcutsAction->setIcon(QIcon(":/images/viewer_toolbar/shortcuts.svg")); showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y); showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y)); connect(showShorcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show); showInfoAction = new QAction(tr("Show Info"), this); - showInfoAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/info"))); + showInfoAction->setIcon(QIcon(":/images/viewer_toolbar/info.svg")); showInfoAction->setData(SHOW_INFO_ACTION_Y); showInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_INFO_ACTION_Y)); connect(showInfoAction, &QAction::triggered, viewer, &Viewer::informationSwitch); closeAction = new QAction(tr("Close"), this); - closeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/close"))); + closeAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); closeAction->setData(CLOSE_ACTION_Y); closeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CLOSE_ACTION_Y)); connect(closeAction, &QAction::triggered, this, &QWidget::close); showDictionaryAction = new QAction(tr("Show Dictionary"), this); - showDictionaryAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/translator"))); + showDictionaryAction->setIcon(QIcon(":/images/viewer_toolbar/translator.svg")); // showDictionaryAction->setCheckable(true); showDictionaryAction->setData(SHOW_DICTIONARY_ACTION_Y); showDictionaryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_DICTIONARY_ACTION_Y)); connect(showDictionaryAction, &QAction::triggered, viewer, &Viewer::translatorSwitch); showFlowAction = new QAction(tr("Show go to flow"), this); - showFlowAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/flow"))); + showFlowAction->setIcon(QIcon(":/images/viewer_toolbar/flow.svg")); showFlowAction->setData(SHOW_FLOW_ACTION_Y); showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y)); connect(showFlowAction, &QAction::triggered, viewer, &Viewer::goToFlowSwitch); @@ -1159,10 +1160,22 @@ void MainWindowViewer::processReset() void MainWindowViewer::setUpShortcutsManagement() { + // Set up icon mapping for theme changes + QMap> iconMapping; + iconMapping[tr("Comics")] = [](const Theme &t) { return t.shortcutsIcons.comicsIcon; }; + iconMapping[tr("General")] = [](const Theme &t) { return t.shortcutsIcons.generalIcon; }; + iconMapping[tr("Magnifiying glass")] = [](const Theme &t) { return t.shortcutsIcons.magnifyingGlassIcon; }; + iconMapping[tr("Page adjustement")] = [](const Theme &t) { return t.shortcutsIcons.pageIcon; }; + iconMapping[tr("Reading")] = [](const Theme &t) { return t.shortcutsIcons.readingIcon; }; + editShortcutsDialog->setGroupIconMapping(iconMapping); + QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), + // Get current theme for initial icons + const auto &theme = ThemeManager::instance().getCurrentTheme(); + + editShortcutsDialog->addActionsGroup(tr("Comics"), theme.shortcutsIcons.comicsIcon, tmpList = { openAction, openLatestComicAction, openFolderAction, @@ -1178,7 +1191,7 @@ void MainWindowViewer::setUpShortcutsManagement() auto *const toggleToolbarsAction = addActionWithShortcut(tr("Hide/show toolbar"), TOGGLE_TOOL_BARS_ACTION_Y); connect(toggleToolbarsAction, &QAction::triggered, this, &MainWindowViewer::toggleToolBars); - editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup(tr("General"), theme.shortcutsIcons.generalIcon, tmpList = QList() << optionsAction << helpAboutAction @@ -1216,7 +1229,7 @@ void MainWindowViewer::setUpShortcutsManagement() zoomInMglassAction, zoomOutMglassAction, resetMglassAction }; - editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts/shortcuts_group_mglass.svg"), + editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), theme.shortcutsIcons.magnifyingGlassIcon, tmpList = QList() << showMagnifyingGlassAction << mglassActions); @@ -1227,7 +1240,7 @@ void MainWindowViewer::setUpShortcutsManagement() CHANGE_FIT_ACTION_Y); connect(toggleFitToScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleWidthHeight); - editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts/shortcuts_group_page.svg"), + editShortcutsDialog->addActionsGroup(tr("Page adjustement"), theme.shortcutsIcons.pageIcon, tmpList = QList() << adjustHeightAction << adjustWidthAction @@ -1304,7 +1317,7 @@ void MainWindowViewer::setUpShortcutsManagement() offsetDoublePageToTheLeft, offsetDoublePageToTheRight }; - editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts/shortcuts_group_reading.svg"), + editShortcutsDialog->addActionsGroup(tr("Reading"), theme.shortcutsIcons.readingIcon, tmpList = QList() << goToPageOnTheRightAction << goToPageOnTheLeftAction diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index db24d2f5..f480ef28 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -174,8 +174,6 @@ private: void setMglassActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled); - void applyTheme(const Theme &theme) override; - //! Manejadores de evento: // void resizeEvent(QResizeEvent * event); void mouseDoubleClickEvent(QMouseEvent *event) override; @@ -201,6 +199,7 @@ protected: void sendComic(); void updatePrevNextActions(bool thereIsPrevious, bool thereIsNext); void afterLaunchTasks(); + void applyTheme(const Theme &theme) override; public: MainWindowViewer(); diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 03ee9765..4df071c3 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -33,7 +33,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto path = new QHBoxLayout(); path->addWidget(pathEdit = new QLineEdit()); - path->addWidget(pathFindButton = new QPushButton(QIcon(":/images/find_folder.png"), "")); + path->addWidget(pathFindButton = new QPushButton("")); pathBox->setLayout(path); QGroupBox *displayBox = new QGroupBox(tr("Display")); @@ -223,6 +223,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) setWindowTitle(tr("Options")); this->layout()->setSizeConstraint(QLayout::SetFixedSize); + + initTheme(this); +} + +void OptionsDialog::applyTheme(const Theme &theme) +{ + pathFindButton->setIcon(theme.dialogIcons.findFolderIcon); } void OptionsDialog::findFolder() @@ -247,7 +254,7 @@ void OptionsDialog::saveOptions() Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); - if (currentColor != ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor) { + if (currentColor != theme.viewer.defaultBackgroundColor) { settings->setValue(BACKGROUND_COLOR, currentColor); } else { settings->remove(BACKGROUND_COLOR); @@ -285,7 +292,7 @@ void OptionsDialog::restoreOptions(QSettings *settings) showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); - updateColor(settings->value(BACKGROUND_COLOR, ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor).value()); + updateColor(settings->value(BACKGROUND_COLOR, theme.viewer.defaultBackgroundColor).value()); // fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100); quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool()); @@ -402,5 +409,5 @@ void OptionsDialog::clearBackgroundColor() { settings->remove(BACKGROUND_COLOR); - updateColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor); + updateColor(theme.viewer.defaultBackgroundColor); } diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index f1d96767..7c2ef6cc 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -2,6 +2,7 @@ #define __OPTIONS_DIALOG_H #include "yacreader_options_dialog.h" +#include "themable.h" class QDialog; class QLabel; @@ -12,12 +13,15 @@ class QPushButton; class QRadioButton; class YACReaderSpinSliderWidget; -class OptionsDialog : public YACReaderOptionsDialog +class OptionsDialog : public YACReaderOptionsDialog, protected Themable { Q_OBJECT public: OptionsDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: // QLabel * pathLabel; QLineEdit *pathEdit; diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 9754f30c..50994209 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -4,6 +4,7 @@ #include #include "help_about_dialog_theme.h" +#include "whats_new_dialog_theme.h" struct ToolbarThemeTemplates { QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" @@ -126,11 +127,26 @@ struct GoToFlowWidgetTheme { QIcon goToIcon; }; +struct ShortcutsIconsTheme { + QIcon comicsIcon; + QIcon generalIcon; + QIcon magnifyingGlassIcon; + QIcon pageIcon; + QIcon readingIcon; +}; + +struct DialogIconsTheme { + QIcon findFolderIcon; +}; + struct Theme { ToolbarTheme toolbar; ViewerTheme viewer; GoToFlowWidgetTheme goToFlowWidget; HelpAboutDialogTheme helpAboutDialog; + WhatsNewDialogTheme whatsNewDialog; + ShortcutsIconsTheme shortcutsIcons; + DialogIconsTheme dialogIcons; }; #endif // THEME_H diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 3f48955a..7fd7d1f7 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -1,5 +1,7 @@ #include "theme_factory.h" +#include + #include "icon_utils.h" struct ToolbarParams { @@ -39,6 +41,20 @@ struct GoToFlowWidgetParams { QColor iconColor; }; +struct WhatsNewDialogParams { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QColor closeButtonColor; + QColor headerDecorationColor; +}; + +struct ShortcutsIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + struct ThemeParams { QString themeName; @@ -46,6 +62,8 @@ struct ThemeParams { ViewerParams viewerParams; GoToFlowWidgetParams goToFlowWidgetParams; HelpAboutDialogTheme helpAboutDialogParams; + WhatsNewDialogParams whatsNewDialogParams; + ShortcutsIconsParams shortcutsIconsParams; }; void setToolbarIconPair(QIcon &icon, @@ -157,6 +175,38 @@ Theme makeTheme(const ThemeParams ¶ms) theme.helpAboutDialog = params.helpAboutDialogParams; // end HelpAboutDialog + // WhatsNewDialog + const auto &wn = params.whatsNewDialogParams; + theme.whatsNewDialog.backgroundColor = wn.backgroundColor; + theme.whatsNewDialog.headerTextColor = wn.headerTextColor; + theme.whatsNewDialog.versionTextColor = wn.versionTextColor; + theme.whatsNewDialog.contentTextColor = wn.contentTextColor; + theme.whatsNewDialog.linkColor = wn.linkColor; + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + // end WhatsNewDialog + + // ShortcutsIcons + const auto &sci = params.shortcutsIconsParams; + auto makeShortcutsIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + return QIcon(path); + }; + + theme.shortcutsIcons.comicsIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_comics.svg"); + theme.shortcutsIcons.generalIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_general.svg"); + theme.shortcutsIcons.magnifyingGlassIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_mglass.svg"); + theme.shortcutsIcons.pageIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_page.svg"); + theme.shortcutsIcons.readingIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_reading.svg"); + // end ShortcutsIcons + + // FindFolder icon (used in OptionsDialog) + { + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", params.toolbarParams.iconColor, params.themeName); + const qreal dpr = qApp->devicePixelRatio(); + theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); + } + return theme; } @@ -220,6 +270,19 @@ ThemeParams classicThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); + params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x404040); // Dark icons for light background + params.shortcutsIconsParams = sci; + return params; } @@ -267,6 +330,19 @@ ThemeParams lightThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); + params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x606060); // Dark icons for light background + params.shortcutsIconsParams = sci; + return params; } @@ -314,6 +390,19 @@ ThemeParams darkThemeParams() params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + params.whatsNewDialogParams.backgroundColor = QColor(0x2A2A2A); + params.whatsNewDialogParams.headerTextColor = QColor(0xE0E0E0); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0xE0E0E0); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0xDDDDDD); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xD0D0D0); // Light icons for dark background + params.shortcutsIconsParams = sci; + return params; } diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index 3a145e43..ed7b9a8e 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -2,7 +2,7 @@ ../images/icon-new.svg ../images/goto.png - ../images/find_folder.png + ../images/find_folder.svg ../images/flow1.png ../images/flow2.png ../images/flow3.png @@ -19,8 +19,8 @@ ../images/dropDownArrow.png ../images/translatorSearch.png ../images/speaker.png - ../images/clear_shortcut.svg - ../images/accept_shortcut.svg + ../images/shortcuts/clear_shortcut.svg + ../images/shortcuts/accept_shortcut.svg ../images/shortcuts/shortcuts_group_comics.svg ../images/shortcuts/shortcuts_group_folders.svg ../images/shortcuts/shortcuts_group_general.svg diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 4d6d0059..e7ca65bc 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -125,6 +125,7 @@ HEADERS += \ yacreader_history_controller.h \ yacreader_navigation_controller.h \ empty_label_widget.h \ + empty_folder_widget.h \ empty_container_info.h \ empty_special_list.h \ empty_reading_list_widget.h \ @@ -210,6 +211,7 @@ SOURCES += \ yacreader_history_controller.cpp \ yacreader_navigation_controller.cpp \ empty_label_widget.cpp \ + empty_folder_widget.cpp \ empty_container_info.cpp \ empty_special_list.cpp \ empty_reading_list_widget.cpp \ diff --git a/YACReaderLibrary/add_label_dialog.cpp b/YACReaderLibrary/add_label_dialog.cpp index 18f3f9ed..1e06fa36 100644 --- a/YACReaderLibrary/add_label_dialog.cpp +++ b/YACReaderLibrary/add_label_dialog.cpp @@ -1,5 +1,22 @@ #include "add_label_dialog.h" +namespace { +const char *labelColorNames[] = { + QT_TR_NOOP("red"), + QT_TR_NOOP("orange"), + QT_TR_NOOP("yellow"), + QT_TR_NOOP("green"), + QT_TR_NOOP("cyan"), + QT_TR_NOOP("blue"), + QT_TR_NOOP("violet"), + QT_TR_NOOP("purple"), + QT_TR_NOOP("pink"), + QT_TR_NOOP("white"), + QT_TR_NOOP("light"), + QT_TR_NOOP("dark") +}; +} + AddLabelDialog::AddLabelDialog(QWidget *parent) : QDialog(parent) { @@ -11,21 +28,10 @@ AddLabelDialog::AddLabelDialog(QWidget *parent) layout->addWidget(new QLabel(tr("Choose a color:"))); layout->addWidget(list = new QListWidget()); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_red.svg"), tr("red"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_orange.svg"), tr("orange"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_yellow.svg"), tr("yellow"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_green.svg"), tr("green"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_cyan.svg"), tr("cyan"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_blue.svg"), tr("blue"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_violet.svg"), tr("violet"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_purple.svg"), tr("purple"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_pink.svg"), tr("pink"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_white.svg"), tr("white"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_light.svg"), tr("light"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_dark.svg"), tr("dark"))); + for (const auto &colorName : labelColorNames) { + list->addItem(new QListWidgetItem(tr(colorName))); + } - QColor backgroundColor = this->palette().window().color(); - list->setStyleSheet(QString("QListWidget {border : none; background-color: rgb(%1,%2,%3);}").arg(backgroundColor.red()).arg(backgroundColor.green()).arg(backgroundColor.blue())); list->setMinimumHeight(225); setModal(true); @@ -50,6 +56,22 @@ AddLabelDialog::AddLabelDialog(QWidget *parent) connect(edit, &QLineEdit::textChanged, this, &AddLabelDialog::validateName); connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close); connect(acceptButton, &QAbstractButton::clicked, this, &QDialog::accept); + + initTheme(this); +} + +void AddLabelDialog::applyTheme(const Theme &theme) +{ + const auto &icons = theme.readingListIcons.labelIcons; + + for (int i = 0; i < list->count(); ++i) { + const QString colorName = labelColorNames[i]; + if (icons.contains(colorName)) { + list->item(i)->setIcon(icons[colorName]); + } + } + + list->setStyleSheet("QListWidget {border : none;}"); } YACReader::LabelColors AddLabelDialog::selectedColor() diff --git a/YACReaderLibrary/add_label_dialog.h b/YACReaderLibrary/add_label_dialog.h index f18351be..e16216d6 100644 --- a/YACReaderLibrary/add_label_dialog.h +++ b/YACReaderLibrary/add_label_dialog.h @@ -4,8 +4,9 @@ #include #include "yacreader_global.h" +#include "themable.h" -class AddLabelDialog : public QDialog +class AddLabelDialog : public QDialog, protected Themable { Q_OBJECT public: @@ -21,6 +22,8 @@ protected slots: void validateName(const QString &name); protected: + void applyTheme(const Theme &theme) override; + QLineEdit *edit; QListWidget *list; diff --git a/YACReaderLibrary/add_library_dialog.cpp b/YACReaderLibrary/add_library_dialog.cpp index 80c2e8a1..d5ebc09b 100644 --- a/YACReaderLibrary/add_library_dialog.cpp +++ b/YACReaderLibrary/add_library_dialog.cpp @@ -30,7 +30,7 @@ void AddLibraryDialog::setupUI() cancel = new QPushButton(tr("Cancel")); connect(cancel, &QPushButton::clicked, this, &AddLibraryDialog::close); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &AddLibraryDialog::findPath); auto content = new QGridLayout; @@ -54,16 +54,22 @@ void AddLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/openLibrary.png"); - imgLabel->setPixmap(p); - imgMainLayout->addWidget(imgLabel); //,0,Qt::AlignTop); + imgLabel = new QLabel(this); + imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); setLayout(imgMainLayout); setModal(true); setWindowTitle(tr("Add an existing library")); + + initTheme(this); +} + +void AddLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.openLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void AddLibraryDialog::add() diff --git a/YACReaderLibrary/add_library_dialog.h b/YACReaderLibrary/add_library_dialog.h index 1176d933..041c7991 100644 --- a/YACReaderLibrary/add_library_dialog.h +++ b/YACReaderLibrary/add_library_dialog.h @@ -1,19 +1,25 @@ #ifndef __ADD_LIBRARY_DIALOG_H #define __ADD_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include #include #include -class AddLibraryDialog : public QDialog +class AddLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: AddLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLineEdit *path; diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index e3280f1e..e3eccd48 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -5,10 +5,8 @@ #include "QStackedWidget" #include "comic_flow_widget.h" -#include "QsLog.h" #include "shortcuts_manager.h" #include "yacreader_table_view.h" -#include "yacreader_tool_bar_stretch.h" ClassicComicsView::ClassicComicsView(QWidget *parent) : ComicsView(parent), searching(false) @@ -87,11 +85,23 @@ ClassicComicsView::ClassicComicsView(QWidget *parent) hideFlowViewAction->setText(tr("Hide comic flow")); hideFlowViewAction->setData(HIDE_COMIC_VIEW_ACTION_YL); hideFlowViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HIDE_COMIC_VIEW_ACTION_YL)); - hideFlowViewAction->setIcon(QIcon(":/images/comics_view_toolbar/hideComicFlow.svg")); hideFlowViewAction->setCheckable(true); hideFlowViewAction->setChecked(false); connect(hideFlowViewAction, &QAction::toggled, this, &ClassicComicsView::hideComicFlow); + + initTheme(this); +} + +void ClassicComicsView::applyTheme(const Theme &theme) +{ + // Update searching icon background to match comic flow + searchingIcon->setStyleSheet(QString("QWidget {border: none; background-color: %1;}").arg(theme.comicFlow.backgroundColor.name())); + searchingIconLabel->setPixmap(theme.emptyContainer.searchingIcon); + + sVertical->setStyleSheet(theme.contentSplitter.verticalSplitterQSS); + + hideFlowViewAction->setIcon(theme.comicsViewToolbar.hideComicFlowIcon); } void ClassicComicsView::hideComicFlow(bool hide) @@ -406,15 +416,10 @@ void ClassicComicsView::setupSearchingIcon() auto h = new QHBoxLayout; - QPixmap p(":/images/searching_icon.png"); - QLabel *l = new QLabel(searchingIcon); - l->setPixmap(p); - l->setFixedSize(p.size()); - h->addWidget(l, 0, Qt::AlignCenter); + searchingIconLabel = new QLabel(searchingIcon); + h->addWidget(searchingIconLabel, 0, Qt::AlignCenter); searchingIcon->setLayout(h); - searchingIcon->setStyleSheet(QString("QWidget {border : none; background-color: #000000;}")); - hideSearchingIcon(); } diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h index c492a033..af67ee67 100644 --- a/YACReaderLibrary/classic_comics_view.h +++ b/YACReaderLibrary/classic_comics_view.h @@ -2,6 +2,7 @@ #define CLASSIC_COMICS_VIEW_H #include "comics_view.h" +#include "themable.h" #include #include @@ -15,11 +16,14 @@ class ComicModel; class YACReaderTableView; class YACReaderToolBarStretch; -class ClassicComicsView : public ComicsView +class ClassicComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit ClassicComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; @@ -69,6 +73,7 @@ private: QByteArray previousSplitterStatus; QWidget *searchingIcon; + QLabel *searchingIconLabel; bool searching; void setupSearchingIcon(); void showSearchingIcon(); diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index 5df9bd08..7e54ae6a 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -14,10 +14,25 @@ ComicFlowWidget::ComicFlowWidget(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); - QPalette Pal(palette()); - Pal.setColor(QPalette::Window, Qt::black); setAutoFillBackground(true); - setPalette(Pal); + + initTheme(this); +} + +void ComicFlowWidget::applyTheme(const Theme &theme) +{ + setBackgroundColor(theme.comicFlow.backgroundColor); + setTextColor(theme.comicFlow.textColor); +} + +void ComicFlowWidget::setBackgroundColor(const QColor &color) +{ + flow->setBackgroundColor(color); +} + +void ComicFlowWidget::setTextColor(const QColor &color) +{ + flow->setTextColor(color); } QSize ComicFlowWidget::minimumSizeHint() const diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index b99c90a8..8492bfa2 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -7,14 +7,17 @@ #include "yacreader_comic_flow_rhi.h" #include "yacreader_global_gui.h" +#include "themable.h" -class ComicFlowWidget : public QWidget +class ComicFlowWidget : public QWidget, protected Themable { Q_OBJECT public: ComicFlowWidget(QWidget *parent = nullptr); public slots: + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); void setShowMarks(bool value); void setMarks(QVector marks); void setMarkImage(QImage &image); @@ -39,6 +42,7 @@ signals: void selected(unsigned int); protected: + void applyTheme(const Theme &theme) override; void keyPressEvent(QKeyEvent *event) override; void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.h b/YACReaderLibrary/comic_vine/scraper_results_paginator.h index 873ece50..ca7591f0 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.h +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.h @@ -16,6 +16,7 @@ public: void update(const QString &json); int getCurrentPage(); void setCustomLabel(const QString &label); + signals: void loadNextPage(); void loadPreviousPage(); diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 7ce33d6c..1ad00c8e 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -12,6 +12,7 @@ class TitleHeader : public QWidget, protected Themable Q_OBJECT public: TitleHeader(QWidget *parent = nullptr); + public slots: void setTitle(const QString &title); void setSubTitle(const QString &title); diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp index bde188b3..0c083d93 100644 --- a/YACReaderLibrary/comics_view_transition.cpp +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -1,32 +1,21 @@ #include "comics_view_transition.h" -#include -#include -#include -#include -#include -#include #include -#include "yacreader_global.h" - ComicsViewTransition::ComicsViewTransition(QWidget *parent) : QWidget(parent) { -#ifdef Y_MAC_UI - setStyleSheet("QWidget {background:#FFFFFF}"); -#else - setStyleSheet("QWidget {background:#2A2A2A}"); -#endif + initTheme(this); +} + +void ComicsViewTransition::applyTheme(const Theme &theme) +{ + setStyleSheet(QString("QWidget {background:%1}").arg(theme.defaultContentBackgroundColor.name())); + update(); } void ComicsViewTransition::paintEvent(QPaintEvent *) { QPainter painter(this); - -#ifdef Y_MAC_UI - painter.fillRect(0, 0, width(), height(), QColor("#FFFFFF")); -#else - painter.fillRect(0, 0, width(), height(), QColor("#2A2A2A")); -#endif + painter.fillRect(0, 0, width(), height(), theme.defaultContentBackgroundColor); } diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h index 78a08c3e..d428e674 100644 --- a/YACReaderLibrary/comics_view_transition.h +++ b/YACReaderLibrary/comics_view_transition.h @@ -3,13 +3,16 @@ #include -class ComicsViewTransition : public QWidget +#include "themable.h" + +class ComicsViewTransition : public QWidget, protected Themable { Q_OBJECT public: explicit ComicsViewTransition(QWidget *parent = nullptr); protected: + void applyTheme(const Theme &theme) override; void paintEvent(QPaintEvent *) override; }; diff --git a/YACReaderLibrary/create_library_dialog.cpp b/YACReaderLibrary/create_library_dialog.cpp index 8fbce093..4fe22327 100644 --- a/YACReaderLibrary/create_library_dialog.cpp +++ b/YACReaderLibrary/create_library_dialog.cpp @@ -35,7 +35,7 @@ void CreateLibraryDialog::setupUI() connect(cancel, &QAbstractButton::clicked, this, &CreateLibraryDialog::cancelCreate); connect(cancel, &QAbstractButton::clicked, this, &CreateLibraryDialog::close); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &CreateLibraryDialog::findPath); auto content = new QGridLayout; @@ -66,9 +66,7 @@ void CreateLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/new.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -76,6 +74,14 @@ void CreateLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Create new library")); + + initTheme(this); +} + +void CreateLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.newLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void CreateLibraryDialog::open(const YACReaderLibraries &libs) diff --git a/YACReaderLibrary/create_library_dialog.h b/YACReaderLibrary/create_library_dialog.h index 83658034..6adfb661 100644 --- a/YACReaderLibrary/create_library_dialog.h +++ b/YACReaderLibrary/create_library_dialog.h @@ -2,6 +2,7 @@ #define __CREATE_LIBRARY_DIALOG_H #include "yacreader_libraries.h" +#include "themable.h" #include #include @@ -10,13 +11,17 @@ #include #include -class CreateLibraryDialog : public QDialog +class CreateLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: CreateLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *message; diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 74bb75c4..d659a19c 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -10,48 +10,47 @@ #include "yacreader_global_gui.h" #include +#include #include using namespace YACReader; -#ifdef Y_MAC_UI -#include -QIcon finishedFolderIcon; -void drawMacOSXFinishedFolderIcon() +QIcon drawFinishedFolderIcon(const QPixmap &overlay) { + QIcon finishedIcon; QIcon ico = QFileIconProvider().icon(QFileIconProvider::Folder); QPixmap pixNormalOff = ico.pixmap(16, 16, QIcon::Normal, QIcon::Off); QPixmap pixNormalOn = ico.pixmap(16, 16, QIcon::Normal, QIcon::On); QPixmap pixSelectedOff = ico.pixmap(16, 16, QIcon::Selected, QIcon::Off); QPixmap pixSelectedOn = ico.pixmap(16, 16, QIcon::Selected, QIcon::On); - QPixmap tick(":/images/folder_finished_macosx.png"); { QPainter p(&pixNormalOff); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixNormalOff, QIcon::Normal, QIcon::Off); + finishedIcon.addPixmap(pixNormalOff, QIcon::Normal, QIcon::Off); { QPainter p(&pixNormalOn); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixNormalOn, QIcon::Normal, QIcon::On); + finishedIcon.addPixmap(pixNormalOn, QIcon::Normal, QIcon::On); { QPainter p(&pixSelectedOff); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixSelectedOff, QIcon::Selected, QIcon::Off); + finishedIcon.addPixmap(pixSelectedOff, QIcon::Selected, QIcon::Off); { QPainter p(&pixSelectedOn); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixSelectedOn, QIcon::Selected, QIcon::On); + finishedIcon.addPixmap(pixSelectedOn, QIcon::Selected, QIcon::On); + + return finishedIcon; } -#endif #define ROOT 1 @@ -132,8 +131,22 @@ FolderItem *createRoot(QSqlDatabase &db) } FolderModel::FolderModel(QObject *parent) - : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr), folderIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg")), folderFinishedIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder_finished.svg")), showRecent(false), recentDays(1) + : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr), showRecent(false), recentDays(1) { + initTheme(this); +} + +void FolderModel::applyTheme(const Theme &theme) +{ + const auto &sidebarIcons = theme.sidebarIcons; + + if (sidebarIcons.useSystemFolderIcons) { + folderIcon = QFileIconProvider().icon(QFileIconProvider::Folder); + folderFinishedIcon = drawFinishedFolderIcon(sidebarIcons.folderReadOverlay); + } else { + folderIcon = sidebarIcons.folderIcon; + folderFinishedIcon = sidebarIcons.folderFinishedIcon; + } } FolderModel::~FolderModel() @@ -368,22 +381,10 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const } if (role == Qt::DecorationRole) { -#ifdef Y_MAC_UI - if (item->data(FolderModel::Finished).toBool()) { - if (finishedFolderIcon.isNull()) { - drawMacOSXFinishedFolderIcon(); - } - - return QVariant(finishedFolderIcon); - } else { - return QVariant(QFileIconProvider().icon(QFileIconProvider::Folder)); - } -#else if (item->data(FolderModel::Finished).toBool()) return QVariant(folderFinishedIcon); else return QVariant(folderIcon); -#endif } if (role == FolderModel::FolderNameRole) { diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index 85ccfa23..84a759d2 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -13,6 +13,7 @@ #include "folder.h" #include "folder_query_result_processor.h" #include "yacreader_global.h" +#include "themable.h" class FolderItem; @@ -35,7 +36,7 @@ protected: bool filterEnabled; }; -class FolderModel : public QAbstractItemModel +class FolderModel : public QAbstractItemModel, protected Themable { Q_OBJECT @@ -146,6 +147,9 @@ private: bool showRecent; qlonglong recentDays; + +protected: + void applyTheme(const Theme &theme) override; }; #endif diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index fc3c6a5d..98e3bf57 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -4,6 +4,7 @@ #include #include "QsLog.h" +#include "theme_manager.h" ListItem::ListItem(const QList &data) : itemData(data) @@ -35,8 +36,18 @@ SpecialListItem::SpecialListItem(const QList &data) QIcon SpecialListItem::getIcon() const { if (itemData.count() > Id) { - QString id = itemData.at(Id).toString(); - return YACReader::noHighlightedIcon(QString(":/images/lists/default_%1.svg").arg(id)); + int id = itemData.at(Id).toInt(); + const auto &icons = ThemeManager::instance().getCurrentTheme().readingListIcons; + switch (id) { + case 0: + return icons.readingListIcon; + case 1: + return icons.favoritesIcon; + case 2: + return icons.currentlyReadingIcon; + default: + break; + } } QLOG_WARN() << "Icon for SpecialListItem not available"; @@ -75,8 +86,11 @@ LabelItem::LabelItem(const QList &data) QIcon LabelItem::getIcon() const { if (itemData.count() > Color) { - QString color = itemData.at(Color).toString(); - return YACReader::noHighlightedIcon(QString(":/images/lists/label_%1.svg").arg(color).toLower()); + QString color = itemData.at(Color).toString().toLower(); + const auto &icons = ThemeManager::instance().getCurrentTheme().readingListIcons; + if (icons.labelIcons.contains(color)) { + return icons.labelIcons[color]; + } } QLOG_WARN() << "Icon for label item not available"; @@ -127,20 +141,19 @@ qulonglong LabelItem::getId() const //------------------------------------------------------ ReadingListItem::ReadingListItem(const QList &data, ReadingListItem *p) - : ListItem(data), parent(p), list(YACReader::noHighlightedIcon(":/images/lists/list.svg")), folder(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg")) + : ListItem(data), parent(p) { } QIcon ReadingListItem::getIcon() const { + const auto &theme = ThemeManager::instance().getCurrentTheme(); if (parent->getId() == 0) - return list; // top level list - else -#ifdef Y_MAC_UI + return theme.readingListIcons.listIcon; // top level list + else if (theme.sidebarIcons.useSystemFolderIcons) return QFileIconProvider().icon(QFileIconProvider::Folder); -#else - return folder; // sublist -#endif + else + return theme.sidebarIcons.folderIcon; // sublist } int ReadingListItem::childCount() const diff --git a/YACReaderLibrary/db/reading_list_item.h b/YACReaderLibrary/db/reading_list_item.h index b7d06685..58af7483 100644 --- a/YACReaderLibrary/db/reading_list_item.h +++ b/YACReaderLibrary/db/reading_list_item.h @@ -82,9 +82,6 @@ public: private: QList childItems; - QIcon list; - QIcon folder; - enum DataIndexes { Name, Id, diff --git a/YACReaderLibrary/empty_container_info.cpp b/YACReaderLibrary/empty_container_info.cpp index 5fb1d514..e06eabfe 100644 --- a/YACReaderLibrary/empty_container_info.cpp +++ b/YACReaderLibrary/empty_container_info.cpp @@ -5,16 +5,10 @@ EmptyContainerInfo::EmptyContainerInfo(QWidget *parent) : QWidget(parent), iconLabel(new QLabel()), titleLabel(new QLabel()) { -#ifdef Y_MAC_UI - backgroundColor = "#FFFFFF"; - titleLabel->setStyleSheet("QLabel {color:#888888; font-size:24px;font-family:Arial;font-weight:bold;}"); -#else - backgroundColor = "#2A2A2A"; - titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); -#endif - iconLabel->setAlignment(Qt::AlignCenter); titleLabel->setAlignment(Qt::AlignCenter); + + initTheme(this); } void EmptyContainerInfo::setPixmap(const QPixmap &pixmap) @@ -45,5 +39,11 @@ QVBoxLayout *EmptyContainerInfo::setUpDefaultLayout(bool addStretch) void EmptyContainerInfo::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(backgroundColor)); + painter.fillRect(0, 0, width(), height(), theme.emptyContainer.backgroundColor); +} + +void EmptyContainerInfo::applyTheme(const Theme &theme) +{ + titleLabel->setStyleSheet(theme.emptyContainer.titleLabelQSS); + update(); // Trigger repaint for background color } diff --git a/YACReaderLibrary/empty_container_info.h b/YACReaderLibrary/empty_container_info.h index 1a1b3632..ac61a3ec 100644 --- a/YACReaderLibrary/empty_container_info.h +++ b/YACReaderLibrary/empty_container_info.h @@ -3,7 +3,9 @@ #include -class EmptyContainerInfo : public QWidget +#include "themable.h" + +class EmptyContainerInfo : public QWidget, protected Themable { Q_OBJECT public: @@ -17,10 +19,10 @@ public slots: protected: void paintEvent(QPaintEvent *) override; + void applyTheme(const Theme &theme) override; QLabel *iconLabel; QLabel *titleLabel; - QString backgroundColor; }; #endif // EMPTY_CONTAINER_INFO_H diff --git a/YACReaderLibrary/empty_folder_widget.cpp b/YACReaderLibrary/empty_folder_widget.cpp new file mode 100644 index 00000000..421a501c --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.cpp @@ -0,0 +1,15 @@ +#include "empty_folder_widget.h" + +EmptyFolderWidget::EmptyFolderWidget(QWidget *parent) + : EmptyContainerInfo(parent) +{ + setUpDefaultLayout(true); + setPixmap(theme.emptyContainer.emptyFolderIcon); + setText(tr("This folder doesn't contain comics yet")); +} + +void EmptyFolderWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.emptyFolderIcon); +} diff --git a/YACReaderLibrary/empty_folder_widget.h b/YACReaderLibrary/empty_folder_widget.h new file mode 100644 index 00000000..02803925 --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.h @@ -0,0 +1,17 @@ +#ifndef EMPTY_FOLDER_WIDGET_H +#define EMPTY_FOLDER_WIDGET_H + +#include +#include "empty_container_info.h" + +class EmptyFolderWidget : public EmptyContainerInfo +{ + Q_OBJECT +public: + explicit EmptyFolderWidget(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; +}; + +#endif // EMPTY_FOLDER_WIDGET_H diff --git a/YACReaderLibrary/empty_label_widget.cpp b/YACReaderLibrary/empty_label_widget.cpp index 0680dea8..75c36c0b 100644 --- a/YACReaderLibrary/empty_label_widget.cpp +++ b/YACReaderLibrary/empty_label_widget.cpp @@ -4,18 +4,20 @@ EmptyLabelWidget::EmptyLabelWidget(QWidget *parent) : EmptyContainerInfo(parent) { setUpDefaultLayout(true); - - iconLabel->setPixmap(QPixmap(":/images/empty_label.png")); - - // titleLabel->setText(tr("This label doesn't contain comics yet") + QString("

%1

").arg(tr("Drag and drop folders and comics here"))); titleLabel->setText(tr("This label doesn't contain comics yet")); } void EmptyLabelWidget::setColor(YACReader::LabelColors color) { - QPixmap p(":/images/empty_label.png"); - QImage img = p.toImage().convertToFormat(QImage::Format_ARGB32); - QColor destColor(YACReader::labelColorToRGBString(color)); - YACReader::colorize(img, destColor); - iconLabel->setPixmap(QPixmap::fromImage(img)); + currentColor = color; + auto it = theme.emptyContainer.emptyLabelIcons.find(static_cast(color)); + if (it != theme.emptyContainer.emptyLabelIcons.end()) { + setPixmap(it.value()); + } +} + +void EmptyLabelWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setColor(currentColor); } diff --git a/YACReaderLibrary/empty_label_widget.h b/YACReaderLibrary/empty_label_widget.h index 850b6fd9..a9ac9826 100644 --- a/YACReaderLibrary/empty_label_widget.h +++ b/YACReaderLibrary/empty_label_widget.h @@ -12,11 +12,11 @@ public: explicit EmptyLabelWidget(QWidget *parent = nullptr); void setColor(YACReader::LabelColors color); -signals: - -public slots: - protected: + void applyTheme(const Theme &theme) override; + +private: + YACReader::LabelColors currentColor = YACReader::YRed; }; #endif // EMPTY_LABEL_WIDGET_H diff --git a/YACReaderLibrary/empty_reading_list_widget.cpp b/YACReaderLibrary/empty_reading_list_widget.cpp index 1e79943a..59b3e329 100644 --- a/YACReaderLibrary/empty_reading_list_widget.cpp +++ b/YACReaderLibrary/empty_reading_list_widget.cpp @@ -4,6 +4,12 @@ EmptyReadingListWidget::EmptyReadingListWidget(QWidget *parent) : EmptyContainerInfo(parent) { setUpDefaultLayout(true); - setPixmap(QPixmap(":/images/empty_reading_list")); + setPixmap(theme.emptyContainer.emptyReadingListIcon); setText(tr("This reading list does not contain any comics yet")); } + +void EmptyReadingListWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.emptyReadingListIcon); +} diff --git a/YACReaderLibrary/empty_reading_list_widget.h b/YACReaderLibrary/empty_reading_list_widget.h index 4fa7fa25..70ef65eb 100644 --- a/YACReaderLibrary/empty_reading_list_widget.h +++ b/YACReaderLibrary/empty_reading_list_widget.h @@ -8,6 +8,9 @@ class EmptyReadingListWidget : public EmptyContainerInfo { public: EmptyReadingListWidget(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; }; #endif // EMPTY_READING_LIST_WIDGET_H diff --git a/YACReaderLibrary/empty_special_list.cpp b/YACReaderLibrary/empty_special_list.cpp index 44a428d3..8f0b9d1a 100644 --- a/YACReaderLibrary/empty_special_list.cpp +++ b/YACReaderLibrary/empty_special_list.cpp @@ -5,3 +5,45 @@ EmptySpecialListWidget::EmptySpecialListWidget(QWidget *parent) { setUpDefaultLayout(true); } + +void EmptySpecialListWidget::showFavorites() +{ + currentType = Favorites; + setPixmap(theme.emptyContainer.emptyFavoritesIcon); + setText(tr("No favorites")); +} + +void EmptySpecialListWidget::showReading() +{ + currentType = Reading; + setPixmap(theme.emptyContainer.emptyCurrentReadingsIcon); + setText(tr("You are not reading anything yet, come on!!")); +} + +void EmptySpecialListWidget::showRecent() +{ + currentType = Recent; + setPixmap(QPixmap()); + setText(tr("There are no recent comics!")); +} + +void EmptySpecialListWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + updateIcon(); +} + +void EmptySpecialListWidget::updateIcon() +{ + switch (currentType) { + case Favorites: + setPixmap(theme.emptyContainer.emptyFavoritesIcon); + break; + case Reading: + setPixmap(theme.emptyContainer.emptyCurrentReadingsIcon); + break; + case Recent: + case None: + break; + } +} diff --git a/YACReaderLibrary/empty_special_list.h b/YACReaderLibrary/empty_special_list.h index 481bd9e7..0c926144 100644 --- a/YACReaderLibrary/empty_special_list.h +++ b/YACReaderLibrary/empty_special_list.h @@ -7,7 +7,25 @@ class EmptySpecialListWidget : public EmptyContainerInfo { public: + enum SpecialListType { + None, + Favorites, + Reading, + Recent + }; + EmptySpecialListWidget(QWidget *parent = nullptr); + + void showFavorites(); + void showReading(); + void showRecent(); + +protected: + void applyTheme(const Theme &theme) override; + +private: + void updateIcon(); + SpecialListType currentType = None; }; #endif // EMPTY_SPECIAL_LIST_H diff --git a/YACReaderLibrary/export_comics_info_dialog.cpp b/YACReaderLibrary/export_comics_info_dialog.cpp index 1cd9c7fa..dac2ac80 100644 --- a/YACReaderLibrary/export_comics_info_dialog.cpp +++ b/YACReaderLibrary/export_comics_info_dialog.cpp @@ -23,7 +23,7 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ExportComicsInfoDialog::close); connect(cancel, &QAbstractButton::clicked, this, &QDialog::rejected); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ExportComicsInfoDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -45,9 +45,7 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/exportComicsInfo.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -55,6 +53,14 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) setModal(true); setWindowTitle(tr("Export comics info")); + + initTheme(this); +} + +void ExportComicsInfoDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.exportComicsInfoIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } ExportComicsInfoDialog::~ExportComicsInfoDialog() diff --git a/YACReaderLibrary/export_comics_info_dialog.h b/YACReaderLibrary/export_comics_info_dialog.h index f5a8e82f..fb679c38 100644 --- a/YACReaderLibrary/export_comics_info_dialog.h +++ b/YACReaderLibrary/export_comics_info_dialog.h @@ -1,12 +1,14 @@ #ifndef EXPORT_COMICS_INFO_DIALOG_H #define EXPORT_COMICS_INFO_DIALOG_H +#include "themable.h" + #include #include #include #include -class ExportComicsInfoDialog : public QDialog +class ExportComicsInfoDialog : public QDialog, protected Themable { Q_OBJECT @@ -15,12 +17,16 @@ public: ~ExportComicsInfoDialog() override; QString source; +protected: + void applyTheme(const Theme &theme) override; + public slots: void findPath(); void exportComicsInfo(); void close(); private: + QLabel *imgLabel; QLabel *progress; QLabel *textLabel; QLineEdit *path; diff --git a/YACReaderLibrary/export_library_dialog.cpp b/YACReaderLibrary/export_library_dialog.cpp index 971ca9af..066f7192 100644 --- a/YACReaderLibrary/export_library_dialog.cpp +++ b/YACReaderLibrary/export_library_dialog.cpp @@ -20,7 +20,7 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ExportLibraryDialog::close); connect(cancel, &QAbstractButton::clicked, this, &QDialog::rejected); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ExportLibraryDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -48,9 +48,7 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/exportLibrary.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -58,6 +56,14 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) setModal(true); setWindowTitle(tr("Create covers package")); + + initTheme(this); +} + +void ExportLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.exportLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void ExportLibraryDialog::exportLibrary() diff --git a/YACReaderLibrary/export_library_dialog.h b/YACReaderLibrary/export_library_dialog.h index 1c3e8025..5321dcb4 100644 --- a/YACReaderLibrary/export_library_dialog.h +++ b/YACReaderLibrary/export_library_dialog.h @@ -1,6 +1,8 @@ #ifndef EXPORT_LIBRARY_DIALOG_H #define EXPORT_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include @@ -10,17 +12,22 @@ #include #include -class ExportLibraryDialog : public QDialog +class ExportLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: ExportLibraryDialog(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; + public slots: void exportLibrary(); void findPath(); void close(); private: + QLabel *imgLabel; int progressCount; QProgressBar *progressBar; QLabel *textLabel; diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index d3cc901d..79d87fa3 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -7,6 +7,7 @@ #include "yacreader_tool_bar_stretch.h" #include "comic.h" #include "comic_files_manager.h" +#include "theme_manager.h" #include "QsLog.h" @@ -17,7 +18,7 @@ using namespace YACReader; FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWidget *parent) - : QWidget { parent }, parent(QModelIndex()), comicModel(new ComicModel()), folderModel(new FolderModel()) + : QWidget { parent }, parent(QModelIndex()), comicModel(new ComicModel()), folderModel(new FolderModel()), smallZoomLabel(nullptr), bigZoomLabel(nullptr) { qmlRegisterType("com.yacreader.FolderModel", 1, 0, "FolderModel"); @@ -41,14 +42,16 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid coverSizeSlider->setOrientation(Qt::Horizontal); coverSizeSlider->setRange(YACREADER_MIN_GRID_ZOOM_WIDTH, YACREADER_MAX_GRID_ZOOM_WIDTH); + const auto &comicsToolbar = theme.comicsViewToolbar; + auto horizontalLayout = new QHBoxLayout(); - QLabel *smallLabel = new QLabel(); - smallLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(smallLabel); + smallZoomLabel = new QLabel(); + smallZoomLabel->setPixmap(comicsToolbar.smallGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(smallZoomLabel); horizontalLayout->addWidget(coverSizeSlider, 0, Qt::AlignVCenter); - QLabel *bigLabel = new QLabel(); - bigLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(bigLabel); + bigZoomLabel = new QLabel(); + bigZoomLabel->setPixmap(comicsToolbar.bigGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(bigZoomLabel); horizontalLayout->addSpacing(10); horizontalLayout->setContentsMargins(0, 0, 0, 0); @@ -57,10 +60,6 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid connect(coverSizeSlider, &QAbstractSlider::valueChanged, this, &FolderContentView::setCoversSize); toolbar = new QToolBar(); - toolbar->setStyleSheet(R"( - QToolBar { border: none; } - QToolButton:checked { background-color: #cccccc; } - )"); toolbar->setIconSize(QSize(18, 18)); toolbar->addWidget(new YACReaderToolBarStretch); toolbar->addAction(toogleRecentVisibilityAction); @@ -77,84 +76,16 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif + // fonts settings (not theme-dependent) + int fontSize = QApplication::font().pointSize(); + if (fontSize == -1) + fontSize = QApplication::font().pixelSize(); + ctxt->setContextProperty("fontSize", fontSize); + ctxt->setContextProperty("fontFamily", QApplication::font().family()); + ctxt->setContextProperty("fontSpacing", 0.5); - if (theme == Light) { - ctxt->setContextProperty("continueReadingBackgroundColor", "#E8E8E8"); - ctxt->setContextProperty("continueReadingColor", "#000000"); - - ctxt->setContextProperty("backgroundColor", "#F6F6F6"); - ctxt->setContextProperty("cellColor", "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); - ctxt->setContextProperty("selectedBorderColor", "#007AFF"); - ctxt->setContextProperty("borderColor", "#DBDBDB"); - ctxt->setContextProperty("titleColor", "#121212"); - ctxt->setContextProperty("textColor", "#636363"); - // fonts settings - ctxt->setContextProperty("fontSize", 11); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - } else { - ctxt->setContextProperty("continueReadingBackgroundColor", "#88000000"); - ctxt->setContextProperty("continueReadingColor", "#FFFFFF"); - - ctxt->setContextProperty("backgroundColor", "#2A2A2A"); - ctxt->setContextProperty("cellColor", "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); - ctxt->setContextProperty("selectedBorderColor", "#121212"); - ctxt->setContextProperty("borderColor", "#121212"); - ctxt->setContextProperty("titleColor", "#FFFFFF"); - ctxt->setContextProperty("textColor", "#A8A8A8"); - ctxt->setContextProperty("dropShadow", QVariant(false)); - // fonts settings - int fontSize = QApplication::font().pointSize(); - if (fontSize == -1) - fontSize = QApplication::font().pixelSize(); - ctxt->setContextProperty("fontSize", fontSize); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - } + // Apply theme colors + initTheme(this); updateCoversSizeInContext(YACREADER_MIN_COVER_WIDTH, ctxt); @@ -328,3 +259,49 @@ void FolderContentView::droppedFiles(const QList &urls, Qt::DropAction act emit copyComicsToCurrentFolder(droppedFiles); } } + +void FolderContentView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + toolbar->setStyleSheet(theme.comicsViewToolbar.toolbarQSS); + + // Continue reading section colors + ctxt->setContextProperty("continueReadingBackgroundColor", qv.continueReadingBackgroundColor); + ctxt->setContextProperty("continueReadingColor", qv.continueReadingColor); + + // Grid colors + ctxt->setContextProperty("backgroundColor", qv.backgroundColor); + ctxt->setContextProperty("cellColor", qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); + ctxt->setContextProperty("borderColor", qv.borderColor); + ctxt->setContextProperty("titleColor", qv.titleColor); + ctxt->setContextProperty("textColor", qv.textColor); + ctxt->setContextProperty("dropShadow", QVariant(qv.showDropShadow)); + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + // Update zoom slider icons + if (smallZoomLabel) { + smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18)); + } + if (bigZoomLabel) { + bigZoomLabel->setPixmap(theme.comicsViewToolbar.bigGridZoomIcon.pixmap(18, 18)); + } +} diff --git a/YACReaderLibrary/folder_content_view.h b/YACReaderLibrary/folder_content_view.h index f199491b..cd0187f7 100644 --- a/YACReaderLibrary/folder_content_view.h +++ b/YACReaderLibrary/folder_content_view.h @@ -4,6 +4,7 @@ #include #include "comic_model.h" +#include "themable.h" #include "folder.h" #include "comic_db.h" @@ -15,7 +16,7 @@ class YACReaderToolBarStretch; class QQuickWidget; class QQmlContext; -class FolderContentView : public QWidget +class FolderContentView : public QWidget, protected Themable { Q_OBJECT public: @@ -28,6 +29,7 @@ public: void setRecentRange(int days); FolderModel *currentFolderModel() { return folderModel; } + public slots: void updateSettings(); @@ -62,6 +64,8 @@ protected: std::unique_ptr comicModel; FolderModel *folderModel; + void applyTheme(const Theme &theme) override; + private: QSettings *settings; QToolBar *toolbar; @@ -72,6 +76,10 @@ private: QAction *coverSizeSliderAction; QAction *showInfoAction; QAction *showInfoSeparatorAction; + + // Zoom slider labels (for theming) + QLabel *smallZoomLabel; + QLabel *bigZoomLabel; }; #endif // FOLDERCONTENTVIEW_H diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 48512863..f30e4f90 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -5,6 +5,7 @@ #include #include "comic.h" +#include "theme_manager.h" #include "comic_files_manager.h" #include "QsLog.h" #include "yacreader_global.h" @@ -15,7 +16,7 @@ #include "current_comic_view_helper.h" GridComicsView::GridComicsView(QWidget *parent) - : ComicsView(parent), filterEnabled(false) + : ComicsView(parent), filterEnabled(false), smallZoomLabel(nullptr), bigZoomLabel(nullptr) { settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat, this); settings->beginGroup("libraryConfig"); @@ -29,83 +30,13 @@ GridComicsView::GridComicsView(QWidget *parent) QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif - - if (theme == Light) { - ctxt->setContextProperty("backgroundColor", "#F6F6F6"); - ctxt->setContextProperty("cellColor", "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); - ctxt->setContextProperty("selectedBorderColor", "#007AFF"); - ctxt->setContextProperty("borderColor", "#DBDBDB"); - ctxt->setContextProperty("titleColor", "#121212"); - ctxt->setContextProperty("textColor", "#636363"); - ctxt->setContextProperty("showDropShadow", QVariant(false)); - // fonts settings - ctxt->setContextProperty("fontSize", 11); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("currentComicBackgroundColor", "#88FFFFFF"); - } else { - ctxt->setContextProperty("backgroundColor", "#2A2A2A"); - ctxt->setContextProperty("cellColor", "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); - ctxt->setContextProperty("selectedBorderColor", "#FFCC00"); - ctxt->setContextProperty("borderColor", "#121212"); - ctxt->setContextProperty("titleColor", "#FFFFFF"); - ctxt->setContextProperty("textColor", "#A8A8A8"); - ctxt->setContextProperty("showDropShadow", QVariant(true)); - // fonts settings - int fontSize = QApplication::font().pointSize(); - if (fontSize == -1) - fontSize = QApplication::font().pixelSize(); - ctxt->setContextProperty("fontSize", fontSize); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("currentComicBackgroundColor", "#88000000"); - } + // fonts settings (not theme-dependent) + int fontSize = QApplication::font().pointSize(); + if (fontSize == -1) + fontSize = QApplication::font().pixelSize(); + ctxt->setContextProperty("fontSize", fontSize); + ctxt->setContextProperty("fontFamily", QApplication::font().family()); + ctxt->setContextProperty("fontSpacing", 0.5); ctxt->setContextProperty("backgroundImage", QUrl()); ctxt->setContextProperty("backgroundBlurOpacity", 0.0); @@ -144,11 +75,13 @@ GridComicsView::GridComicsView(QWidget *parent) QQmlProperty(infoContainer, "width").write(settings->value(COMICS_GRID_INFO_WIDTH, 350)); showInfoAction = new QAction(tr("Show info"), this); - showInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/show_comic_info.svg")); showInfoAction->setCheckable(true); showInfoAction->setChecked(showInfo); connect(showInfoAction, &QAction::toggled, this, &GridComicsView::showInfo); + // Apply theme colors (must be after showInfoAction is created) + initTheme(this); + setShowMarks(true); // TODO save this in settings auto l = new QVBoxLayout; @@ -175,14 +108,16 @@ void GridComicsView::createCoverSizeSliderWidget() coverSizeSlider->setOrientation(Qt::Horizontal); coverSizeSlider->setRange(YACREADER_MIN_GRID_ZOOM_WIDTH, YACREADER_MAX_GRID_ZOOM_WIDTH); + const auto &comicsToolbar = theme.comicsViewToolbar; + auto horizontalLayout = new QHBoxLayout(); - QLabel *smallLabel = new QLabel(); - smallLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(smallLabel); + smallZoomLabel = new QLabel(); + smallZoomLabel->setPixmap(comicsToolbar.smallGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(smallZoomLabel); horizontalLayout->addWidget(coverSizeSlider, 0, Qt::AlignVCenter); - QLabel *bigLabel = new QLabel(); - bigLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(bigLabel); + bigZoomLabel = new QLabel(); + bigZoomLabel->setPixmap(comicsToolbar.bigGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(bigZoomLabel); horizontalLayout->addSpacing(10); horizontalLayout->setContentsMargins(0, 0, 0, 0); @@ -283,13 +218,10 @@ void GridComicsView::updateBackgroundConfig() ctxt->setContextProperty("backgroundBlurVisible", QVariant(false)); } -#ifdef Y_MAC_UI - ctxt->setContextProperty("cellColor", useBackgroundImage ? "#99FFFFFF" : "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); -#else - ctxt->setContextProperty("cellColor", useBackgroundImage ? "#99212121" : "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); -#endif + // Use theme colors for cell and selected colors + const auto &qv = theme.qmlView; + ctxt->setContextProperty("cellColor", useBackgroundImage ? qv.cellColorWithBackground : qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); } void GridComicsView::showInfo() @@ -552,6 +484,55 @@ void GridComicsView::selectedItem(int index) emit selected(index); } +void GridComicsView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + // Grid colors + ctxt->setContextProperty("backgroundColor", qv.backgroundColor); + ctxt->setContextProperty("cellColor", qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); + ctxt->setContextProperty("borderColor", qv.borderColor); + ctxt->setContextProperty("titleColor", qv.titleColor); + ctxt->setContextProperty("textColor", qv.textColor); + ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + // Current comic banner + ctxt->setContextProperty("currentComicBackgroundColor", qv.currentComicBackgroundColor); + + // Update background config to apply theme cell colors + updateBackgroundConfig(); + + // Update show info action icon + showInfoAction->setIcon(theme.comicsViewToolbar.showComicInfoIcon); + + // Update zoom slider icons (if they exist - created in setToolBar) + if (smallZoomLabel) { + smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18)); + } + if (bigZoomLabel) { + bigZoomLabel->setPixmap(theme.comicsViewToolbar.bigGridZoomIcon.pixmap(18, 18)); + } +} + void GridComicsView::setShowMarks(bool show) { QQmlContext *ctxt = view->rootContext(); diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 50d3c03c..6ba587fd 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -2,6 +2,7 @@ #define GRID_COMICS_VIEW_H #include "comics_view.h" +#include "themable.h" #include @@ -32,11 +33,14 @@ const unsigned int YACREADER_MIN_COVER_WIDTH = YACREADER_MIN_GRID_ZOOM_WIDTH; const unsigned int YACREADER_MIN_ITEM_HEIGHT = YACREADER_MAX_COVER_HEIGHT + 51; // 51 is the height of the bottom rectangle used for title and other info const unsigned int YACREADER_MIN_ITEM_WIDTH = YACREADER_MIN_COVER_WIDTH; -class GridComicsView : public ComicsView +class GridComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit GridComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; ~GridComicsView() override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; @@ -114,6 +118,10 @@ private: bool dummy; void closeEvent(QCloseEvent *event) override; void createCoverSizeSliderWidget(); + + // Zoom slider labels (for theming) + QLabel *smallZoomLabel; + QLabel *bigZoomLabel; }; #endif // GRID_COMICS_VIEW_H diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 17516208..d0749b7f 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -1,7 +1,7 @@ - ../images/accept_shortcut.svg - ../images/clear_shortcut.svg + ../images/shortcuts/accept_shortcut.svg + ../images/shortcuts/clear_shortcut.svg ../images/comic_vine/downArrow.svg ../images/comic_vine/nextPage.svg ../images/comic_vine/previousPage.svg @@ -28,30 +28,41 @@ ../images/comics_view_toolbar/setNormal.svg ../images/comics_view_toolbar/showRecentIndicator.svg ../images/defaultCover.png - ../images/edit.png - ../images/empty_current_readings.png - ../images/empty_favorites.png - ../images/empty_label.png - ../images/exportComicsInfo.png - ../images/exportLibrary.png + ../images/library_dialogs/edit.svg + ../images/empty_container/empty_current_readings.svg + ../images/empty_container/empty_favorites.svg + ../images/empty_container/empty_folder.svg + ../images/empty_container/empty_label.svg + ../images/empty_container/empty_reading_list.svg + ../images/library_dialogs/exportComicsInfo.svg + ../images/library_dialogs/exportLibrary.svg ../images/f_overlayed.png ../images/f_overlayed_retina.png - ../images/find_folder.png + ../images/find_folder.svg ../images/flow1.png ../images/flow2.png ../images/flow3.png ../images/flow4.png ../images/flow5.png ../images/glowLine.png - ../images/loadCustomCover.svg - ../images/hiddenCovers.png + ../images/metadata_dialog/loadCustomCover.svg + ../images/import/coversToggle.svg ../images/icon-new.svg ../images/iconLibrary.png - ../images/importBottomCoversDecoration.png - ../images/importComicsInfo.png - ../images/importingIcon.png - ../images/importLibrary.png - ../images/importTopCoversDecoration.png + ../images/import/importBottomCoversDecoration.svg + ../images/library_dialogs/importComicsInfo.svg + ../images/import/importingIcon.svg + ../images/library_dialogs/importLibrary.svg + ../images/import/importTopCoversDecoration.svg + ../images/main_toolbar/back.svg + ../images/main_toolbar/forward.svg + ../images/main_toolbar/settings.svg + ../images/main_toolbar/server.svg + ../images/main_toolbar/help.svg + ../images/main_toolbar/fullscreen.svg + ../images/main_toolbar/flow.svg + ../images/main_toolbar/grid.svg + ../images/main_toolbar/info.svg ../images/main_toolbar/divider.svg ../images/menus_icons/editIcon.svg ../images/menus_icons/exportComicsInfoIcon.svg @@ -62,18 +73,18 @@ ../images/menus_icons/updateLibraryIcon.svg ../images/menus_icons/open_containing_folder.svg ../images/menus_icons/update_current_folder.svg - ../images/new.png - ../images/nextCoverPage.png - ../images/noLibrariesIcon.png + ../images/library_dialogs/new.svg + ../images/metadata_dialog/nextCoverPage.svg + ../images/noLibrariesIcon.svg ../images/noLibrariesLine.png ../images/notCover.png - ../images/openLibrary.png - ../images/previousCoverPage.png + ../images/library_dialogs/openLibrary.svg + ../images/metadata_dialog/previousCoverPage.svg ../images/readingRibbon.png ../images/readRibbon.png - ../images/resetCover.svg - ../images/searching_icon.png - ../images/serverConfigBackground.png + ../images/metadata_dialog/resetCover.svg + ../images/search_result.svg + ../images/serverConfigBackground.svg ../images/shortcuts/shortcuts_group_comics.svg ../images/shortcuts/shortcuts_group_folders.svg ../images/shortcuts/shortcuts_group_general.svg @@ -82,7 +93,16 @@ ../images/shortcuts/shortcuts_group_page.svg ../images/shortcuts/shortcuts_group_reading.svg ../images/shortcuts/shortcuts_group_visualization.svg - ../images/shownCovers.png + ../images/sidebar/libraryIcon.svg + ../images/sidebar/setRoot.svg + ../images/sidebar/expand.svg + ../images/sidebar/colapse.svg + ../images/sidebar/newLibraryIcon.svg + ../images/sidebar/openLibraryIcon.svg + ../images/sidebar/addNew_sidebar.svg + ../images/sidebar/delete_sidebar.svg + ../images/sidebar/addLabelIcon.svg + ../images/sidebar/renameListIcon.svg ../images/sidebar/branch-closed.svg ../images/sidebar/branch-open.svg ../images/sidebar/collapsed_branch_osx.png @@ -91,28 +111,20 @@ ../images/sidebar/expanded_branch_selected.png ../images/sidebar/folder.svg ../images/sidebar/folder_finished.svg + ../images/sidebar/folder_read_overlay.svg ../images/sidebar/libraryIconSelected.svg ../images/sidebar/libraryOptions.svg - ../images/updatingIcon.png + ../images/import/updatingIcon.svg ../images/custom_dialog/custom_close_button.svg ../images/whats_new/whatsnew_header.svg ../images/lists/default_0.svg ../images/lists/default_1.svg ../images/lists/default_2.svg - - ../images/lists/label_blue.svg - ../images/lists/label_cyan.svg - ../images/lists/label_dark.svg - ../images/lists/label_green.svg - ../images/lists/label_light.svg - ../images/lists/label_orange.svg - ../images/lists/label_pink.svg - ../images/lists/label_purple.svg - ../images/lists/label_red.svg - ../images/lists/label_violet.svg - ../images/lists/label_white.svg - ../images/lists/label_yellow.svg + ../images/lists/label_template.svg ../images/lists/list.svg + + ../images/clearSearchNew.svg + ../images/iconSearchNew.svg diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc index 15a289e5..a26df5b0 100644 --- a/YACReaderLibrary/images_osx.qrc +++ b/YACReaderLibrary/images_osx.qrc @@ -1,30 +1,5 @@ - ../images/folder_finished_macosx.png - ../images/empty_folder_osx.png - ../images/empty_search_osx.png - ../images/empty_reading_list_osx.png - ../images/sidebar/libraryIcon_osx.png - ../images/sidebar/setRoot_osx.png - ../images/sidebar/expand_osx.png - ../images/sidebar/colapse_osx.png - ../images/sidebar/newLibraryIcon_osx.png - ../images/sidebar/openLibraryIcon_osx.png - ../images/sidebar/addNew_sidebar_osx.png - ../images/sidebar/delete_sidebar_osx.png - ../images/sidebar/addLabelIcon_osx.png - ../images/sidebar/renameListIcon_osx.png - ../images/sidebar/setRoot_osx@2x.png - ../images/sidebar/expand_osx@2x.png - ../images/sidebar/colapse_osx@2x.png - ../images/sidebar/newLibraryIcon_osx@2x.png - ../images/sidebar/openLibraryIcon_osx@2x.png - ../images/sidebar/addNew_sidebar_osx@2x.png - ../images/sidebar/delete_sidebar_osx@2x.png - ../images/sidebar/addLabelIcon_osx@2x.png - ../images/sidebar/renameListIcon_osx@2x.png - ../images/viewer_toolbar/close_osx.png - ../images/viewer_toolbar/close_osx@2x.png macostrayicon.svg diff --git a/YACReaderLibrary/images_win.qrc b/YACReaderLibrary/images_win.qrc index 3fa00b2f..9eb496ef 100644 --- a/YACReaderLibrary/images_win.qrc +++ b/YACReaderLibrary/images_win.qrc @@ -1,31 +1,5 @@ - ../images/main_toolbar/back.svg - ../images/main_toolbar/back_disabled.png - ../images/main_toolbar/forward.svg - ../images/main_toolbar/forward_disabled.png - ../images/main_toolbar/settings.svg - ../images/main_toolbar/server.svg - ../images/main_toolbar/help.svg - ../images/main_toolbar/fullscreen.svg - ../images/main_toolbar/flow.svg - ../images/main_toolbar/grid.svg - ../images/main_toolbar/info.svg - ../images/sidebar/libraryIcon.svg - ../images/sidebar/setRoot.svg - ../images/sidebar/expand.svg - ../images/sidebar/colapse.svg - ../images/sidebar/newLibraryIcon.svg - ../images/sidebar/openLibraryIcon.svg - ../images/sidebar/addNew_sidebar.svg - ../images/sidebar/delete_sidebar.svg - ../images/sidebar/addLabelIcon.svg - ../images/sidebar/renameListIcon.svg - ../images/empty_folder.png - ../images/empty_search.png - ../images/iconSearchNew.svg - ../images/clearSearchNew.svg - ../images/empty_reading_list.png ../images/viewer_toolbar/close.svg icon.ico diff --git a/YACReaderLibrary/import_comics_info_dialog.cpp b/YACReaderLibrary/import_comics_info_dialog.cpp index 2ed5fd56..3018c572 100644 --- a/YACReaderLibrary/import_comics_info_dialog.cpp +++ b/YACReaderLibrary/import_comics_info_dialog.cpp @@ -25,7 +25,7 @@ ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ImportComicsInfoDialog::close); // connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected())); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ImportComicsInfoDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -54,15 +54,21 @@ ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/importComicsInfo.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); setLayout(imgMainLayout); setModal(true); + + initTheme(this); +} + +void ImportComicsInfoDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.importComicsInfoIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } ImportComicsInfoDialog::~ImportComicsInfoDialog() diff --git a/YACReaderLibrary/import_comics_info_dialog.h b/YACReaderLibrary/import_comics_info_dialog.h index 01ea022f..37d7d8e9 100644 --- a/YACReaderLibrary/import_comics_info_dialog.h +++ b/YACReaderLibrary/import_comics_info_dialog.h @@ -1,6 +1,8 @@ #ifndef IMPORT_COMICS_INFO_DIALOG_H #define IMPORT_COMICS_INFO_DIALOG_H +#include "themable.h" + #include #include #include @@ -19,7 +21,7 @@ private: void run() override; }; -class ImportComicsInfoDialog : public QDialog +class ImportComicsInfoDialog : public QDialog, protected Themable { Q_OBJECT @@ -28,7 +30,11 @@ public: ~ImportComicsInfoDialog(); QString dest; +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *destLabel; diff --git a/YACReaderLibrary/import_library_dialog.cpp b/YACReaderLibrary/import_library_dialog.cpp index 2a065bd6..aad7b823 100644 --- a/YACReaderLibrary/import_library_dialog.cpp +++ b/YACReaderLibrary/import_library_dialog.cpp @@ -35,10 +35,10 @@ void ImportLibraryDialog::setupUI() connect(cancel, &QAbstractButton::clicked, this, &ImportLibraryDialog::close); // connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected())); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ImportLibraryDialog::findPath); - findDest = new QPushButton(QIcon(":/images/find_folder.png"), ""); + findDest = new QPushButton(""); connect(findDest, &QAbstractButton::clicked, this, &ImportLibraryDialog::findDestination); auto content = new QGridLayout; @@ -75,9 +75,7 @@ void ImportLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/importLibrary.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -85,6 +83,15 @@ void ImportLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Extract a catalog")); + + initTheme(this); +} + +void ImportLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.importLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); + findDest->setIcon(theme.dialogIcons.findFolderIcon); } void ImportLibraryDialog::open(const YACReaderLibraries &libs) { diff --git a/YACReaderLibrary/import_library_dialog.h b/YACReaderLibrary/import_library_dialog.h index 632ea547..de1cceed 100644 --- a/YACReaderLibrary/import_library_dialog.h +++ b/YACReaderLibrary/import_library_dialog.h @@ -1,6 +1,7 @@ #ifndef IMPORT_LIBRARY_DIALOG_H #define IMPORT_LIBRARY_DIALOG_H #include "yacreader_libraries.h" +#include "themable.h" #include #include @@ -9,13 +10,17 @@ #include #include -class ImportLibraryDialog : public QDialog +class ImportLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: ImportLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *destLabel; diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp index 7d721b48..f899353f 100644 --- a/YACReaderLibrary/import_widget.cpp +++ b/YACReaderLibrary/import_widget.cpp @@ -85,28 +85,17 @@ ImportWidget::ImportWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - QPalette p(palette()); - p.setColor(QPalette::Window, QColor(250, 250, 250)); setAutoFillBackground(true); - setPalette(p); - QPixmap icon(":/images/importingIcon.png"); iconLabel = new QLabel(); - iconLabel->setPixmap(icon); - - /*QPixmap line(":/images/noLibrariesLine.png"); - QLabel * lineLabel = new QLabel(); - lineLabel->setPixmap(line);*/ auto activityIndicator = new YACReaderActivityIndicatorWidget(); - text = new QLabel(); //""+tr("Importing comics")+""); - text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); - textDescription = new QLabel(); //""+tr("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")+""); + text = new QLabel(); + textDescription = new QLabel(); textDescription->setWordWrap(true); textDescription->setMaximumWidth(330); - currentComicLabel = new QLabel("..."); + currentComicLabel = new QLabel("..."); coversViewContainer = new QWidget(this); auto coversViewLayout = new QVBoxLayout; @@ -115,11 +104,9 @@ ImportWidget::ImportWidget(QWidget *parent) coversViewContainer->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum); coversView = new QGraphicsView(); - // coversView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); coversView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); coversView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); coversView->setMaximumHeight(300); - coversView->setStyleSheet("QGraphicsView {background-color: #E6E6E6;border:none;}"); coversScene = new QGraphicsScene(); coversView->setAlignment(Qt::AlignLeft); @@ -130,16 +117,10 @@ ImportWidget::ImportWidget(QWidget *parent) scrollAnimation = new QPropertyAnimation(coversView->horizontalScrollBar(), "value"); - QLabel *topDecorator = new QLabel(); - QLabel *bottomDecorator = new QLabel(); - QPixmap top(":/images/importTopCoversDecoration.png"); - QPixmap bottom(":/images/importBottomCoversDecoration.png"); - topDecorator->setPixmap(top); - bottomDecorator->setPixmap(bottom); + topDecorator = new QLabel(); + bottomDecorator = new QLabel(); topDecorator->setScaledContents(true); bottomDecorator->setScaledContents(true); - topDecorator->setFixedHeight(top.height()); - bottomDecorator->setFixedHeight(bottom.height()); coversViewLayout->addWidget(topDecorator, 0); coversViewLayout->addWidget(coversView, 1); @@ -187,12 +168,13 @@ ImportWidget::ImportWidget(QWidget *parent) layout->addLayout(buttonLayout, 0); layout->addSpacing(10); layout->addStretch(); - coversLabel = new QLabel("" + tr("Some of the comics being added...") + ""); + coversLabel = new QLabel(tr("Some of the comics being added...")); hideButton = new QToolButton(this); hideButton->setFixedSize(25, 18); - hideButton->setStyleSheet("QToolButton {background: url(\":/images/shownCovers.png\"); border:none;}" - " QToolButton:checked {background:url(\":/images/hiddenCovers.png\"); border:none;}"); + hideButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" + "QToolButton:pressed { border: none; padding: 0px; }" + "QToolButton:checked { border: none; padding: 0px; }"); hideButton->setCheckable(true); connect(hideButton, &QAbstractButton::toggled, this, &ImportWidget::showCovers); @@ -210,6 +192,8 @@ ImportWidget::ImportWidget(QWidget *parent) updatingCovers = false; elapsedTimer = new QElapsedTimer(); elapsedTimer->start(); + + initTheme(this); } void ImportWidget::newComic(const QString &path, const QString &coverPath) @@ -217,7 +201,7 @@ void ImportWidget::newComic(const QString &path, const QString &coverPath) if (!this->isVisible()) return; - currentComicLabel->setText("" + path + ""); + currentComicLabel->setText(path); if (((elapsedTimer->elapsed() >= 1100) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed() >= 500))) && scrollAnimation->state() != QAbstractAnimation::Running) // todo elapsed time { @@ -323,16 +307,16 @@ void ImportWidget::clear() updatingCovers = false; - currentComicLabel->setText("..."); + currentComicLabel->setText("..."); this->i = 0; } void ImportWidget::setImportLook() { - iconLabel->setPixmap(QPixmap(":/images/importingIcon.png")); - text->setText("" + tr("Importing comics") + ""); - textDescription->setText("" + tr("

YACReaderLibrary is now creating a new library.

Create a library could take several minutes. You can stop the process and update the library later for completing the task.

") + "
"); + iconLabel->setPixmap(theme.importWidget.importingIcon); + text->setText(tr("Importing comics")); + textDescription->setText(tr("

YACReaderLibrary is now creating a new library.

Create a library could take several minutes. You can stop the process and update the library later for completing the task.

")); stopButton->setVisible(true); coversLabel->setVisible(true); @@ -342,9 +326,9 @@ void ImportWidget::setImportLook() void ImportWidget::setUpdateLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Updating the library") + ""); - textDescription->setText("" + tr("

The current library is being updated. For faster updates, please, update your libraries frequently.

You can stop the process and continue updating this library later.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Updating the library")); + textDescription->setText(tr("

The current library is being updated. For faster updates, please, update your libraries frequently.

You can stop the process and continue updating this library later.

")); stopButton->setVisible(true); coversLabel->setVisible(true); @@ -354,9 +338,9 @@ void ImportWidget::setUpdateLook() void ImportWidget::setUpgradeLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Upgrading the library") + ""); - textDescription->setText("" + tr("

The current library is being upgraded, please wait.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Upgrading the library")); + textDescription->setText(tr("

The current library is being upgraded, please wait.

")); stopButton->setVisible(false); coversLabel->setVisible(false); @@ -366,9 +350,9 @@ void ImportWidget::setUpgradeLook() void ImportWidget::setXMLScanLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Scanning the library") + ""); - textDescription->setText("" + tr("

Current library is being scanned for legacy XML metadata information.

This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Scanning the library")); + textDescription->setText(tr("

Current library is being scanned for legacy XML metadata information.

This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.

")); stopButton->setVisible(true); coversLabel->setVisible(false); @@ -392,3 +376,53 @@ void ImportWidget::resizeEvent(QResizeEvent *event) QWidget::resizeEvent(event); } + +void ImportWidget::applyTheme(const Theme &theme) +{ + const auto &importTheme = theme.importWidget; + + // Covers toggle button + hideButton->setIcon(importTheme.coversToggleIcon); + hideButton->setIconSize(hideButton->size()); + + // Background + QPalette p(palette()); + p.setColor(QPalette::Window, importTheme.backgroundColor); + setPalette(p); + + // Covers view background + coversView->setStyleSheet(QString("QGraphicsView {background-color: %1; border:none;}") + .arg(importTheme.coversViewBackgroundColor.name())); + + // Covers decorations + topDecorator->setPixmap(importTheme.topCoversDecoration); + topDecorator->setFixedHeight(importTheme.topCoversDecoration.height()); + bottomDecorator->setPixmap(importTheme.bottomCoversDecoration); + bottomDecorator->setFixedHeight(importTheme.bottomCoversDecoration.height()); + + // Apply text colors + updateTextColors(); +} + +void ImportWidget::updateTextColors() +{ + const auto &importTheme = theme.importWidget; + + // Title text + text->setStyleSheet(importTheme.titleLabelQSS); + + // Description text + QPalette descPalette = textDescription->palette(); + descPalette.setColor(QPalette::WindowText, importTheme.descriptionTextColor); + textDescription->setPalette(descPalette); + + // Current comic label + QPalette comicPalette = currentComicLabel->palette(); + comicPalette.setColor(QPalette::WindowText, importTheme.currentComicTextColor); + currentComicLabel->setPalette(comicPalette); + + // Covers label + QPalette coversLabelPalette = coversLabel->palette(); + coversLabelPalette.setColor(QPalette::WindowText, importTheme.coversLabelColor); + coversLabel->setPalette(coversLabelPalette); +} diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h index 21d4c755..83366062 100644 --- a/YACReaderLibrary/import_widget.h +++ b/YACReaderLibrary/import_widget.h @@ -3,12 +3,17 @@ #include -class ImportWidget : public QWidget +#include "themable.h" + +class ImportWidget : public QWidget, protected Themable { Q_OBJECT public: explicit ImportWidget(QWidget *parent = 0); +protected: + void applyTheme(const Theme &theme) override; + signals: void stop(); public slots: @@ -41,8 +46,11 @@ private: quint64 i; QToolButton *hideButton; + QLabel *topDecorator; + QLabel *bottomDecorator; void resizeEvent(QResizeEvent *event) override; + void updateTextColors(); }; #endif // IMPORT_WIDGET_H diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 0bd68764..e81ec140 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -1,6 +1,7 @@ #include "info_comics_view.h" #include "yacreader_global.h" +#include "theme_manager.h" #include #include @@ -22,52 +23,8 @@ InfoComicsView::InfoComicsView(QWidget *parent) QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif - - if (theme == Light) { - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("showDropShadow", QVariant(false)); - } else { - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("showDropShadow", QVariant(true)); - } + // Apply theme colors + initTheme(this); ctxt->setContextProperty("backgroundImage", QUrl()); ctxt->setContextProperty("comicsList", new ComicModel()); @@ -263,3 +220,28 @@ void InfoComicsView::selectedItem(int index) { emit selected(index); } + +void InfoComicsView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); +} + diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h index 3cc925c8..596b60c4 100644 --- a/YACReaderLibrary/info_comics_view.h +++ b/YACReaderLibrary/info_comics_view.h @@ -2,17 +2,22 @@ #define INFOCOMICSVIEW_H #include "comics_view.h" +#include +#include "themable.h" class QQuickView; class YACReaderComicsSelectionHelper; class YACReaderComicInfoHelper; -class InfoComicsView : public ComicsView +class InfoComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit InfoComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; ~InfoComicsView() override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 2ae2f521..031eac89 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -54,7 +54,6 @@ #include "comic_vine_dialog.h" #include "api_key_dialog.h" -// #include "yacreader_social_dialog.h" #include "comics_view.h" @@ -85,6 +84,8 @@ #include "cover_utils.h" +#include "theme_manager.h" + #include "QsLog.h" #include "yacreader_http_server.h" @@ -233,25 +234,28 @@ void LibraryWindow::setupUI() showMaximized(); trayIconController = new TrayIconController(settings, this); + + initTheme(this); +} + +void LibraryWindow::applyTheme(const Theme &theme) +{ + editInfoToolBar->setStyleSheet(theme.comicsViewToolbar.toolbarQSS); + mainSplitter->setStyleSheet(theme.contentSplitter.horizontalSplitterQSS); + + // Update main toolbar and comics view toolbar icons + actions.updateTheme(theme); } void LibraryWindow::doLayout() { // LAYOUT ELEMENTS------------------------------------------------------------ - auto sHorizontal = new QSplitter(Qt::Horizontal); // spliter principal -#ifdef Y_MAC_UI - sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}"); -#else - sHorizontal->setStyleSheet("QSplitter::handle:vertical {height:4px;}"); -#endif + mainSplitter = new QSplitter(Qt::Horizontal); // spliter principal + auto sHorizontal = mainSplitter; // Keep local alias for existing code // TOOLBARS------------------------------------------------------------------- //--------------------------------------------------------------------------- editInfoToolBar = new QToolBar(); - editInfoToolBar->setStyleSheet(R"( - QToolBar { border: none; } - QToolButton:checked { background-color: #cccccc; } - )"); #ifdef Y_MAC_UI libraryToolBar = new YACReaderMacOSXToolbar(this); @@ -1402,12 +1406,14 @@ void LibraryWindow::showGridFoldersContextMenu(QPoint point, Folder folder) { QMenu menu; + const auto &menuIcons = theme.menuIcons; + auto openContainingFolderAction = new QAction(); openContainingFolderAction->setText(tr("Open folder...")); - openContainingFolderAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); + openContainingFolderAction->setIcon(menuIcons.openContainingFolderIcon); auto updateFolderAction = new QAction(tr("Update folder"), this); - updateFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); + updateFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); auto rescanLibraryForXMLInfoAction = new QAction(tr("Rescan library for XML info"), this); @@ -1563,7 +1569,7 @@ void LibraryWindow::showContinueReadingContextMenu(QPoint point, ComicDB comic) auto setAsUnReadAction = new QAction(); setAsUnReadAction->setText(tr("Set as unread")); - setAsUnReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.svg")); + setAsUnReadAction->setIcon(theme.comicsViewToolbar.setAsUnreadIcon); menu.addAction(setAsUnReadAction); @@ -2642,19 +2648,6 @@ void LibraryWindow::showFoldersContextMenu(const QPoint &point) menu.exec(foldersView->mapToGlobal(point)); } -/* -void LibraryWindow::showSocial() -{ - socialDialog->move(this->mapToGlobal(QPoint(width()-socialDialog->width()-10, centralWidget()->pos().y()+10))); - - QModelIndexList indexList = getSelectedComics(); - - ComicDB comic = dmCV->getComic(indexList.at(0)); - - socialDialog->setComic(comic,currentPath()); - socialDialog->setHidden(false); -}*/ - void LibraryWindow::libraryAlreadyExists(const QString &name) { QMessageBox::information(this, tr("Library name already exists"), tr("There is another library with the name '%1'.").arg(name)); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index c200a8b8..091ef275 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -16,6 +16,8 @@ #include "comic_query_result_processor.h" #include "folder_query_result_processor.h" +#include "themable.h" + #include "comic_model.h" #include "comic_db.h" #include "folder.h" @@ -94,13 +96,14 @@ class XMLInfoLibraryScanner; using namespace YACReader; -class LibraryWindow : public QMainWindow +class LibraryWindow : public QMainWindow, protected Themable { friend class YACReaderNavigationController; Q_OBJECT public: YACReaderSideBar *sideBar; + QSplitter *mainSplitter; CreateLibraryDialog *createLibraryDialog; ExportLibraryDialog *exportLibraryDialog; @@ -115,7 +118,6 @@ public: PropertiesDialog *propertiesDialog; ComicVineDialog *comicVineDialog; EditShortcutsDialog *editShortcutsDialog; - // YACReaderSocialDialog * socialDialog; bool fullscreen; bool importedCovers; // if true, the library is read only (not updates,open comic or properties) bool fromMaximized; @@ -215,6 +217,7 @@ public: protected: virtual void closeEvent(QCloseEvent *event) override; + void applyTheme(const Theme &theme) override; public: LibraryWindow(); @@ -290,7 +293,6 @@ public slots: void deleteComics(); void deleteComicsFromDisk(); void deleteComicsFromList(); - // void showSocial(); void showFoldersContextMenu(const QPoint &point); void showGridFoldersContextMenu(QPoint point, Folder folder); void showContinueReadingContextMenu(QPoint point, ComicDB comic); diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index 011321e6..cebf7b51 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -12,6 +12,7 @@ #include "server_config_dialog.h" #include "yacreader_folders_view.h" #include "yacreader_options_dialog.h" +#include "theme_manager.h" #include #include @@ -25,76 +26,59 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti auto tr = [](const char *text) { return QObject::tr(text); }; backAction = new QAction(window); - QIcon icoBackButton; - icoBackButton.addFile(addExtensionToIconPath(":/images/main_toolbar/back"), QSize(), QIcon::Normal); - // icoBackButton.addPixmap(QPixmap(":/images/main_toolbar/back_disabled.png"), QIcon::Disabled); backAction->setData(BACK_ACTION_YL); backAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(BACK_ACTION_YL)); - backAction->setIcon(icoBackButton); backAction->setDisabled(true); forwardAction = new QAction(window); - QIcon icoFordwardButton; - icoFordwardButton.addFile(addExtensionToIconPath(":/images/main_toolbar/forward"), QSize(), QIcon::Normal); - // icoFordwardButton.addPixmap(QPixmap(":/images/main_toolbar/forward_disabled.png"), QIcon::Disabled); forwardAction->setData(FORWARD_ACTION_YL); forwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORWARD_ACTION_YL)); - forwardAction->setIcon(icoFordwardButton); forwardAction->setDisabled(true); createLibraryAction = new QAction(window); createLibraryAction->setToolTip(tr("Create a new library")); createLibraryAction->setData(CREATE_LIBRARY_ACTION_YL); createLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CREATE_LIBRARY_ACTION_YL)); - createLibraryAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/newLibraryIcon"))); openLibraryAction = new QAction(window); openLibraryAction->setToolTip(tr("Open an existing library")); openLibraryAction->setData(OPEN_LIBRARY_ACTION_YL); openLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_LIBRARY_ACTION_YL)); - openLibraryAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/openLibraryIcon"))); exportComicsInfoAction = new QAction(tr("Export comics info"), window); exportComicsInfoAction->setToolTip(tr("Export comics info")); exportComicsInfoAction->setData(EXPORT_COMICS_INFO_ACTION_YL); exportComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_COMICS_INFO_ACTION_YL)); - exportComicsInfoAction->setIcon(QIcon(":/images/menus_icons/exportComicsInfoIcon.svg")); importComicsInfoAction = new QAction(tr("Import comics info"), window); importComicsInfoAction->setToolTip(tr("Import comics info")); importComicsInfoAction->setData(IMPORT_COMICS_INFO_ACTION_YL); importComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_COMICS_INFO_ACTION_YL)); - importComicsInfoAction->setIcon(QIcon(":/images/menus_icons/importComicsInfoIcon.svg")); exportLibraryAction = new QAction(tr("Pack covers"), window); exportLibraryAction->setToolTip(tr("Pack the covers of the selected library")); exportLibraryAction->setData(EXPORT_LIBRARY_ACTION_YL); exportLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_LIBRARY_ACTION_YL)); - exportLibraryAction->setIcon(QIcon(":/images/menus_icons/exportLibraryIcon.svg")); importLibraryAction = new QAction(tr("Unpack covers"), window); importLibraryAction->setToolTip(tr("Unpack a catalog")); importLibraryAction->setData(IMPORT_LIBRARY_ACTION_YL); importLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_LIBRARY_ACTION_YL)); - importLibraryAction->setIcon(QIcon(":/images/menus_icons/importLibraryIcon.svg")); updateLibraryAction = new QAction(tr("Update library"), window); updateLibraryAction->setToolTip(tr("Update current library")); updateLibraryAction->setData(UPDATE_LIBRARY_ACTION_YL); updateLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_LIBRARY_ACTION_YL)); - updateLibraryAction->setIcon(QIcon(":/images/menus_icons/updateLibraryIcon.svg")); renameLibraryAction = new QAction(tr("Rename library"), window); renameLibraryAction->setToolTip(tr("Rename current library")); renameLibraryAction->setData(RENAME_LIBRARY_ACTION_YL); renameLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIBRARY_ACTION_YL)); - renameLibraryAction->setIcon(QIcon(":/images/menus_icons/editIcon.svg")); removeLibraryAction = new QAction(tr("Remove library"), window); removeLibraryAction->setToolTip(tr("Remove current library from your collection")); removeLibraryAction->setData(REMOVE_LIBRARY_ACTION_YL); removeLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_LIBRARY_ACTION_YL)); - removeLibraryAction->setIcon(QIcon(":/images/menus_icons/removeLibraryIcon.svg")); rescanLibraryForXMLInfoAction = new QAction(tr("Rescan library for XML info"), window); rescanLibraryForXMLInfoAction->setToolTip(tr("Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files.")); @@ -110,7 +94,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openComicAction->setToolTip(tr("Open current comic on YACReader")); openComicAction->setData(OPEN_COMIC_ACTION_YL); openComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_COMIC_ACTION_YL)); - openComicAction->setIcon(QIcon(":/images/comics_view_toolbar/openInYACReader.svg")); saveCoversToAction = new QAction(tr("Save selected covers to..."), window); saveCoversToAction->setToolTip(tr("Save covers of the selected comics as JPG files")); @@ -121,25 +104,21 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti setAsReadAction->setToolTip(tr("Set comic as read")); setAsReadAction->setData(SET_AS_READ_ACTION_YL); setAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_READ_ACTION_YL)); - setAsReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setReadButton.svg")); setAsNonReadAction = new QAction(tr("Set as unread"), window); setAsNonReadAction->setToolTip(tr("Set comic as unread")); setAsNonReadAction->setData(SET_AS_NON_READ_ACTION_YL); setAsNonReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NON_READ_ACTION_YL)); - setAsNonReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.svg")); setMangaAction = new QAction(tr("manga"), window); setMangaAction->setToolTip(tr("Set issue as manga")); setMangaAction->setData(SET_AS_MANGA_ACTION_YL); setMangaAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_MANGA_ACTION_YL)); - setMangaAction->setIcon(QIcon(":/images/comics_view_toolbar/setManga.svg")); setNormalAction = new QAction(tr("comic"), window); setNormalAction->setToolTip(tr("Set issue as normal")); setNormalAction->setData(SET_AS_NORMAL_ACTION_YL); setNormalAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NORMAL_ACTION_YL)); - setNormalAction->setIcon(QIcon(":/images/comics_view_toolbar/setNormal.svg")); setWesternMangaAction = new QAction(tr("western manga"), window); setWesternMangaAction->setToolTip(tr("Set issue as western manga")); @@ -163,7 +142,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti showHideMarksAction->setData(SHOW_HIDE_MARKS_ACTION_YL); showHideMarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_MARKS_ACTION_YL)); showHideMarksAction->setCheckable(true); - showHideMarksAction->setIcon(QIcon(":/images/comics_view_toolbar/showMarks.svg")); showHideMarksAction->setChecked(true); toogleShowRecentIndicatorAction = new QAction(tr("Show/Hide recent indicator"), window); @@ -171,7 +149,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti toogleShowRecentIndicatorAction->setData(SHOW_HIDE_RECENT_INDICATOR_ACTION_YL); toogleShowRecentIndicatorAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_RECENT_INDICATOR_ACTION_YL)); toogleShowRecentIndicatorAction->setCheckable(true); - toogleShowRecentIndicatorAction->setIcon(QIcon(":/images/comics_view_toolbar/showRecentIndicator.svg")); toogleShowRecentIndicatorAction->setChecked(settings->value(DISPLAY_RECENTLY_INDICATOR, true).toBool()); #ifndef Q_OS_MACOS @@ -179,79 +156,52 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti toggleFullScreenAction->setToolTip(tr("Fullscreen mode on/off")); toggleFullScreenAction->setData(TOGGLE_FULL_SCREEN_ACTION_YL); toggleFullScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_YL)); - QIcon icoFullscreenButton; - icoFullscreenButton.addFile(addExtensionToIconPath(":/images/main_toolbar/fullscreen"), QSize(), QIcon::Normal); - toggleFullScreenAction->setIcon(icoFullscreenButton); #endif helpAboutAction = new QAction(window); helpAboutAction->setToolTip(tr("Help, About YACReader")); helpAboutAction->setData(HELP_ABOUT_ACTION_YL); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_YL)); - QIcon icoHelpButton; - icoHelpButton.addFile(addExtensionToIconPath(":/images/main_toolbar/help"), QSize(), QIcon::Normal); - helpAboutAction->setIcon(icoHelpButton); addFolderAction = new QAction(tr("Add new folder"), window); addFolderAction->setData(ADD_FOLDER_ACTION_YL); addFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_FOLDER_ACTION_YL)); addFolderAction->setToolTip(tr("Add new folder to the current library")); - addFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addNew_sidebar"))); deleteFolderAction = new QAction(tr("Delete folder"), window); deleteFolderAction->setData(REMOVE_FOLDER_ACTION_YL); deleteFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_FOLDER_ACTION_YL)); deleteFolderAction->setToolTip(tr("Delete current folder from disk")); - deleteFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/delete_sidebar"))); setRootIndexAction = new QAction(window); setRootIndexAction->setData(SET_ROOT_INDEX_ACTION_YL); setRootIndexAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_ROOT_INDEX_ACTION_YL)); setRootIndexAction->setToolTip(tr("Select root node")); - setRootIndexAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/setRoot"))); expandAllNodesAction = new QAction(window); expandAllNodesAction->setToolTip(tr("Expand all nodes")); expandAllNodesAction->setData(EXPAND_ALL_NODES_ACTION_YL); expandAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPAND_ALL_NODES_ACTION_YL)); - expandAllNodesAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/expand"))); colapseAllNodesAction = new QAction(window); colapseAllNodesAction->setToolTip(tr("Collapse all nodes")); colapseAllNodesAction->setData(COLAPSE_ALL_NODES_ACTION_YL); colapseAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(COLAPSE_ALL_NODES_ACTION_YL)); - colapseAllNodesAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/colapse"))); optionsAction = new QAction(window); optionsAction->setToolTip(tr("Show options dialog")); optionsAction->setData(OPTIONS_ACTION_YL); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_YL)); - QIcon icoSettingsButton; - icoSettingsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/settings"), QSize(), QIcon::Normal); - optionsAction->setIcon(icoSettingsButton); serverConfigAction = new QAction(window); serverConfigAction->setToolTip(tr("Show comics server options dialog")); serverConfigAction->setData(SERVER_CONFIG_ACTION_YL); serverConfigAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SERVER_CONFIG_ACTION_YL)); - QIcon icoServerButton; - icoServerButton.addFile(addExtensionToIconPath(":/images/main_toolbar/server"), QSize(), QIcon::Normal); - serverConfigAction->setIcon(icoServerButton); toggleComicsViewAction = new QAction(tr("Change between comics views"), window); toggleComicsViewAction->setToolTip(tr("Change between comics views")); - QIcon icoViewsButton; - - if (!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/grid"), QSize(), QIcon::Normal); - else if (settings->value(COMICS_VIEW_STATUS) == Grid) - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/info"), QSize(), QIcon::Normal); - else - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/flow"), QSize(), QIcon::Normal); toggleComicsViewAction->setData(TOGGLE_COMICS_VIEW_ACTION_YL); toggleComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_COMICS_VIEW_ACTION_YL)); - toggleComicsViewAction->setIcon(icoViewsButton); - // socialAction = new QAction(this); //---- @@ -259,7 +209,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openContainingFolderAction->setText(tr("Open folder...")); openContainingFolderAction->setData(OPEN_CONTAINING_FOLDER_ACTION_YL); openContainingFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_ACTION_YL)); - openContainingFolderAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); setFolderAsNotCompletedAction = new QAction(window); setFolderAsNotCompletedAction->setText(tr("Set as uncompleted")); @@ -322,7 +271,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openContainingFolderComicAction->setText(tr("Open containing folder...")); openContainingFolderComicAction->setData(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL); openContainingFolderComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL)); - openContainingFolderComicAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); resetComicRatingAction = new QAction(window); resetComicRatingAction->setText(tr("Reset comic rating")); @@ -334,19 +282,16 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti selectAllComicsAction->setText(tr("Select all comics")); selectAllComicsAction->setData(SELECT_ALL_COMICS_ACTION_YL); selectAllComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SELECT_ALL_COMICS_ACTION_YL)); - selectAllComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/selectAll.svg")); editSelectedComicsAction = new QAction(window); editSelectedComicsAction->setText(tr("Edit")); editSelectedComicsAction->setData(EDIT_SELECTED_COMICS_ACTION_YL); editSelectedComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EDIT_SELECTED_COMICS_ACTION_YL)); - editSelectedComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/editComic.svg")); asignOrderAction = new QAction(window); asignOrderAction->setText(tr("Assign current order to comics")); asignOrderAction->setData(ASIGN_ORDER_ACTION_YL); asignOrderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ASIGN_ORDER_ACTION_YL)); - asignOrderAction->setIcon(QIcon(":/images/comics_view_toolbar/asignNumber.svg")); forceCoverExtractedAction = new QAction(window); forceCoverExtractedAction->setText(tr("Update cover")); @@ -358,7 +303,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti deleteComicsAction->setText(tr("Delete selected comics")); deleteComicsAction->setData(DELETE_COMICS_ACTION_YL); deleteComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DELETE_COMICS_ACTION_YL)); - deleteComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/trash.svg")); deleteMetadataAction = new QAction(window); deleteMetadataAction->setText(tr("Delete metadata from selected comics")); @@ -369,7 +313,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti getInfoAction->setData(GET_INFO_ACTION_YL); getInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GET_INFO_ACTION_YL)); getInfoAction->setText(tr("Download tags from Comic Vine")); - getInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/getInfo.svg")); //------------------------------------------------------------------------- focusSearchLineAction = new QAction(tr("Focus search line"), window); @@ -390,19 +333,17 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti window->addAction(showEditShortcutsAction); quitAction = new QAction(tr("&Quit"), window); - quitAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); + // quitAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); quitAction->setData(QUIT_ACTION_YL); quitAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(QUIT_ACTION_YL)); // TODO: is `quitAction->setMenuRole(QAction::QuitRole);` useful on macOS? window->addAction(quitAction); updateFolderAction = new QAction(tr("Update folder"), window); - updateFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); updateCurrentFolderAction = new QAction(tr("Update current folder"), window); updateCurrentFolderAction->setData(UPDATE_CURRENT_FOLDER_ACTION_YL); updateCurrentFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_CURRENT_FOLDER_ACTION_YL)); - updateCurrentFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); rescanXMLFromCurrentFolderAction = new QAction(tr("Scan legacy XML metadata"), window); rescanXMLFromCurrentFolderAction->setData(SCAN_XML_FROM_CURRENT_FOLDER_ACTION_YL); @@ -412,25 +353,21 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti addReadingListAction->setData(ADD_READING_LIST_ACTION_YL); addReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_READING_LIST_ACTION_YL)); addReadingListAction->setToolTip(tr("Add a new reading list to the current library")); - addReadingListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addNew_sidebar"))); deleteReadingListAction = new QAction(tr("Remove reading list"), window); deleteReadingListAction->setData(REMOVE_READING_LIST_ACTION_YL); deleteReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_READING_LIST_ACTION_YL)); deleteReadingListAction->setToolTip(tr("Remove current reading list from the library")); - deleteReadingListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/delete_sidebar"))); addLabelAction = new QAction(tr("Add new label"), window); addLabelAction->setData(ADD_LABEL_ACTION_YL); addLabelAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_LABEL_ACTION_YL)); addLabelAction->setToolTip(tr("Add a new label to this library")); - addLabelAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addLabelIcon"))); renameListAction = new QAction(tr("Rename selected list"), window); renameListAction->setData(RENAME_LIST_ACTION_YL); renameListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIST_ACTION_YL)); renameListAction->setToolTip(tr("Rename any selected labels or lists")); - renameListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/renameListIcon"))); //-- addToMenuAction = new QAction(tr("Add to..."), window); @@ -439,7 +376,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti addToFavoritesAction->setData(ADD_TO_FAVORITES_ACTION_YL); addToFavoritesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_TO_FAVORITES_ACTION_YL)); addToFavoritesAction->setToolTip(tr("Add selected comics to favorites list")); - addToFavoritesAction->setIcon(QIcon(":/images/lists/default_1.svg")); // global actions window->addAction(openComicAction); // this fixes opening comics in fullscreen mode using the keyboard shortcut @@ -609,11 +545,23 @@ void LibraryWindowActions::createConnections( void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editShortcutsDialog) { + // Set up icon mapping for theme changes + QMap> iconMapping; + iconMapping["Comics"] = [](const Theme &t) { return t.shortcutsIcons.comicsIcon; }; + iconMapping["Folders"] = [](const Theme &t) { return t.shortcutsIcons.foldersIcon; }; + iconMapping["Lists"] = [](const Theme &t) { return t.shortcutsIcons.foldersIcon; }; // TODO change icon + iconMapping["General"] = [](const Theme &t) { return t.shortcutsIcons.generalIcon; }; + iconMapping["Libraries"] = [](const Theme &t) { return t.shortcutsIcons.librariesIcon; }; + iconMapping["Visualization"] = [](const Theme &t) { return t.shortcutsIcons.visualizationIcon; }; + editShortcutsDialog->setGroupIconMapping(iconMapping); QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup("Comics", QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), + // Get current theme for initial icons + const auto &theme = ThemeManager::instance().getCurrentTheme(); + + editShortcutsDialog->addActionsGroup("Comics", theme.shortcutsIcons.comicsIcon, tmpList = QList() << openComicAction << saveCoversToAction @@ -632,7 +580,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Folders", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), + editShortcutsDialog->addActionsGroup("Folders", theme.shortcutsIcons.foldersIcon, tmpList = QList() << addFolderAction << deleteFolderAction @@ -652,7 +600,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << deleteCustomFolderCoverAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("Lists", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), // TODO change icon + editShortcutsDialog->addActionsGroup("Lists", theme.shortcutsIcons.foldersIcon, // TODO change icon tmpList = QList() << addReadingListAction << deleteReadingListAction @@ -660,7 +608,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << renameListAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("General", QIcon(":/images/shortcuts/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup("General", theme.shortcutsIcons.generalIcon, tmpList = QList() << backAction << forwardAction @@ -674,7 +622,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Libraries", QIcon(":/images/shortcuts/shortcuts_group_libraries.svg"), + editShortcutsDialog->addActionsGroup("Libraries", theme.shortcutsIcons.librariesIcon, tmpList = QList() << createLibraryAction << openLibraryAction @@ -690,7 +638,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Visualization", QIcon(":/images/shortcuts/shortcuts_group_visualization.svg"), + editShortcutsDialog->addActionsGroup("Visualization", theme.shortcutsIcons.visualizationIcon, tmpList = QList() << showHideMarksAction << toogleShowRecentIndicatorAction @@ -774,3 +722,67 @@ void LibraryWindowActions::disableAllActions() disableLibrariesActions(true); disableFoldersActions(true); } + +void LibraryWindowActions::updateTheme(const Theme &theme) +{ + const auto &mainToolbar = theme.mainToolbar; + const auto &comicsToolbar = theme.comicsViewToolbar; + const auto &readingListIcons = theme.readingListIcons; + const auto &menuIcons = theme.menuIcons; + + // Update sidebar action icons + const auto &sidebarIcons = theme.sidebarIcons; + createLibraryAction->setIcon(sidebarIcons.newLibraryIcon); + openLibraryAction->setIcon(sidebarIcons.openLibraryIcon); + addFolderAction->setIcon(sidebarIcons.addNewIcon); + deleteFolderAction->setIcon(sidebarIcons.deleteIcon); + setRootIndexAction->setIcon(sidebarIcons.setRootIcon); + expandAllNodesAction->setIcon(sidebarIcons.expandIcon); + colapseAllNodesAction->setIcon(sidebarIcons.colapseIcon); + addReadingListAction->setIcon(sidebarIcons.addNewIcon); + deleteReadingListAction->setIcon(sidebarIcons.deleteIcon); + addLabelAction->setIcon(sidebarIcons.addLabelIcon); + renameListAction->setIcon(sidebarIcons.renameListIcon); + + // Main toolbar icons + backAction->setIcon(mainToolbar.backIcon); + forwardAction->setIcon(mainToolbar.forwardIcon); + helpAboutAction->setIcon(mainToolbar.helpIcon); + optionsAction->setIcon(mainToolbar.settingsIcon); + serverConfigAction->setIcon(mainToolbar.serverIcon); +#ifndef Q_OS_MACOS + toggleFullScreenAction->setIcon(mainToolbar.fullscreenIcon); +#endif + + // Comics view toolbar icons + openComicAction->setIcon(comicsToolbar.openInYACReaderIcon); + setAsReadAction->setIcon(comicsToolbar.setAsReadIcon); + setAsNonReadAction->setIcon(comicsToolbar.setAsUnreadIcon); + setMangaAction->setIcon(comicsToolbar.setAsMangaIcon); + setNormalAction->setIcon(comicsToolbar.setAsNormalIcon); + showHideMarksAction->setIcon(comicsToolbar.showMarksIcon); + toogleShowRecentIndicatorAction->setIcon(comicsToolbar.showRecentIndicatorIcon); + selectAllComicsAction->setIcon(comicsToolbar.selectAllIcon); + editSelectedComicsAction->setIcon(comicsToolbar.editComicIcon); + asignOrderAction->setIcon(comicsToolbar.assignNumberIcon); + deleteComicsAction->setIcon(comicsToolbar.deleteIcon); + getInfoAction->setIcon(comicsToolbar.getInfoIcon); + + // Reading list icons + addToFavoritesAction->setIcon(readingListIcons.favoritesIcon); + + // Menu icons (context menus) + exportComicsInfoAction->setIcon(menuIcons.exportComicsInfoIcon); + importComicsInfoAction->setIcon(menuIcons.importComicsInfoIcon); + exportLibraryAction->setIcon(menuIcons.exportLibraryIcon); + importLibraryAction->setIcon(menuIcons.importLibraryIcon); + updateLibraryAction->setIcon(menuIcons.updateLibraryIcon); + renameLibraryAction->setIcon(menuIcons.renameLibraryIcon); + removeLibraryAction->setIcon(menuIcons.removeLibraryIcon); + openContainingFolderAction->setIcon(menuIcons.openContainingFolderIcon); + openContainingFolderComicAction->setIcon(menuIcons.openContainingFolderIcon); + updateFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); + updateCurrentFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); + + quitAction->setIcon(menuIcons.quitIcon); +} diff --git a/YACReaderLibrary/library_window_actions.h b/YACReaderLibrary/library_window_actions.h index 30494236..583595a4 100644 --- a/YACReaderLibrary/library_window_actions.h +++ b/YACReaderLibrary/library_window_actions.h @@ -16,6 +16,7 @@ class YACReaderFoldersView; class YACReaderOptionsDialog; class ServerConfigDialog; class RecentVisibilityCoordinator; +struct Theme; class LibraryWindowActions { @@ -48,7 +49,6 @@ public: QAction *optionsAction; QAction *serverConfigAction; QAction *toggleComicsViewAction; - // QAction * socialAction; // tree actions QAction *addFolderAction; @@ -139,6 +139,7 @@ public: void disableFoldersActions(bool disabled); void disableAllActions(); void setUpShortcutsManagement(EditShortcutsDialog *editShortcutsDialog); + void updateTheme(const Theme &theme); }; #endif // LIBRARY_WINDOW_ACTIONS_H diff --git a/YACReaderLibrary/no_libraries_widget.cpp b/YACReaderLibrary/no_libraries_widget.cpp index c0e05441..7603db7f 100644 --- a/YACReaderLibrary/no_libraries_widget.cpp +++ b/YACReaderLibrary/no_libraries_widget.cpp @@ -9,23 +9,17 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - QPalette p(palette()); - p.setColor(QPalette::Window, QColor(250, 250, 250)); setAutoFillBackground(true); - setPalette(p); - QPixmap icon(":/images/noLibrariesIcon.png"); - QLabel *iconLabel = new QLabel(); - iconLabel->setPixmap(icon); + iconLabel = new QLabel(); QPixmap line(":/images/noLibrariesLine.png"); QLabel *lineLabel = new QLabel(); lineLabel->setPixmap(line); - QLabel *text = new QLabel("" + tr("You don't have any libraries yet") + ""); + text = new QLabel(tr("You don't have any libraries yet")); text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); - QLabel *textDescription = new QLabel("" + tr("

You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.

Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.

") + "
"); + textDescription = new QLabel(tr("

You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.

Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.

")); textDescription->setWordWrap(true); textDescription->setMaximumWidth(330); @@ -75,4 +69,25 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) connect(createButton, &QAbstractButton::clicked, this, &NoLibrariesWidget::createNewLibrary); connect(addButton, &QAbstractButton::clicked, this, &NoLibrariesWidget::addExistingLibrary); + + initTheme(this); +} + +void NoLibrariesWidget::applyTheme(const Theme &theme) +{ + auto emptyTheme = theme.emptyContainer; + + QPalette p(palette()); + p.setColor(QPalette::Window, emptyTheme.backgroundColor); + setPalette(p); + + QPalette textPalette = text->palette(); + textPalette.setColor(QPalette::WindowText, emptyTheme.textColor); + text->setPalette(textPalette); + + QPalette descPalette = textDescription->palette(); + descPalette.setColor(QPalette::WindowText, emptyTheme.descriptionTextColor); + textDescription->setPalette(descPalette); + + iconLabel->setPixmap(emptyTheme.noLibrariesIcon); } diff --git a/YACReaderLibrary/no_libraries_widget.h b/YACReaderLibrary/no_libraries_widget.h index ee1a7b82..9ccfb751 100644 --- a/YACReaderLibrary/no_libraries_widget.h +++ b/YACReaderLibrary/no_libraries_widget.h @@ -3,7 +3,11 @@ #include -class NoLibrariesWidget : public QWidget +#include "themable.h" + +class QLabel; + +class NoLibrariesWidget : public QWidget, protected Themable { Q_OBJECT public: @@ -13,6 +17,14 @@ signals: void createNewLibrary(); void addExistingLibrary(); public slots: + +protected: + void applyTheme(const Theme &theme) override; + +private: + QLabel *iconLabel; + QLabel *text; + QLabel *textDescription; }; #endif // NO_LIBRARIES_WIDGET_H diff --git a/YACReaderLibrary/no_search_results_widget.cpp b/YACReaderLibrary/no_search_results_widget.cpp index bda1096c..e1238d8f 100644 --- a/YACReaderLibrary/no_search_results_widget.cpp +++ b/YACReaderLibrary/no_search_results_widget.cpp @@ -1,53 +1,19 @@ #include "no_search_results_widget.h" -#include "yacreader_global.h" - -#include -#include -#include - NoSearchResultsWidget::NoSearchResultsWidget(QWidget *parent) - : QWidget(parent) + : EmptyContainerInfo(parent) { -#ifdef Y_MAC_UI - backgroundColor = "#FFFFFF"; -#else - backgroundColor = "#2A2A2A"; -#endif + setUpDefaultLayout(true); - auto layout = new QVBoxLayout; - - iconLabel = new QLabel(); - iconLabel->setPixmap(QPixmap(":/images/empty_search.png")); - iconLabel->setAlignment(Qt::AlignCenter); - - titleLabel = new QLabel("No results"); - titleLabel->setAlignment(Qt::AlignCenter); - -#ifdef Y_MAC_UI - titleLabel->setStyleSheet("QLabel {color:#888888; font-size:24px;font-family:Arial;font-weight:bold;}"); -#else - titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); -#endif - - layout->addSpacing(100); - layout->addWidget(iconLabel); - layout->addSpacing(30); - layout->addWidget(titleLabel); - layout->addStretch(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); + setPixmap(theme.emptyContainer.noSearchResultsIcon); + setText(tr("No results")); setContentsMargins(0, 0, 0, 0); - - setStyleSheet(QString("QWidget {background:%1}").arg(backgroundColor)); - setSizePolicy(QSizePolicy ::Expanding, QSizePolicy ::Expanding); - setLayout(layout); } -void NoSearchResultsWidget::paintEvent(QPaintEvent *) +void NoSearchResultsWidget::applyTheme(const Theme &theme) { - QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(backgroundColor)); + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.noSearchResultsIcon); } diff --git a/YACReaderLibrary/no_search_results_widget.h b/YACReaderLibrary/no_search_results_widget.h index 57939af7..48df514a 100644 --- a/YACReaderLibrary/no_search_results_widget.h +++ b/YACReaderLibrary/no_search_results_widget.h @@ -1,25 +1,16 @@ #ifndef NO_SEARCH_RESULTS_WIDGET_H #define NO_SEARCH_RESULTS_WIDGET_H -#include +#include "empty_container_info.h" -class QLabel; - -class NoSearchResultsWidget : public QWidget +class NoSearchResultsWidget : public EmptyContainerInfo { Q_OBJECT public: explicit NoSearchResultsWidget(QWidget *parent = nullptr); -signals: - -public slots: - protected: - QLabel *iconLabel; - QLabel *titleLabel; - void paintEvent(QPaintEvent *) override; - QString backgroundColor; + void applyTheme(const Theme &theme) override; }; #endif // NO_SEARCH_RESULTS_WIDGET_H diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index 55b66c9d..435e0d6d 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -106,21 +106,21 @@ void PropertiesDialog::createCoverBox() coverPageEdit = new YACReaderFieldEdit(); showPreviousCoverPageButton = new QToolButton(); - showPreviousCoverPageButton->setIcon(QIcon(":/images/previousCoverPage.png")); + showPreviousCoverPageButton->setIcon(QIcon(":/images/metadata_dialog/previousCoverPage.svg")); showPreviousCoverPageButton->setToolTip(tr("Load previous page as cover")); showPreviousCoverPageButton->setStyleSheet("QToolButton {border:none;}"); showNextCoverPageButton = new QToolButton(); - showNextCoverPageButton->setIcon(QIcon(":/images/nextCoverPage.png")); + showNextCoverPageButton->setIcon(QIcon(":/images/metadata_dialog/nextCoverPage.svg")); showNextCoverPageButton->setToolTip(tr("Load next page as cover")); showNextCoverPageButton->setStyleSheet("QToolButton {border:none;}"); resetCoverButton = new QToolButton(); - resetCoverButton->setIcon(QIcon(":/images/resetCover.svg")); + resetCoverButton->setIcon(QIcon(":/images/metadata_dialog/resetCover.svg")); resetCoverButton->setToolTip(tr("Reset cover to the default image")); resetCoverButton->setStyleSheet("QToolButton {border:none;}"); loadCustomCoverImageButton = new QToolButton(); - loadCustomCoverImageButton->setIcon(QIcon(":/images/loadCustomCover.svg")); + loadCustomCoverImageButton->setIcon(QIcon(":/images/metadata_dialog/loadCustomCover.svg")); loadCustomCoverImageButton->setToolTip(tr("Load custom cover image")); loadCustomCoverImageButton->setStyleSheet("QToolButton {border:none;}"); diff --git a/YACReaderLibrary/rename_library_dialog.cpp b/YACReaderLibrary/rename_library_dialog.cpp index b249a22c..724dfd34 100644 --- a/YACReaderLibrary/rename_library_dialog.cpp +++ b/YACReaderLibrary/rename_library_dialog.cpp @@ -39,9 +39,7 @@ void RenameLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/edit.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -49,6 +47,13 @@ void RenameLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Rename current library")); + + initTheme(this); +} + +void RenameLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.editIcon); } void RenameLibraryDialog::rename() diff --git a/YACReaderLibrary/rename_library_dialog.h b/YACReaderLibrary/rename_library_dialog.h index 38561415..c8145c59 100644 --- a/YACReaderLibrary/rename_library_dialog.h +++ b/YACReaderLibrary/rename_library_dialog.h @@ -1,18 +1,24 @@ #ifndef __RENAME_LIBRARY_DIALOG_H #define __RENAME_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include #include -class RenameLibraryDialog : public QDialog +class RenameLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: RenameLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *newNameLabel; QLineEdit *newNameEdit; QPushButton *accept; diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index eacd28c1..9352db74 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -11,42 +11,45 @@ #include "ip_config_helper.h" #include "qrcodegen.hpp" +#include "theme_manager.h" extern YACReaderHttpServer *httpServer; ServerConfigDialog::ServerConfigDialog(QWidget *parent) : QDialog(parent) { + // Background decoration (SVG on left side) + backgroundDecoration = new QLabel(this); + backgroundDecoration->move(0, 0); + backgroundDecoration->setFixedSize(329, 595); + backgroundDecoration->setScaledContents(true); + accept = new QPushButton(tr("set port"), this); + qrCode = new QLabel(this); qrCode->move(64, 112); qrCode->setFixedSize(200, 200); qrCode->setScaledContents(true); - QLabel *title1 = new QLabel(tr("Server connectivity information"), this); - title1->move(332, 61); - title1->setStyleSheet("QLabel {color:#474747; font-size:30px; font-family: Arial;}"); + titleLabel = new QLabel(tr("Server connectivity information"), this); + titleLabel->move(332, 61); - QLabel *qrMessage = new QLabel(tr("Scan it!"), this); - qrMessage->move(135, 388); // 373,627); - qrMessage->setStyleSheet("QLabel {color:#A3A3A3; font-size:18px; font-family: Arial;}"); - qrMessage->setWordWrap(true); - qrMessage->setFixedWidth(200); + qrMessageLabel = new QLabel(tr("Scan it!"), this); + qrMessageLabel->move(135, 388); + qrMessageLabel->setWordWrap(true); + qrMessageLabel->setFixedWidth(200); - 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); + propagandaLabel = new QLabel(tr("YACReader is available for iOS and Android devices.
Discover it for iOS or Android."), this); + propagandaLabel->move(332, 505); + propagandaLabel->setOpenExternalLinks(true); // FORM--------------------------------------------------------------------- - QLabel *ipLabel = new QLabel(tr("Choose an IP address"), this); + ipLabel = new QLabel(tr("Choose an IP address"), this); ipLabel->move(332, 117); - ipLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); - QLabel *portLabel = new QLabel(tr("Port"), this); + portLabel = new QLabel(tr("Port"), this); portLabel->move(332, 211); - portLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); ip = new QComboBox(this); connect(ip, &QComboBox::currentTextChanged, this, &ServerConfigDialog::regenerateQR); @@ -78,15 +81,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) check = new QCheckBox(this); check->move(332, 314); check->setText(tr("enable the server")); - check->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); - QPalette palette; - QImage image(":/images/serverConfigBackground.png"); - palette.setBrush(this->backgroundRole(), QBrush(image)); - - setPalette(palette); - - this->setFixedSize(image.size()); + this->setFixedSize(770, 595); QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); settings->beginGroup("libraryConfig"); @@ -105,6 +101,28 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) settings->endGroup(); connect(check, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableServer); + + // Initialize theme + initTheme(this); +} + +void ServerConfigDialog::applyTheme(const Theme &theme) +{ + // Apply pre-built QSS from theme + setStyleSheet(theme.serverConfigDialog.dialogQSS); + titleLabel->setStyleSheet(theme.serverConfigDialog.titleLabelQSS); + qrMessageLabel->setStyleSheet(theme.serverConfigDialog.qrMessageLabelQSS); + propagandaLabel->setStyleSheet(theme.serverConfigDialog.propagandaLabelQSS); + ipLabel->setStyleSheet(theme.serverConfigDialog.labelQSS); + portLabel->setStyleSheet(theme.serverConfigDialog.labelQSS); + check->setStyleSheet(theme.serverConfigDialog.checkBoxQSS); + + // Set background decoration (SVG on left) + backgroundDecoration->setPixmap(theme.serverConfigDialog.backgroundDecoration); + backgroundDecoration->lower(); // Send to back so other widgets appear on top + + // Regenerate QR code with new theme colors + generateQR(); } void ServerConfigDialog::showEvent(QShowEvent *event) @@ -156,16 +174,22 @@ void ServerConfigDialog::generateQR(const QString &serverAddress) { qrCode->clear(); + auto backgroundColor = theme.serverConfigDialog.qrBackgroundColor; + auto foregroundColor = theme.serverConfigDialog.qrForegroundColor; + qrcodegen::QrCode code = qrcodegen::QrCode::encodeText( serverAddress.toLocal8Bit(), qrcodegen::QrCode::Ecc::LOW); - QBitmap image(code.getSize(), code.getSize()); - image.fill(); - QPainter painter; - painter.begin(&image); - for (int x = 0; x < code.getSize(); x++) { - for (int y = 0; y < code.getSize(); y++) { + int qrSize = code.getSize(); + QPixmap qrPixmap(qrSize, qrSize); + qrPixmap.fill(backgroundColor); + + QPainter painter(&qrPixmap); + painter.setPen(foregroundColor); + painter.setBrush(foregroundColor); + for (int x = 0; x < qrSize; x++) { + for (int y = 0; y < qrSize; y++) { if (code.getModule(x, y)) { painter.drawPoint(x, y); } @@ -173,14 +197,11 @@ void ServerConfigDialog::generateQR(const QString &serverAddress) } painter.end(); - image = image.scaled(qrCode->size() * devicePixelRatioF()); + // Scale to label size + qrPixmap = qrPixmap.scaled(qrCode->size() * devicePixelRatioF(), Qt::KeepAspectRatio, Qt::FastTransformation); + qrPixmap.setDevicePixelRatio(devicePixelRatioF()); - QPixmap pMask(image.size()); - pMask.fill(QColor(66, 66, 66)); - pMask.setMask(image.createMaskFromColor(Qt::white)); - pMask.setDevicePixelRatio(devicePixelRatioF()); - - qrCode->setPixmap(pMask); + qrCode->setPixmap(qrPixmap); } void ServerConfigDialog::regenerateQR(const QString &ip) diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index 7d0e9cfa..e882e573 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -8,13 +8,18 @@ #include #include -class ServerConfigDialog : public QDialog +#include "themable.h" + +class ServerConfigDialog : public QDialog, protected Themable { Q_OBJECT public: ServerConfigDialog(QWidget *parent = 0); void showEvent(QShowEvent *event) override; +protected: + void applyTheme(const Theme &theme) override; + private: QComboBox *ip; QLineEdit *port; @@ -24,6 +29,14 @@ private: QPushButton *close; QPushButton *accept; QLabel *qrCode; + + // Labels for themable styling + QLabel *titleLabel; + QLabel *qrMessageLabel; + QLabel *propagandaLabel; + QLabel *ipLabel; + QLabel *portLabel; + QLabel *backgroundDecoration; public slots: void generateQR(); diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index ed8b7a1c..bf3b7a1d 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -5,6 +5,7 @@ #include "yacreader_icon.h" #include "help_about_dialog_theme.h" +#include "whats_new_dialog_theme.h" struct ComicVineThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; @@ -95,6 +96,339 @@ struct ComicFlowColors { QColor textColor; }; +struct TableViewThemeTemplates { + QString tableViewQSS = "QTableView {alternate-background-color: %1; background-color: %2; outline: 0px; border: none;}" + "QTableCornerButton::section {background-color:%3; border:none; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4);}" + "QTableView::item {outline: 0px; border-bottom: 1px solid %6; border-top: 1px solid %7; padding-bottom:1px; color:%8;}" + "QTableView::item:selected {outline: 0px; border-bottom: 1px solid %9; border-top: 1px solid %9; padding-bottom:1px; background-color: %9; color: %10; }" + "QHeaderView::section:horizontal {background-color:%3; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4); border-left:none; border-top:none; padding:4px; color:%11;}" + "QHeaderView::section:vertical {border-bottom: 1px solid %6; border-top: 1px solid %7;}"; +}; + +struct TableViewTheme { + QString tableViewQSS; + QColor starRatingColor; + QColor starRatingSelectedColor; +}; + +struct EmptyContainerThemeTemplates { + QString titleLabelQSS = "QLabel {color:%1; font-size:24px;font-family:Arial;font-weight:bold;}"; +}; + +struct EmptyContainerTheme { + QColor backgroundColor; + QString titleLabelQSS; + + // For NoLibrariesWidget + QColor textColor; + QColor descriptionTextColor; + QPixmap noLibrariesIcon; + + // Search-related icons (themed from search_result.svg) + QPixmap searchingIcon; // For ClassicComicsView searching state + QPixmap noSearchResultsIcon; // For NoSearchResultsWidget empty state + + // Empty container icons (themed from SVGs) + QPixmap emptyFolderIcon; + QPixmap emptyFavoritesIcon; + QPixmap emptyCurrentReadingsIcon; + QPixmap emptyReadingListIcon; + QMap emptyLabelIcons; // Keyed by YACReader::LabelColors enum value +}; + +struct SidebarThemeTemplates { + // Non-macOS splitter template: %1 = background color, %2 = height + QString styledSplitterQSS = "QSplitter::handle { image: none; background-color: %1; }" + "QSplitter::handle:vertical { height: %2px;}"; + + // macOS splitter template: %1 = height, %2 = background color + QString nativeSplitterQSS = "QSplitter::handle:vertical { height: %1px; background-color: %2;}"; +}; + +struct SidebarTheme { + QColor backgroundColor; + QColor separatorColor; + QColor sectionSeparatorColor; // Horizontal separators between sidebar sections + QString splitterQSS; + + // When true, section title strings are uppercased after translation + bool uppercaseLabels; + + // Title bar colors + QColor titleTextColor; + QColor titleDropShadowColor; + QColor busyIndicatorColor; +}; + +struct ImportWidgetThemeTemplates { + QString titleLabelQSS = "QLabel {color:%1; font-size:25px;font-weight:bold;}"; +}; + +struct ImportWidgetTheme { + QColor backgroundColor; + QString titleLabelQSS; + QColor descriptionTextColor; + QColor currentComicTextColor; + QColor coversViewBackgroundColor; + QColor coversLabelColor; + + QPixmap topCoversDecoration; + QPixmap bottomCoversDecoration; + QPixmap importingIcon; + QPixmap updatingIcon; + QIcon coversToggleIcon; +}; + +struct TreeViewThemeTemplates { + // Styled tree view template with custom scroll bars + // %1 = text color, %2 = selection/hover background, %3 = scroll background, %4 = scroll handle, %5 = selected text color + QString styledTreeViewQSS = "QTreeView {background-color:transparent; border: none; color:%1; outline:0; show-decoration-selected: 0;}" + "QTreeView::item:selected {background-color: %2; color:%5; font:bold;}" + "QTreeView::item:hover {background-color:%2; color:%5; font:bold;}" + "QTreeView::branch:selected {background-color:%2;}" + "QScrollBar:vertical { border: none; background: %3; width: 7px; margin: 0 3px 0 0; }" + "QScrollBar::handle:vertical { background: %4; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" + "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url('%6');}" + "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url('%6');}" + "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url('%7');}" + "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%7');}"; + + // Native tree view template (uses system scroll bars) - for macOS + QString nativeTreeViewQSS = "QTreeView {background-color:transparent; border: none;}" + "QTreeView::item:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" + "QTreeView::branch:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" + "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" + "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}"; +}; + +struct TreeViewTheme { + QString treeViewQSS; + QColor folderIndicatorColor; // For incomplete folders and recently updated folders +}; + +// QML view theme colors (used by GridComicsView, FolderContentView, InfoComicsView) +struct QmlViewTheme { + // Grid colors + QColor backgroundColor; + QColor cellColor; + QColor cellColorWithBackground; + QColor selectedColor; + QColor selectedBorderColor; + QColor borderColor; + QColor titleColor; + QColor textColor; + bool showDropShadow; + + // Info panel colors + QColor infoBackgroundColor; + QString topShadow; // Image filename + QString infoShadow; // Image filename + QString infoIndicator; // Image filename + QColor infoTextColor; + QColor infoTitleColor; + + // Rating and favorite colors + QColor ratingUnselectedColor; + QColor ratingSelectedColor; + QColor favUncheckedColor; + QColor favCheckedColor; + QColor readTickUncheckedColor; + QColor readTickCheckedColor; + + // Current comic banner + QColor currentComicBackgroundColor; + + // Continue reading section (FolderContentView) + QColor continueReadingBackgroundColor; + QColor continueReadingColor; +}; + +struct MainToolbarThemeTemplates { + // Toolbar QSS: %1 = background color + QString toolbarQSS = "QToolButton {border:none;}"; + + // Folder name label QSS: %1 = text color + QString folderNameLabelQSS = "QLabel {color:%1; font-size:22px; font-weight:bold;}"; +}; + +struct ContentSplitterThemeTemplates { + QString horizontalSplitterQSS = "QSplitter::handle { image: none; background-color: %1; height: %2px; }"; + QString verticalSplitterQSS = "QSplitter::handle { image: none; background-color: %1; height: %2px; }"; +}; + +struct ComicsViewToolbarThemeTemplates { + QString toolbarQSS = R"( + QToolBar { border: none; } + QToolButton:checked { background-color: %1; } + )"; +}; + +struct SearchLineEditThemeTemplates { + // %1 = text color, %2 = background color, %3 = padding-left, %4 = padding-right + QString lineEditQSS = "QLineEdit {color: %1; border:none; border-radius: 4px; background-color:%2; padding-left: %3px; padding-right: %4px; padding-bottom: 1px; margin-right: 9px;} "; + QString searchLabelQSS = "QLabel { border: none; padding: 0px; }"; + QString clearButtonQSS = "QToolButton { border: none; padding: 0px; }"; +}; + +struct ContentSplitterTheme { + QString horizontalSplitterQSS; // For Qt::Horizontal splitters (vertical handle bar) + QString verticalSplitterQSS; // For Qt::Vertical splitters (horizontal handle bar) +}; + +struct SidebarIconsTheme { + // When true, use QFileIconProvider for folder icons and overlay folderReadOverlay for finished folders + // When false, use the themed folderIcon and folderFinishedIcon SVGs + bool useSystemFolderIcons; + QPixmap folderReadOverlay; // Tick overlay drawn on system folder icons when useSystemFolderIcons is true + + // Folder icons (for FolderModel, ReadingListItem) + QIcon folderIcon; + QIcon folderFinishedIcon; + + // Library icon (for YACReaderLibraryItemWidget - unselected state) + QIcon libraryIcon; + + // Action icons (for LibraryWindowActions - toolbar buttons) + QIcon newLibraryIcon; + QIcon openLibraryIcon; + QIcon addNewIcon; + QIcon deleteIcon; + QIcon setRootIcon; + QIcon expandIcon; + QIcon colapseIcon; + QIcon addLabelIcon; + QIcon renameListIcon; + + // Branch icons (for TreeView QSS) + QString branchClosedIconPath; + QString branchOpenIconPath; +}; + +struct LibraryItemTheme { + QColor textColor; + QColor selectedTextColor; + QColor selectedBackgroundColor; + QIcon libraryIconSelected; // Library icon when selected + QIcon libraryOptionsIcon; // Options icon (shown only when selected) +}; + +struct SearchLineEditTheme { + QString lineEditQSS; + QString searchLabelQSS; + QString clearButtonQSS; + QPixmap searchIcon; + QPixmap clearIcon; +}; + +struct ReadingListIconsTheme { + // Label icons by color name (red, orange, yellow, green, cyan, blue, violet, purple, pink, white, light, dark) + QMap labelIcons; + + // Special list icons (Reading, Favorites, Currently Reading) + QIcon readingListIcon; // default_0 - bookmark + QIcon favoritesIcon; // default_1 - heart + QIcon currentlyReadingIcon; // default_2 - circle with star + + // Reading list icon + QIcon listIcon; +}; + +struct DialogIconsTheme { + QPixmap newLibraryIcon; + QPixmap openLibraryIcon; + QPixmap editIcon; + QPixmap exportComicsInfoIcon; + QPixmap importComicsInfoIcon; + QPixmap exportLibraryIcon; + QPixmap importLibraryIcon; + QIcon findFolderIcon; +}; + +struct MenuIconsTheme { + // Library context menu + QIcon exportComicsInfoIcon; + QIcon importComicsInfoIcon; + QIcon exportLibraryIcon; + QIcon importLibraryIcon; + QIcon updateLibraryIcon; + QIcon renameLibraryIcon; // editIcon + QIcon removeLibraryIcon; + + // Folder/Comic context menu + QIcon openContainingFolderIcon; + QIcon updateCurrentFolderIcon; + + // App + QIcon quitIcon; +}; + +struct ShortcutsIconsTheme { + QIcon comicsIcon; + QIcon foldersIcon; + QIcon generalIcon; + QIcon librariesIcon; + QIcon visualizationIcon; +}; + +struct ServerConfigDialogTheme { + QString dialogQSS; + QString titleLabelQSS; + QString qrMessageLabelQSS; + QString propagandaLabelQSS; + QString labelQSS; + QString checkBoxQSS; + QColor qrBackgroundColor; + QColor qrForegroundColor; + QPixmap backgroundDecoration; +}; + +struct ComicsViewToolbarTheme { + QString toolbarQSS; + + QIcon openInYACReaderIcon; + QIcon setAsReadIcon; + QIcon setAsUnreadIcon; + QIcon showComicInfoIcon; + QIcon setAsNormalIcon; + QIcon setAsMangaIcon; + QIcon editComicIcon; + QIcon getInfoIcon; + QIcon assignNumberIcon; + QIcon selectAllIcon; + QIcon deleteIcon; + QIcon hideComicFlowIcon; + QIcon showMarksIcon; + QIcon showRecentIndicatorIcon; + QIcon bigGridZoomIcon; + QIcon smallGridZoomIcon; +}; + +struct MainToolbarTheme { + QColor backgroundColor; + QColor folderNameColor; + QPixmap dividerPixmap; + + // Icons (contain both Normal and Disabled states) + QIcon backIcon; + QIcon forwardIcon; + QIcon settingsIcon; + QIcon serverIcon; + QIcon helpIcon; + QIcon gridIcon; + QIcon flowIcon; + QIcon infoIcon; + QIcon fullscreenIcon; + + // QSS + QString toolbarQSS; + QString folderNameLabelQSS; +}; + struct ComicVineTheme { QString defaultLabelQSS; QString titleLabelQSS; @@ -129,9 +463,29 @@ struct ComicVineTheme { }; struct Theme { + QColor defaultContentBackgroundColor; + ComicFlowColors comicFlow; ComicVineTheme comicVine; HelpAboutDialogTheme helpAboutDialog; + WhatsNewDialogTheme whatsNewDialog; + EmptyContainerTheme emptyContainer; + SidebarTheme sidebar; + SidebarIconsTheme sidebarIcons; + LibraryItemTheme libraryItem; + ImportWidgetTheme importWidget; + ServerConfigDialogTheme serverConfigDialog; + TreeViewTheme treeView; + TableViewTheme tableView; + QmlViewTheme qmlView; + MainToolbarTheme mainToolbar; + ContentSplitterTheme contentSplitter; + ComicsViewToolbarTheme comicsViewToolbar; + SearchLineEditTheme searchLineEdit; + ReadingListIconsTheme readingListIcons; + DialogIconsTheme dialogIcons; + MenuIconsTheme menuIcons; + ShortcutsIconsTheme shortcutsIcons; }; #endif // THEME_H diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index bdd589f4..5f7c4969 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1,6 +1,9 @@ #include "theme_factory.h" +#include + #include "icon_utils.h" +#include "yacreader_global.h" struct ComicVineParams { ComicVineThemeTemplates t; @@ -49,18 +52,273 @@ struct ComicVineParams { QColor rowIconColor; }; +struct EmptyContainerParams { + EmptyContainerThemeTemplates t; + + QColor backgroundColor; + QColor titleTextColor; + + // For NoLibrariesWidget + QColor textColor; + QColor descriptionTextColor; + + QColor searchIconColor; // Color for search-related icons (replaces #f0f in search_result.svg) +}; + +struct SidebarParams { + SidebarThemeTemplates t; + bool useStyledSplitter; // true for non-macOS, false for macOS + + QColor backgroundColor; + QColor separatorColor; + QColor sectionSeparatorColor; // Horizontal separators between sidebar sections + + // Splitter parameters + QColor splitterBackgroundColor; + int splitterHeight; + + bool uppercaseLabels; + + // Title bar colors + QColor titleTextColor; + QColor titleDropShadowColor; + QColor busyIndicatorColor; +}; + +struct ImportWidgetParams { + ImportWidgetThemeTemplates t; + + QColor backgroundColor; + QColor titleTextColor; + QColor descriptionTextColor; + QColor currentComicTextColor; + QColor coversViewBackgroundColor; + QColor coversLabelColor; + QColor coversDecorationBgColor; + QColor coversDecorationShadowColor; + QColor modeIconColor; + QColor iconColor; + QColor iconCheckedColor; +}; + +struct TreeViewParams { + TreeViewThemeTemplates t; + bool useStyledTemplate; // true for non-macOS themes, false for macOS themes + + // For styled template: %1=text, %2=selection bg, %3=scroll bg, %4=scroll handle, %5=selected text + QColor textColor; + QColor selectionBackgroundColor; + QColor scrollBackgroundColor; + QColor scrollHandleColor; + QColor selectedTextColor; + + // For native (macOS) template: %1=selection color + QColor nativeSelectionColor; + + QColor folderIndicatorColor; +}; + +struct TableViewParams { + TableViewThemeTemplates t; + + QColor alternateBackgroundColor; + QColor backgroundColor; + QColor cornerButtonBackgroundColor; + QColor cornerButtonBorderColor; + QColor cornerButtonGradientColor; + QColor itemBorderBottomColor; + QColor itemBorderTopColor; + QColor itemTextColor; + QColor selectedColor; + QColor selectedTextColor; + QColor headerTextColor; + + QColor starRatingColor; + QColor starRatingSelectedColor; +}; + +struct QmlViewParams { + // Grid colors + QColor backgroundColor; + QColor cellColor; + QColor cellColorWithBackground; + QColor selectedColor; + QColor selectedBorderColor; + QColor borderColor; + QColor titleColor; + QColor textColor; + bool showDropShadow; + + // Info panel colors + QColor infoBackgroundColor; + QString topShadow; // Image filename + QString infoShadow; // Image filename + QString infoIndicator; // Image filename + QColor infoTextColor; + QColor infoTitleColor; + + // Rating and favorite colors + QColor ratingUnselectedColor; + QColor ratingSelectedColor; + QColor favUncheckedColor; + QColor favCheckedColor; + QColor readTickUncheckedColor; + QColor readTickCheckedColor; + + // Current comic banner + QColor currentComicBackgroundColor; + + // Continue reading section (FolderContentView) + QColor continueReadingBackgroundColor; + QColor continueReadingColor; +}; + +struct MainToolbarParams { + MainToolbarThemeTemplates t; + + QColor backgroundColor; + QColor folderNameColor; + QColor dividerColor; + QColor iconColor; + QColor iconDisabledColor; +}; + +struct ContentSplitterParams { + ContentSplitterThemeTemplates t; + + QColor handleColor; + int horizontalHandleHeight; // for vertical splitter (horizontal handle) + int verticalHandleWidth; // for horizontal splitter (vertical handle) +}; + +struct SidebarIconsParams { + // Icon colors - #f0f placeholder gets replaced with these + QColor iconColor; // Main icon color (replaces #f0f) + QColor shadowColor; // Shadow color (replaces #0ff) + QColor extraColor; // Extra info like ticks (replaces #ff0) + + // When true, use QFileIconProvider for folder icons and overlay a tick for finished folders + bool useSystemFolderIcons; + QColor folderReadOverlayColor; // Color for the tick overlay (replaces #f0f in folder_read_overlay.svg) +}; + +struct ServerConfigDialogThemeTemplates { + QString dialogQSS = "ServerConfigDialog { background-color: %1; }"; + QString titleLabelQSS = "QLabel { color: %1; font-size: 30px; font-family: Arial; }"; + QString qrMessageLabelQSS = "QLabel { color: %1; font-size: 18px; font-family: Arial; }"; + QString propagandaLabelQSS = "QLabel { color: %1; font-size: 13px; font-family: Arial; font-style: italic; }"; + QString labelQSS = "QLabel { color: %1; font-size: 18px; font-family: Arial; }"; + QString checkBoxQSS = "QCheckBox { color: %1; font-size: 13px; font-family: Arial; }"; +}; + +struct LibraryItemParams { + QColor textColor; + QColor selectedTextColor; + QColor selectedBackgroundColor; + QColor libraryIconSelectedColor; // Color for the library icon when selected + QColor libraryOptionsIconColor; // Color for the options icon (shown only when selected) +}; + +struct ComicsViewToolbarParams { + ComicsViewToolbarThemeTemplates t; + + QColor checkedBackgroundColor; + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct SearchLineEditParams { + SearchLineEditThemeTemplates t; + + QColor textColor; + QColor backgroundColor; + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ReadingListIconsParams { + QMap labelColors; // Label colors by name (e.g., "red" -> #f67a7b) + QColor labelShadowColor; // Shadow color for labels (replaces #0ff) + + // Special list icon colors + QColor readingListMainColor; // default_0 main color (replaces #f0f) + QColor favoritesMainColor; // default_1 main color (replaces #f0f) + QColor currentlyReadingMainColor; // default_2 main color (replaces #f0f) + QColor currentlyReadingOuterColor; // default_2 outer circle (replaces #ff0) + QColor specialListShadowColor; // Shadow color for special lists (replaces #0ff) + + // List icon colors + QColor listMainColor; // main color (replaces #f0f) + QColor listShadowColor; // shadow color (replaces #0ff) + QColor listDetailColor; // detail/checkbox color (replaces #ff0) +}; + +struct DialogIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct MenuIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ShortcutsIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ServerConfigDialogParams { + ServerConfigDialogThemeTemplates t; + QColor backgroundColor; + QColor titleTextColor; + QColor qrMessageTextColor; + QColor propagandaTextColor; + QColor labelTextColor; + QColor checkBoxTextColor; + QColor qrBackgroundColor; + QColor qrForegroundColor; + QColor decorationColor; +}; + +struct WhatsNewDialogParams { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QColor closeButtonColor; + QColor headerDecorationColor; +}; + struct ThemeParams { QString themeName; + QColor defaultContentBackgroundColor; ComicFlowColors comicFlowColors; ComicVineParams comicVineParams; HelpAboutDialogTheme helpAboutDialogParams; + EmptyContainerParams emptyContainerParams; + SidebarParams sidebarParams; + SidebarIconsParams sidebarIconsParams; + LibraryItemParams libraryItemParams; + ImportWidgetParams importWidgetParams; + ServerConfigDialogParams serverConfigDialogParams; + MainToolbarParams mainToolbarParams; + ContentSplitterParams contentSplitterParams; + TreeViewParams treeViewParams; + TableViewParams tableViewParams; + QmlViewParams qmlViewParams; + ComicsViewToolbarParams comicsViewToolbarParams; + SearchLineEditParams searchLineEditParams; + ReadingListIconsParams readingListIconsParams; + DialogIconsParams dialogIconsParams; + MenuIconsParams menuIconsParams; + ShortcutsIconsParams shortcutsIconsParams; + WhatsNewDialogParams whatsNewDialogParams; }; Theme makeTheme(const ThemeParams ¶ms) { Theme theme; + theme.defaultContentBackgroundColor = params.defaultContentBackgroundColor; + // Comic Flow const auto &cf = params.comicFlowColors; theme.comicFlow.backgroundColor = cf.backgroundColor; @@ -91,19 +349,19 @@ Theme makeTheme(const ThemeParams ¶ms) theme.comicVine.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(cv.contentBackgroundColor.name(), cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name()); theme.comicVine.scraperTableViewQSS = t.scraperTableViewQSS - .arg(cv.tableHeaderTextColor.name()) - .arg(cv.tableAltBackgroundColor.name()) - .arg(cv.tableBackgroundColor.name()) - .arg(cv.tableSelectedColor.name()) - .arg(cv.tableHeaderBackgroundColor.name()) - .arg(cv.tableHeaderBorderColor.name()) - .arg(cv.tableHeaderTextColor.name()) - .arg(cv.tableSectionBorderDark.name()) - .arg(cv.tableSectionBorderLight.name()) - .arg(cv.tableScrollHandleColor.name()) - .arg(cv.tableScrollBackgroundColor.name()) - .arg(recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor)) - .arg(recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); + .arg(cv.tableHeaderTextColor.name(), + cv.tableAltBackgroundColor.name(), + cv.tableBackgroundColor.name(), + cv.tableSelectedColor.name(), + cv.tableHeaderBackgroundColor.name(), + cv.tableHeaderBorderColor.name(), + cv.tableHeaderTextColor.name(), + cv.tableSectionBorderDark.name(), + cv.tableSectionBorderLight.name(), + cv.tableScrollHandleColor.name(), + cv.tableScrollBackgroundColor.name(), + recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor), + recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); @@ -120,6 +378,455 @@ Theme makeTheme(const ThemeParams ¶ms) theme.helpAboutDialog = params.helpAboutDialogParams; // end HelpAboutDialog + // WhatsNewDialog + const auto &wn = params.whatsNewDialogParams; + theme.whatsNewDialog.backgroundColor = wn.backgroundColor; + theme.whatsNewDialog.headerTextColor = wn.headerTextColor; + theme.whatsNewDialog.versionTextColor = wn.versionTextColor; + theme.whatsNewDialog.contentTextColor = wn.contentTextColor; + theme.whatsNewDialog.linkColor = wn.linkColor; + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + // end WhatsNewDialog + + // EmptyContainer + const auto &ec = params.emptyContainerParams; + const auto &ect = ec.t; + + theme.emptyContainer.backgroundColor = ec.backgroundColor; + theme.emptyContainer.titleLabelQSS = ect.titleLabelQSS.arg(ec.titleTextColor.name()); + theme.emptyContainer.textColor = ec.textColor; + theme.emptyContainer.descriptionTextColor = ec.descriptionTextColor; + theme.emptyContainer.noLibrariesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", ec.searchIconColor, params.themeName), 165, 160, qApp->devicePixelRatio()); + { + const qreal dpr = qApp->devicePixelRatio(); + theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_searching" }), 97, dpr); + theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_no_results" }), 239, dpr); + + theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.searchIconColor, params.themeName), 319, 243, dpr); + theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", QColor(0xe84853), params.themeName), 238, 223, dpr); + theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.searchIconColor, params.themeName), 167, 214, dpr); + theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.searchIconColor, params.themeName), 248, 187, dpr); + + // Generate empty label icons for each label color + const auto &rli = params.readingListIconsParams; + for (int c = YACReader::YRed; c <= YACReader::YDark; ++c) { + auto labelColor = static_cast(c); + auto colorName = YACReader::colorToName(labelColor); + auto it = rli.labelColors.find(colorName); + if (it != rli.labelColors.end()) { + theme.emptyContainer.emptyLabelIcons[c] = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/empty_container/empty_label.svg", it.value(), params.themeName, { .suffix = "_" + colorName }), 243, 243, dpr); + } + } + } + // end EmptyContainer + + // Sidebar + const auto &sb = params.sidebarParams; + theme.sidebar.backgroundColor = sb.backgroundColor; + theme.sidebar.separatorColor = sb.separatorColor; + theme.sidebar.sectionSeparatorColor = sb.sectionSeparatorColor; + if (sb.useStyledSplitter) { + theme.sidebar.splitterQSS = sb.t.styledSplitterQSS + .arg(sb.splitterBackgroundColor.name()) + .arg(sb.splitterHeight); + } else { + theme.sidebar.splitterQSS = sb.t.nativeSplitterQSS + .arg(sb.splitterHeight) + .arg(sb.splitterBackgroundColor.name()); + } + theme.sidebar.uppercaseLabels = sb.uppercaseLabels; + theme.sidebar.titleTextColor = sb.titleTextColor; + theme.sidebar.titleDropShadowColor = sb.titleDropShadowColor; + theme.sidebar.busyIndicatorColor = sb.busyIndicatorColor; + // end Sidebar + + // ImportWidget + const auto &iw = params.importWidgetParams; + const auto &iwt = iw.t; + theme.importWidget.backgroundColor = iw.backgroundColor; + theme.importWidget.titleLabelQSS = iwt.titleLabelQSS.arg(iw.titleTextColor.name()); + theme.importWidget.descriptionTextColor = iw.descriptionTextColor; + theme.importWidget.currentComicTextColor = iw.currentComicTextColor; + theme.importWidget.coversViewBackgroundColor = iw.coversViewBackgroundColor; + theme.importWidget.coversLabelColor = iw.coversLabelColor; + theme.importWidget.topCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importTopCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); + theme.importWidget.bottomCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importBottomCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); + theme.importWidget.importingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/importingIcon.svg", iw.modeIconColor, params.themeName)); + theme.importWidget.updatingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/updatingIcon.svg", iw.modeIconColor, params.themeName)); + { + QIcon coversToggle; + const QString normalPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconColor, params.themeName); + const QString checkedPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconCheckedColor, params.themeName, { .suffix = "_checked" }); + coversToggle.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + coversToggle.addFile(checkedPath, QSize(), QIcon::Normal, QIcon::On); + theme.importWidget.coversToggleIcon = coversToggle; + } + // end ImportWidget + + // TableView + const auto &tav = params.tableViewParams; + const auto &tavt = tav.t; + theme.tableView.tableViewQSS = tavt.tableViewQSS + .arg(tav.alternateBackgroundColor.name(), + tav.backgroundColor.name(), + tav.cornerButtonBackgroundColor.name(), + tav.cornerButtonBorderColor.name(), + tav.cornerButtonGradientColor.name(), + tav.itemBorderBottomColor.name(), + tav.itemBorderTopColor.name(), + tav.itemTextColor.name(), + tav.selectedColor.name(), + tav.selectedTextColor.name(), + tav.headerTextColor.name()); + theme.tableView.starRatingColor = tav.starRatingColor; + theme.tableView.starRatingSelectedColor = tav.starRatingSelectedColor; + // end TableView + + // QmlView + const auto &qv = params.qmlViewParams; + theme.qmlView.backgroundColor = qv.backgroundColor; + theme.qmlView.cellColor = qv.cellColor; + theme.qmlView.cellColorWithBackground = qv.cellColorWithBackground; + theme.qmlView.selectedColor = qv.selectedColor; + theme.qmlView.selectedBorderColor = qv.selectedBorderColor; + theme.qmlView.borderColor = qv.borderColor; + theme.qmlView.titleColor = qv.titleColor; + theme.qmlView.textColor = qv.textColor; + theme.qmlView.showDropShadow = qv.showDropShadow; + theme.qmlView.infoBackgroundColor = qv.infoBackgroundColor; + theme.qmlView.topShadow = qv.topShadow; + theme.qmlView.infoShadow = qv.infoShadow; + theme.qmlView.infoIndicator = qv.infoIndicator; + theme.qmlView.infoTextColor = qv.infoTextColor; + theme.qmlView.infoTitleColor = qv.infoTitleColor; + theme.qmlView.ratingUnselectedColor = qv.ratingUnselectedColor; + theme.qmlView.ratingSelectedColor = qv.ratingSelectedColor; + theme.qmlView.favUncheckedColor = qv.favUncheckedColor; + theme.qmlView.favCheckedColor = qv.favCheckedColor; + theme.qmlView.readTickUncheckedColor = qv.readTickUncheckedColor; + theme.qmlView.readTickCheckedColor = qv.readTickCheckedColor; + theme.qmlView.currentComicBackgroundColor = qv.currentComicBackgroundColor; + theme.qmlView.continueReadingBackgroundColor = qv.continueReadingBackgroundColor; + theme.qmlView.continueReadingColor = qv.continueReadingColor; + // end QmlView + + // MainToolbar + const auto &mt = params.mainToolbarParams; + theme.mainToolbar.backgroundColor = mt.backgroundColor; + theme.mainToolbar.folderNameColor = mt.folderNameColor; + theme.mainToolbar.toolbarQSS = mt.t.toolbarQSS; + theme.mainToolbar.folderNameLabelQSS = mt.t.folderNameLabelQSS.arg(mt.folderNameColor.name()); + + // Build divider pixmap with gradient (HiDPI aware) + { + const qreal dpr = qApp->devicePixelRatio(); + const int width = 1; + const int height = 34; + + QPixmap pixmap(width * dpr, height * dpr); + pixmap.setDevicePixelRatio(dpr); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + + QLinearGradient gradient(0, 0, 0, height); + QColor transparentColor = mt.dividerColor; + transparentColor.setAlpha(0); + + gradient.setColorAt(0.0, transparentColor); + gradient.setColorAt(0.5, mt.dividerColor); + gradient.setColorAt(1.0, transparentColor); + + painter.setPen(QPen(QBrush(gradient), 1)); + painter.drawLine(0, 0, 0, height); + + theme.mainToolbar.dividerPixmap = pixmap; + } + + // Build icons with Normal and Disabled states + auto makeToolbarIcon = [&](const QString &basePath) { + QIcon icon; + const QString normalPath = recoloredSvgToThemeFile(basePath, mt.iconColor, params.themeName); + const QString disabledPath = recoloredSvgToThemeFile(basePath, mt.iconDisabledColor, params.themeName, { .suffix = "_disabled" }); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); + return icon; + }; + + theme.mainToolbar.backIcon = makeToolbarIcon(":/images/main_toolbar/back.svg"); + theme.mainToolbar.forwardIcon = makeToolbarIcon(":/images/main_toolbar/forward.svg"); + theme.mainToolbar.settingsIcon = makeToolbarIcon(":/images/main_toolbar/settings.svg"); + theme.mainToolbar.serverIcon = makeToolbarIcon(":/images/main_toolbar/server.svg"); + theme.mainToolbar.helpIcon = makeToolbarIcon(":/images/main_toolbar/help.svg"); + theme.mainToolbar.gridIcon = makeToolbarIcon(":/images/main_toolbar/grid.svg"); + theme.mainToolbar.flowIcon = makeToolbarIcon(":/images/main_toolbar/flow.svg"); + theme.mainToolbar.infoIcon = makeToolbarIcon(":/images/main_toolbar/info.svg"); + theme.mainToolbar.fullscreenIcon = makeToolbarIcon(":/images/main_toolbar/fullscreen.svg"); + // end MainToolbar + + // SidebarIcons + const auto &si = params.sidebarIconsParams; + + // Helper to create icons with shadow (two-color: #f0f main, #0ff shadow) + // Adds both Normal and Selected modes to prevent Qt from applying a selection tint + auto makeSidebarIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // Helper for icons with extra color (three-color: #f0f main, #0ff shadow, #ff0 extra) + auto makeSidebarIconWithExtra = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, si.extraColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // Helper for single-color icons (only #f0f main) + auto makeSingleColorIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // System folder icons flag and overlay + theme.sidebarIcons.useSystemFolderIcons = si.useSystemFolderIcons; + if (si.useSystemFolderIcons) { + const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", si.folderReadOverlayColor, params.themeName); + theme.sidebarIcons.folderReadOverlay = QPixmap(overlayPath); + } + + // Folder icons + theme.sidebarIcons.folderIcon = makeSidebarIcon(":/images/sidebar/folder.svg"); + theme.sidebarIcons.folderFinishedIcon = makeSidebarIconWithExtra(":/images/sidebar/folder_finished.svg"); + + // Library icon (unselected state uses sidebar colors) + theme.sidebarIcons.libraryIcon = makeSidebarIcon(":/images/sidebar/libraryIcon.svg"); + + // Action icons + theme.sidebarIcons.newLibraryIcon = makeSidebarIcon(":/images/sidebar/newLibraryIcon.svg"); + theme.sidebarIcons.openLibraryIcon = makeSidebarIcon(":/images/sidebar/openLibraryIcon.svg"); + theme.sidebarIcons.addNewIcon = makeSidebarIcon(":/images/sidebar/addNew_sidebar.svg"); + theme.sidebarIcons.deleteIcon = makeSidebarIcon(":/images/sidebar/delete_sidebar.svg"); + theme.sidebarIcons.setRootIcon = makeSidebarIcon(":/images/sidebar/setRoot.svg"); + theme.sidebarIcons.expandIcon = makeSidebarIcon(":/images/sidebar/expand.svg"); + theme.sidebarIcons.colapseIcon = makeSidebarIcon(":/images/sidebar/colapse.svg"); + theme.sidebarIcons.addLabelIcon = makeSidebarIcon(":/images/sidebar/addLabelIcon.svg"); + theme.sidebarIcons.renameListIcon = makeSidebarIcon(":/images/sidebar/renameListIcon.svg"); + + // Branch icons (paths for QSS) + theme.sidebarIcons.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", si.iconColor, params.themeName); + theme.sidebarIcons.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", si.iconColor, params.themeName); + // end SidebarIcons + + // LibraryItem + const auto &li = params.libraryItemParams; + theme.libraryItem.textColor = li.textColor; + theme.libraryItem.selectedTextColor = li.selectedTextColor; + theme.libraryItem.selectedBackgroundColor = li.selectedBackgroundColor; + + // Library icon when selected (uses its own color to contrast with selected background) + const QString libraryIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIconSelected.svg", li.libraryIconSelectedColor, params.themeName); + theme.libraryItem.libraryIconSelected = QIcon(libraryIconSelectedPath); + + // Library options icon (shown only when selected, uses its own color) + const QString libraryOptionsPath = recoloredSvgToThemeFile(":/images/sidebar/libraryOptions.svg", li.libraryOptionsIconColor, params.themeName); + theme.libraryItem.libraryOptionsIcon = QIcon(libraryOptionsPath); + // end LibraryItem + + // TreeView (must come after SidebarIcons for branch icon paths) + const auto &tv = params.treeViewParams; + if (tv.useStyledTemplate) { + theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS + .arg(tv.textColor.name(), + tv.selectionBackgroundColor.name(), + tv.scrollBackgroundColor.name(), + tv.scrollHandleColor.name(), + tv.selectedTextColor.name(), + theme.sidebarIcons.branchClosedIconPath, + theme.sidebarIcons.branchOpenIconPath); + } else { + theme.treeView.treeViewQSS = tv.t.nativeTreeViewQSS.arg(tv.nativeSelectionColor.name()); + } + theme.treeView.folderIndicatorColor = tv.folderIndicatorColor; + // end TreeView + + // ContentSplitter + const auto &cs = params.contentSplitterParams; + theme.contentSplitter.horizontalSplitterQSS = cs.t.horizontalSplitterQSS + .arg(cs.handleColor.name()) + .arg(cs.verticalHandleWidth); + theme.contentSplitter.verticalSplitterQSS = cs.t.verticalSplitterQSS + .arg(cs.handleColor.name()) + .arg(cs.horizontalHandleHeight); + // end ContentSplitter + + // ComicsViewToolbar + const auto &cvt = params.comicsViewToolbarParams; + + // Helper to create single-color icons for comics view toolbar + auto makeComicsViewIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, cvt.iconColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS.arg(cvt.checkedBackgroundColor.name()); + theme.comicsViewToolbar.openInYACReaderIcon = makeComicsViewIcon(":/images/comics_view_toolbar/openInYACReader.svg"); + theme.comicsViewToolbar.setAsReadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setReadButton.svg"); + theme.comicsViewToolbar.setAsUnreadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setUnread.svg"); + theme.comicsViewToolbar.showComicInfoIcon = makeComicsViewIcon(":/images/comics_view_toolbar/show_comic_info.svg"); + theme.comicsViewToolbar.setAsNormalIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setNormal.svg"); + theme.comicsViewToolbar.setAsMangaIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setManga.svg"); + theme.comicsViewToolbar.editComicIcon = makeComicsViewIcon(":/images/comics_view_toolbar/editComic.svg"); + theme.comicsViewToolbar.getInfoIcon = makeComicsViewIcon(":/images/comics_view_toolbar/getInfo.svg"); + theme.comicsViewToolbar.assignNumberIcon = makeComicsViewIcon(":/images/comics_view_toolbar/asignNumber.svg"); + theme.comicsViewToolbar.selectAllIcon = makeComicsViewIcon(":/images/comics_view_toolbar/selectAll.svg"); + theme.comicsViewToolbar.deleteIcon = makeComicsViewIcon(":/images/comics_view_toolbar/trash.svg"); + theme.comicsViewToolbar.hideComicFlowIcon = makeComicsViewIcon(":/images/comics_view_toolbar/hideComicFlow.svg"); + theme.comicsViewToolbar.showMarksIcon = makeComicsViewIcon(":/images/comics_view_toolbar/showMarks.svg"); + theme.comicsViewToolbar.showRecentIndicatorIcon = makeComicsViewIcon(":/images/comics_view_toolbar/showRecentIndicator.svg"); + theme.comicsViewToolbar.bigGridZoomIcon = makeComicsViewIcon(":/images/comics_view_toolbar/big_size_grid_zoom.svg"); + theme.comicsViewToolbar.smallGridZoomIcon = makeComicsViewIcon(":/images/comics_view_toolbar/small_size_grid_zoom.svg"); + // end ComicsViewToolbar + + // SearchLineEdit + const auto &sle = params.searchLineEditParams; + + theme.searchLineEdit.lineEditQSS = sle.t.lineEditQSS + .arg(sle.textColor.name(), + sle.backgroundColor.name()); + theme.searchLineEdit.searchLabelQSS = sle.t.searchLabelQSS; + theme.searchLineEdit.clearButtonQSS = sle.t.clearButtonQSS; + + const qreal dpr = qApp->devicePixelRatio(); + theme.searchLineEdit.searchIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/iconSearchNew.svg", sle.iconColor, params.themeName), 15, dpr); + theme.searchLineEdit.clearIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/clearSearchNew.svg", sle.iconColor, params.themeName), 12, dpr); + // end SearchLineEdit + + // ReadingListIcons + const auto &rli = params.readingListIconsParams; + + // Helper to create label icons from template (uses color name to generate label_.svg files) + auto makeLabelIcon = [&](const QString &colorName, const QColor &mainColor) { + const QString path = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.themeName, { .fileName = "label_" + colorName }); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + for (auto it = rli.labelColors.constBegin(); it != rli.labelColors.constEnd(); ++it) { + theme.readingListIcons.labelIcons[it.key()] = makeLabelIcon(it.key(), it.value()); + } + + // Special list icons + auto makeSpecialIcon = [&](const QString &basePath, const QColor &mainColor) { + const QString path = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + theme.readingListIcons.readingListIcon = makeSpecialIcon(":/images/lists/default_0.svg", rli.readingListMainColor); + theme.readingListIcons.favoritesIcon = makeSpecialIcon(":/images/lists/default_1.svg", rli.favoritesMainColor); + + // Currently reading has 3 colors + { + const QString path = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + theme.readingListIcons.currentlyReadingIcon = icon; + } + + // List icon (3 colors) + { + const QString path = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + theme.readingListIcons.listIcon = icon; + } + // end ReadingListIcons + + // MenuIcons + const auto &mi = params.menuIconsParams; + auto makeMenuIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, mi.iconColor, params.themeName); + return QIcon(path); + }; + + theme.menuIcons.exportComicsInfoIcon = makeMenuIcon(":/images/menus_icons/exportComicsInfoIcon.svg"); + theme.menuIcons.importComicsInfoIcon = makeMenuIcon(":/images/menus_icons/importComicsInfoIcon.svg"); + theme.menuIcons.exportLibraryIcon = makeMenuIcon(":/images/menus_icons/exportLibraryIcon.svg"); + theme.menuIcons.importLibraryIcon = makeMenuIcon(":/images/menus_icons/importLibraryIcon.svg"); + theme.menuIcons.updateLibraryIcon = makeMenuIcon(":/images/menus_icons/updateLibraryIcon.svg"); + theme.menuIcons.renameLibraryIcon = makeMenuIcon(":/images/menus_icons/editIcon.svg"); + theme.menuIcons.removeLibraryIcon = makeMenuIcon(":/images/menus_icons/removeLibraryIcon.svg"); + theme.menuIcons.openContainingFolderIcon = makeMenuIcon(":/images/menus_icons/open_containing_folder.svg"); + theme.menuIcons.updateCurrentFolderIcon = makeMenuIcon(":/images/menus_icons/update_current_folder.svg"); + theme.menuIcons.quitIcon = makeMenuIcon(":/images/viewer_toolbar/close.svg"); + // end MenuIcons + + // DialogIcons + const auto &di = params.dialogIconsParams; + auto makeDialogIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, di.iconColor, params.themeName); + return QPixmap(path); + }; + theme.dialogIcons.newLibraryIcon = makeDialogIcon(":/images/library_dialogs/new.svg"); + theme.dialogIcons.openLibraryIcon = makeDialogIcon(":/images/library_dialogs/openLibrary.svg"); + theme.dialogIcons.editIcon = makeDialogIcon(":/images/library_dialogs/edit.svg"); + theme.dialogIcons.exportComicsInfoIcon = makeDialogIcon(":/images/library_dialogs/exportComicsInfo.svg"); + theme.dialogIcons.importComicsInfoIcon = makeDialogIcon(":/images/library_dialogs/importComicsInfo.svg"); + theme.dialogIcons.exportLibraryIcon = makeDialogIcon(":/images/library_dialogs/exportLibrary.svg"); + theme.dialogIcons.importLibraryIcon = makeDialogIcon(":/images/library_dialogs/importLibrary.svg"); + { + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", di.iconColor, params.themeName); + const qreal dpr = qApp->devicePixelRatio(); + theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); + } + // end DialogIcons + + // ShortcutsIcons + const auto &sci = params.shortcutsIconsParams; + auto makeShortcutsIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + return QIcon(path); + }; + + theme.shortcutsIcons.comicsIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_comics.svg"); + theme.shortcutsIcons.foldersIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_folders.svg"); + theme.shortcutsIcons.generalIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_general.svg"); + theme.shortcutsIcons.librariesIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_libraries.svg"); + theme.shortcutsIcons.visualizationIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_visualization.svg"); + // end ShortcutsIcons + + // ServerConfigDialog + const auto &scd = params.serverConfigDialogParams; + theme.serverConfigDialog.dialogQSS = scd.t.dialogQSS.arg(scd.backgroundColor.name()); + theme.serverConfigDialog.titleLabelQSS = scd.t.titleLabelQSS.arg(scd.titleTextColor.name()); + theme.serverConfigDialog.qrMessageLabelQSS = scd.t.qrMessageLabelQSS.arg(scd.qrMessageTextColor.name()); + theme.serverConfigDialog.propagandaLabelQSS = scd.t.propagandaLabelQSS.arg(scd.propagandaTextColor.name()); + theme.serverConfigDialog.labelQSS = scd.t.labelQSS.arg(scd.labelTextColor.name()); + theme.serverConfigDialog.checkBoxQSS = scd.t.checkBoxQSS.arg(scd.checkBoxTextColor.name()); + theme.serverConfigDialog.qrBackgroundColor = scd.qrBackgroundColor; + theme.serverConfigDialog.qrForegroundColor = scd.qrForegroundColor; + theme.serverConfigDialog.backgroundDecoration = QPixmap(recoloredSvgToThemeFile(":/images/serverConfigBackground.svg", scd.decorationColor, params.themeName)); + return theme; } @@ -129,6 +836,7 @@ ThemeParams darkThemeParams(); Theme makeTheme(ThemeId themeId) { + switch (themeId) { case ThemeId::Classic: return makeTheme(classicThemeParams()); @@ -145,6 +853,7 @@ ThemeParams classicThemeParams() { ThemeParams params; params.themeName = "classic"; + params.defaultContentBackgroundColor = QColor(0x2A2A2A); ComicFlowColors cf; cf.backgroundColor = Qt::black; @@ -176,7 +885,7 @@ ThemeParams classicThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; @@ -202,6 +911,196 @@ ThemeParams classicThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0x2A2A2A); + wnp.headerTextColor = QColor(0xE0E0E0); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0xE0E0E0); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0xDDDDDD); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0x2A2A2A); + ec.titleTextColor = QColor(0xCCCCCC); + ec.textColor = QColor(0xCCCCCC); + ec.descriptionTextColor = QColor(0xAAAAAA); + ec.searchIconColor = QColor(0x4C4C4C); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0x454545); + sb.separatorColor = QColor(0xBDBFBF); + sb.sectionSeparatorColor = QColor(0x575757); + sb.splitterBackgroundColor = QColor(0x454545); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0xBDBFBF); + sb.titleDropShadowColor = Qt::black; + sb.busyIndicatorColor = Qt::white; + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0x2A2A2A); + iw.titleTextColor = QColor(0xCCCCCC); + iw.descriptionTextColor = QColor(0xAAAAAA); + iw.currentComicTextColor = QColor(0xAAAAAA); + iw.coversViewBackgroundColor = QColor(0x3A3A3A); + iw.coversLabelColor = QColor(0xAAAAAA); + iw.coversDecorationBgColor = QColor(0x3A3A3A); + iw.coversDecorationShadowColor = QColor(0x1A1A1A); + iw.modeIconColor = QColor(0x4A4A4A); + iw.iconColor = QColor(0xCCCCCC); + iw.iconCheckedColor = QColor(0xAAAAAA); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = QColor(0xDDDFDF); + tv.selectionBackgroundColor = QColor(0x2E2E2E); + tv.scrollBackgroundColor = QColor(0x404040); + tv.scrollHandleColor = QColor(0xDDDDDD); + tv.selectedTextColor = Qt::white; + tv.folderIndicatorColor = QColor(237, 197, 24); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0xF2F2F2); + tav.backgroundColor = QColor(0xFAFAFA); + tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); + tav.cornerButtonBorderColor = QColor(0xB8BDC4); + tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.itemBorderBottomColor = QColor(0xDFDFDF); + tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemTextColor = QColor(0x252626); + tav.selectedColor = QColor(0xD4D4D4); + tav.selectedTextColor = QColor(0x252626); + tav.headerTextColor = QColor(0x313232); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0x2A2A2A); + qv.cellColor = QColor(0x212121); + qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); + qv.selectedColor = QColor(0x121212); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0x121212); + qv.titleColor = QColor(0xFFFFFF); + qv.textColor = QColor(0xA8A8A8); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0x2E2E2E); + qv.topShadow = "info-top-shadow.png"; + qv.infoShadow = "info-shadow.png"; + qv.infoIndicator = "info-indicator.png"; + qv.infoTextColor = QColor(0xB0B0B0); + qv.infoTitleColor = QColor(0xFFFFFF); + qv.ratingUnselectedColor = QColor(0x1C1C1C); + qv.ratingSelectedColor = QColor(0xFFFFFF); + qv.favUncheckedColor = QColor(0x1C1C1C); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0x1C1C1C); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingColor = QColor(0xFFFFFF); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0xF0F0F0); + mt.folderNameColor = QColor(0x404040); + mt.dividerColor = QColor(0xB8BDC4); + mt.iconColor = QColor(0x404040); + mt.iconDisabledColor = QColor(0xB0B0B0); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0xB8B8B8); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0xE0E0E0); + si.shadowColor = QColor(0xFF000000); + si.extraColor = QColor(0x464646); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0xDDDFDF); + li.selectedTextColor = Qt::white; + li.selectedBackgroundColor = QColor(0x2E2E2E); + li.libraryIconSelectedColor = Qt::white; + li.libraryOptionsIconColor = Qt::white; + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0xCCCCCC); + cvt.iconColor = QColor(0x404040); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0xABABAB); + sle.backgroundColor = QColor(0x404040); + sle.iconColor = QColor(0xF7F7F7); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = Qt::black; + rli.readingListMainColor = QColor(0xe7e7e7); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = Qt::black; + rli.listMainColor = QColor(0xe7e7e7); + rli.listShadowColor = Qt::black; + rli.listDetailColor = QColor(0x464646); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0xF7F7F7); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xF7F7F7); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0x2A2A2A); + scd.titleTextColor = QColor(0x474747); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0x4D4D4D); + scd.labelTextColor = QColor(0x575757); + scd.checkBoxTextColor = QColor(0x262626); + scd.qrBackgroundColor = QColor(0x2A2A2A); + scd.qrForegroundColor = Qt::white; + scd.decorationColor = QColor(0xF7F7F7); + params.serverConfigDialogParams = scd; + return params; } @@ -209,6 +1108,7 @@ ThemeParams lightThemeParams() { ThemeParams params; params.themeName = "light"; + params.defaultContentBackgroundColor = QColor(0xFFFFFF); ComicFlowColors cf; cf.backgroundColor = Qt::white; @@ -266,6 +1166,196 @@ ThemeParams lightThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0xFFFFFF); + wnp.headerTextColor = QColor(0x0A0A0A); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0x0A0A0A); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0x444444); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0xFFFFFF); + ec.titleTextColor = QColor(0x888888); + ec.textColor = QColor(0x495252); + ec.descriptionTextColor = QColor(0x565959); + ec.searchIconColor = QColor(0xCCCCCC); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0xF1F1F1); + sb.separatorColor = QColor(0x808080); + sb.sectionSeparatorColor = QColor(0xD0D0D0); + sb.splitterBackgroundColor = QColor(0xF1F1F1); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0x808080); + sb.titleDropShadowColor = QColor(0xFFFFFF); + sb.busyIndicatorColor = QColor(0x808080); + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0xFAFAFA); + iw.titleTextColor = QColor(0x495252); + iw.descriptionTextColor = QColor(0x565959); + iw.currentComicTextColor = QColor(0x565959); + iw.coversViewBackgroundColor = QColor(0xE6E6E6); + iw.coversLabelColor = QColor(0x565959); + iw.coversDecorationBgColor = QColor(0xE6E6E6); + iw.coversDecorationShadowColor = QColor(0xA1A1A1); + iw.modeIconColor = QColor(0xE6E6E6); + iw.iconColor = QColor(0x495252); + iw.iconCheckedColor = QColor(0x565959); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = Qt::black; + tv.selectionBackgroundColor = QColor(0xD0D0D0); + tv.scrollBackgroundColor = QColor(0xE0E0E0); + tv.scrollHandleColor = QColor(0x888888); + tv.selectedTextColor = QColor(0x1A1A1A); + tv.folderIndicatorColor = QColor(85, 95, 127); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0xF2F2F2); + tav.backgroundColor = QColor(0xFAFAFA); + tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); + tav.cornerButtonBorderColor = QColor(0xB8BDC4); + tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.itemBorderBottomColor = QColor(0xDFDFDF); + tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemTextColor = QColor(0x252626); + tav.selectedColor = QColor(0x3875D7); + tav.selectedTextColor = QColor(0xFFFFFF); + tav.headerTextColor = QColor(0x313232); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0xF6F6F6); + qv.cellColor = QColor(0xFFFFFF); + qv.cellColorWithBackground = QColor(0xFF, 0xFF, 0xFF, 0x99); + qv.selectedColor = QColor(0xFFFFFF); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0xDBDBDB); + qv.titleColor = QColor(0x121212); + qv.textColor = QColor(0x636363); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0xFFFFFF); + qv.topShadow = ""; + qv.infoShadow = "info-shadow-light.png"; + qv.infoIndicator = "info-indicator-light.png"; + qv.infoTextColor = QColor(0x404040); + qv.infoTitleColor = QColor(0x2E2E2E); + qv.ratingUnselectedColor = QColor(0xDEDEDE); + qv.ratingSelectedColor = QColor(0x2B2B2B); + qv.favUncheckedColor = QColor(0xDEDEDE); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0xDEDEDE); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0xFF, 0xFF, 0xFF, 0x88); + qv.continueReadingBackgroundColor = QColor(0xE8E8E8); + qv.continueReadingColor = QColor::fromRgb(0x000000); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0xF0F0F0); + mt.folderNameColor = QColor(0x404040); + mt.dividerColor = QColor(0xB8BDC4); + mt.iconColor = QColor(0x404040); + mt.iconDisabledColor = QColor(0xB0B0B0); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0xB8B8B8); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0x606060); + si.shadowColor = QColor(0xFFFFFF); + si.extraColor = QColor(0xFFFFFF); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0x404040); + li.selectedTextColor = QColor(0x1A1A1A); + li.selectedBackgroundColor = QColor(0xD0D0D0); + li.libraryIconSelectedColor = QColor(0x404040); + li.libraryOptionsIconColor = QColor(0x404040); + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0xCCCCCC); + cvt.iconColor = QColor(0x404040); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0x606060); + sle.backgroundColor = QColor(0xE0E0E0); + sle.iconColor = QColor(0x808080); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = QColor(0xa0a0a0); + rli.readingListMainColor = QColor(0x808080); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = QColor(0xa0a0a0); + rli.listMainColor = QColor(0x808080); + rli.listShadowColor = QColor(0xc0c0c0); + rli.listDetailColor = QColor(0xFFFFFF); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0x606060); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x606060); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0xFFFFFF); + scd.titleTextColor = QColor(0x474747); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0x4D4D4D); + scd.labelTextColor = QColor(0x575757); + scd.checkBoxTextColor = QColor(0x262626); + scd.qrBackgroundColor = Qt::white; + scd.qrForegroundColor = QColor(0x606060); + scd.decorationColor = QColor(0x606060); + params.serverConfigDialogParams = scd; + return params; } @@ -273,6 +1363,7 @@ ThemeParams darkThemeParams() { ThemeParams params; params.themeName = "dark"; + params.defaultContentBackgroundColor = QColor(0x2A2A2A); ComicFlowColors cf; cf.backgroundColor = QColor(0x111111); @@ -304,7 +1395,7 @@ ThemeParams darkThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; @@ -330,5 +1421,195 @@ ThemeParams darkThemeParams() params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0x2A2A2A); + wnp.headerTextColor = QColor(0xE0E0E0); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0xE0E0E0); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0xDDDDDD); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0x2A2A2A); + ec.titleTextColor = QColor(0xCCCCCC); + ec.textColor = QColor(0xCCCCCC); + ec.descriptionTextColor = QColor(0xAAAAAA); + ec.searchIconColor = QColor(0x4C4C4C); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0x454545); + sb.separatorColor = QColor(0xBDBFBF); + sb.sectionSeparatorColor = QColor(0x575757); + sb.splitterBackgroundColor = QColor(0x454545); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0xBDBFBF); + sb.titleDropShadowColor = Qt::black; + sb.busyIndicatorColor = Qt::white; + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0x2A2A2A); + iw.titleTextColor = QColor(0xCCCCCC); + iw.descriptionTextColor = QColor(0xAAAAAA); + iw.currentComicTextColor = QColor(0xAAAAAA); + iw.coversViewBackgroundColor = QColor(0x3A3A3A); + iw.coversLabelColor = QColor(0xAAAAAA); + iw.coversDecorationBgColor = QColor(0x3A3A3A); + iw.coversDecorationShadowColor = QColor(0x1A1A1A); + iw.modeIconColor = QColor(0x4A4A4A); + iw.iconColor = QColor(0xCCCCCC); + iw.iconCheckedColor = QColor(0xAAAAAA); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = QColor(0xDDDFDF); + tv.selectionBackgroundColor = QColor(0x2E2E2E); + tv.scrollBackgroundColor = QColor(0x404040); + tv.scrollHandleColor = QColor(0xDDDDDD); + tv.selectedTextColor = Qt::white; + tv.folderIndicatorColor = QColor(237, 197, 24); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0x2E2E2E); + tav.backgroundColor = QColor(0x2A2A2A); + tav.cornerButtonBackgroundColor = QColor(0x2A2A2A); + tav.cornerButtonBorderColor = QColor(0x1F1F1F); + tav.cornerButtonGradientColor = QColor(0x252525); + tav.itemBorderBottomColor = QColor(0x1F1F1F); + tav.itemBorderTopColor = QColor(0x353535); + tav.itemTextColor = QColor(0xDDDDDD); + tav.selectedColor = QColor(0x555555); + tav.selectedTextColor = QColor(0xFFFFFF); + tav.headerTextColor = QColor(0xDDDDDD); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0x2A2A2A); + qv.cellColor = QColor(0x212121); + qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); + qv.selectedColor = QColor(0x121212); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0x121212); + qv.titleColor = QColor(0xFFFFFF); + qv.textColor = QColor(0xA8A8A8); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0x2E2E2E); + qv.topShadow = "info-top-shadow.png"; + qv.infoShadow = "info-shadow.png"; + qv.infoIndicator = "info-indicator.png"; + qv.infoTextColor = QColor(0xB0B0B0); + qv.infoTitleColor = QColor(0xFFFFFF); + qv.ratingUnselectedColor = QColor(0x1C1C1C); + qv.ratingSelectedColor = QColor(0xFFFFFF); + qv.favUncheckedColor = QColor(0x1C1C1C); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0x1C1C1C); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingColor = QColor(0xFFFFFF); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0x2A2A2A); + mt.folderNameColor = QColor(0xDDDDDD); + mt.dividerColor = QColor(0x555555); + mt.iconColor = QColor(0xDDDDDD); + mt.iconDisabledColor = QColor(0x666666); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0x1F1F1F); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0xE0E0E0); + si.shadowColor = QColor(0xFF000000); + si.extraColor = QColor(0x222222); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0xDDDFDF); + li.selectedTextColor = Qt::white; + li.selectedBackgroundColor = QColor(0x2E2E2E); + li.libraryIconSelectedColor = Qt::white; + li.libraryOptionsIconColor = Qt::white; + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0x555555); + cvt.iconColor = QColor(0xDDDDDD); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0xABABAB); + sle.backgroundColor = QColor(0x404040); + sle.iconColor = QColor(0xF7F7F7); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = Qt::black; + rli.readingListMainColor = QColor(0xe7e7e7); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = Qt::black; + rli.listMainColor = QColor(0xe7e7e7); + rli.listShadowColor = Qt::black; + rli.listDetailColor = QColor(0x464646); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0xF7F7F7); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xF7F7F7); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0x2A2A2A); + scd.titleTextColor = QColor(0xD0D0D0); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0xB0B0B0); + scd.labelTextColor = QColor(0xC0C0C0); + scd.checkBoxTextColor = QColor(0xDDDDDD); + scd.qrBackgroundColor = QColor(0x2A2A2A); + scd.qrForegroundColor = Qt::white; + scd.decorationColor = QColor(0xF7F7F7); + params.serverConfigDialogParams = scd; + return params; } diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index e2597cb1..b36f33d6 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -10,6 +10,7 @@ #include "empty_label_widget.h" #include "empty_special_list.h" #include "empty_reading_list_widget.h" +#include "empty_folder_widget.h" #include "no_search_results_widget.h" #include "yacreader_sidebar.h" @@ -17,6 +18,7 @@ //-- #include "yacreader_search_line_edit.h" #include "options_dialog.h" +#include "theme_manager.h" YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, LibraryWindow *parent) : QObject(parent), libraryWindow(parent), classicComicsView(nullptr), gridComicsView(nullptr), infoComicsView(nullptr) @@ -50,6 +52,7 @@ YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget()); comicsViewStack->addWidget(emptySpecialList = new EmptySpecialListWidget()); comicsViewStack->addWidget(emptyReadingList = new EmptyReadingListWidget()); + comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget()); comicsViewStack->addWidget(noSearchResultsWidget = new NoSearchResultsWidget()); comicsViewStack->addWidget(comicsView); @@ -60,6 +63,8 @@ YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, connect(folderContentView, &FolderContentView::copyComicsToCurrentFolder, libraryWindow, &LibraryWindow::copyAndImportComicsToCurrentFolder); connect(folderContentView, &FolderContentView::moveComicsToCurrentFolder, libraryWindow, &LibraryWindow::moveAndImportComicsToCurrentFolder); connect(libraryWindow->optionsDialog, &YACReaderOptionsDialog::optionsChanged, folderContentView, &FolderContentView::updateSettings); + + initTheme(this); } QWidget *YACReaderContentViewsManager::containerWidget() @@ -152,6 +157,11 @@ void YACReaderContentViewsManager::showEmptyReadingListWidget() comicsViewStack->setCurrentWidget(emptyReadingList); } +void YACReaderContentViewsManager::showEmptyFolderWidget() +{ + comicsViewStack->setCurrentWidget(emptyFolderWidget); +} + void YACReaderContentViewsManager::showNoSearchResultsView() { comicsViewStack->setCurrentWidget(noSearchResultsWidget); @@ -235,10 +245,11 @@ void YACReaderContentViewsManager::showComicsViewTransition() void YACReaderContentViewsManager::_toggleComicsView() { + const auto &mainToolbar = theme.mainToolbar; + switch (comicsViewStatus) { case Flow: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/info"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.infoIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -255,8 +266,7 @@ void YACReaderContentViewsManager::_toggleComicsView() } case Grid: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/flow"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.flowIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -271,8 +281,7 @@ void YACReaderContentViewsManager::_toggleComicsView() } case Info: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/grid"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.gridIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -292,3 +301,28 @@ void YACReaderContentViewsManager::_toggleComicsView() if (comicsViewStack->currentWidget() == comicsViewTransition) showComicsView(); } + +void YACReaderContentViewsManager::applyTheme(const Theme &theme) +{ + const auto &mainToolbar = theme.mainToolbar; + + // Update the toggle button icon based on current view status + // The icon shows what the NEXT view will be when clicked + QIcon icon; + switch (comicsViewStatus) { + case Flow: + icon = mainToolbar.gridIcon; + break; + case Grid: + icon = mainToolbar.infoIcon; + break; + case Info: + icon = mainToolbar.flowIcon; + break; + } + + libraryWindow->actions.toggleComicsViewAction->setIcon(icon); +#ifdef Y_MAC_UI + libraryWindow->libraryToolBar->updateViewSelectorIcon(icon); +#endif +} diff --git a/YACReaderLibrary/yacreader_content_views_manager.h b/YACReaderLibrary/yacreader_content_views_manager.h index 67119a0b..8ef45fd1 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.h +++ b/YACReaderLibrary/yacreader_content_views_manager.h @@ -4,6 +4,7 @@ #include #include "yacreader_global_gui.h" +#include "themable.h" class LibraryWindow; @@ -16,11 +17,12 @@ class FolderContentView; class EmptyLabelWidget; class EmptySpecialListWidget; class EmptyReadingListWidget; +class EmptyFolderWidget; class NoSearchResultsWidget; using namespace YACReader; -class YACReaderContentViewsManager : public QObject +class YACReaderContentViewsManager : public QObject, protected Themable { Q_OBJECT public: @@ -36,6 +38,7 @@ public: EmptyLabelWidget *emptyLabelWidget; EmptySpecialListWidget *emptySpecialList; EmptyReadingListWidget *emptyReadingList; + EmptyFolderWidget *emptyFolderWidget; NoSearchResultsWidget *noSearchResultsWidget; @@ -56,6 +59,8 @@ protected: GridComicsView *gridComicsView; InfoComicsView *infoComicsView; + void applyTheme(const Theme &theme) override; + signals: public slots: @@ -67,6 +72,7 @@ public slots: void showEmptyLabelView(); void showEmptySpecialList(); void showEmptyReadingListWidget(); + void showEmptyFolderWidget(); void showNoSearchResultsView(); protected slots: diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index c042a6e6..57f6f5b8 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -1,6 +1,7 @@ #include "yacreader_folders_view.h" #include "yacreader_global.h" +#include "yacreader_treeview.h" #include "folder_item.h" #include "folder_model.h" @@ -80,13 +81,15 @@ YACReaderFoldersViewItemDeletegate::YACReaderFoldersViewItemDeletegate(QObject * void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + // Get indicator color from parent tree view + QColor indicatorColor(237, 197, 24); // Default fallback + if (auto treeView = qobject_cast(parent())) { + indicatorColor = treeView->folderIndicatorColor(); + } + if (!index.data(FolderModel::CompletedRole).toBool()) { painter->save(); -#ifdef Y_MAC_UI - painter->setBrush(QBrush(QColor(85, 95, 127))); -#else - painter->setBrush(QBrush(QColor(237, 197, 24))); -#endif + painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawRect(0, option.rect.y(), 2, option.rect.height()); painter->restore(); @@ -105,11 +108,7 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp if (now - added < daysInSeconds || now - updated < daysInSeconds) { painter->save(); painter->setRenderHint(QPainter::Antialiasing); -#ifdef Y_MAC_UI - painter->setBrush(QBrush(QColor(85, 95, 127))); -#else - painter->setBrush(QBrush(QColor(237, 197, 24))); -#endif + painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawEllipse(option.rect.x() + 13, option.rect.y() + 2, 7, 7); painter->restore(); diff --git a/YACReaderLibrary/yacreader_main_toolbar.cpp b/YACReaderLibrary/yacreader_main_toolbar.cpp index c879ef6f..93a76a10 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.cpp +++ b/YACReaderLibrary/yacreader_main_toolbar.cpp @@ -14,8 +14,6 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) mainLayout = new QHBoxLayout; currentFolder = new QLabel(this); - // currentFolder->setAlignment(Qt::AlignCenter); - currentFolder->setStyleSheet(" QLabel {color:#404040; font-size:22px; font-weight:bold;}"); QFont f = currentFolder->font(); f.setStyleStrategy(QFont::PreferAntialias); @@ -76,6 +74,8 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) setLayout(mainLayout); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + initTheme(this); } QSize YACReaderMainToolBar::sizeHint() const @@ -95,7 +95,7 @@ void YACReaderMainToolBar::paintEvent(QPaintEvent *event) Q_UNUSED(event); QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor("#F0F0F0")); + painter.fillRect(0, 0, width(), height(), theme.mainToolbar.backgroundColor); } void YACReaderMainToolBar::resizeEvent(QResizeEvent *event) @@ -116,9 +116,9 @@ void YACReaderMainToolBar::resizeEvent(QResizeEvent *event) void YACReaderMainToolBar::addDivider() { - QPixmap img(":/images/main_toolbar/divider.svg"); QLabel *divider = new QLabel(); - divider->setPixmap(img); + divider->setPixmap(theme.mainToolbar.dividerPixmap); + dividers.append(divider); mainLayout->addSpacing(5); mainLayout->addWidget(divider, 0, Qt::AlignVCenter); @@ -149,3 +149,34 @@ void YACReaderMainToolBar::setCurrentFolderName(const QString &name) currentFolder->adjustSize(); currentFolder->move((width() - currentFolder->width()) / 2, (height() - currentFolder->height()) / 2); } + +void YACReaderMainToolBar::applyTheme(const Theme &theme) +{ + const auto &mt = theme.mainToolbar; + + currentFolder->setStyleSheet(mt.folderNameLabelQSS); + + // Update dividers + for (QLabel *divider : dividers) { + divider->setPixmap(mt.dividerPixmap); + } + + // Update action icons via the button's default action + // (buttons get their icons from their default actions when setDefaultAction is called) + if (auto action = backButton->defaultAction()) + action->setIcon(mt.backIcon); + if (auto action = forwardButton->defaultAction()) + action->setIcon(mt.forwardIcon); + if (auto action = settingsButton->defaultAction()) + action->setIcon(mt.settingsIcon); + if (auto action = serverButton->defaultAction()) + action->setIcon(mt.serverIcon); + if (auto action = helpButton->defaultAction()) + action->setIcon(mt.helpIcon); + if (auto action = fullscreenButton->defaultAction()) + action->setIcon(mt.fullscreenIcon); + + // toggleComicsViewButton icon is handled by YACReaderContentViewsManager::applyTheme() + + update(); // Repaint with new background color +} diff --git a/YACReaderLibrary/yacreader_main_toolbar.h b/YACReaderLibrary/yacreader_main_toolbar.h index d010782a..06d49043 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.h +++ b/YACReaderLibrary/yacreader_main_toolbar.h @@ -3,6 +3,8 @@ #include +#include "themable.h" + class QToolButton; class QLabel; class QResizeEvent; @@ -10,7 +12,7 @@ class QPaintEvent; class QHBoxLayout; // TODO create methods for adding actions, separators and sctreches dynimically -class YACReaderMainToolBar : public QWidget +class YACReaderMainToolBar : public QWidget, protected Themable { Q_OBJECT public: @@ -40,8 +42,13 @@ private: QLabel *currentFolder; QString currentFolderName; + QList dividers; + void addDivider(); void addWideDivider(); + +protected: + void applyTheme(const Theme &theme) override; }; #endif // YACREADER_MAIN_TOOLBAR_H diff --git a/YACReaderLibrary/yacreader_navigation_controller.cpp b/YACReaderLibrary/yacreader_navigation_controller.cpp index 9e477fe6..43ab4bee 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.cpp +++ b/YACReaderLibrary/yacreader_navigation_controller.cpp @@ -64,11 +64,15 @@ void YACReaderNavigationController::loadFolderInfo(const QModelIndex &modelIndex contentViewsManager->comicsView->setModel(libraryWindow->comicsModel); contentViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); - } else { - // showEmptyFolder + } else if (libraryWindow->foldersModel->rowCount(modelIndex) > 0 || !modelIndex.isValid()) { + // folder has subfolders (or is root), show folder content view loadEmptyFolderInfo(modelIndex); contentViewsManager->showFolderContentView(); libraryWindow->disableComicsActions(true); + } else { + // folder has no comics and no subfolders + contentViewsManager->showEmptyFolderWidget(); + libraryWindow->disableComicsActions(true); } // libraryWindow->updateFoldersViewConextMenu(modelIndex); @@ -122,16 +126,13 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model // setup empty special list widget switch (type) { case ReadingListModel::TypeSpecialList::Favorites: - contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png")); - contentViewsManager->emptySpecialList->setText(tr("No favorites")); + contentViewsManager->emptySpecialList->showFavorites(); break; case ReadingListModel::TypeSpecialList::Reading: - contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png")); - contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!")); + contentViewsManager->emptySpecialList->showReading(); break; case ReadingListModel::TypeSpecialList::Recent: - contentViewsManager->emptySpecialList->setPixmap(QPixmap()); - contentViewsManager->emptySpecialList->setText(tr("There are no recent comics!")); + contentViewsManager->emptySpecialList->showRecent(); break; } diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index bf043d2f..abc2bc5a 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -2815,19 +2815,6 @@ um die Leistung zu verbessern Schließen - - YACReaderDeletingProgress - - - cancel - Abbrechen - - - - Please wait, deleting in progress... - Bitte warten, Löschvorgang läuft... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_en.ts b/YACReaderLibrary/yacreaderlibrary_en.ts index 2540f02e..0d9528dc 100644 --- a/YACReaderLibrary/yacreaderlibrary_en.ts +++ b/YACReaderLibrary/yacreaderlibrary_en.ts @@ -2549,19 +2549,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_es.ts b/YACReaderLibrary/yacreaderlibrary_es.ts index c2309aa6..643c55b0 100644 --- a/YACReaderLibrary/yacreaderlibrary_es.ts +++ b/YACReaderLibrary/yacreaderlibrary_es.ts @@ -2822,19 +2822,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Cerrar - - YACReaderDeletingProgress - - - cancel - cancelar - - - - Please wait, deleting in progress... - Borrando, por favor espera... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts index abf9377f..5212a145 100644 --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -2726,19 +2726,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - cancel - Annuler - - - - Please wait, deleting in progress... - Attendez, suppression en cours... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index ed29a7c7..8f32caea 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -2803,19 +2803,6 @@ Migliora le prestazioni! - - YACReaderDeletingProgress - - - cancel - Cancella - - - - Please wait, deleting in progress... - Aspetta, cancellazione in corso... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index e53185ef..c81d9960 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -2666,19 +2666,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - cancel - annuleren - - - - Please wait, deleting in progress... - Even geduld, verwijderen ... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index f116002c..add794dd 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -2598,19 +2598,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index d99a7977..306c4972 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -2779,19 +2779,6 @@ to improve the performance - - YACReaderDeletingProgress - - - cancel - отменить - - - - Please wait, deleting in progress... - Пожалуйста подождите, удаление в процессе... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_source.ts b/YACReaderLibrary/yacreaderlibrary_source.ts index 87e65214..17e29eea 100644 --- a/YACReaderLibrary/yacreaderlibrary_source.ts +++ b/YACReaderLibrary/yacreaderlibrary_source.ts @@ -2003,19 +2003,6 @@ to improve the performance - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_tr.ts b/YACReaderLibrary/yacreaderlibrary_tr.ts index 2f346366..04e56a16 100644 --- a/YACReaderLibrary/yacreaderlibrary_tr.ts +++ b/YACReaderLibrary/yacreaderlibrary_tr.ts @@ -2817,19 +2817,6 @@ performansı iyileştirmek için Kapat - - YACReaderDeletingProgress - - - cancel - vazgeç - - - - Please wait, deleting in progress... - Lütfen bekleyin, silme işlemi yapılıyor... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts index 0b375553..dcf00248 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts @@ -2862,19 +2862,6 @@ to improve the performance 关闭 - - YACReaderDeletingProgress - - - cancel - 取消 - - - - Please wait, deleting in progress... - 请稍候,正在删除... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts index 8c1f52aa..32a397dc 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts @@ -2827,19 +2827,6 @@ to improve the performance 關閉 - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - 請稍候,正在刪除... - - - - cancel - 取消 - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts index f7042bb6..1b66465e 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts @@ -2827,19 +2827,6 @@ to improve the performance 關閉 - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - 請稍候,正在刪除... - - - - cancel - 取消 - - YACReaderFieldEdit diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 8ef969ea..93bd88a7 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1270,9 +1270,8 @@ void YACReaderFlow3D::setTextColor(const QColor &color) { textColor = color; - QPalette palette = indexLabel->palette(); - palette.setColor(QPalette::WindowText, textColor); - indexLabel->setPalette(palette); + auto styleSheet = QString("QLabel { color: %1; }").arg(textColor.name()); + indexLabel->setStyleSheet(styleSheet); update(); } @@ -1424,9 +1423,8 @@ void YACReaderFlow3D::updateIndexLabelStyle() QFont font("Arial", newFontSize); indexLabel->setFont(font); - QPalette palette = indexLabel->palette(); - palette.setColor(QPalette::WindowText, textColor); - indexLabel->setPalette(palette); + auto styleSheet = QString("QLabel { color: %1; }").arg(textColor.name()); + indexLabel->setStyleSheet(styleSheet); indexLabel->move(10, 10); indexLabel->adjustSize(); @@ -1435,9 +1433,7 @@ void YACReaderFlow3D::updateIndexLabelStyle() #if defined(YACREADER_RHI_PERF) if (perfLabel) { perfLabel->setFont(font); - QPalette p = perfLabel->palette(); - p.setColor(QPalette::WindowText, textColor); - perfLabel->setPalette(p); + perfLabel->setStyleSheet(styleSheet); perfLabel->move(10, 10 + indexLabel->height() + 4); perfLabel->adjustSize(); } diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index bfa0fead..f0ca5f9d 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -1,7 +1,28 @@ #include "icon_utils.h" +#include + #include "yacreader_global.h" +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalSize, qreal devicePixelRatio) +{ + return renderSvgToPixmap(svgPath, logicalSize, logicalSize, devicePixelRatio); +} + +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalWidth, int logicalHeight, qreal devicePixelRatio) +{ + const int pixelWidth = qRound(logicalWidth * devicePixelRatio); + const int pixelHeight = qRound(logicalHeight * devicePixelRatio); + QPixmap pixmap(pixelWidth, pixelHeight); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QSvgRenderer renderer(svgPath); + renderer.render(&painter); + painter.end(); + pixmap.setDevicePixelRatio(devicePixelRatio); + return pixmap; +} + QString readSvg(const QString &resourcePath) { QFile in(resourcePath); diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index 8575590d..48b4462c 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -3,6 +3,11 @@ #include +// Render an SVG file to a QPixmap at a specific logical size with HiDPI support. +// Uses QSvgRenderer to rasterize directly at the target resolution (no upscaling). +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalSize, qreal devicePixelRatio); +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalWidth, int logicalHeight, qreal devicePixelRatio); + struct RecolorOptions { QString suffix; QString fileName; diff --git a/common/themes/shared/whats_new_dialog_theme.h b/common/themes/shared/whats_new_dialog_theme.h new file mode 100644 index 00000000..cd882957 --- /dev/null +++ b/common/themes/shared/whats_new_dialog_theme.h @@ -0,0 +1,17 @@ +#ifndef WHATS_NEW_DIALOG_THEME_H +#define WHATS_NEW_DIALOG_THEME_H + +#include +#include + +struct WhatsNewDialogTheme { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QPixmap closeButtonIcon; + QPixmap headerDecoration; +}; + +#endif // WHATS_NEW_DIALOG_THEME_H diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 4bfabb21..081a7147 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -6,6 +6,8 @@ #include #include +// TODO: add API to force color scheme //styleHints->setColorScheme(Qt::ColorScheme::Dark); + ThemeManager::ThemeManager() { } diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri index bed4ed5c..f246882c 100644 --- a/common/themes/themes_common.pri +++ b/common/themes/themes_common.pri @@ -8,6 +8,7 @@ HEADERS += \ $$PWD/themable.h \ $$PWD/yacreader_icon.h \ $$PWD/shared/help_about_dialog_theme.h \ + $$PWD/shared/whats_new_dialog_theme.h \ SOURCES += \ diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index abf4be55..f80f1aff 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -53,22 +53,6 @@ QList YACReader::mimeDataToComicsIds(const QMimeData *data) return comicIds; } -// TODO some SVG assets are missing in macos (WIP) -// we need two sets of icons, one for the toolbar and one for the context menu because of this bug (QTBUG-96553): https://bugreports.qt.io/browse/QTBUG-96553 - -QString YACReader::addExtensionToIconPath(const QString &path) -{ -#ifdef YACREADER_LIBRARY -#ifdef Q_OS_MACOS // TODO_Y_MAC_UI - return path + ".png"; -#else - return path + ".svg"; -#endif -#else - return path + ".svg"; -#endif -} - QString YACReader::addExtensionToIconPathInToolbar(const QString &path) { return path + "_18x18.svg"; diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 84f8e64c..7f25ad99 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -110,7 +110,6 @@ QAction *createSeparator(); QIcon noHighlightedIcon(const QString &path); void colorize(QImage &img, const QColor &col); QList mimeDataToComicsIds(const QMimeData *data); -QString addExtensionToIconPath(const QString &path); QString addExtensionToIconPathInToolbar(const QString &path); QAction *actionWithCustomIcon(const QIcon &icon, QAction *action); QPixmap hdpiPixmap(const QString &file, QSize size); diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri index 3341bd40..e9f61afd 100644 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ b/custom_widgets/custom_widgets_yacreaderlibrary.pri @@ -13,7 +13,6 @@ HEADERS += \ $$PWD/yacreader_spin_slider_widget.h \ $$PWD/yacreader_tool_bar_stretch.h \ $$PWD/yacreader_titled_toolbar.h \ - $$PWD/yacreader_deleting_progress.h \ $$PWD/yacreader_table_view.h \ $$PWD/yacreader_sidebar.h \ $$PWD/yacreader_library_list_widget.h \ @@ -38,7 +37,6 @@ SOURCES += \ $$PWD/yacreader_spin_slider_widget.cpp \ $$PWD/yacreader_tool_bar_stretch.cpp \ $$PWD/yacreader_titled_toolbar.cpp \ - $$PWD/yacreader_deleting_progress.cpp \ $$PWD/yacreader_table_view.cpp \ $$PWD/yacreader_sidebar.cpp \ $$PWD/yacreader_library_list_widget.cpp \ diff --git a/custom_widgets/rounded_corners_dialog.cpp b/custom_widgets/rounded_corners_dialog.cpp index 5210b6f7..2529b6d7 100644 --- a/custom_widgets/rounded_corners_dialog.cpp +++ b/custom_widgets/rounded_corners_dialog.cpp @@ -9,6 +9,12 @@ YACReader::RoundedCornersDialog::RoundedCornersDialog(QWidget *parent) setAttribute(Qt::WA_TranslucentBackground); } +void YACReader::RoundedCornersDialog::setBackgroundColor(const QColor &color) +{ + m_backgroundColor = color; + update(); +} + void YACReader::RoundedCornersDialog::paintEvent(QPaintEvent *) { qreal radius = 14.0; // desired radius in absolute pixels @@ -26,7 +32,7 @@ void YACReader::RoundedCornersDialog::paintEvent(QPaintEvent *) // Set the brush from palette role. // p.setBrush(palette().brush(backgroundRole())); - p.setBrush(QBrush(QColor(255, 255, 255))); // TODO: the rest of the colors are hardcoded + p.setBrush(QBrush(m_backgroundColor)); // Got radius? Otherwise draw a quicker rect. if (radius > 0.0) p.drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize); diff --git a/custom_widgets/rounded_corners_dialog.h b/custom_widgets/rounded_corners_dialog.h index 04679fb8..3e5c3ce1 100644 --- a/custom_widgets/rounded_corners_dialog.h +++ b/custom_widgets/rounded_corners_dialog.h @@ -1,6 +1,7 @@ #ifndef ROUNDEDCORNERSDIALOG_H #define ROUNDEDCORNERSDIALOG_H +#include #include namespace YACReader { @@ -12,6 +13,10 @@ public: protected: void paintEvent(QPaintEvent *) override; + void setBackgroundColor(const QColor &color); + +private: + QColor m_backgroundColor { 255, 255, 255 }; }; } diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 4f0e1dcc..6f9689d9 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -22,114 +22,121 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) content->setStyleSheet("background-color:transparent;" "border:none;"); - auto headerImageLabel = new QLabel(); - QPixmap headerImage(":/images/whats_new/whatsnew_header.svg"); - headerImageLabel->setPixmap(headerImage); - headerImageLabel->setFixedSize(headerImage.size()); + headerImageLabel = new QLabel(); - auto headerLabel = new QLabel(); + headerLabel = new QLabel(); headerLabel->setText("What's New in\nYACReader"); QFont headerLabelFont("Arial", 34, QFont::ExtraBold); headerLabel->setFont(headerLabelFont); headerLabel->setAlignment(Qt::AlignCenter); - headerLabel->setStyleSheet("padding: 18px 0 0 0;" - "background-color:transparent;" - "color:#0A0A0A;"); - auto versionLabel = new QLabel(); + versionLabel = new QLabel(); versionLabel->setText(VERSION); QFont versionLabelFont("Arial", 12, QFont::Normal); versionLabel->setFont(versionLabelFont); 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 exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
" - "
" - "YACReader
" - " • 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
" - " • Fix current page/time label content when the content is too long. (new in 9.16.3)
" - "
" - "YACReaderLibrary
" - " • 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
" - " • Fixed cover loading in Comic Vine scraper (new in 9.16.1)
" - " • Added a customizable User Agent string to use it with Comic Vine. It can be set in YACReaderLibrary.ini in the [ComicVine] section using the COMIC_VINE_USER_AGENT key (new in 9.16.2)
" - " • Prevent crash when opening the folders context menu if a folder is not selected. (new in 9.16.2)
" - " • Fix crash when using the `Set type` menu on libraries. (new in 9.16.2)
" - " • Fix table view last section stretch. Before it was only working randomly. (new in 9.16.3)
" - " • Fix empty table view caused by wront state being saved. You'll need to reconfigure the table view headers to your liking after this udpate. (new in 9.16.3)
" - "
" - "YACReaderLibraryServer
" - " • Log libraries validation when the app starts
" - "
" - "All apps
" - " • PDF support has been updated in all Windows apps
" - "
" - "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. " - "Remember that there is an iOS version available in the Apple App Store, " - "and there is a brand new app for Android that you can get on the Google Play Store."); + textLabel = new QLabel(); + htmlTemplate = "This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
" + "
" + "YACReader
" + " • 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
" + " • Fix current page/time label content when the content is too long. (new in 9.16.3)
" + "
" + "YACReaderLibrary
" + " • 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
" + " • Fixed cover loading in Comic Vine scraper (new in 9.16.1)
" + " • Added a customizable User Agent string to use it with Comic Vine. It can be set in YACReaderLibrary.ini in the [ComicVine] section using the COMIC_VINE_USER_AGENT key (new in 9.16.2)
" + " • Prevent crash when opening the folders context menu if a folder is not selected. (new in 9.16.2)
" + " • Fix crash when using the `Set type` menu on libraries. (new in 9.16.2)
" + " • Fix table view last section stretch. Before it was only working randomly. (new in 9.16.3)
" + " • Fix empty table view caused by wront state being saved. You'll need to reconfigure the table view headers to your liking after this udpate. (new in 9.16.3)
" + "
" + "YACReaderLibraryServer
" + " • Log libraries validation when the app starts
" + "
" + "All apps
" + " • PDF support has been updated in all Windows apps
" + "
" + "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. " + "Remember that there is an iOS version available in the Apple App Store, " + "and there is a brand new app for Android that you can get on the Google Play Store."; QFont textLabelFont("Arial", 15, QFont::Light); - text->setFont(textLabelFont); - text->setStyleSheet("padding:51px;" - "background-color:transparent;" - "color:#0A0A0A;"); - text->setWordWrap(true); - text->setOpenExternalLinks(true); + textLabel->setFont(textLabelFont); + textLabel->setWordWrap(true); + textLabel->setOpenExternalLinks(true); contentLayout->addItem(new QSpacerItem(0, 50), 0, 0); contentLayout->addWidget(headerImageLabel, 1, 0, Qt::AlignTop | Qt::AlignHCenter); contentLayout->addWidget(headerLabel, 1, 0, Qt::AlignTop | Qt::AlignHCenter); contentLayout->addWidget(versionLabel, 2, 0, Qt::AlignTop | Qt::AlignHCenter); - contentLayout->addWidget(text, 3, 0, Qt::AlignTop); + contentLayout->addWidget(textLabel, 3, 0, Qt::AlignTop); contentLayout->setRowStretch(3, 1); content->setLayout(contentLayout); mainLayout->addWidget(scrollArea); - // containerLayout->addWidget(content); scrollArea->setWidget(content); scrollArea->setWidgetResizable(true); this->setLayout(mainLayout); - auto closeButton = new QPushButton(this); + closeButton = new QPushButton(this); closeButton->setFlat(true); closeButton->setStyleSheet("background-color:transparent;"); - auto closeIcon = QPixmap(":/images/custom_dialog/custom_close_button.svg"); - if (!closeIcon.isNull()) { - closeButton->setIcon(QPixmap(":/images/custom_dialog/custom_close_button.svg")); - closeButton->setIconSize(QSize(44, 44)); - closeButton->setFixedSize(44, 44); - closeButton->move(656, 20); - } else { - closeButton->setText(tr("Close")); - auto font = closeButton->font(); - font.setPointSize(16); - closeButton->setFont(font); - closeButton->move(616, 20); - } + closeButton->setIconSize(QSize(44, 44)); + closeButton->setFixedSize(44, 44); + closeButton->move(656, 20); scrollArea->setFixedSize(720, 640); setFixedSize(720, 640); setModal(true); connect(closeButton, &QPushButton::clicked, this, &QDialog::close); + + initTheme(this); +} + +void YACReader::WhatsNewDialog::applyTheme(const Theme &theme) +{ + auto whatsNewTheme = theme.whatsNewDialog; + + setBackgroundColor(whatsNewTheme.backgroundColor); + + headerImageLabel->setPixmap(whatsNewTheme.headerDecoration); + headerImageLabel->setFixedSize(whatsNewTheme.headerDecoration.size()); + + headerLabel->setStyleSheet(QString("padding: 18px 0 0 0;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.headerTextColor.name())); + + versionLabel->setStyleSheet(QString("padding:0 0 0 0;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.versionTextColor.name())); + + textLabel->setStyleSheet(QString("padding:51px;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.contentTextColor.name())); + textLabel->setText(htmlTemplate.arg(whatsNewTheme.linkColor.name())); + + closeButton->setIcon(whatsNewTheme.closeButtonIcon); } diff --git a/custom_widgets/whats_new_dialog.h b/custom_widgets/whats_new_dialog.h index 8ec3722b..a580b668 100644 --- a/custom_widgets/whats_new_dialog.h +++ b/custom_widgets/whats_new_dialog.h @@ -2,15 +2,29 @@ #define WHATSNEWDIALOG_H #include "rounded_corners_dialog.h" -#include +#include "themable.h" + +class QLabel; +class QPushButton; namespace YACReader { -class WhatsNewDialog : public RoundedCornersDialog +class WhatsNewDialog : public RoundedCornersDialog, protected Themable { Q_OBJECT public: explicit WhatsNewDialog(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; + +private: + QLabel *headerImageLabel; + QLabel *headerLabel; + QLabel *versionLabel; + QLabel *textLabel; + QPushButton *closeButton; + QString htmlTemplate; }; } diff --git a/custom_widgets/yacreader_deleting_progress.cpp b/custom_widgets/yacreader_deleting_progress.cpp deleted file mode 100644 index fc54476b..00000000 --- a/custom_widgets/yacreader_deleting_progress.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "yacreader_deleting_progress.h" - -#include -#include -#include -#include -#include -#include - -YACReaderDeletingProgress::YACReaderDeletingProgress(QWidget *parent) - : QWidget(parent) -{ - QVBoxLayout *contentLayout = new QVBoxLayout(this); - - QLabel *iconLabel = new QLabel(); - QPixmap icon(":/images/deleting_progress/icon.png"); - iconLabel->setPixmap(icon); - iconLabel->setStyleSheet("QLabel {padding:0px; margin:0px;}"); - - textMessage = new QLabel(tr("Please wait, deleting in progress...")); - - textMessage->setStyleSheet("QLabel {color:#ABABAB; padding:0 0 0 0px; margin:0px; font-size:18px; font-weight:bold;}"); - - QProgressBar *progressBar = new QProgressBar(); - - progressBar->setTextVisible(false); - progressBar->setFixedHeight(6); - progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - progressBar->setRange(0, 10); - progressBar->setValue(5); - progressBar->setStyleSheet( - "QProgressBar { border: none; border-radius: 3px; background: #ABABAB; margin:0; margin-left:16; margin-right:16px;}" - "QProgressBar::chunk {background-color: #FFC745; border: none; border-radius: 3px;}"); - - QPushButton *button = new QPushButton(tr("cancel")); - - button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - contentLayout->addSpacing(16); - contentLayout->addWidget(iconLabel, 0, Qt::AlignHCenter); - contentLayout->addSpacing(11); - contentLayout->addWidget(textMessage, 0, Qt::AlignHCenter); - contentLayout->addSpacing(13); - contentLayout->addWidget(progressBar); - contentLayout->addSpacing(13); - contentLayout->addWidget(button, 0, Qt::AlignHCenter); - contentLayout->addSpacing(18); - - contentLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(contentLayout); - - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - resize(sizeHint()); -} - -void YACReaderDeletingProgress::paintEvent(QPaintEvent *event) -{ - int borderTop, borderRight, borderBottom, borderLeft; - - QPixmap pL(":/images/deleting_progress/imgTopLeft.png"); - QPixmap pM(":/images/deleting_progress/imgTopMiddle.png"); - QPixmap pR(":/images/deleting_progress/imgTopRight.png"); - - QPixmap pLM(":/images/deleting_progress/imgLeftMiddle.png"); - - QPixmap pRM(":/images/deleting_progress/imgRightMiddle.png"); - - QPixmap pBL(":/images/deleting_progress/imgBottomLeft.png"); - QPixmap pBM(":/images/deleting_progress/imgBottomMiddle.png"); - QPixmap pBR(":/images/deleting_progress/imgBottomRight.png"); - - borderTop = pL.height(); - borderRight = pRM.width(); - borderBottom = pBM.height(); - borderLeft = pLM.width(); - - int width = this->width() - borderRight - borderLeft; - int height = this->height() - borderTop - borderBottom; - - QPainter painter(this); - - // corners - painter.drawPixmap(0, 0, pL); - painter.drawPixmap(this->width() - borderRight, 0, pR); - painter.drawPixmap(0, this->height() - pBL.height(), pBL); - painter.drawPixmap(this->width() - pBR.width(), this->height() - borderBottom, pBR); - - // middle - painter.drawPixmap(borderRight, 0, width, borderTop, pM); - painter.drawPixmap(0, borderTop, borderLeft, height, pLM); - painter.drawPixmap(width + borderLeft, borderTop, borderRight, height, pRM); - painter.drawPixmap(pBR.width(), height + borderTop, this->width() - pBR.width() - pBL.width(), pBR.height(), pBM); - - // center - painter.fillRect(borderLeft, borderTop, width, height, QColor("#FAFAFA")); - - QWidget::paintEvent(event); -} - -QSize YACReaderDeletingProgress::sizeHint() const -{ - return QSize(textMessage->sizeHint().width() + 120, 185); -} diff --git a/custom_widgets/yacreader_deleting_progress.h b/custom_widgets/yacreader_deleting_progress.h deleted file mode 100644 index b1e7cc02..00000000 --- a/custom_widgets/yacreader_deleting_progress.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef YACREADER_DELETING_PROGRESS_H -#define YACREADER_DELETING_PROGRESS_H - -#include - -class QLabel; - -class YACReaderDeletingProgress : public QWidget -{ - Q_OBJECT -public: - explicit YACReaderDeletingProgress(QWidget *parent = 0); - QSize sizeHint() const; -signals: - -public slots: - -protected: - void paintEvent(QPaintEvent *); - -private: - QLabel *textMessage; -}; - -#endif // YACREADER_DELETING_PROGRESS_H diff --git a/custom_widgets/yacreader_library_item_widget.cpp b/custom_widgets/yacreader_library_item_widget.cpp index f7cbec8e..295714f9 100644 --- a/custom_widgets/yacreader_library_item_widget.cpp +++ b/custom_widgets/yacreader_library_item_widget.cpp @@ -19,20 +19,15 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin // installEventFilter(this); - QPixmap iconPixmap = hdpiPixmap(addExtensionToIconPath(":/images/sidebar/libraryIcon"), QSize(16, 16)); icon = new QLabel(this); - icon->setPixmap(iconPixmap); nameLabel = new QLabel(name, this); options = new QToolButton(this); - QPixmap iconOptionsPixmap = hdpiPixmap(":/images/sidebar/libraryOptions.svg", QSize(8, 8)); - iconOptionsPixmap.setDevicePixelRatio(devicePixelRatioF()); - QLabel *helperLabel = new QLabel(options); - helperLabel->move(4, 3); - helperLabel->setFixedSize(14, 14); - helperLabel->setPixmap(iconOptionsPixmap); + optionsIconLabel = new QLabel(options); + optionsIconLabel->move(4, 3); + optionsIconLabel->setFixedSize(14, 14); options->setHidden(true); options->setIconSize(QSize(18, 18)); @@ -57,10 +52,6 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin mainLayout->addWidget(down);*/ setLayout(mainLayout); -#ifndef Y_MAC_UI - QString styleSheet = "background-color:transparent; color:#DDDFDF;"; - setStyleSheet(styleSheet); -#endif QString iconStyleSheet = "QLabel {padding:0 0 0 24px; margin:0px}"; icon->setStyleSheet(iconStyleSheet); @@ -70,6 +61,35 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin setMinimumHeight(20); setAttribute(Qt::WA_StyledBackground, true); + + initTheme(this); +} + +void YACReaderLibraryItemWidget::applyTheme(const Theme &theme) +{ + const auto &icons = theme.sidebarIcons; + const auto &li = theme.libraryItem; + + // Update icon based on current selection state + QIcon iconToUse = isSelected ? li.libraryIconSelected : icons.libraryIcon; + icon->setPixmap(iconToUse.pixmap(16, 16)); + + // Update options icon (uses libraryItem theme since it's only shown when selected) + QPixmap optionsPixmap = li.libraryOptionsIcon.pixmap(8, 8); + optionsPixmap.setDevicePixelRatio(devicePixelRatioF()); + optionsIconLabel->setPixmap(optionsPixmap); + + // Update widget styling based on selection state + if (isSelected) { + QString styleSheet = QString("color: %1; background-color: %2; font-weight:bold;") + .arg(li.selectedTextColor.name()) + .arg(li.selectedBackgroundColor.name()); + setStyleSheet(styleSheet); + } else { + QString styleSheet = QString("background-color:transparent; color: %1;") + .arg(li.textColor.name()); + setStyleSheet(styleSheet); + } } void YACReaderLibraryItemWidget::showUpDownButtons(bool show) @@ -117,17 +137,11 @@ bool YACReaderLibraryItemWidget::eventFilter(QObject *object, QEvent *event){ void YACReaderLibraryItemWidget::deselect() { - -#ifdef Y_MAC_UI - QString styleSheet = "background-color:transparent;"; + QString styleSheet = QString("background-color:transparent; color: %1;") + .arg(theme.libraryItem.textColor.name()); setStyleSheet(styleSheet); -#else - QString styleSheet = "background-color:transparent; color:#DDDFDF;"; - setStyleSheet(styleSheet); -#endif - QPixmap iconPixmap = hdpiPixmap(addExtensionToIconPath(":/images/sidebar/libraryIcon"), QSize(16, 16)); - icon->setPixmap(iconPixmap); + icon->setPixmap(theme.sidebarIcons.libraryIcon.pixmap(16, 16)); /*up->setHidden(true); down->setHidden(true);*/ @@ -138,18 +152,15 @@ void YACReaderLibraryItemWidget::deselect() void YACReaderLibraryItemWidget::select() { -#ifdef Y_MAC_UI - // QString styleSheet ="color: white; background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6BAFE4, stop: 1 #3984D2); border-top: 2px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5EA3DF, stop: 1 #73B8EA); border-left:none;border-right:none;border-bottom:1px solid #3577C2;"; - QString styleSheet = "color: white; background-color:#91c4f4; border-bottom:1px solid #91c4f4;"; -#else - QString styleSheet = "color: white; background-color:#2E2E2E; font-weight:bold;"; -#endif + const auto &li = theme.libraryItem; + QString styleSheet = QString("color: %1; background-color: %2; font-weight:bold;") + .arg(li.selectedTextColor.name()) + .arg(li.selectedBackgroundColor.name()); setStyleSheet(styleSheet); options->setHidden(false); - QPixmap iconPixmap = hdpiPixmap(":/images/sidebar/libraryIconSelected.svg", QSize(16, 16)); - icon->setPixmap(iconPixmap); + icon->setPixmap(theme.libraryItem.libraryIconSelected.pixmap(16, 16)); isSelected = true; } diff --git a/custom_widgets/yacreader_library_item_widget.h b/custom_widgets/yacreader_library_item_widget.h index d2af6d10..33462b56 100644 --- a/custom_widgets/yacreader_library_item_widget.h +++ b/custom_widgets/yacreader_library_item_widget.h @@ -2,13 +2,16 @@ #define YACREADER_LIBRARY_ITEM_WIDGET_H #include +#include + +#include "themable.h" class QLabel; class QToolButton; class QMouseEvent; class QEvent; -class YACReaderLibraryItemWidget : public QWidget +class YACReaderLibraryItemWidget : public QWidget, protected Themable { Q_OBJECT @@ -32,12 +35,16 @@ public slots: private: QLabel *icon; QLabel *nameLabel; + QLabel *optionsIconLabel; QToolButton *options; QToolButton *up; QToolButton *down; bool isSelected; + +protected: + void applyTheme(const Theme &theme) override; }; #endif // YACREADER_LIBRARY_ITEM_WIDGET_H diff --git a/custom_widgets/yacreader_macosx_toolbar.h b/custom_widgets/yacreader_macosx_toolbar.h index 18cdccb5..f07de90c 100644 --- a/custom_widgets/yacreader_macosx_toolbar.h +++ b/custom_widgets/yacreader_macosx_toolbar.h @@ -1,92 +1,6 @@ #ifndef YACREADER_MACOSX_TOOLBAR_H #define YACREADER_MACOSX_TOOLBAR_H -#include -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#include -#include - -#include "yacreader_global.h" - -// Wrapper for NSTextField -class YACReaderMacOSXSearchLineEdit : public QObject -{ - Q_OBJECT -public: - YACReaderMacOSXSearchLineEdit(); - void setFocus(Qt::FocusReason reason); - void *getNSTextField(); - -public slots: - QString text(); - void clear(); - void clearText(); // no signal emited - void setDisabled(bool disabled); - void setEnabled(bool enabled); - -private: - void *nstextfield; - -signals: - // convenience signal for YACReaderLibrary search edit - void filterChanged(QString); -}; - -class MacToolBarItemWrapper : public QObject -{ - Q_OBJECT -public: - MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem); - -public slots: - void actionToggled(bool toogled); - -private: - QAction *action; - QMacToolBarItem *toolbaritem; - - void updateIcon(bool checked); -}; - -class YACReaderMacOSXToolbar : public QMacToolBar -{ - Q_OBJECT -public: - explicit YACReaderMacOSXToolbar(QObject *parent = 0); - void addAction(QAction *action); - void addDropDownItem(const QList &actions, const QAction *defaultAction = 0); - void addSpace(int size); // size in points - void addSeparator(); - void addStretch(); - void addWidget(QWidget *widget); - void show(); - void hide(); - QMap actions; - - // hacks everywhere - // convenience method for YACReaderLibrary search edit - YACReaderMacOSXSearchLineEdit *addSearchEdit(); - // convenience method for showing the fit to width slider in MacOSX - QAction *addFitToWidthSlider(QAction *attachToAction); - - // convenience method for switching the icon of the view selector - void updateViewSelectorIcon(const QIcon &icon); - - void attachToWindow(QMainWindow *window); - -signals: - -public slots: - -protected: - NSToolbar *nativeToolBar; - void *delegate; - bool yosemite; - QMacToolBarItem *viewSelector; -}; -#else - #ifdef YACREADER_LIBRARY #include "yacreader_main_toolbar.h" @@ -149,6 +63,4 @@ public slots: #endif -#endif - #endif // YACREADER_MACOSX_TOOLBAR_H diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index e2d07450..487bc90f 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -1,403 +1,8 @@ #include "yacreader_macosx_toolbar.h" #include "QtWidgets/qmainwindow.h" -#include #include -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#include -#include -#include -#include - -#import -#import -#import - -#import "shortcuts_manager.h" - -//---------------------------- -// A custom items separator for NSToolbar -@interface CustomSeparator : NSView - -@end - -@implementation CustomSeparator - -- (void)drawRect:(NSRect)rect -{ - [[NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1] setFill]; - NSRectFill(rect); - [super drawRect:rect]; -} - -@end - -//---------------------------- -// Toolbar delegate, needed for allow disabled/enabled items -@interface MyToolbarDelegate : NSObject { -@public - YACReaderMacOSXToolbar *mytoolbar; -} - -- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL)willBeInserted; -- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar; -- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar; -//- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar; -- (IBAction)itemClicked:(id)sender; -- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem; -@end - -@implementation MyToolbarDelegate - -- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem *item, items) { - [array addObject:item->nativeToolBarItem().itemIdentifier]; - } - return array; -} - -- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem *item, items) { - [array addObject:item->nativeToolBarItem().itemIdentifier]; - } - return array; -} - -/* -- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem * item, items) { - [array addObject : item->nativeToolBarItem().itemIdentifier]; - } - return array; - //NSMutableArray *array = toolbarPrivate->getItemIdentifiers(toolbarPrivate->items, true); - //[array addObjectsFromArray:toolbarPrivate->getItemIdentifiers(toolbarPrivate->allowedItems, true)]; - //return array; -}*/ - -- (IBAction)itemClicked:(id)sender -{ - if ([sender respondsToSelector:@selector(itemIdentifier)]) { - NSToolbarItem *item = reinterpret_cast(sender); - - QString identifier = QString::fromNSString([item itemIdentifier]); - QMacToolBarItem *toolButton = reinterpret_cast(identifier.toULongLong()); - Q_EMIT toolButton->activated(); - } -} - -- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInserted -{ - Q_UNUSED(toolbar); - Q_UNUSED(willBeInserted); - QList items = mytoolbar->items(); - - foreach (const QMacToolBarItem *item, items) { - NSToolbarItem *toolbarItem = item->nativeToolBarItem(); - if ([toolbarItem.itemIdentifier isEqual:itemIdentifier]) { - - [toolbarItem setTarget:self]; - [toolbarItem setAction:@selector(itemClicked:)]; - - return toolbarItem; - } - } - return nil; -} - -- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem -{ - QString identifier = QString::fromNSString(theItem.itemIdentifier); - - if (mytoolbar->actions.contains(identifier)) { - return mytoolbar->actions.value(identifier)->isEnabled(); - } else - return NO; -} -@end - -//---------------------------- -// detect changes in native text field -// TODO implement validation and auto completion -@interface MyTextFieldDelegate : NSObject { -@public - YACReaderMacOSXSearchLineEdit *mylineedit; -} -@end - -@implementation MyTextFieldDelegate - -- (void)controlTextDidChange:(NSNotification *)notification -{ - NSTextField *textField = [notification object]; - NSLog(@"%@", [textField stringValue]); - Q_EMIT mylineedit->filterChanged(QString::fromNSString([textField stringValue])); -} - -@end -//---------------------------- - -YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QObject *parent) - : viewSelector(0) -{ - // setup native toolbar - nativeToolBar = nativeToolbar(); - [nativeToolBar setDisplayMode:NSToolbarDisplayModeIconOnly]; - [nativeToolBar setAllowsUserCustomization:NO]; - - delegate = [[MyToolbarDelegate alloc] init]; - ((MyToolbarDelegate *)delegate)->mytoolbar = this; - [nativeToolBar setDelegate:(MyToolbarDelegate *)delegate]; - -#ifdef YACREADER_LIBRARY - NSWindow *nswindow = (NSWindow *)qApp->platformNativeInterface()->nativeResourceForWindow("nswindow", ((QMainWindow *)parent)->windowHandle()); - if ([nswindow respondsToSelector:@selector(setTitleVisibility:)]) { - yosemite = true; - // TODO yosemite new constants are not found in compilation time - [nswindow setTitleVisibility:NSWindowTitleHidden]; - // TODO NSFullSizeContentViewWindowMask produces an offset in the windows' content - // nswindow.styleMask |= 1 << 15; // NSFullSizeContentViewWindowMask; - [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; // TODO figure out how to load specific images in Yosemite - } else { - [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; - yosemite = false; - } -#else - yosemite = false; - [nativeToolBar setAutosavesConfiguration:YES]; // TODO this doesn't work - [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; -#endif -} - -void YACReaderMacOSXToolbar::addAction(QAction *action) -{ - QMacToolBarItem *toolBarItem = addItem(action->icon(), action->text()); - if (action->data().toString() == TOGGLE_COMICS_VIEW_ACTION_YL) - viewSelector = toolBarItem; - connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); }); - - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - actions.insert(QString::fromNSString(nativeItem.itemIdentifier), action); - - MacToolBarItemWrapper *wrapper = new MacToolBarItemWrapper(action, toolBarItem); - // wrapper->actionToogled(true); -} - -void YACReaderMacOSXToolbar::addDropDownItem(const QList &actions, const QAction *defaultAction) -{ - // TODO -} - -void YACReaderMacOSXToolbar::addSpace(int size) -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - static const NSRect frameRect = { { 0.0, 0.0 }, { CGFloat(size), 16.0 } }; - NSView *view = [[NSView alloc] initWithFrame:frameRect]; - - [nativeItem setView:view]; -} - -// reimplemented for convenience -void YACReaderMacOSXToolbar::addSeparator() -{ - // QMacToolBar::addSeparator(); - - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - static const NSRect frameRect = { { 0.0, 0.0 }, { 1, 16.0 } }; - CustomSeparator *view = [[CustomSeparator alloc] initWithFrame:frameRect]; - - [nativeItem setView:view]; -} - -void YACReaderMacOSXToolbar::addStretch() -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - toolBarItem->setStandardItem(QMacToolBarItem::FlexibleSpace); -} - -void YACReaderMacOSXToolbar::addWidget(QWidget *widget) -{ - // TODO fix it - /* QMacNativeWidget *nativeWidget = new QMacNativeWidget(); - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(widget); - nativeWidget->setLayout(layout); - - - NSView *nativeWidgetView = reinterpret_cast(nativeWidget->winId()); - QMacToolBarItem *toolBarItem = addItem(QIcon(),""); - NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); - [nativeItem setView:nativeWidgetView];*/ -} - -void YACReaderMacOSXToolbar::show() -{ - [nativeToolBar setVisible:YES]; -} - -void YACReaderMacOSXToolbar::hide() -{ - [nativeToolBar setVisible:NO]; -} - -YACReaderMacOSXSearchLineEdit *YACReaderMacOSXToolbar::addSearchEdit() -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - YACReaderMacOSXSearchLineEdit *searchEdit = new YACReaderMacOSXSearchLineEdit(); - - if (yosemite) - [nativeItem setView:(NSTextField *)searchEdit->getNSTextField()]; - else { - static const NSRect searchEditFrameRect = { { 0.0, 0.0 }, { 165, 26.0 } }; - NSView *view = [[NSView alloc] initWithFrame:searchEditFrameRect]; - [view addSubview:((NSTextField *)searchEdit->getNSTextField())]; - [nativeItem setView:view]; - } - - return searchEdit; -} - -// deprecated -QAction *YACReaderMacOSXToolbar::addFitToWidthSlider(QAction *attachToAction) -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(":/images/viewer_toolbar/toWidthSlider.png"), "fit to width slider"); - - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - actions.insert(QString::fromNSString(nativeItem.itemIdentifier), attachToAction); - - QAction *action = new QAction("", attachToAction->parent()); - - connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); }); - - return action; -} - -void YACReaderMacOSXToolbar::updateViewSelectorIcon(const QIcon &icon) -{ - if (viewSelector) - viewSelector->setIcon(icon); -} - -void YACReaderMacOSXToolbar::attachToWindow(QMainWindow *window) -{ - QMacToolBar::attachToWindow(window->windowHandle()); -} - -YACReaderMacOSXSearchLineEdit::YACReaderMacOSXSearchLineEdit() - : QObject() -{ - NSRect searchEditFrameRect = { { 0.0, -3.0 }, { 165, 32.0 } }; - // NSTextField * searchEdit = [[NSTextField alloc] initWithFrame:searchEditFrameRect]; - - NSTextField *searchEdit = [[NSSearchField alloc] initWithFrame:searchEditFrameRect]; - //[searchEdit setBezelStyle:NSTextFieldRoundedBezel]; - - [[searchEdit cell] setPlaceholderString:@"type to search"]; - - MyTextFieldDelegate *delegate = [[MyTextFieldDelegate alloc] init]; - delegate->mylineedit = this; - [searchEdit setDelegate:delegate]; - - nstextfield = searchEdit; -} - -void YACReaderMacOSXSearchLineEdit::setFocus(Qt::FocusReason reason) -{ - Q_UNUSED(reason) - - [((NSTextField *)nstextfield) becomeFirstResponder]; -} - -void *YACReaderMacOSXSearchLineEdit::getNSTextField() -{ - return nstextfield; -} - -QString YACReaderMacOSXSearchLineEdit::text() -{ - return QString::fromNSString([((NSTextField *)nstextfield) stringValue]); -} - -void YACReaderMacOSXSearchLineEdit::clear() -{ - [((NSTextField *)nstextfield) setStringValue:@""]; - emit filterChanged(""); -} - -void YACReaderMacOSXSearchLineEdit::clearText() -{ - // TODO be sure that this will not generate any event.... - [((NSTextField *)nstextfield) setStringValue:@""]; -} - -void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled) -{ - [((NSTextField *)nstextfield) setEnabled:!disabled]; -} - -void YACReaderMacOSXSearchLineEdit::setEnabled(bool enabled) -{ - [((NSTextField *)nstextfield) setEnabled:enabled]; -} - -MacToolBarItemWrapper::MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem) - : action(action), toolbaritem(toolbaritem) -{ - if (action->isCheckable()) { - connect(action, &QAction::toggled, this, &MacToolBarItemWrapper::actionToggled); - connect(toolbaritem, &QMacToolBarItem::activated, action, &QAction::toggle); - updateIcon(action->isChecked()); - } -} - -void MacToolBarItemWrapper::actionToggled(bool toogled) -{ - updateIcon(toogled); -} - -void MacToolBarItemWrapper::updateIcon(bool enabled) -{ - if (enabled) { - QIcon icon = action->icon(); - QPixmap tempPixmap = icon.pixmap(QSize(24, 24)); - QPainter painter; - painter.begin(&tempPixmap); - painter.fillRect(QRect(3, 21, 18, 1), QColor("#3F3F3F")); - painter.fillRect(QRect(3, 22, 18, 1), QColor("#6E6E6E")); - painter.fillRect(QRect(3, 23, 18, 1), QColor("#EEEEEE")); - painter.end(); - - toolbaritem->setIcon(QIcon(tempPixmap)); - } else - toolbaritem->setIcon(action->icon()); -} -#else - #import #import #import @@ -462,9 +67,17 @@ void bindActionToNSToolbarItem(QAction *action, NSToolbarItem *toolbarItem, cons toolbarItem.toolTip = tooltip.isEmpty() ? @"" : [NSString stringWithUTF8String:tooltip.toUtf8().constData()]; QIcon icon = action->icon(); + if (icon.isNull()) { + return; + } __auto_type image = QIconToNSImage(icon, { 24, 24 }, iconColor); + if (image.size.width == 0 || image.size.height == 0) { + [image release]; + return; + } + if (action->isChecked()) { NSSize size = image.size; NSImage *decoratedImage = [[NSImage alloc] initWithSize:size]; @@ -950,5 +563,3 @@ void YACReaderMacOSXToolbar::hide() } #endif - -#endif diff --git a/custom_widgets/yacreader_search_line_edit.cpp b/custom_widgets/yacreader_search_line_edit.cpp index e1e105b8..7c2b08f2 100644 --- a/custom_widgets/yacreader_search_line_edit.cpp +++ b/custom_widgets/yacreader_search_line_edit.cpp @@ -1,81 +1,50 @@ #include "yacreader_search_line_edit.h" -#include "yacreader_global.h" -#include "yacreader_global_gui.h" - #include #include #include -#include "QsLog.h" - YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent) - : QLineEdit(parent) + : QLineEdit(parent), paddingLeft(0), paddingRight(0) { clearButton = new QToolButton(this); searchLabel = new QLabel(this); -#ifdef Y_MAC_UI - QPixmap clearIcon; - QPixmap searchIcon; - - clearIcon.setDevicePixelRatio(devicePixelRatioF()); - searchIcon.setDevicePixelRatio(devicePixelRatioF()); - - if (devicePixelRatioF() > 1) { - if (!clearIcon.load(":/images/clearSearch@2x.png")) { - clearIcon.load(":/images/clearSearch.png"); - } - if (!searchIcon.load(":/images/iconSearch@2x.png")) { - searchIcon.load(":/images/iconSearch.png"); - } - } else { - clearIcon.load(":/images/clearSearch.png"); - searchIcon.load(":/images/iconSearch.png"); - } -#else - QPixmap clearIcon = YACReader::hdpiPixmap(":/images/clearSearch.svg", QSize(15, 15)); - QPixmap searchIcon = YACReader::hdpiPixmap(":/images/iconSearch.svg", QSize(15, 15)); -#endif - - searchLabel->setStyleSheet("QLabel { border: none; padding: 0px; }"); - searchLabel->setPixmap(searchIcon); - - clearButton->setIcon(QIcon(clearIcon)); - -#ifdef Y_MAC_UI - clearButton->setIconSize(QSize(14, 14)); -#else clearButton->setIconSize(QSize(12, 12)); -#endif clearButton->setCursor(Qt::ArrowCursor); - clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); clearButton->hide(); connect(clearButton, &QAbstractButton::clicked, this, &QLineEdit::clear); connect(this, &QLineEdit::textChanged, this, &YACReaderSearchLineEdit::updateCloseButton); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); -#ifdef Y_MAC_UI - setStyleSheet(QString("QLineEdit {border-top:1px solid #9F9F9F; border-bottom:1px solid #ACACAC; border-right:1px solid #ACACAC; border-left:1px solid #ACACAC; border-radius: 4px; background-color:#EEEEEE; padding-left: %1px; padding-right: %2px; padding-bottom: 1px; margin-bottom: 1px;} ").arg(searchLabel->sizeHint().width() + frameWidth + 6).arg(clearButton->sizeHint().width() + frameWidth + 2)); -#else - setStyleSheet(QString("QLineEdit {color: #ABABAB; border:none; border-radius: 4px; background-color:#404040; padding-left: %1px; padding-right: %2px; padding-bottom: 1px; margin-right: 9px;} ").arg(searchLabel->sizeHint().width() + frameWidth + 6 + 5).arg(clearButton->sizeHint().width() + frameWidth + 2)); -#endif + paddingLeft = 15 + frameWidth + 6 + 5; + paddingRight = 12 + frameWidth + 10; + QSize msz = minimumSizeHint(); setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2), qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2)); -#ifdef Y_MAC_UI - setMaximumWidth(212); - setFixedHeight(26); -#else setMaximumWidth(255); setFixedHeight(26); -#endif - setAttribute(Qt::WA_MacShowFocusRect, false); setPlaceholderText(tr("type to search")); connect(this, &QLineEdit::textChanged, this, &YACReaderSearchLineEdit::processText); + + initTheme(this); +} + +void YACReaderSearchLineEdit::applyTheme(const Theme &theme) +{ + const auto &searchTheme = theme.searchLineEdit; + + setStyleSheet(searchTheme.lineEditQSS.arg(paddingLeft).arg(paddingRight)); + searchLabel->setStyleSheet(searchTheme.searchLabelQSS); + clearButton->setStyleSheet(searchTheme.clearButtonQSS); + + searchLabel->setPixmap(searchTheme.searchIcon); + clearButton->setIcon(QIcon(searchTheme.clearIcon)); } void YACReaderSearchLineEdit::clearText() @@ -92,15 +61,6 @@ const QString YACReaderSearchLineEdit::text() void YACReaderSearchLineEdit::resizeEvent(QResizeEvent *) { -#ifdef Y_MAC_UI - QSize sz = clearButton->sizeHint(); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - clearButton->move(rect().right() - frameWidth - sz.width(), - (rect().bottom() + 1 - sz.height()) / 2); - - QSize szl = searchLabel->sizeHint(); - searchLabel->move(6, (rect().bottom() + 1 - szl.height()) / 2); -#else QSize sz = clearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); int marginRight = style()->pixelMetric(QStyle::PM_LayoutRightMargin); @@ -109,7 +69,6 @@ void YACReaderSearchLineEdit::resizeEvent(QResizeEvent *) QSize szl = searchLabel->sizeHint(); searchLabel->move(8, (rect().bottom() + 2 - szl.height()) / 2); -#endif } void YACReaderSearchLineEdit::updateCloseButton(const QString &text) diff --git a/custom_widgets/yacreader_search_line_edit.h b/custom_widgets/yacreader_search_line_edit.h index fdedef1d..3f901dc6 100644 --- a/custom_widgets/yacreader_search_line_edit.h +++ b/custom_widgets/yacreader_search_line_edit.h @@ -5,11 +5,12 @@ #include #include "yacreader_global.h" +#include "themable.h" class QToolButton; class QLabel; -class YACReaderSearchLineEdit : public QLineEdit +class YACReaderSearchLineEdit : public QLineEdit, protected Themable { Q_OBJECT @@ -20,6 +21,7 @@ public: protected: void resizeEvent(QResizeEvent *); + void applyTheme(const Theme &theme) override; signals: void filterChanged(QString); @@ -31,6 +33,9 @@ private slots: private: QToolButton *clearButton; QLabel *searchLabel; + + int paddingLeft; + int paddingRight; }; #endif // YACREADER_SEARCH_LINE_EDIT_H diff --git a/custom_widgets/yacreader_sidebar.cpp b/custom_widgets/yacreader_sidebar.cpp index 13f72dc5..bac2364c 100644 --- a/custom_widgets/yacreader_sidebar.cpp +++ b/custom_widgets/yacreader_sidebar.cpp @@ -25,28 +25,14 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) readingListsView = new YACReaderReadingListsView; selectedLibrary = new YACReaderLibraryListWidget; -#ifdef Y_MAC_UI - librariesTitle = new YACReaderTitledToolBar(tr("Libraries")); - foldersTitle = new YACReaderTitledToolBar(tr("Folders")); - readingListsTitle = new YACReaderTitledToolBar(tr("Reading Lists")); -#else - librariesTitle = new YACReaderTitledToolBar(tr("LIBRARIES")); - foldersTitle = new YACReaderTitledToolBar(tr("FOLDERS")); - readingListsTitle = new YACReaderTitledToolBar(tr("READING LISTS")); -#endif + // Titles will be set from theme in applyTheme + librariesTitle = new YACReaderTitledToolBar(""); + foldersTitle = new YACReaderTitledToolBar(""); + readingListsTitle = new YACReaderTitledToolBar(""); splitter = new QSplitter(this); splitter->setOrientation(Qt::Vertical); -#ifndef Y_MAC_UI - splitter->setStyleSheet("QSplitter::handle { " - " image: none; background-color = black; " - " }" - "QSplitter::handle:vertical { height: 39px;}"); -#else - splitter->setStyleSheet("QSplitter::handle:vertical { height: 26px; background-color: transparent;}"); -#endif - selectedLibrary->setContextMenuPolicy(Qt::ActionsContextMenu); selectedLibrary->setAttribute(Qt::WA_MacShowFocusRect, false); selectedLibrary->setFocusPolicy(Qt::NoFocus); @@ -57,24 +43,18 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); // LIBRARIES------------------------------------------------------- -#ifndef Y_MAC_UI l->addSpacing(5); -#endif l->addWidget(librariesTitle); -#ifndef Y_MAC_UI l->addSpacing(4); - l->addWidget(new YACReaderSideBarSeparator(this)); + auto sep1 = new YACReaderSideBarSeparator(this); + separators.append(sep1); + l->addWidget(sep1); l->addSpacing(3); -#endif l->addWidget(selectedLibrary); -#ifndef Y_MAC_UI l->addSpacing(11); -#else - l->addSpacing(6); -#endif // END LIBRARIES--------------------------------------------------- @@ -84,23 +64,18 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) foldersLayout->setContentsMargins(0, 0, 0, 0); foldersLayout->setSpacing(0); -#ifndef Y_MAC_UI - // foldersLayout->addSpacing(6); - - // foldersLayout->addSpacing(5); - foldersLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep2 = new YACReaderSideBarSeparator(this); + separators.append(sep2); + foldersLayout->addWidget(sep2); foldersLayout->addSpacing(4); -#else - // foldersLayout->addSpacing(6); -#endif foldersLayout->addWidget(foldersTitle); -#ifndef Y_MAC_UI foldersLayout->addSpacing(4); - foldersLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep3 = new YACReaderSideBarSeparator(this); + separators.append(sep3); + foldersLayout->addWidget(sep3); foldersLayout->addSpacing(4); -#endif foldersLayout->addWidget(foldersView); foldersLayout->addSpacing(6); @@ -116,28 +91,21 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) readingListsHeaderLayout->setContentsMargins(0, 0, 0, 0); readingListsHeaderLayout->setSpacing(0); -#ifndef Y_MAC_UI - // readingListsHeaderLayout->addSpacing(6); - - // readingListsHeaderLayout->addSpacing(5); - readingListsHeaderLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep4 = new YACReaderSideBarSeparator(this); + separators.append(sep4); + readingListsHeaderLayout->addWidget(sep4); readingListsHeaderLayout->addSpacing(4); -#else - // readingListsHeaderLayout->addSpacing(6); -#endif readingListsHeaderLayout->addWidget(readingListsTitle); -#ifndef Y_MAC_UI readingListsHeaderLayout->addSpacing(4); - readingListsHeaderLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep5 = new YACReaderSideBarSeparator(this); + separators.append(sep5); + readingListsHeaderLayout->addWidget(sep5); readingListsHeaderLayout->addSpacing(4); -#endif - // readingListsLayout->addWidget(readingListsView); readingListsHeaderLayout->addStretch(); QSplitterHandle *handle = splitter->handle(1); - // handle->setCursor(QCursor(Qt::ArrowCursor)); handle->setLayout(readingListsHeaderLayout); // END READING LISTS------------------------------------------------ @@ -148,30 +116,16 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) if (settings->contains(SIDEBAR_SPLITTER_STATUS)) splitter->restoreState(settings->value(SIDEBAR_SPLITTER_STATUS).toByteArray()); + + initTheme(this); } void YACReaderSideBar::paintEvent(QPaintEvent *event) { Q_UNUSED(event) -#ifdef Y_MAC_UI QPainter painter(this); - - painter.fillRect(0, 0, width(), height(), QColor("#F1F1F1")); -#else - QPainter painter(this); - - painter.fillRect(0, 0, width(), height(), QColor("#454545")); - // QWidget::paintEvent(event); -#endif - - // QPixmap shadow(":/images/side_bar/shadow.png"); - // painter.drawPixmap(width()-shadow.width(),0,shadow.width(),height(),shadow); - - // painter.setRenderHint(QPainter::Antialiasing); - // painter.drawLine(rect().topLeft(), rect().bottomRight()); - - // QWidget::paintEvent(event); + painter.fillRect(0, 0, width(), height(), theme.sidebar.backgroundColor); } void YACReaderSideBar::closeEvent(QCloseEvent *event) @@ -186,17 +140,40 @@ QSize YACReaderSideBar::sizeHint() const return QSize(275, 200); } +void YACReaderSideBar::applyTheme(const Theme &theme) +{ + splitter->setStyleSheet(theme.sidebar.splitterQSS); + + // Titles are per-instance, toolbars handle their own colors via Themable + auto applyCase = [&](const QString &s) { return theme.sidebar.uppercaseLabels ? s.toUpper() : s; }; + librariesTitle->setTitle(applyCase(QObject::tr("Libraries"))); + foldersTitle->setTitle(applyCase(QObject::tr("Folders"))); + readingListsTitle->setTitle(applyCase(QObject::tr("Reading Lists"))); + + for (auto separator : separators) { + separator->setColor(theme.sidebar.sectionSeparatorColor); + } + + update(); // Trigger repaint for background color +} + YACReaderSideBarSeparator::YACReaderSideBarSeparator(QWidget *parent) - : QWidget(parent) + : QWidget(parent), separatorColor(QColor("#575757")) { setFixedHeight(1); } +void YACReaderSideBarSeparator::setColor(const QColor &color) +{ + separatorColor = color; + update(); +} + void YACReaderSideBarSeparator::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter painter(this); - painter.fillRect(5, 0, width() - 10, height(), QColor("#575757")); + painter.fillRect(5, 0, width() - 10, height(), separatorColor); } diff --git a/custom_widgets/yacreader_sidebar.h b/custom_widgets/yacreader_sidebar.h index e04405b6..ca511b78 100644 --- a/custom_widgets/yacreader_sidebar.h +++ b/custom_widgets/yacreader_sidebar.h @@ -3,6 +3,8 @@ #include +#include "themable.h" + class YACReaderFoldersView; class YACReaderLibraryListWidget; class YACReaderSearchLineEdit; @@ -14,12 +16,16 @@ class YACReaderSideBarSeparator : public QWidget { public: explicit YACReaderSideBarSeparator(QWidget *parent = 0); + void setColor(const QColor &color); protected: void paintEvent(QPaintEvent *event); + +private: + QColor separatorColor; }; -class YACReaderSideBar : public QWidget +class YACReaderSideBar : public QWidget, protected Themable { Q_OBJECT public: @@ -40,8 +46,11 @@ public slots: protected: void paintEvent(QPaintEvent *); void closeEvent(QCloseEvent *event); + void applyTheme(const Theme &theme) override; + QSettings *settings; QSplitter *splitter; + QList separators; }; #endif // YACREADER_SIDEBAR_H diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 7e291e89..7c8b2507 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -19,26 +18,11 @@ #include "comic_model.h" YACReaderTableView::YACReaderTableView(QWidget *parent) - : QTableView(parent), showDelete(false), editing(false), myeditor(0) + : QTableView(parent), editing(false), myeditor(0) { setAlternatingRowColors(true); verticalHeader()->setAlternatingRowColors(true); - setStyleSheet("QTableView {alternate-background-color: #F2F2F2;background-color: #FAFAFA; outline: 0px;}" // border: 1px solid #999999; border-right:none; border-bottom:none;}" - "QTableCornerButton::section {background-color:#F5F5F5; border:none; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4);}" - "QTableView::item {outline: 0px; border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE; padding-bottom:1px; color:#252626;}" - "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:1px solid #B8B8B8;border-right:none;}" -#ifdef Y_MAC_UI - "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:none;border-right:none;}" - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #3875D7;border-top: 1px solid #3875D7; padding-bottom:1px; background-color: #3875D7; color: #FFFFFF; }" -#else - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #D4D4D4;border-top: 1px solid #D4D4D4; padding-bottom:1px; background-color: #D4D4D4; }" -#endif - "QHeaderView::section:horizontal {background-color:#F5F5F5; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4); border-left:none; border-top:none; padding:4px; color:#313232;}" - "QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}" - //"QTableView::item:hover {border-bottom: 1px solid #A3A3A3;border-top: 1px solid #A3A3A3; padding-bottom:1px; background-color: #A3A3A3; color: #FFFFFF; }" - ""); - // comicView->setItemDelegate(new YACReaderComicViewDelegate()); setContextMenuPolicy(Qt::ActionsContextMenu); setShowGrid(false); @@ -72,16 +56,19 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) setEditTriggers(QAbstractItemView::NoEditTriggers); setMouseTracking(true); - /*deletingProgress = new YACReaderDeletingProgress(this); - - showDeletingProgressAnimation = new QPropertyAnimation(deletingProgress,"pos"); - showDeletingProgressAnimation->setDuration(150);*/ // drag: if the default drag is enabled there is no way for setting a custom image // TODO report bug/suggestion // setDragEnabled(true); // setDragDropMode(QAbstractItemView::DragDrop); setAcceptDrops(true); + + initTheme(this); +} + +void YACReaderTableView::applyTheme(const Theme &theme) +{ + setStyleSheet(theme.tableView.tableViewQSS); } void YACReaderTableView::mouseMoveEvent(QMouseEvent *event) @@ -204,36 +191,8 @@ void YACReaderTableView::commitData(QWidget *editor) emit comicRated(((StarEditor *)editor)->starRating().starCount(), currentIndexEditing); } -void YACReaderTableView::showDeleteProgress() -{ - /*showDelete = true; - - showDeletingProgressAnimation->setStartValue(deletingProgress->pos()); - showDeletingProgressAnimation->setEndValue(QPoint((width()-deletingProgress->width())/2 ,1)); - showDeletingProgressAnimation->start();*/ -} - -void YACReaderTableView::hideDeleteProgress() -{ - /*showDelete = false; - - if(showDeletingProgressAnimation->state()==QPropertyAnimation::Running) - showDeletingProgressAnimation->stop(); - - showDeletingProgressAnimation->setStartValue(deletingProgress->pos()); - showDeletingProgressAnimation->setEndValue(QPoint((width()-deletingProgress->width())/2 ,-deletingProgress->height())); - showDeletingProgressAnimation->start();*/ -} - void YACReaderTableView::resizeEvent(QResizeEvent *event) { - /*event->size(); - - if(showDelete) - deletingProgress->move((event->size().width()-deletingProgress->width())/2 ,1); - else - deletingProgress->move((event->size().width()-deletingProgress->width())/2 ,-deletingProgress->height());*/ - QTableView::resizeEvent(event); } @@ -247,15 +206,23 @@ void YACReaderRatingDelegate::paint(QPainter *painter, const QStyleOptionViewIte StarRating starRating(rating); + // Get colors from parent table view + QColor ratingColor(0xE9BE0F); + QColor ratingSelectedColor(Qt::white); + if (auto tableView = qobject_cast(parent())) { + ratingColor = tableView->starRatingColor(); + ratingSelectedColor = tableView->starRatingSelectedColor(); + } + QStyledItemDelegate::paint(painter, option, index); if (!(option.state & QStyle::State_Editing)) { if (option.state & QStyle::State_Selected) starRating.paintSelected(painter, option.rect, option.palette, - StarRating::ReadOnly); + StarRating::ReadOnly, ratingSelectedColor); else starRating.paint(painter, option.rect, option.palette, - StarRating::ReadOnly); + StarRating::ReadOnly, ratingColor); } } @@ -344,6 +311,12 @@ QSize StarRating::sizeHint() const void StarRating::paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const +{ + paint(painter, rect, palette, mode, QColor("#e9be0f")); +} + +void StarRating::paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const { Q_UNUSED(palette) painter->save(); @@ -351,12 +324,8 @@ void StarRating::paint(QPainter *painter, const QRect &rect, painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); - // if (mode == Editable) { - // painter->setBrush(palette.highlight()); - // } else { - QBrush brush(QColor("#e9be0f")); + QBrush brush(color); painter->setBrush(brush); - //} int yOffset = (rect.height() - PaintingScaleFactor) / 2; painter->translate(rect.x(), rect.y() + yOffset); @@ -366,7 +335,7 @@ void StarRating::paint(QPainter *painter, const QRect &rect, if (i < myStarCount) { painter->drawPolygon(starPolygon, Qt::WindingFill); } else if (mode == Editable) { - painter->drawEllipse(QPointF(0.5, 0.5), 0.08, 0.08); //(diamondPolygon, Qt::WindingFill); + painter->drawEllipse(QPointF(0.5, 0.5), 0.08, 0.08); } painter->translate(1.0, 0.0); } diff --git a/custom_widgets/yacreader_table_view.h b/custom_widgets/yacreader_table_view.h index 183797c7..7c17e34f 100644 --- a/custom_widgets/yacreader_table_view.h +++ b/custom_widgets/yacreader_table_view.h @@ -4,21 +4,24 @@ #include #include -class YACReaderDeletingProgress; -class QResizeEvent; -class QPropertyAnimation; +#include "themable.h" -class YACReaderTableView : public QTableView +class QResizeEvent; + +class YACReaderTableView : public QTableView, protected Themable { Q_OBJECT public: explicit YACReaderTableView(QWidget *parent = 0); + QColor starRatingColor() const { return theme.tableView.starRatingColor; } + QColor starRatingSelectedColor() const { return theme.tableView.starRatingSelectedColor; } + +protected: + void applyTheme(const Theme &theme) override; signals: void comicRated(int, QModelIndex); public slots: - void showDeleteProgress(); - void hideDeleteProgress(); void closeRatingEditor(); protected slots: @@ -26,10 +29,6 @@ protected slots: virtual void commitData(QWidget *editor); private: - YACReaderDeletingProgress *deletingProgress; - bool showDelete; - QPropertyAnimation *showDeletingProgressAnimation; - void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); @@ -84,6 +83,8 @@ public: void paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const; + void paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const; void paintSelected(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode, QColor color) const; void paintSelected(QPainter *painter, const QRect &rect, diff --git a/custom_widgets/yacreader_titled_toolbar.cpp b/custom_widgets/yacreader_titled_toolbar.cpp index 51a955d5..0265bc46 100644 --- a/custom_widgets/yacreader_titled_toolbar.cpp +++ b/custom_widgets/yacreader_titled_toolbar.cpp @@ -43,9 +43,7 @@ void DropShadowLabel::paintEvent(QPaintEvent *event) QPainter painter(this); painter.setFont(font()); -#ifndef Y_MAC_UI drawTextEffect(&painter, QPoint(contentsMargins().left(), 1)); -#endif drawText(&painter, QPoint(contentsMargins().left(), 0)); } @@ -73,23 +71,10 @@ YACReaderTitledToolBar::YACReaderTitledToolBar(const QString &title, QWidget *pa busyIndicator = new BusyIndicator(this, 12); connect(busyIndicator, &BusyIndicator::clicked, this, &YACReaderTitledToolBar::cancelOperationRequested); busyIndicator->setIndicatorStyle(BusyIndicator::StyleArc); -#ifdef Y_MAC_UI - busyIndicator->setColor(QColor("#808080")); -#else - busyIndicator->setColor(Qt::white); -#endif busyIndicator->setHidden(true); nameLabel->setText(title); -#ifdef Y_MAC_UI QString nameLabelStyleSheet = "QLabel {padding:0 0 0 10px; margin:0px; font-size:11px; font-weight:bold;}"; - nameLabel->setColor(QColor("#808080")); - // nameLabel->setDropShadowColor(QColor("#F9FAFB")); -#else - QString nameLabelStyleSheet = "QLabel {padding:0 0 0 10px; margin:0px; font-size:11px; font-weight:bold;}"; - nameLabel->setColor(QColor("#BDBFBF")); - nameLabel->setDropShadowColor(QColor("#000000")); -#endif nameLabel->setStyleSheet(nameLabelStyleSheet); mainLayout->addWidget(nameLabel); @@ -101,32 +86,21 @@ YACReaderTitledToolBar::YACReaderTitledToolBar(const QString &title, QWidget *pa setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); setMinimumHeight(25); + + initTheme(this); } void YACReaderTitledToolBar::addAction(QAction *action) { QHBoxLayout *mainLayout = dynamic_cast(layout()); -// fix for QToolButton and retina support in OSX -#ifdef Q_OS_MACOS // TODO_Y_MAC_UI - QPushButton *pb = new QPushButton(this); - pb->setCursor(QCursor(Qt::ArrowCursor)); - pb->setIcon(action->icon()); - pb->addAction(action); - - connect(pb, &QPushButton::clicked, action, &QAction::triggered); - - mainLayout->addWidget(pb); -#else QToolButton *tb = new QToolButton(this); tb->setCursor(QCursor(Qt::ArrowCursor)); tb->setDefaultAction(action); tb->setIconSize(QSize(16, 16)); tb->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - // tb->setStyleSheet("QToolButton:hover {background-color:#C5C5C5;}"); mainLayout->addWidget(tb); -#endif } void YACReaderTitledToolBar::addSpacing(int spacing) @@ -142,11 +116,8 @@ void YACReaderTitledToolBar::addSepartor() QWidget *w = new QWidget(this); w->setFixedSize(1, 14); -#ifdef Y_MAC_UI - w->setStyleSheet("QWidget {background-color:#AFAFAF;}"); -#else - w->setStyleSheet("QWidget {background-color:#6F6F6F;}"); -#endif + w->setStyleSheet(QString("QWidget {background-color:%1;}").arg(theme.sidebar.separatorColor.name())); + separators.append(w); mainLayout->addSpacing(10); mainLayout->addWidget(w); @@ -162,3 +133,24 @@ void YACReaderTitledToolBar::hideBusyIndicator() { busyIndicator->setHidden(true); } + +void YACReaderTitledToolBar::setTitle(const QString &title) +{ + nameLabel->setText(title); +} + +void YACReaderTitledToolBar::applyTheme(const Theme &theme) +{ + auto sidebarTheme = theme.sidebar; + + nameLabel->setColor(sidebarTheme.titleTextColor); + nameLabel->setDropShadowColor(sidebarTheme.titleDropShadowColor); + nameLabel->update(); + + busyIndicator->setColor(sidebarTheme.busyIndicatorColor); + + QString qss = QString("QWidget {background-color:%1;}").arg(sidebarTheme.separatorColor.name()); + for (auto separator : separators) { + separator->setStyleSheet(qss); + } +} diff --git a/custom_widgets/yacreader_titled_toolbar.h b/custom_widgets/yacreader_titled_toolbar.h index de1386aa..6856394a 100644 --- a/custom_widgets/yacreader_titled_toolbar.h +++ b/custom_widgets/yacreader_titled_toolbar.h @@ -7,6 +7,8 @@ #include #include +#include "themable.h" + class QIcon; class BusyIndicator; @@ -27,7 +29,7 @@ private: void drawTextEffect(QPainter *painter, QPoint offset); }; -class YACReaderTitledToolBar : public QWidget +class YACReaderTitledToolBar : public QWidget, protected Themable { Q_OBJECT public: @@ -42,10 +44,15 @@ public slots: void addSepartor(); void showBusyIndicator(); void hideBusyIndicator(); + void setTitle(const QString &title); + +protected: + void applyTheme(const Theme &theme) override; private: DropShadowLabel *nameLabel; BusyIndicator *busyIndicator; + QList separators; }; #endif // YACREADER_TITLED_TOOLBAR_H diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 2a9799f2..4a07424e 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -9,10 +9,6 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) setDragDropMode(QAbstractItemView::DropOnly); setItemsExpandable(true); - // setDragEnabled(true); - /*viewport()->setAcceptDrops(true); - setDropIndicatorShown(true);*/ - setContextMenuPolicy(Qt::CustomContextMenu); header()->hide(); @@ -20,38 +16,12 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) setSelectionBehavior(QAbstractItemView::SelectRows); setAttribute(Qt::WA_MacShowFocusRect, false); -#ifdef Y_MAC_UI + initTheme(this); +} - setStyleSheet("QTreeView {background-color:transparent; border: none;}" - "QTreeView::item:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" - "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}" - - ); - -#else - setStyleSheet("QTreeView {background-color:transparent; border: none; color:#DDDFDF; outline:0; show-decoration-selected: 0;}" - "QTreeView::item:selected {background-color: #2E2E2E; color:white; font:bold;}" - "QTreeView::item:hover {background-color:#2E2E2E; color:white; font:bold;}" - "QTreeView::branch:selected {background-color:#2E2E2E;}" - - "QScrollBar:vertical { border: none; background: #404040; width: 7px; margin: 0 3px 0 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" - - "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/branch-closed.svg');}" - "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/collapsed_branch_selected.png');}" - - "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/branch-open.svg');}" - "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url(':/images/sidebar/expanded_branch_selected.png');}"); -#endif +void YACReaderTreeView::applyTheme(const Theme &theme) +{ + setStyleSheet(theme.treeView.treeViewQSS); } void YACReaderTreeView::mousePressEvent(QMouseEvent *event) diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index 380af038..78b0154f 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -3,11 +3,16 @@ #include -class YACReaderTreeView : public QTreeView +#include "themable.h" + +class YACReaderTreeView : public QTreeView, protected Themable { Q_OBJECT public: explicit YACReaderTreeView(QWidget *parent = 0); + QColor folderIndicatorColor() const { return theme.treeView.folderIndicatorColor; } + +private: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; signals: @@ -24,6 +29,7 @@ protected: void dropEvent(QDropEvent *event) override; void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; + void applyTheme(const Theme &theme) override; // fix for drop auto expand QTimer expandTimer; diff --git a/images/clearSearch.png b/images/clearSearch.png deleted file mode 100644 index f895c564..00000000 Binary files a/images/clearSearch.png and /dev/null differ diff --git a/images/clearSearch@2x.png b/images/clearSearch@2x.png deleted file mode 100644 index 738fc2e7..00000000 Binary files a/images/clearSearch@2x.png and /dev/null differ diff --git a/images/clearSearchNew.svg b/images/clearSearchNew.svg index 9f29aec3..a5d0bb46 100644 --- a/images/clearSearchNew.svg +++ b/images/clearSearchNew.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/comics_view_toolbar/asignNumber.svg b/images/comics_view_toolbar/asignNumber.svg index 3342ffae..0b658fe6 100644 --- a/images/comics_view_toolbar/asignNumber.svg +++ b/images/comics_view_toolbar/asignNumber.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/big_size_grid_zoom.svg b/images/comics_view_toolbar/big_size_grid_zoom.svg index 52cef716..0717f053 100644 --- a/images/comics_view_toolbar/big_size_grid_zoom.svg +++ b/images/comics_view_toolbar/big_size_grid_zoom.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/editComic.svg b/images/comics_view_toolbar/editComic.svg index 8da5f200..6eafb7fe 100644 --- a/images/comics_view_toolbar/editComic.svg +++ b/images/comics_view_toolbar/editComic.svg @@ -1 +1,14 @@ - + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/getInfo.svg b/images/comics_view_toolbar/getInfo.svg index 5ebd74e7..a9884473 100644 --- a/images/comics_view_toolbar/getInfo.svg +++ b/images/comics_view_toolbar/getInfo.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/hideComicFlow.svg b/images/comics_view_toolbar/hideComicFlow.svg index 01652ba4..e4fbb55c 100644 --- a/images/comics_view_toolbar/hideComicFlow.svg +++ b/images/comics_view_toolbar/hideComicFlow.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/openInYACReader.svg b/images/comics_view_toolbar/openInYACReader.svg index 91c4d420..ae8e4c5c 100644 --- a/images/comics_view_toolbar/openInYACReader.svg +++ b/images/comics_view_toolbar/openInYACReader.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/selectAll.svg b/images/comics_view_toolbar/selectAll.svg index d61862a9..148b6b48 100644 --- a/images/comics_view_toolbar/selectAll.svg +++ b/images/comics_view_toolbar/selectAll.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setManga.svg b/images/comics_view_toolbar/setManga.svg index f9be7e9a..72c3e368 100644 --- a/images/comics_view_toolbar/setManga.svg +++ b/images/comics_view_toolbar/setManga.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setNormal.svg b/images/comics_view_toolbar/setNormal.svg index 7e8c385c..4c12dd77 100644 --- a/images/comics_view_toolbar/setNormal.svg +++ b/images/comics_view_toolbar/setNormal.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setReadButton.svg b/images/comics_view_toolbar/setReadButton.svg index 89f40057..e44d0cde 100644 --- a/images/comics_view_toolbar/setReadButton.svg +++ b/images/comics_view_toolbar/setReadButton.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setUnread.svg b/images/comics_view_toolbar/setUnread.svg index fbc97ea0..bba65778 100644 --- a/images/comics_view_toolbar/setUnread.svg +++ b/images/comics_view_toolbar/setUnread.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/showMarks.svg b/images/comics_view_toolbar/showMarks.svg index 63205d92..470e92be 100644 --- a/images/comics_view_toolbar/showMarks.svg +++ b/images/comics_view_toolbar/showMarks.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/showRecentIndicator.svg b/images/comics_view_toolbar/showRecentIndicator.svg index 5f12b064..0d82d6c9 100644 --- a/images/comics_view_toolbar/showRecentIndicator.svg +++ b/images/comics_view_toolbar/showRecentIndicator.svg @@ -1,11 +1,12 @@ - + + - + \ No newline at end of file diff --git a/images/comics_view_toolbar/show_comic_info.svg b/images/comics_view_toolbar/show_comic_info.svg index 3e0da8bc..22b596bd 100644 --- a/images/comics_view_toolbar/show_comic_info.svg +++ b/images/comics_view_toolbar/show_comic_info.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/small_size_grid_zoom.svg b/images/comics_view_toolbar/small_size_grid_zoom.svg index 44d20c85..eb4d48a7 100644 --- a/images/comics_view_toolbar/small_size_grid_zoom.svg +++ b/images/comics_view_toolbar/small_size_grid_zoom.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/trash.svg b/images/comics_view_toolbar/trash.svg index 4767dab7..f28dcd02 100644 --- a/images/comics_view_toolbar/trash.svg +++ b/images/comics_view_toolbar/trash.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/custom_dialog/custom_close_button.svg b/images/custom_dialog/custom_close_button.svg index 1a6ad742..7bb61f31 100644 --- a/images/custom_dialog/custom_close_button.svg +++ b/images/custom_dialog/custom_close_button.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/deleting_progress/icon.png b/images/deleting_progress/icon.png deleted file mode 100644 index 70774190..00000000 Binary files a/images/deleting_progress/icon.png and /dev/null differ diff --git a/images/deleting_progress/imgBottomLeft.png b/images/deleting_progress/imgBottomLeft.png deleted file mode 100644 index 9c2f77ec..00000000 Binary files a/images/deleting_progress/imgBottomLeft.png and /dev/null differ diff --git a/images/deleting_progress/imgBottomMiddle.png b/images/deleting_progress/imgBottomMiddle.png deleted file mode 100644 index da7fbc49..00000000 Binary files a/images/deleting_progress/imgBottomMiddle.png and /dev/null differ diff --git a/images/deleting_progress/imgBottomRight.png b/images/deleting_progress/imgBottomRight.png deleted file mode 100644 index c33e6aee..00000000 Binary files a/images/deleting_progress/imgBottomRight.png and /dev/null differ diff --git a/images/deleting_progress/imgLeftMiddle.png b/images/deleting_progress/imgLeftMiddle.png deleted file mode 100644 index 84cb9241..00000000 Binary files a/images/deleting_progress/imgLeftMiddle.png and /dev/null differ diff --git a/images/deleting_progress/imgRightMiddle.png b/images/deleting_progress/imgRightMiddle.png deleted file mode 100644 index f29c1b1e..00000000 Binary files a/images/deleting_progress/imgRightMiddle.png and /dev/null differ diff --git a/images/deleting_progress/imgTopLeft.png b/images/deleting_progress/imgTopLeft.png deleted file mode 100644 index ea44e354..00000000 Binary files a/images/deleting_progress/imgTopLeft.png and /dev/null differ diff --git a/images/deleting_progress/imgTopMiddle.png b/images/deleting_progress/imgTopMiddle.png deleted file mode 100644 index a4ad9904..00000000 Binary files a/images/deleting_progress/imgTopMiddle.png and /dev/null differ diff --git a/images/deleting_progress/imgTopRight.png b/images/deleting_progress/imgTopRight.png deleted file mode 100644 index c528653e..00000000 Binary files a/images/deleting_progress/imgTopRight.png and /dev/null differ diff --git a/images/edit.png b/images/edit.png deleted file mode 100644 index 7ac38c8c..00000000 Binary files a/images/edit.png and /dev/null differ diff --git a/images/empty_container/empty_current_readings.svg b/images/empty_container/empty_current_readings.svg new file mode 100644 index 00000000..ceaabeb5 --- /dev/null +++ b/images/empty_container/empty_current_readings.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_favorites.svg b/images/empty_container/empty_favorites.svg new file mode 100644 index 00000000..8ca30b6e --- /dev/null +++ b/images/empty_container/empty_favorites.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_folder.svg b/images/empty_container/empty_folder.svg new file mode 100644 index 00000000..39a5b9dd --- /dev/null +++ b/images/empty_container/empty_folder.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_label.svg b/images/empty_container/empty_label.svg new file mode 100644 index 00000000..3d5d6d00 --- /dev/null +++ b/images/empty_container/empty_label.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_reading_list.svg b/images/empty_container/empty_reading_list.svg new file mode 100644 index 00000000..9419898c --- /dev/null +++ b/images/empty_container/empty_reading_list.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/empty_current_readings.png b/images/empty_current_readings.png deleted file mode 100644 index 776fb0c3..00000000 Binary files a/images/empty_current_readings.png and /dev/null differ diff --git a/images/empty_favorites.png b/images/empty_favorites.png deleted file mode 100644 index c0fce602..00000000 Binary files a/images/empty_favorites.png and /dev/null differ diff --git a/images/empty_folder.png b/images/empty_folder.png deleted file mode 100644 index fa3b13cd..00000000 Binary files a/images/empty_folder.png and /dev/null differ diff --git a/images/empty_folder_osx.png b/images/empty_folder_osx.png deleted file mode 100644 index f33e65e0..00000000 Binary files a/images/empty_folder_osx.png and /dev/null differ diff --git a/images/empty_label.png b/images/empty_label.png deleted file mode 100644 index 4c085723..00000000 Binary files a/images/empty_label.png and /dev/null differ diff --git a/images/empty_reading_list.png b/images/empty_reading_list.png deleted file mode 100644 index 36669888..00000000 Binary files a/images/empty_reading_list.png and /dev/null differ diff --git a/images/empty_reading_list_osx.png b/images/empty_reading_list_osx.png deleted file mode 100644 index 59667e1f..00000000 Binary files a/images/empty_reading_list_osx.png and /dev/null differ diff --git a/images/empty_search.png b/images/empty_search.png deleted file mode 100644 index f012d8ec..00000000 Binary files a/images/empty_search.png and /dev/null differ diff --git a/images/empty_search_osx.png b/images/empty_search_osx.png deleted file mode 100644 index d9b8cee5..00000000 Binary files a/images/empty_search_osx.png and /dev/null differ diff --git a/images/exportComicsInfo.png b/images/exportComicsInfo.png deleted file mode 100644 index 5299eb71..00000000 Binary files a/images/exportComicsInfo.png and /dev/null differ diff --git a/images/exportLibrary.png b/images/exportLibrary.png deleted file mode 100644 index 67d23757..00000000 Binary files a/images/exportLibrary.png and /dev/null differ diff --git a/images/find_folder.png b/images/find_folder.png deleted file mode 100644 index f645dfe4..00000000 Binary files a/images/find_folder.png and /dev/null differ diff --git a/images/find_folder.svg b/images/find_folder.svg new file mode 100644 index 00000000..79714373 --- /dev/null +++ b/images/find_folder.svg @@ -0,0 +1 @@ + diff --git a/images/folder_finished_macosx.png b/images/folder_finished_macosx.png deleted file mode 100644 index e1dc09ec..00000000 Binary files a/images/folder_finished_macosx.png and /dev/null differ diff --git a/images/hiddenCovers.png b/images/hiddenCovers.png deleted file mode 100644 index 8689db16..00000000 Binary files a/images/hiddenCovers.png and /dev/null differ diff --git a/images/iconSearch.png b/images/iconSearch.png deleted file mode 100644 index 6a238061..00000000 Binary files a/images/iconSearch.png and /dev/null differ diff --git a/images/iconSearch@2x.png b/images/iconSearch@2x.png deleted file mode 100644 index 1393f10f..00000000 Binary files a/images/iconSearch@2x.png and /dev/null differ diff --git a/images/iconSearchNew.svg b/images/iconSearchNew.svg index e7fa3683..79714373 100644 --- a/images/iconSearchNew.svg +++ b/images/iconSearchNew.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/import/coversToggle.svg b/images/import/coversToggle.svg new file mode 100644 index 00000000..e7f4195b --- /dev/null +++ b/images/import/coversToggle.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/import/importBottomCoversDecoration.svg b/images/import/importBottomCoversDecoration.svg new file mode 100644 index 00000000..73fd3b74 --- /dev/null +++ b/images/import/importBottomCoversDecoration.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/images/import/importTopCoversDecoration.svg b/images/import/importTopCoversDecoration.svg new file mode 100644 index 00000000..b2ad35f3 --- /dev/null +++ b/images/import/importTopCoversDecoration.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/images/import/importingIcon.svg b/images/import/importingIcon.svg new file mode 100644 index 00000000..a79f3c28 --- /dev/null +++ b/images/import/importingIcon.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/import/updatingIcon.svg b/images/import/updatingIcon.svg new file mode 100644 index 00000000..2d82a53c --- /dev/null +++ b/images/import/updatingIcon.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/importBottomCoversDecoration.png b/images/importBottomCoversDecoration.png deleted file mode 100644 index 7508ce17..00000000 Binary files a/images/importBottomCoversDecoration.png and /dev/null differ diff --git a/images/importComicsInfo.png b/images/importComicsInfo.png deleted file mode 100644 index 6830bc07..00000000 Binary files a/images/importComicsInfo.png and /dev/null differ diff --git a/images/importLibrary.png b/images/importLibrary.png deleted file mode 100644 index fa9366bf..00000000 Binary files a/images/importLibrary.png and /dev/null differ diff --git a/images/importTopCoversDecoration.png b/images/importTopCoversDecoration.png deleted file mode 100644 index 0343fdb4..00000000 Binary files a/images/importTopCoversDecoration.png and /dev/null differ diff --git a/images/importingIcon.png b/images/importingIcon.png deleted file mode 100644 index a53e768a..00000000 Binary files a/images/importingIcon.png and /dev/null differ diff --git a/images/library_dialogs/edit.svg b/images/library_dialogs/edit.svg new file mode 100644 index 00000000..37f087e9 --- /dev/null +++ b/images/library_dialogs/edit.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/exportComicsInfo.svg b/images/library_dialogs/exportComicsInfo.svg new file mode 100644 index 00000000..9117d72d --- /dev/null +++ b/images/library_dialogs/exportComicsInfo.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/exportLibrary.svg b/images/library_dialogs/exportLibrary.svg new file mode 100644 index 00000000..b834319c --- /dev/null +++ b/images/library_dialogs/exportLibrary.svg @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/importComicsInfo.svg b/images/library_dialogs/importComicsInfo.svg new file mode 100644 index 00000000..71a8b717 --- /dev/null +++ b/images/library_dialogs/importComicsInfo.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/importLibrary.svg b/images/library_dialogs/importLibrary.svg new file mode 100644 index 00000000..ec5f096b --- /dev/null +++ b/images/library_dialogs/importLibrary.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/new.svg b/images/library_dialogs/new.svg new file mode 100644 index 00000000..a755c580 --- /dev/null +++ b/images/library_dialogs/new.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/openLibrary.svg b/images/library_dialogs/openLibrary.svg new file mode 100644 index 00000000..1a64f11e --- /dev/null +++ b/images/library_dialogs/openLibrary.svg @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_0.svg b/images/lists/default_0.svg index 1b290d53..75babfca 100644 --- a/images/lists/default_0.svg +++ b/images/lists/default_0.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_1.svg b/images/lists/default_1.svg index 837ec29c..c4ddc284 100644 --- a/images/lists/default_1.svg +++ b/images/lists/default_1.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_2.svg b/images/lists/default_2.svg index 88ab6868..eea9ed7e 100644 --- a/images/lists/default_2.svg +++ b/images/lists/default_2.svg @@ -1,19 +1,28 @@ - + + - - + + - - + + \ No newline at end of file diff --git a/images/lists/label_blue.svg b/images/lists/label_blue.svg deleted file mode 100644 index d735f3bc..00000000 --- a/images/lists/label_blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_cyan.svg b/images/lists/label_cyan.svg deleted file mode 100644 index e028467b..00000000 --- a/images/lists/label_cyan.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_dark.svg b/images/lists/label_dark.svg deleted file mode 100644 index c25fb521..00000000 --- a/images/lists/label_dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_green.svg b/images/lists/label_green.svg deleted file mode 100644 index 7cbe3942..00000000 --- a/images/lists/label_green.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_light.svg b/images/lists/label_light.svg deleted file mode 100644 index fea8b87f..00000000 --- a/images/lists/label_light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_orange.svg b/images/lists/label_orange.svg deleted file mode 100644 index a2838c64..00000000 --- a/images/lists/label_orange.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_pink.svg b/images/lists/label_pink.svg deleted file mode 100644 index c957673d..00000000 --- a/images/lists/label_pink.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_purple.svg b/images/lists/label_purple.svg deleted file mode 100644 index 85dd2a23..00000000 --- a/images/lists/label_purple.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_red.svg b/images/lists/label_red.svg deleted file mode 100644 index 8ef4a8a8..00000000 --- a/images/lists/label_red.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_template.svg b/images/lists/label_template.svg new file mode 100644 index 00000000..5b13b18f --- /dev/null +++ b/images/lists/label_template.svg @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/lists/label_violet.svg b/images/lists/label_violet.svg deleted file mode 100644 index 3400101f..00000000 --- a/images/lists/label_violet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_white.svg b/images/lists/label_white.svg deleted file mode 100644 index dfe2ffc8..00000000 --- a/images/lists/label_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_yellow.svg b/images/lists/label_yellow.svg deleted file mode 100644 index 3d2f0da1..00000000 --- a/images/lists/label_yellow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/list.svg b/images/lists/list.svg index aabef84b..a24c621b 100644 --- a/images/lists/list.svg +++ b/images/lists/list.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/lists/original colors.md b/images/lists/original colors.md new file mode 100644 index 00000000..7e5859ed --- /dev/null +++ b/images/lists/original colors.md @@ -0,0 +1,24 @@ + +shadow in all icons is represented with #0ff -> original color was #000000 + +all labels have shadow and the icons should be generated from `label_template.svg`, this is the list of actual colors needed per label +label_blue.svg -> #82c7ff +label_cyan.svg -> #a0fddb +label_dark.svg -> #b7b7b7 +label_green.svg -> #ade738 +label_light.svg -> #cbcbcb +label_orange.svg -> #f5c240 +label_pink.svg -> #fd9cda +label_purple.svg -> #d692fc +label_red.svg -> #f67a7b +label_violet.svg -> #8f95ff +label_white.svg -> #fcfcfc +label_yellow.svg -> #f2e446 + +other icons + +default_2.svg -> #f0f -> #ffcc00 #0ff -> #000000 #ff0 -> #33000000 +default_1.svg -> #f0f -> #e15055 #0ff -> #000000 +default_0.svg -> #f0f -> #e7e7e7 #0ff -> #000000 + +list.svg -> #f0f -> #e7e7e7 #0ff -> #000000 #ff0 -> #464646 \ No newline at end of file diff --git a/images/main_toolbar/back.svg b/images/main_toolbar/back.svg index 08a5777f..f6a4cc94 100644 --- a/images/main_toolbar/back.svg +++ b/images/main_toolbar/back.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/back_disabled.png b/images/main_toolbar/back_disabled.png deleted file mode 100644 index 9e09b69a..00000000 Binary files a/images/main_toolbar/back_disabled.png and /dev/null differ diff --git a/images/main_toolbar/flow.svg b/images/main_toolbar/flow.svg index afde5c5b..c84719fc 100644 --- a/images/main_toolbar/flow.svg +++ b/images/main_toolbar/flow.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/forward.svg b/images/main_toolbar/forward.svg index 50a5f21a..2a786f99 100644 --- a/images/main_toolbar/forward.svg +++ b/images/main_toolbar/forward.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/forward_disabled.png b/images/main_toolbar/forward_disabled.png deleted file mode 100644 index 1e4b070a..00000000 Binary files a/images/main_toolbar/forward_disabled.png and /dev/null differ diff --git a/images/main_toolbar/fullscreen.svg b/images/main_toolbar/fullscreen.svg index f0bf9e9c..b7ac674c 100644 --- a/images/main_toolbar/fullscreen.svg +++ b/images/main_toolbar/fullscreen.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/grid.svg b/images/main_toolbar/grid.svg index 6c6d534d..4787059c 100644 --- a/images/main_toolbar/grid.svg +++ b/images/main_toolbar/grid.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/help.svg b/images/main_toolbar/help.svg index f0d09053..ce5fc309 100644 --- a/images/main_toolbar/help.svg +++ b/images/main_toolbar/help.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/info.svg b/images/main_toolbar/info.svg index 4b7510e0..a8e8bb54 100644 --- a/images/main_toolbar/info.svg +++ b/images/main_toolbar/info.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/server.svg b/images/main_toolbar/server.svg index 0bd8cfeb..57c4f2d7 100644 --- a/images/main_toolbar/server.svg +++ b/images/main_toolbar/server.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/settings.svg b/images/main_toolbar/settings.svg index 4f01a4d0..d97d6f54 100644 --- a/images/main_toolbar/settings.svg +++ b/images/main_toolbar/settings.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/editIcon.svg b/images/menus_icons/editIcon.svg index ef898daa..0404a54e 100644 --- a/images/menus_icons/editIcon.svg +++ b/images/menus_icons/editIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/exportComicsInfoIcon.svg b/images/menus_icons/exportComicsInfoIcon.svg index 2f2d32a6..ef26e40c 100644 --- a/images/menus_icons/exportComicsInfoIcon.svg +++ b/images/menus_icons/exportComicsInfoIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/exportLibraryIcon.svg b/images/menus_icons/exportLibraryIcon.svg index e36a771c..677f74d4 100644 --- a/images/menus_icons/exportLibraryIcon.svg +++ b/images/menus_icons/exportLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/importComicsInfoIcon.svg b/images/menus_icons/importComicsInfoIcon.svg index fc2c0dc8..c5eb625c 100644 --- a/images/menus_icons/importComicsInfoIcon.svg +++ b/images/menus_icons/importComicsInfoIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/importLibraryIcon.svg b/images/menus_icons/importLibraryIcon.svg index 752ba386..b897d65a 100644 --- a/images/menus_icons/importLibraryIcon.svg +++ b/images/menus_icons/importLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/open_containing_folder.svg b/images/menus_icons/open_containing_folder.svg index 3080991e..7258b0d2 100644 --- a/images/menus_icons/open_containing_folder.svg +++ b/images/menus_icons/open_containing_folder.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/removeLibraryIcon.svg b/images/menus_icons/removeLibraryIcon.svg index 51141dd4..6dfb053d 100644 --- a/images/menus_icons/removeLibraryIcon.svg +++ b/images/menus_icons/removeLibraryIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/updateLibraryIcon.svg b/images/menus_icons/updateLibraryIcon.svg index 016c9622..f99b0e60 100644 --- a/images/menus_icons/updateLibraryIcon.svg +++ b/images/menus_icons/updateLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/update_current_folder.svg b/images/menus_icons/update_current_folder.svg index 016c9622..f99b0e60 100644 --- a/images/menus_icons/update_current_folder.svg +++ b/images/menus_icons/update_current_folder.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/loadCustomCover.svg b/images/metadata_dialog/loadCustomCover.svg similarity index 100% rename from images/loadCustomCover.svg rename to images/metadata_dialog/loadCustomCover.svg diff --git a/images/metadata_dialog/nextCoverPage.svg b/images/metadata_dialog/nextCoverPage.svg new file mode 100644 index 00000000..73be5c01 --- /dev/null +++ b/images/metadata_dialog/nextCoverPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/metadata_dialog/previousCoverPage.svg b/images/metadata_dialog/previousCoverPage.svg new file mode 100644 index 00000000..b598c43f --- /dev/null +++ b/images/metadata_dialog/previousCoverPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/resetCover.svg b/images/metadata_dialog/resetCover.svg similarity index 100% rename from images/resetCover.svg rename to images/metadata_dialog/resetCover.svg diff --git a/images/new.png b/images/new.png deleted file mode 100644 index 7ca94411..00000000 Binary files a/images/new.png and /dev/null differ diff --git a/images/nextCoverPage.png b/images/nextCoverPage.png deleted file mode 100644 index 67e06399..00000000 Binary files a/images/nextCoverPage.png and /dev/null differ diff --git a/images/noLibrariesIcon.png b/images/noLibrariesIcon.png deleted file mode 100644 index cf11b95d..00000000 Binary files a/images/noLibrariesIcon.png and /dev/null differ diff --git a/images/noLibrariesIcon.svg b/images/noLibrariesIcon.svg new file mode 100644 index 00000000..99c432a0 --- /dev/null +++ b/images/noLibrariesIcon.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/openLibrary.png b/images/openLibrary.png deleted file mode 100644 index 320e6882..00000000 Binary files a/images/openLibrary.png and /dev/null differ diff --git a/images/previousCoverPage.png b/images/previousCoverPage.png deleted file mode 100644 index 5a99a7e9..00000000 Binary files a/images/previousCoverPage.png and /dev/null differ diff --git a/images/search_result.svg b/images/search_result.svg new file mode 100644 index 00000000..dd1cf23b --- /dev/null +++ b/images/search_result.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/searching_icon.png b/images/searching_icon.png deleted file mode 100644 index 95355bfc..00000000 Binary files a/images/searching_icon.png and /dev/null differ diff --git a/images/serverConfigBackground.png b/images/serverConfigBackground.png deleted file mode 100644 index c89bf73b..00000000 Binary files a/images/serverConfigBackground.png and /dev/null differ diff --git a/images/serverConfigBackground.svg b/images/serverConfigBackground.svg new file mode 100644 index 00000000..c15d8d61 --- /dev/null +++ b/images/serverConfigBackground.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/accept_shortcut.svg b/images/shortcuts/accept_shortcut.svg similarity index 100% rename from images/accept_shortcut.svg rename to images/shortcuts/accept_shortcut.svg diff --git a/images/clear_shortcut.svg b/images/shortcuts/clear_shortcut.svg similarity index 100% rename from images/clear_shortcut.svg rename to images/shortcuts/clear_shortcut.svg diff --git a/images/shortcuts/shortcuts_group_comics.svg b/images/shortcuts/shortcuts_group_comics.svg index 66cc3bd6..d7fadd8a 100644 --- a/images/shortcuts/shortcuts_group_comics.svg +++ b/images/shortcuts/shortcuts_group_comics.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_folders.svg b/images/shortcuts/shortcuts_group_folders.svg index d66245ab..8b650c1c 100644 --- a/images/shortcuts/shortcuts_group_folders.svg +++ b/images/shortcuts/shortcuts_group_folders.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_general.svg b/images/shortcuts/shortcuts_group_general.svg index eb25e4de..76247179 100644 --- a/images/shortcuts/shortcuts_group_general.svg +++ b/images/shortcuts/shortcuts_group_general.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_libraries.svg b/images/shortcuts/shortcuts_group_libraries.svg index 250963dc..59b168dc 100644 --- a/images/shortcuts/shortcuts_group_libraries.svg +++ b/images/shortcuts/shortcuts_group_libraries.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_mglass.svg b/images/shortcuts/shortcuts_group_mglass.svg index 64c1e780..38d2ae65 100644 --- a/images/shortcuts/shortcuts_group_mglass.svg +++ b/images/shortcuts/shortcuts_group_mglass.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_page.svg b/images/shortcuts/shortcuts_group_page.svg index 950d2890..5ce4138e 100644 --- a/images/shortcuts/shortcuts_group_page.svg +++ b/images/shortcuts/shortcuts_group_page.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_reading.svg b/images/shortcuts/shortcuts_group_reading.svg index eccd1f81..9f8ff719 100644 --- a/images/shortcuts/shortcuts_group_reading.svg +++ b/images/shortcuts/shortcuts_group_reading.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_visualization.svg b/images/shortcuts/shortcuts_group_visualization.svg index ee2b6c0b..2924e94c 100644 --- a/images/shortcuts/shortcuts_group_visualization.svg +++ b/images/shortcuts/shortcuts_group_visualization.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shownCovers.png b/images/shownCovers.png deleted file mode 100644 index 089baaf0..00000000 Binary files a/images/shownCovers.png and /dev/null differ diff --git a/images/sidebar/addLabelIcon.svg b/images/sidebar/addLabelIcon.svg index 732fb362..bd2f8ede 100644 --- a/images/sidebar/addLabelIcon.svg +++ b/images/sidebar/addLabelIcon.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/addLabelIcon_osx.png b/images/sidebar/addLabelIcon_osx.png deleted file mode 100755 index 3f8a8a51..00000000 Binary files a/images/sidebar/addLabelIcon_osx.png and /dev/null differ diff --git a/images/sidebar/addLabelIcon_osx@2x.png b/images/sidebar/addLabelIcon_osx@2x.png deleted file mode 100755 index e0e1fea8..00000000 Binary files a/images/sidebar/addLabelIcon_osx@2x.png and /dev/null differ diff --git a/images/sidebar/addNew_sidebar.svg b/images/sidebar/addNew_sidebar.svg index 4c8b6e42..585a1cbf 100644 --- a/images/sidebar/addNew_sidebar.svg +++ b/images/sidebar/addNew_sidebar.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/addNew_sidebar_osx.png b/images/sidebar/addNew_sidebar_osx.png deleted file mode 100755 index aa101d8b..00000000 Binary files a/images/sidebar/addNew_sidebar_osx.png and /dev/null differ diff --git a/images/sidebar/addNew_sidebar_osx@2x.png b/images/sidebar/addNew_sidebar_osx@2x.png deleted file mode 100755 index 30c05b8a..00000000 Binary files a/images/sidebar/addNew_sidebar_osx@2x.png and /dev/null differ diff --git a/images/sidebar/branch-closed.svg b/images/sidebar/branch-closed.svg index ea226963..ba3cabfb 100644 --- a/images/sidebar/branch-closed.svg +++ b/images/sidebar/branch-closed.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + diff --git a/images/sidebar/branch-open.svg b/images/sidebar/branch-open.svg index c60277d1..e07abfe7 100644 --- a/images/sidebar/branch-open.svg +++ b/images/sidebar/branch-open.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + diff --git a/images/sidebar/colapse.svg b/images/sidebar/colapse.svg index 3a4f09fe..fcb89d1c 100644 --- a/images/sidebar/colapse.svg +++ b/images/sidebar/colapse.svg @@ -1 +1,17 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/colapse_osx.png b/images/sidebar/colapse_osx.png deleted file mode 100755 index b5b33008..00000000 Binary files a/images/sidebar/colapse_osx.png and /dev/null differ diff --git a/images/sidebar/colapse_osx@2x.png b/images/sidebar/colapse_osx@2x.png deleted file mode 100755 index 9c746a47..00000000 Binary files a/images/sidebar/colapse_osx@2x.png and /dev/null differ diff --git a/images/sidebar/delete_sidebar.svg b/images/sidebar/delete_sidebar.svg index bc7f2fb7..66c75d57 100644 --- a/images/sidebar/delete_sidebar.svg +++ b/images/sidebar/delete_sidebar.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/sidebar/delete_sidebar_osx.png b/images/sidebar/delete_sidebar_osx.png deleted file mode 100755 index 61bf6f9e..00000000 Binary files a/images/sidebar/delete_sidebar_osx.png and /dev/null differ diff --git a/images/sidebar/delete_sidebar_osx@2x.png b/images/sidebar/delete_sidebar_osx@2x.png deleted file mode 100755 index b15e34f6..00000000 Binary files a/images/sidebar/delete_sidebar_osx@2x.png and /dev/null differ diff --git a/images/sidebar/expand.svg b/images/sidebar/expand.svg index 4918efd7..22ee714f 100644 --- a/images/sidebar/expand.svg +++ b/images/sidebar/expand.svg @@ -1 +1,17 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/expand_osx.png b/images/sidebar/expand_osx.png deleted file mode 100755 index 754d92c1..00000000 Binary files a/images/sidebar/expand_osx.png and /dev/null differ diff --git a/images/sidebar/expand_osx@2x.png b/images/sidebar/expand_osx@2x.png deleted file mode 100755 index 7bb3316e..00000000 Binary files a/images/sidebar/expand_osx@2x.png and /dev/null differ diff --git a/images/sidebar/folder.svg b/images/sidebar/folder.svg index acd1186b..2cce9a56 100644 --- a/images/sidebar/folder.svg +++ b/images/sidebar/folder.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/folder_finished.svg b/images/sidebar/folder_finished.svg index 7a437f00..7d3aa461 100644 --- a/images/sidebar/folder_finished.svg +++ b/images/sidebar/folder_finished.svg @@ -1 +1,24 @@ - \ No newline at end of file + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/folder_read_overlay.svg b/images/sidebar/folder_read_overlay.svg new file mode 100644 index 00000000..3b8628e5 --- /dev/null +++ b/images/sidebar/folder_read_overlay.svg @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIcon.svg b/images/sidebar/libraryIcon.svg index b9d1deb3..fc7089d4 100644 --- a/images/sidebar/libraryIcon.svg +++ b/images/sidebar/libraryIcon.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIconSelected.svg b/images/sidebar/libraryIconSelected.svg index 032e708e..1303e578 100644 --- a/images/sidebar/libraryIconSelected.svg +++ b/images/sidebar/libraryIconSelected.svg @@ -1 +1,13 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIcon_osx.png b/images/sidebar/libraryIcon_osx.png deleted file mode 100644 index ce99dde6..00000000 Binary files a/images/sidebar/libraryIcon_osx.png and /dev/null differ diff --git a/images/sidebar/libraryOptions.svg b/images/sidebar/libraryOptions.svg index f2fddde2..2bdef9c7 100644 --- a/images/sidebar/libraryOptions.svg +++ b/images/sidebar/libraryOptions.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + diff --git a/images/sidebar/newLibraryIcon.svg b/images/sidebar/newLibraryIcon.svg index 4c8b6e42..585a1cbf 100644 --- a/images/sidebar/newLibraryIcon.svg +++ b/images/sidebar/newLibraryIcon.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/newLibraryIcon_osx.png b/images/sidebar/newLibraryIcon_osx.png deleted file mode 100755 index 7c4a5aea..00000000 Binary files a/images/sidebar/newLibraryIcon_osx.png and /dev/null differ diff --git a/images/sidebar/newLibraryIcon_osx@2x.png b/images/sidebar/newLibraryIcon_osx@2x.png deleted file mode 100755 index 30c05b8a..00000000 Binary files a/images/sidebar/newLibraryIcon_osx@2x.png and /dev/null differ diff --git a/images/sidebar/openLibraryIcon.svg b/images/sidebar/openLibraryIcon.svg index 3e49f2c1..d266567e 100644 --- a/images/sidebar/openLibraryIcon.svg +++ b/images/sidebar/openLibraryIcon.svg @@ -1 +1,37 @@ - \ No newline at end of file + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/openLibraryIcon_osx.png b/images/sidebar/openLibraryIcon_osx.png deleted file mode 100755 index 0a61bd9a..00000000 Binary files a/images/sidebar/openLibraryIcon_osx.png and /dev/null differ diff --git a/images/sidebar/openLibraryIcon_osx@2x.png b/images/sidebar/openLibraryIcon_osx@2x.png deleted file mode 100755 index 0875b44d..00000000 Binary files a/images/sidebar/openLibraryIcon_osx@2x.png and /dev/null differ diff --git a/images/sidebar/renameListIcon.svg b/images/sidebar/renameListIcon.svg index dded4036..93b8a966 100644 --- a/images/sidebar/renameListIcon.svg +++ b/images/sidebar/renameListIcon.svg @@ -1 +1,25 @@ - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/renameListIcon_osx.png b/images/sidebar/renameListIcon_osx.png deleted file mode 100755 index 3ed190fd..00000000 Binary files a/images/sidebar/renameListIcon_osx.png and /dev/null differ diff --git a/images/sidebar/renameListIcon_osx@2x.png b/images/sidebar/renameListIcon_osx@2x.png deleted file mode 100755 index 9a6a25c9..00000000 Binary files a/images/sidebar/renameListIcon_osx@2x.png and /dev/null differ diff --git a/images/sidebar/setRoot.svg b/images/sidebar/setRoot.svg index 49f3e6e9..ddf029f3 100644 --- a/images/sidebar/setRoot.svg +++ b/images/sidebar/setRoot.svg @@ -1 +1,38 @@ - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/setRoot_osx.png b/images/sidebar/setRoot_osx.png deleted file mode 100755 index a2da070d..00000000 Binary files a/images/sidebar/setRoot_osx.png and /dev/null differ diff --git a/images/sidebar/setRoot_osx@2x.png b/images/sidebar/setRoot_osx@2x.png deleted file mode 100755 index 5dfcdd99..00000000 Binary files a/images/sidebar/setRoot_osx@2x.png and /dev/null differ diff --git a/images/social_dialog/close.png b/images/social_dialog/close.png deleted file mode 100644 index 28e7c24f..00000000 Binary files a/images/social_dialog/close.png and /dev/null differ diff --git a/images/social_dialog/facebook.png b/images/social_dialog/facebook.png deleted file mode 100644 index 3d7aa8de..00000000 Binary files a/images/social_dialog/facebook.png and /dev/null differ diff --git a/images/social_dialog/google+.png b/images/social_dialog/google+.png deleted file mode 100644 index 1d0bc355..00000000 Binary files a/images/social_dialog/google+.png and /dev/null differ diff --git a/images/social_dialog/icon.png b/images/social_dialog/icon.png deleted file mode 100644 index a15c47f3..00000000 Binary files a/images/social_dialog/icon.png and /dev/null differ diff --git a/images/social_dialog/separator.png b/images/social_dialog/separator.png deleted file mode 100644 index 4a3b73c4..00000000 Binary files a/images/social_dialog/separator.png and /dev/null differ diff --git a/images/social_dialog/shadow.png b/images/social_dialog/shadow.png deleted file mode 100644 index 49b5d588..00000000 Binary files a/images/social_dialog/shadow.png and /dev/null differ diff --git a/images/social_dialog/twitter.png b/images/social_dialog/twitter.png deleted file mode 100644 index 4a9df502..00000000 Binary files a/images/social_dialog/twitter.png and /dev/null differ diff --git a/images/updatingIcon.png b/images/updatingIcon.png deleted file mode 100644 index bb4f6afb..00000000 Binary files a/images/updatingIcon.png and /dev/null differ diff --git a/images/whats_new/whatsnew_header.svg b/images/whats_new/whatsnew_header.svg index 0cc109c3..2a03d852 100644 --- a/images/whats_new/whatsnew_header.svg +++ b/images/whats_new/whatsnew_header.svg @@ -1,28 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shortcuts_management/actions_groups_model.cpp b/shortcuts_management/actions_groups_model.cpp index d58dbbd0..6656eccc 100644 --- a/shortcuts_management/actions_groups_model.cpp +++ b/shortcuts_management/actions_groups_model.cpp @@ -62,6 +62,15 @@ QList ActionsGroupsModel::getActions(const QModelIndex &mi) return QList(); } +void ActionsGroupsModel::updateGroupIcon(int row, const QIcon &icon) +{ + if (row >= 0 && row < groups.size()) { + groups[row].setIcon(icon); + QModelIndex idx = index(row, 0); + emit dataChanged(idx, idx, { Qt::DecorationRole }); + } +} + //------------------------------------------------------------------- ActionsGroup::ActionsGroup(const QString &name, const QIcon &icon, QList &actions) @@ -74,6 +83,11 @@ QString ActionsGroup::getName() const return name; } +void ActionsGroup::setIcon(const QIcon &newIcon) +{ + icon = newIcon; +} + QIcon ActionsGroup::getIcon() const { return icon; diff --git a/shortcuts_management/actions_groups_model.h b/shortcuts_management/actions_groups_model.h index 82b4c335..31d21f57 100644 --- a/shortcuts_management/actions_groups_model.h +++ b/shortcuts_management/actions_groups_model.h @@ -13,6 +13,7 @@ public: QString getName() const; QIcon getIcon() const; QList getActions() const; + void setIcon(const QIcon &icon); protected: QString name; @@ -34,6 +35,7 @@ public: void addActionsGroup(const ActionsGroup &group); QList getActions(const QModelIndex &mi); + void updateGroupIcon(int row, const QIcon &icon); signals: public slots: diff --git a/shortcuts_management/edit_shortcut_item_delegate.cpp b/shortcuts_management/edit_shortcut_item_delegate.cpp index ca93e88d..90a1b0af 100644 --- a/shortcuts_management/edit_shortcut_item_delegate.cpp +++ b/shortcuts_management/edit_shortcut_item_delegate.cpp @@ -63,12 +63,12 @@ KeySequenceLineEdit::KeySequenceLineEdit(QWidget *parent) acceptButton = new QToolButton(this); QString buttonsStyle = "QToolButton { border: none; padding: 0px; }"; - clearButton->setIcon(QIcon(":/images/clear_shortcut.svg")); + clearButton->setIcon(QIcon(":/images/shortcuts/clear_shortcut.svg")); clearButton->setIconSize(QSize(15, 15)); clearButton->setCursor(Qt::ArrowCursor); clearButton->setStyleSheet(buttonsStyle); - acceptButton->setIcon(QIcon(":/images/accept_shortcut.svg")); + acceptButton->setIcon(QIcon(":/images/shortcuts/accept_shortcut.svg")); acceptButton->setIconSize(QSize(15, 15)); acceptButton->setCursor(Qt::ArrowCursor); acceptButton->setStyleSheet(buttonsStyle); diff --git a/shortcuts_management/edit_shortcuts_dialog.cpp b/shortcuts_management/edit_shortcuts_dialog.cpp index 0f9da75f..8face33d 100644 --- a/shortcuts_management/edit_shortcuts_dialog.cpp +++ b/shortcuts_management/edit_shortcuts_dialog.cpp @@ -71,6 +71,32 @@ EditShortcutsDialog::EditShortcutsDialog(QWidget *parent) setWindowTitle(tr("Shortcuts settings")); setModal(true); + + initTheme(this); +} + +void EditShortcutsDialog::applyTheme(const Theme &theme) +{ + updateGroupIcons(theme); +} + +void EditShortcutsDialog::updateGroupIcons(const Theme &theme) +{ + // Update icons for all groups based on the mapping + for (int i = 0; i < groupsModel->rowCount(); ++i) { + QModelIndex idx = groupsModel->index(i, 0); + QString groupName = groupsModel->data(idx, Qt::DisplayRole).toString(); + + if (groupIconMapping.contains(groupName)) { + QIcon newIcon = groupIconMapping[groupName](theme); + groupsModel->updateGroupIcon(i, newIcon); + } + } +} + +void EditShortcutsDialog::setGroupIconMapping(const QMap> &mapping) +{ + groupIconMapping = mapping; } void EditShortcutsDialog::addActionsGroup(const QString &name, const QIcon &ico, QList &group) diff --git a/shortcuts_management/edit_shortcuts_dialog.h b/shortcuts_management/edit_shortcuts_dialog.h index 2e51b76f..77a8be2b 100644 --- a/shortcuts_management/edit_shortcuts_dialog.h +++ b/shortcuts_management/edit_shortcuts_dialog.h @@ -4,18 +4,21 @@ #include #include +#include "themable.h" + class QListView; class QTableView; class ActionsGroupsModel; class ActionsShortcutsModel; -class EditShortcutsDialog : public QDialog +class EditShortcutsDialog : public QDialog, protected Themable { Q_OBJECT public: explicit EditShortcutsDialog(QWidget *parent = 0); void addActionsGroup(const QString &name, const QIcon &ico, QList &group); + void setGroupIconMapping(const QMap> &mapping); signals: public slots: @@ -24,9 +27,14 @@ public slots: void processConflict(const QString &shortcutInConflict); protected: + void applyTheme(const Theme &theme) override; + void updateGroupIcons(const Theme &theme); + QListView *actionsGroupsListView; QTableView *actionsTableView; ActionsGroupsModel *groupsModel; + + QMap> groupIconMapping; ActionsShortcutsModel *actionsModel; };