mirror of
https://github.com/YACReader/yacreader
synced 2025-05-28 03:10:27 -04:00
commit
6cc92a260c
1
.gitignore
vendored
1
.gitignore
vendored
@ -45,6 +45,7 @@ Makefile*
|
||||
*.xcworkspace*
|
||||
*xcshareddata*
|
||||
*.swp
|
||||
*.qm
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
|
22
CHANGELOG.md
22
CHANGELOG.md
@ -2,6 +2,28 @@
|
||||
|
||||
Version counting is based on semantic versioning (Major.Feature.Patch)
|
||||
|
||||
## 9.10
|
||||
|
||||
### YACReader
|
||||
* Fixed color selection dialog appearing as a subwindow in macos.
|
||||
* Better support for HDPI screens (SVG icons).
|
||||
|
||||
### YACReaderLibrary
|
||||
* Update QtWebApp webserver to v1.8.6
|
||||
* New folder content view that replaces the old `subfolders in this folder` view shown when folders don't have direct comics.
|
||||
* Fixed going forward in history navigation.
|
||||
* Continue Reading view that it is shown for the root folder.
|
||||
* UI gets updated when YACReaderLibrary gets updates from YACReader or YACReader for iOS.
|
||||
* Linux: Add fallback for dynamically loading libqrencode on distros that don't provide unversioned library symlinks
|
||||
* Fixed selected folder restoration after folder updates.
|
||||
* Better support for HDPI screens (SVG icons).
|
||||
* Add option to delete metadata from comics.
|
||||
* Importing ComicInfo.XML is now optional and disabled by default, you can change the behavior in Settings -> General.
|
||||
* Add option to scan XML metadata from all the comics in a folder.
|
||||
|
||||
### Server
|
||||
* Add webui status page (reachable by navigating to server::port/webui)
|
||||
|
||||
## 9.9.2
|
||||
|
||||
### General
|
||||
|
17
README.md
17
README.md
@ -21,6 +21,8 @@ This software has been developed by Luis Ángel San Martín Rodríguez
|
||||
### Official releases:
|
||||
[https://github.com/YACReader/yacreader/releases](https://github.com/YACReader/yacreader/releases)
|
||||
|
||||
[<img src="https://flathub.org/assets/badges/flathub-badge-en.png" width="100"/>](https://flathub.org/apps/details/com.yacreader.YACReader)
|
||||
|
||||
### As a package:
|
||||
|
||||
[](https://repology.org/metapackage/yacreader)
|
||||
@ -47,20 +49,20 @@ If you need help or have any suggestion, please, send me an e-mail.
|
||||
## Contributing
|
||||
If you are interested in contributing to the project the first step should be to contact me so we can plan together the best approach, you can send an e-mail or just open an issue in this repo. For small bug fixes it is usually ok to open a PR directly.
|
||||
|
||||
Contributions are not restricted to code, you can help the project by bringing new UI/UX ideas, designing new assets, writing manuals or tutorials, translating the apps, etc. If you are interested in DevOps, YACReader uses Azure Pipelines for CI/CD, any improvements in that area are welcome. Testing pre-releases is also really appreciated.
|
||||
Contributions are not restricted to coding; you can help the project by bringing new UI/UX ideas, designing new assets, writing manuals or tutorials, translating the apps, etc. If you are interested in DevOps, YACReader uses Azure Pipelines for CI/CD, any improvements in that area are welcome. Testing pre-releases is also really appreciated.
|
||||
|
||||
#### Dev Setup
|
||||
YACReader is developed in *c++/Qt*, so the first thing you need to do is to install a *C++* compiler or environment that supports at least *C++17* and *Qt*. In *Windows* I use *Visual Studio Community Edition 2019* as build system and in *macos* I use Xcode, but I do all the coding using *QtCreator*. The project is adding support to *Qt6* and it alreaady compiles under it but it is not ready to ship, so you need to make sure that everything works in both *Qt5* and *Qt6*, you only need to install *Qt5* for now and *CI* will check that everything builds with *Qt6*.
|
||||
YACReader is developed in *c++/Qt*, so the first thing you need to do is to install a *C++* compiler or environment that supports at least *C++17* and *Qt*. In *Windows* I use *Visual Studio Community Edition 2019* as build system and in *macos* I use Xcode, but I do all the coding using *QtCreator*. The project is adding support to *Qt6* and it already compiles under it but it is not ready to ship, so you need to make sure that everything works in both *Qt5* and *Qt6*, you only need to install *Qt5* for now and *CI* will check that everything builds with *Qt6*.
|
||||
|
||||
The repo includes binaries for the dependencies needed for *Windows* (MSVC compiler) and *macos* (clang) but you need to configure *7zip/p7zip* dependency manually, please take a look at *compressed_archive/README_7zip.txt*.
|
||||
|
||||
##### Running and debuging
|
||||
YACReader needs to find its dependencies at runtime, make sure that *Qt* binaries are in your *PATH* and the third party binaries are next to the executable. The best way to make sure you have all the thirdparty binaries in place is to check YACReader installation and copying the binaries in your output folder.
|
||||
##### Running and debugging
|
||||
YACReader needs to find its dependencies at runtime, make sure that *Qt* binaries are in your *PATH* and the third-party binaries are next to the executable. The best way to make sure you have all the third-party binaries in place is to check YACReader installation and copy the binaries in your output folder.
|
||||
|
||||
If you have the time and the energy, please open a PR with a script that automatizes any of these manual proceses.
|
||||
If you have the time and the energy, please open a PR with a script that automatizes any of these manual processes.
|
||||
|
||||
#### Code Format
|
||||
YACReader uses `clang-format` to ensure a common style and avoid deviances from it. CI checks this and will fail if the correct format is not used. `clang-format` needs to be called recursively in all the folders because some of them have the own `.clang-format` file, mainly to exclude changing the format in third-party libraries which are included in the source code. I recommend to configure your development tools to use `clang-format`, you can try to use it manually, but please, do it always before committing changes. I recommend using QtCreator configured properly, you can find a tutorial [here]( https://www.vikingsoftware.com/using-clang-format-with-qtcreator/).
|
||||
YACReader uses `clang-format` to ensure a common style and avoid deviances from it. CI checks this and will fail if the correct format is not used. `clang-format` needs to be called recursively in all the folders because some of them have their own `.clang-format` file, mainly to exclude changing the format in third-party libraries which are included in the source code. I recommend configuring your development tools to use `clang-format`, you can try to use it manually, but please, do it always before committing changes. I recommend using QtCreator configured properly, you can find a tutorial [here]( https://www.vikingsoftware.com/using-clang-format-with-qtcreator/).
|
||||
|
||||
#### CI/CD
|
||||
Any PR will be validated through CI, and it will not be merged if CI fails.
|
||||
@ -70,3 +72,6 @@ The base and target branch for any PR should always be `develop`.
|
||||
|
||||
## Donations
|
||||
YACReader is free but it needs money to keep being alive, so please, if you like YACReader, visit the home page and make a donation.
|
||||
|
||||
## Hacktoberfest
|
||||
If you are interested in YACReader, please contact me so we can discuss your next steps.
|
||||
|
@ -173,10 +173,6 @@ include(../shortcuts_management/shortcuts_management.pri)
|
||||
RESOURCES += yacreader_images.qrc \
|
||||
yacreader_files.qrc
|
||||
|
||||
win32:RESOURCES += yacreader_images_win.qrc
|
||||
unix:!macx:RESOURCES += yacreader_images_win.qrc
|
||||
macx:RESOURCES += yacreader_images_osx.qrc
|
||||
|
||||
include(../third_party/QsLog/QsLog.pri)
|
||||
|
||||
RC_FILE = icon.rc
|
||||
@ -197,7 +193,28 @@ TRANSLATIONS = yacreader_es.ts \
|
||||
yacreader_zh_TW.ts \
|
||||
yacreader_zh_HK.ts \
|
||||
yacreader_it.ts \
|
||||
yacreader_source.ts
|
||||
yacreader_en.ts
|
||||
|
||||
CONFIG += lrelease
|
||||
|
||||
win32 {
|
||||
CONFIG(release, debug|release) {
|
||||
SOURCE_QM_DIR = $$OUT_PWD/release/*.qm
|
||||
}
|
||||
CONFIG(debug, debug|release) {
|
||||
SOURCE_QM_DIR = $$OUT_PWD/debug/*.qm
|
||||
}
|
||||
|
||||
DEPLOYMENT_OUT_QM_DIR = ../release/languages/
|
||||
OUT_QM_DIR = $${DESTDIR}/languages/
|
||||
|
||||
QMAKE_POST_LINK += $(MKDIR) $$shell_path($${OUT_QM_DIR}) 2> NULL & \
|
||||
$(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${OUT_QM_DIR}) & \
|
||||
$(MKDIR) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) 2> NULL & \
|
||||
$(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${DEPLOYMENT_OUT_QM_DIR})
|
||||
} else {
|
||||
LRELEASE_DIR = ../release/languages/
|
||||
}
|
||||
|
||||
unix:!macx {
|
||||
# set install prefix if it's empty
|
||||
|
@ -173,11 +173,10 @@ int main(int argc, char *argv[])
|
||||
logger.addDestination(std::move(fileDestination));
|
||||
|
||||
QTranslator translator;
|
||||
QString sufix = QLocale::system().name();
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
translator.load(QString(DATADIR) + "/yacreader/languages/yacreader_" + sufix);
|
||||
translator.load(QLocale(), "yacreader", "_", QString(DATADIR) + "/yacreader/languages");
|
||||
#else
|
||||
translator.load(QCoreApplication::applicationDirPath() + "/languages/yacreader_" + sufix);
|
||||
translator.load(QLocale(), "yacreader", "_", "languages");
|
||||
#endif
|
||||
app.installTranslator(&translator);
|
||||
auto mwv = new MainWindowViewer();
|
||||
|
@ -36,41 +36,6 @@
|
||||
#include <QDate>
|
||||
#include <QMenuBar>
|
||||
|
||||
/* TODO remove, no longer used
|
||||
#ifdef Q_OS_MAC
|
||||
class MacToolBarSeparator : public QWidget
|
||||
{
|
||||
public:
|
||||
MacToolBarSeparator(QWidget * parent =0)
|
||||
:QWidget(parent)
|
||||
{
|
||||
setFixedWidth(2);
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainter painter(this);
|
||||
|
||||
QLinearGradient lG(0,0,0,height());
|
||||
|
||||
lG.setColorAt(0,QColor(128,128,128,0));
|
||||
lG.setColorAt(0.5,QColor(128,128,128,255));
|
||||
lG.setColorAt(1,QColor(128,128,128,0));
|
||||
|
||||
painter.fillRect(0,0,1,height(),lG);
|
||||
|
||||
QLinearGradient lG2(1,0,1,height());
|
||||
|
||||
lG2.setColorAt(0,QColor(220,220,220,0));
|
||||
lG2.setColorAt(0.5,QColor(220,220,220,255));
|
||||
lG2.setColorAt(1,QColor(220,220,220,0));
|
||||
|
||||
painter.fillRect(1,0,1,height(),lG2);
|
||||
}
|
||||
};
|
||||
#endif*/
|
||||
|
||||
MainWindowViewer::MainWindowViewer()
|
||||
: QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), isClient(false)
|
||||
{
|
||||
@ -217,7 +182,7 @@ void MainWindowViewer::setupUI()
|
||||
void MainWindowViewer::createActions()
|
||||
{
|
||||
openAction = new QAction(tr("&Open"), this);
|
||||
openAction->setIcon(QIcon(":/images/viewer_toolbar/open.png"));
|
||||
openAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/open")));
|
||||
openAction->setToolTip(tr("Open a comic"));
|
||||
openAction->setData(OPEN_ACTION_Y);
|
||||
openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y));
|
||||
@ -244,7 +209,7 @@ void MainWindowViewer::createActions()
|
||||
#endif
|
||||
|
||||
openFolderAction = new QAction(tr("Open Folder"), this);
|
||||
openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.png"));
|
||||
openFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openFolder")));
|
||||
openFolderAction->setToolTip(tr("Open image folder"));
|
||||
openFolderAction->setData(OPEN_FOLDER_ACTION_Y);
|
||||
openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y));
|
||||
@ -268,28 +233,28 @@ void MainWindowViewer::createActions()
|
||||
connect(clearRecentFilesAction, &QAction::triggered, this, &MainWindowViewer::clearRecentFiles);
|
||||
|
||||
saveImageAction = new QAction(tr("Save"), this);
|
||||
saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.png"));
|
||||
saveImageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/save")));
|
||||
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(":/images/viewer_toolbar/openPrevious.png"));
|
||||
openComicOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openPrevious")));
|
||||
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(":/images/viewer_toolbar/openNext.png"));
|
||||
openComicOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openNext")));
|
||||
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(":/images/viewer_toolbar/previous.png"));
|
||||
goToPageOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/previous")));
|
||||
goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
goToPageOnTheLeftAction->setToolTip(tr("Go to previous page"));
|
||||
goToPageOnTheLeftAction->setData(PREV_ACTION_Y);
|
||||
@ -297,7 +262,7 @@ void MainWindowViewer::createActions()
|
||||
connect(goToPageOnTheLeftAction, &QAction::triggered, viewer, &Viewer::left);
|
||||
|
||||
goToPageOnTheRightAction = new QAction(tr("&Next"), this);
|
||||
goToPageOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/next.png"));
|
||||
goToPageOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/next")));
|
||||
goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut);
|
||||
goToPageOnTheRightAction->setToolTip(tr("Go to next page"));
|
||||
goToPageOnTheRightAction->setData(NEXT_ACTION_Y);
|
||||
@ -305,27 +270,27 @@ void MainWindowViewer::createActions()
|
||||
connect(goToPageOnTheRightAction, &QAction::triggered, viewer, &Viewer::right);
|
||||
|
||||
adjustHeightAction = new QAction(tr("Fit Height"), this);
|
||||
adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.png"));
|
||||
adjustHeightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toHeight")));
|
||||
// adjustWidth->setCheckable(true);
|
||||
adjustHeightAction->setToolTip(tr("Fit image to height"));
|
||||
// adjustWidth->setIcon(QIcon(":/images/fitWidth.png"));
|
||||
// adjustWidth->setIcon(QIcon(":/images/fitWidth.svg"));
|
||||
adjustHeightAction->setData(ADJUST_HEIGHT_ACTION_Y);
|
||||
adjustHeightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_HEIGHT_ACTION_Y));
|
||||
adjustHeightAction->setCheckable(true);
|
||||
connect(adjustHeightAction, &QAction::triggered, this, &MainWindowViewer::fitToHeight);
|
||||
|
||||
adjustWidthAction = new QAction(tr("Fit Width"), this);
|
||||
adjustWidthAction->setIcon(QIcon(":/images/viewer_toolbar/toWidth.png"));
|
||||
adjustWidthAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toWidth")));
|
||||
// adjustWidth->setCheckable(true);
|
||||
adjustWidthAction->setToolTip(tr("Fit image to width"));
|
||||
// adjustWidth->setIcon(QIcon(":/images/fitWidth.png"));
|
||||
// adjustWidth->setIcon(QIcon(":/images/fitWidth.svg"));
|
||||
adjustWidthAction->setData(ADJUST_WIDTH_ACTION_Y);
|
||||
adjustWidthAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_WIDTH_ACTION_Y));
|
||||
adjustWidthAction->setCheckable(true);
|
||||
connect(adjustWidthAction, &QAction::triggered, this, &MainWindowViewer::fitToWidth);
|
||||
|
||||
adjustToFullSizeAction = new QAction(tr("Show full size"), this);
|
||||
adjustToFullSizeAction->setIcon(QIcon(":/images/viewer_toolbar/full.png"));
|
||||
adjustToFullSizeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/full")));
|
||||
adjustToFullSizeAction->setCheckable(false);
|
||||
adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y);
|
||||
adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y));
|
||||
@ -333,7 +298,7 @@ void MainWindowViewer::createActions()
|
||||
connect(adjustToFullSizeAction, &QAction::triggered, this, &MainWindowViewer::adjustToFullSizeSwitch);
|
||||
|
||||
fitToPageAction = new QAction(tr("Fit to page"), this);
|
||||
fitToPageAction->setIcon(QIcon(":/images/viewer_toolbar/fitToPage.png"));
|
||||
fitToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/fitToPage")));
|
||||
fitToPageAction->setData(FIT_TO_PAGE_ACTION_Y);
|
||||
fitToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FIT_TO_PAGE_ACTION_Y));
|
||||
fitToPageAction->setCheckable(true);
|
||||
@ -369,7 +334,7 @@ void MainWindowViewer::createActions()
|
||||
connect(resetZoomAction, &QAction::triggered, this, &MainWindowViewer::resetZoomLevel);
|
||||
|
||||
showZoomSliderlAction = new QAction(tr("Show zoom slider"), this);
|
||||
showZoomSliderlAction->setIcon(QIcon(":/images/viewer_toolbar/zoom.png"));
|
||||
showZoomSliderlAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/zoom")));
|
||||
|
||||
increasePageZoomAction = new QAction(tr("Zoom+"), this);
|
||||
increasePageZoomAction->setData(ZOOM_PLUS_ACTION_Y);
|
||||
@ -382,20 +347,20 @@ void MainWindowViewer::createActions()
|
||||
connect(decreasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::decreasePageZoomLevel);
|
||||
|
||||
leftRotationAction = new QAction(tr("Rotate image to the left"), this);
|
||||
leftRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateL.png"));
|
||||
leftRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateL")));
|
||||
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(":/images/viewer_toolbar/rotateR.png"));
|
||||
rightRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateR")));
|
||||
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(":/images/viewer_toolbar/doublePage.png"));
|
||||
doublePageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doublePage")));
|
||||
doublePageAction->setCheckable(true);
|
||||
doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage());
|
||||
doublePageAction->setData(DOUBLE_PAGE_ACTION_Y);
|
||||
@ -405,7 +370,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(":/images/viewer_toolbar/doubleMangaPage.png"));
|
||||
doubleMangaPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doubleMangaPage")));
|
||||
doubleMangaPageAction->setCheckable(true);
|
||||
doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage());
|
||||
doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y);
|
||||
@ -414,7 +379,7 @@ void MainWindowViewer::createActions()
|
||||
connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch);
|
||||
|
||||
goToPageAction = new QAction(tr("Go To"), this);
|
||||
goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.png"));
|
||||
goToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/goto")));
|
||||
goToPageAction->setToolTip(tr("Go to page ..."));
|
||||
goToPageAction->setData(GO_TO_PAGE_ACTION_Y);
|
||||
goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y));
|
||||
@ -424,20 +389,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(":/images/viewer_toolbar/options.png"));
|
||||
optionsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/options")));
|
||||
|
||||
connect(optionsAction, &QAction::triggered, optionsDialog, &OptionsDialog::show);
|
||||
|
||||
helpAboutAction = new QAction(tr("Help"), this);
|
||||
helpAboutAction->setToolTip(tr("Help, About YACReader"));
|
||||
helpAboutAction->setIcon(QIcon(":/images/viewer_toolbar/help.png"));
|
||||
helpAboutAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/help")));
|
||||
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(":/images/viewer_toolbar/magnifyingGlass.png"));
|
||||
showMagnifyingGlassAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/magnifyingGlass")));
|
||||
showMagnifyingGlassAction->setCheckable(true);
|
||||
showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y);
|
||||
showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y));
|
||||
@ -445,7 +410,7 @@ void MainWindowViewer::createActions()
|
||||
|
||||
setBookmarkAction = new QAction(tr("Set bookmark"), this);
|
||||
setBookmarkAction->setToolTip(tr("Set a bookmark on the current page"));
|
||||
setBookmarkAction->setIcon(QIcon(":/images/viewer_toolbar/bookmark.png"));
|
||||
setBookmarkAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/bookmark")));
|
||||
setBookmarkAction->setCheckable(true);
|
||||
setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y);
|
||||
setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y));
|
||||
@ -455,39 +420,38 @@ void MainWindowViewer::createActions()
|
||||
|
||||
showBookmarksAction = new QAction(tr("Show bookmarks"), this);
|
||||
showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic"));
|
||||
showBookmarksAction->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.png"));
|
||||
showBookmarksAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/showBookmarks")));
|
||||
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(":/images/viewer_toolbar/shortcuts.png"));
|
||||
showShorcutsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/shortcuts")));
|
||||
showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y);
|
||||
showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y));
|
||||
// connect(showShorcutsAction, SIGNAL(triggered()),shortcutsDialog,SLOT(show()));
|
||||
connect(showShorcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show);
|
||||
|
||||
showInfoAction = new QAction(tr("Show Info"), this);
|
||||
showInfoAction->setIcon(QIcon(":/images/viewer_toolbar/info.png"));
|
||||
showInfoAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/info")));
|
||||
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(":/images/viewer_toolbar/close.png"));
|
||||
closeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/close")));
|
||||
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(":/images/viewer_toolbar/translator.png"));
|
||||
showDictionaryAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/translator")));
|
||||
// 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(":/images/viewer_toolbar/flow.png"));
|
||||
showFlowAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/flow")));
|
||||
showFlowAction->setData(SHOW_FLOW_ACTION_Y);
|
||||
showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y));
|
||||
connect(showFlowAction, &QAction::triggered, viewer, &Viewer::goToFlowSwitch);
|
||||
@ -511,20 +475,21 @@ void MainWindowViewer::createToolBars()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
comicToolBar = new YACReaderMacOSXToolbar(this);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
comicToolBar->setIconSize(QSize(18, 18));
|
||||
#endif
|
||||
#else
|
||||
comicToolBar = addToolBar(tr("&File"));
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// comicToolBar->setIconSize(QSize(16,16));
|
||||
#else
|
||||
comicToolBar->setIconSize(QSize(18, 18));
|
||||
#ifndef Q_OS_MAC
|
||||
comicToolBar->setStyleSheet("QToolBar{border:none;}");
|
||||
comicToolBar->setIconSize(QSize(18, 18));
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
comicToolBar->addAction(openAction);
|
||||
comicToolBar->addAction(openFolderAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction));
|
||||
#else
|
||||
auto recentmenu = new QMenu(tr("Open recent"));
|
||||
recentmenu->addActions(recentFilesActionList);
|
||||
@ -533,61 +498,72 @@ void MainWindowViewer::createToolBars()
|
||||
refreshRecentFilesActionList();
|
||||
|
||||
auto tb = new QToolButton();
|
||||
tb->addAction(openAction);
|
||||
tb->addAction(openLatestComicAction);
|
||||
tb->addAction(openFolderAction);
|
||||
auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction);
|
||||
tb->addAction(open);
|
||||
tb->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction));
|
||||
tb->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction));
|
||||
tb->addAction(recentmenu->menuAction());
|
||||
tb->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
tb->setDefaultAction(openAction);
|
||||
tb->setDefaultAction(open);
|
||||
|
||||
comicToolBar->addWidget(tb);
|
||||
#endif
|
||||
|
||||
comicToolBar->addAction(saveImageAction);
|
||||
comicToolBar->addAction(openComicOnTheLeftAction);
|
||||
comicToolBar->addAction(openComicOnTheRightAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openPrevious")), openComicOnTheLeftAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openNext")), openComicOnTheRightAction));
|
||||
|
||||
comicToolBar->addSeparator();
|
||||
|
||||
comicToolBar->addAction(goToPageOnTheLeftAction);
|
||||
comicToolBar->addAction(goToPageOnTheRightAction);
|
||||
comicToolBar->addAction(goToPageAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/previous")), goToPageOnTheLeftAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/next")), goToPageOnTheRightAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/goto")), goToPageAction));
|
||||
|
||||
comicToolBar->addSeparator();
|
||||
|
||||
comicToolBar->addAction(adjustWidthAction);
|
||||
comicToolBar->addAction(adjustHeightAction);
|
||||
auto adjustToWidthTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toWidth")), adjustWidthAction);
|
||||
comicToolBar->addAction(adjustToWidthTBAction);
|
||||
auto adjustToHeightTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toHeight")), adjustHeightAction);
|
||||
comicToolBar->addAction(adjustToHeightTBAction);
|
||||
auto adjustToFullSizeTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/full")), adjustToFullSizeAction);
|
||||
comicToolBar->addAction(adjustToFullSizeAction);
|
||||
comicToolBar->addAction(fitToPageAction);
|
||||
auto fitToPageTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/fitToPage")), fitToPageAction);
|
||||
comicToolBar->addAction(fitToPageTBAction);
|
||||
|
||||
auto fitModes = new QActionGroup(this);
|
||||
fitModes->addAction(adjustToWidthTBAction);
|
||||
fitModes->addAction(adjustToHeightTBAction);
|
||||
fitModes->addAction(adjustToFullSizeTBAction);
|
||||
fitModes->addAction(fitToPageTBAction);
|
||||
|
||||
zoomSliderAction = new YACReaderSlider(this);
|
||||
zoomSliderAction->hide();
|
||||
|
||||
comicToolBar->addAction(showZoomSliderlAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/zoom")), showZoomSliderlAction));
|
||||
|
||||
connect(showZoomSliderlAction, &QAction::triggered, this, &MainWindowViewer::toggleFitToWidthSlider);
|
||||
connect(zoomSliderAction, &YACReaderSlider::zoomRatioChanged, viewer, &Viewer::updateZoomRatio);
|
||||
connect(viewer, &Viewer::zoomUpdated, zoomSliderAction, &YACReaderSlider::updateZoomRatio);
|
||||
|
||||
comicToolBar->addAction(leftRotationAction);
|
||||
comicToolBar->addAction(rightRotationAction);
|
||||
comicToolBar->addAction(doublePageAction);
|
||||
comicToolBar->addAction(doubleMangaPageAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateL")), leftRotationAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateR")), rightRotationAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doublePage")), doublePageAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doubleMangaPage")), doubleMangaPageAction));
|
||||
|
||||
comicToolBar->addSeparator();
|
||||
|
||||
comicToolBar->addAction(showMagnifyingGlassAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/magnifyingGlass")), showMagnifyingGlassAction));
|
||||
|
||||
comicToolBar->addSeparator();
|
||||
|
||||
comicToolBar->addAction(setBookmarkAction);
|
||||
comicToolBar->addAction(showBookmarksAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/bookmark")), setBookmarkAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/showBookmarks")), showBookmarksAction));
|
||||
|
||||
comicToolBar->addSeparator();
|
||||
|
||||
comicToolBar->addAction(showDictionaryAction);
|
||||
comicToolBar->addAction(showFlowAction);
|
||||
comicToolBar->addAction(showInfoAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/translator")), showDictionaryAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/flow")), showFlowAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/info")), showInfoAction));
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
comicToolBar->addStretch();
|
||||
@ -595,10 +571,9 @@ void MainWindowViewer::createToolBars()
|
||||
comicToolBar->addWidget(new YACReaderToolBarStretch());
|
||||
#endif
|
||||
|
||||
comicToolBar->addAction(showShorcutsAction);
|
||||
comicToolBar->addAction(optionsAction);
|
||||
comicToolBar->addAction(helpAboutAction);
|
||||
// comicToolBar->addAction(closeAction);
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/shortcuts")), showShorcutsAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/options")), optionsAction));
|
||||
comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/help")), helpAboutAction));
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
comicToolBar->setMovable(false);
|
||||
@ -1156,7 +1131,7 @@ void MainWindowViewer::setUpShortcutsManagement()
|
||||
QList<QAction *> allActions;
|
||||
QList<QAction *> tmpList;
|
||||
|
||||
editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts_group_comics.png"),
|
||||
editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts_group_comics.svg"),
|
||||
tmpList = { openAction,
|
||||
openLatestComicAction,
|
||||
openFolderAction,
|
||||
@ -1172,7 +1147,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_group_general.png"),
|
||||
editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts_group_general.svg"),
|
||||
tmpList = QList<QAction *>()
|
||||
<< optionsAction
|
||||
<< helpAboutAction
|
||||
@ -1206,7 +1181,7 @@ void MainWindowViewer::setUpShortcutsManagement()
|
||||
mglassActions = { sizeUpMglassAction, sizeDownMglassAction,
|
||||
zoomInMglassAction, zoomOutMglassAction };
|
||||
|
||||
editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts_group_mglass.png"),
|
||||
editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts_group_mglass.svg"),
|
||||
tmpList = QList<QAction *>()
|
||||
<< showMagnifyingGlassAction
|
||||
<< mglassActions);
|
||||
@ -1217,7 +1192,7 @@ void MainWindowViewer::setUpShortcutsManagement()
|
||||
CHANGE_FIT_ACTION_Y);
|
||||
connect(toggleFitToScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleWidthHeight);
|
||||
|
||||
editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts_group_page.png"),
|
||||
editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts_group_page.svg"),
|
||||
tmpList = QList<QAction *>()
|
||||
<< adjustHeightAction
|
||||
<< adjustWidthAction
|
||||
@ -1287,7 +1262,7 @@ void MainWindowViewer::setUpShortcutsManagement()
|
||||
goToFirstPageAction,
|
||||
goToLastPageAction };
|
||||
|
||||
editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts_group_reading.png"),
|
||||
editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts_group_reading.svg"),
|
||||
tmpList = QList<QAction *>()
|
||||
<< goToPageOnTheRightAction
|
||||
<< goToPageOnTheLeftAction
|
||||
|
@ -58,9 +58,6 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
backgroundColor->setPalette(pal);
|
||||
backgroundColor->setAutoFillBackground(true);
|
||||
|
||||
colorDialog = new QColorDialog(Qt::red, this);
|
||||
connect(colorDialog, &QColorDialog::colorSelected, this, &OptionsDialog::updateColor);
|
||||
|
||||
QGroupBox *colorBox = new QGroupBox(tr("Background color"));
|
||||
// backgroundColor->setMinimumWidth(100);
|
||||
colorSelection->addWidget(backgroundColor);
|
||||
@ -68,7 +65,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
colorSelection->setStretchFactor(backgroundColor, 1);
|
||||
colorSelection->setStretchFactor(selectBackgroundColorButton, 0);
|
||||
// colorSelection->addStretch();
|
||||
connect(selectBackgroundColorButton, &QAbstractButton::clicked, colorDialog, &QWidget::show);
|
||||
connect(selectBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::showColorDialog);
|
||||
colorBox->setLayout(colorSelection);
|
||||
|
||||
auto scrollBox = new QGroupBox(tr("Scroll behaviour"));
|
||||
@ -219,6 +216,12 @@ void OptionsDialog::findFolder()
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsDialog::showColorDialog()
|
||||
{
|
||||
auto color = QColorDialog::getColor(currentColor, this);
|
||||
updateColor(color);
|
||||
}
|
||||
|
||||
void OptionsDialog::saveOptions()
|
||||
{
|
||||
settings->setValue(GO_TO_FLOW_SIZE, QSize(static_cast<int>(slideSize->sliderPosition() / SLIDE_ASPECT_RATIO), slideSize->sliderPosition()));
|
||||
@ -232,7 +235,7 @@ void OptionsDialog::saveOptions()
|
||||
|
||||
settings->setValue(PATH, pathEdit->text());
|
||||
|
||||
settings->setValue(BACKGROUND_COLOR, colorDialog->currentColor());
|
||||
settings->setValue(BACKGROUND_COLOR, currentColor);
|
||||
// settings->setValue(FIT_TO_WIDTH_RATIO,fitToWidthRatioS->sliderPosition()/100.0);
|
||||
settings->setValue(QUICK_NAVI_MODE, quickNavi->isChecked());
|
||||
settings->setValue(DISABLE_MOUSE_OVER_GOTO_FLOW, disableShowOnMouseOver->isChecked());
|
||||
@ -288,7 +291,7 @@ void OptionsDialog::updateColor(const QColor &color)
|
||||
pal.setColor(backgroundColor->backgroundRole(), color);
|
||||
backgroundColor->setPalette(pal);
|
||||
backgroundColor->setAutoFillBackground(true);
|
||||
colorDialog->setCurrentColor(color);
|
||||
currentColor = color;
|
||||
|
||||
settings->setValue(BACKGROUND_COLOR, color);
|
||||
|
||||
|
@ -10,7 +10,6 @@ class QPushButton;
|
||||
class QSlider;
|
||||
class QPushButton;
|
||||
class QRadioButton;
|
||||
class QColorDialog;
|
||||
class YACReaderSpinSliderWidget;
|
||||
|
||||
class OptionsDialog : public YACReaderOptionsDialog
|
||||
@ -44,18 +43,18 @@ private:
|
||||
QCheckBox *doNotTurnPageOnScroll;
|
||||
QCheckBox *useSingleScrollStepToTurnPage;
|
||||
|
||||
QColorDialog *colorDialog;
|
||||
|
||||
YACReaderSpinSliderWidget *brightnessS;
|
||||
|
||||
YACReaderSpinSliderWidget *contrastS;
|
||||
|
||||
YACReaderSpinSliderWidget *gammaS;
|
||||
|
||||
QColor currentColor;
|
||||
public slots:
|
||||
void saveOptions() override;
|
||||
void restoreOptions(QSettings *settings) override;
|
||||
void findFolder();
|
||||
void showColorDialog();
|
||||
void updateColor(const QColor &color);
|
||||
// void fitToWidthRatio(int value);
|
||||
void brightnessChanged(int value);
|
||||
|
@ -57,7 +57,7 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent)
|
||||
|
||||
// TITLE BAR
|
||||
auto titleBar = new QHBoxLayout();
|
||||
auto close = new QPushButton(QIcon(QPixmap(":/images/close.png")), "");
|
||||
auto close = new QPushButton(QIcon(":/images/close.svg"), "");
|
||||
close->setFlat(true);
|
||||
auto title = new QLabel(tr("YACReader translator"));
|
||||
title->setStyleSheet("QLabel {font-size:18px; font-family:Arial; color:white;}");
|
||||
|
File diff suppressed because it is too large
Load Diff
1174
YACReader/yacreader_en.ts
Normal file
1174
YACReader/yacreader_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
<file>../images/flow4.png</file>
|
||||
<file>../images/flow5.png</file>
|
||||
<file>../images/notCover.png</file>
|
||||
<file>../images/close.png</file>
|
||||
<file>../images/close.svg</file>
|
||||
<file>../images/up.png</file>
|
||||
<file>../images/down.png</file>
|
||||
<file>../images/imgCenterSlide.png</file>
|
||||
@ -21,17 +21,71 @@
|
||||
<file>../images/dropDownArrow.png</file>
|
||||
<file>../images/translatorSearch.png</file>
|
||||
<file>../images/speaker.png</file>
|
||||
<file>../images/clear_shortcut.png</file>
|
||||
<file>../images/accept_shortcut.png</file>
|
||||
<file>../images/shortcuts_group_comics.png</file>
|
||||
<file>../images/shortcuts_group_folders.png</file>
|
||||
<file>../images/shortcuts_group_general.png</file>
|
||||
<file>../images/shortcuts_group_libraries.png</file>
|
||||
<file>../images/shortcuts_group_mglass.png</file>
|
||||
<file>../images/shortcuts_group_page.png</file>
|
||||
<file>../images/shortcuts_group_reading.png</file>
|
||||
<file>../images/shortcuts_group_visualization.png</file>
|
||||
<file>../images/clear_shortcut.svg</file>
|
||||
<file>../images/accept_shortcut.svg</file>
|
||||
<file>../images/shortcuts_group_comics.svg</file>
|
||||
<file>../images/shortcuts_group_folders.svg</file>
|
||||
<file>../images/shortcuts_group_general.svg</file>
|
||||
<file>../images/shortcuts_group_libraries.svg</file>
|
||||
<file>../images/shortcuts_group_mglass.svg</file>
|
||||
<file>../images/shortcuts_group_page.svg</file>
|
||||
<file>../images/shortcuts_group_reading.svg</file>
|
||||
<file>../images/shortcuts_group_visualization.svg</file>
|
||||
<file>../images/custom_dialog/custom_close_button.svg</file>
|
||||
<file>../images/whats_new/whatsnew_header.svg</file>
|
||||
<file>../images/viewer_toolbar/bookmark.svg</file>
|
||||
<file>../images/viewer_toolbar/close.svg</file>
|
||||
<file>../images/viewer_toolbar/doublePage.svg</file>
|
||||
<file>../images/viewer_toolbar/doubleMangaPage.svg</file>
|
||||
<file>../images/viewer_toolbar/fitToPage.svg</file>
|
||||
<file>../images/viewer_toolbar/flow.svg</file>
|
||||
<file>../images/viewer_toolbar/full.svg</file>
|
||||
<file>../images/viewer_toolbar/goto.svg</file>
|
||||
<file>../images/viewer_toolbar/help.svg</file>
|
||||
<file>../images/viewer_toolbar/info.svg</file>
|
||||
<file>../images/viewer_toolbar/magnifyingGlass.svg</file>
|
||||
<file>../images/viewer_toolbar/next.svg</file>
|
||||
<file>../images/viewer_toolbar/open.svg</file>
|
||||
<file>../images/viewer_toolbar/openFolder.svg</file>
|
||||
<file>../images/viewer_toolbar/openNext.svg</file>
|
||||
<file>../images/viewer_toolbar/openPrevious.svg</file>
|
||||
<file>../images/viewer_toolbar/options.svg</file>
|
||||
<file>../images/viewer_toolbar/previous.svg</file>
|
||||
<file>../images/viewer_toolbar/rotateL.svg</file>
|
||||
<file>../images/viewer_toolbar/rotateR.svg</file>
|
||||
<file>../images/viewer_toolbar/save.svg</file>
|
||||
<file>../images/viewer_toolbar/shortcuts.svg</file>
|
||||
<file>../images/viewer_toolbar/showBookmarks.svg</file>
|
||||
<file>../images/viewer_toolbar/toHeight.svg</file>
|
||||
<file>../images/viewer_toolbar/toWidth.svg</file>
|
||||
<file>../images/viewer_toolbar/translator.svg</file>
|
||||
<file>../images/viewer_toolbar/zoom.svg</file>
|
||||
<file>../images/viewer_toolbar/bookmark_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/close_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/doublePage_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/doubleMangaPage_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/fitToPage_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/flow_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/full_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/goto_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/help_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/info_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/magnifyingGlass_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/next_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/open_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/openFolder_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/openNext_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/openPrevious_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/options_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/previous_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/rotateL_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/rotateR_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/save_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/shortcuts_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/showBookmarks_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/toHeight_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/toWidth_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/translator_18x18.svg</file>
|
||||
<file>../images/viewer_toolbar/zoom_18x18.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,61 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file alias="images/viewer_toolbar/bookmark.png">../images/viewer_toolbar/bookmark_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/bookmark@2x.png">../images/viewer_toolbar/bookmark_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/close.png">../images/viewer_toolbar/close_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/close@2x.png">../images/viewer_toolbar/close_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/doubleMangaPage.png">../images/viewer_toolbar/doubleMangaPage_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/doubleMangaPage@2x.png">../images/viewer_toolbar/doubleMangaPage_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/doublePage.png">../images/viewer_toolbar/doublePage_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/doublePage@2x.png">../images/viewer_toolbar/doublePage_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/fitToPage.png">../images/viewer_toolbar/fitToPage_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/fitToPage@2x.png">../images/viewer_toolbar/fitToPage_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/flow.png">../images/viewer_toolbar/flow_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/flow@2x.png">../images/viewer_toolbar/flow_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/full.png">../images/viewer_toolbar/full_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/full@2x.png">../images/viewer_toolbar/full_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/goto.png">../images/viewer_toolbar/goto_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/goto@2x.png">../images/viewer_toolbar/goto_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/help.png">../images/viewer_toolbar/help_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/help@2x.png">../images/viewer_toolbar/help_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/info.png">../images/viewer_toolbar/info_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/info@2x.png">../images/viewer_toolbar/info_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/magnifyingGlass.png">../images/viewer_toolbar/magnifyingGlass_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/magnifyingGlass@2x.png">../images/viewer_toolbar/magnifyingGlass_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/next.png">../images/viewer_toolbar/next_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/next@2x.png">../images/viewer_toolbar/next_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/open.png">../images/viewer_toolbar/open_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/open@2x.png">../images/viewer_toolbar/open_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/openFolder.png">../images/viewer_toolbar/openFolder_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/openFolder@2x.png">../images/viewer_toolbar/openFolder_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/openNext.png">../images/viewer_toolbar/openNext_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/openNext@2x.png">../images/viewer_toolbar/openNext_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/openPrevious.png">../images/viewer_toolbar/openPrevious_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/openPrevious@2x.png">../images/viewer_toolbar/openPrevious_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/options.png">../images/viewer_toolbar/options_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/options@2x.png">../images/viewer_toolbar/options_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/previous.png">../images/viewer_toolbar/previous_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/previous@2x.png">../images/viewer_toolbar/previous_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/rotateL.png">../images/viewer_toolbar/rotateL_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/rotateL@2x.png">../images/viewer_toolbar/rotateL_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/rotateR.png">../images/viewer_toolbar/rotateR_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/rotateR@2x.png">../images/viewer_toolbar/rotateR_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/save.png">../images/viewer_toolbar/save_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/save@2x.png">../images/viewer_toolbar/save_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/shortcuts.png">../images/viewer_toolbar/shortcuts_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/shortcuts@2x.png">../images/viewer_toolbar/shortcuts_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/showBookmarks.png">../images/viewer_toolbar/showBookmarks_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/showBookmarks@2x.png">../images/viewer_toolbar/showBookmarks_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/toHeight.png">../images/viewer_toolbar/toHeight_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/toHeight@2x.png">../images/viewer_toolbar/toHeight_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/toWidth.png">../images/viewer_toolbar/toWidth_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/toWidth@2x.png">../images/viewer_toolbar/toWidth_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/toWidthSlider.png">../images/viewer_toolbar/toWidthSlider_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/toWidthSlider@2x.png">../images/viewer_toolbar/toWidthSlider_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/translator.png">../images/viewer_toolbar/translator_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/translator@2x.png">../images/viewer_toolbar/translator_osx@2x.png</file>
|
||||
<file alias="images/viewer_toolbar/zoom.png">../images/viewer_toolbar/zoom_osx.png</file>
|
||||
<file alias="images/viewer_toolbar/zoom@2x.png">../images/viewer_toolbar/zoom_osx@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,31 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>../images/viewer_toolbar/bookmark.png</file>
|
||||
<file>../images/viewer_toolbar/close.png</file>
|
||||
<file>../images/viewer_toolbar/doublePage.png</file>
|
||||
<file>../images/viewer_toolbar/doubleMangaPage.png</file>
|
||||
<file>../images/viewer_toolbar/fitToPage.png</file>
|
||||
<file>../images/viewer_toolbar/flow.png</file>
|
||||
<file>../images/viewer_toolbar/full.png</file>
|
||||
<file>../images/viewer_toolbar/goto.png</file>
|
||||
<file>../images/viewer_toolbar/help.png</file>
|
||||
<file>../images/viewer_toolbar/info.png</file>
|
||||
<file>../images/viewer_toolbar/magnifyingGlass.png</file>
|
||||
<file>../images/viewer_toolbar/next.png</file>
|
||||
<file>../images/viewer_toolbar/open.png</file>
|
||||
<file>../images/viewer_toolbar/openFolder.png</file>
|
||||
<file>../images/viewer_toolbar/openNext.png</file>
|
||||
<file>../images/viewer_toolbar/openPrevious.png</file>
|
||||
<file>../images/viewer_toolbar/options.png</file>
|
||||
<file>../images/viewer_toolbar/previous.png</file>
|
||||
<file>../images/viewer_toolbar/rotateL.png</file>
|
||||
<file>../images/viewer_toolbar/rotateR.png</file>
|
||||
<file>../images/viewer_toolbar/save.png</file>
|
||||
<file>../images/viewer_toolbar/shortcuts.png</file>
|
||||
<file>../images/viewer_toolbar/showBookmarks.png</file>
|
||||
<file>../images/viewer_toolbar/toHeight.png</file>
|
||||
<file>../images/viewer_toolbar/toWidth.png</file>
|
||||
<file>../images/viewer_toolbar/translator.png</file>
|
||||
<file>../images/viewer_toolbar/zoom.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -124,17 +124,17 @@
|
||||
<context>
|
||||
<name>HelpAboutDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="25"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="27"/>
|
||||
<source>About</source>
|
||||
<translation>关于</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="28"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="30"/>
|
||||
<source>Help</source>
|
||||
<translation>帮助</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="31"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="33"/>
|
||||
<source>System info</source>
|
||||
<translation>系统信息</translation>
|
||||
</message>
|
||||
@ -190,112 +190,112 @@
|
||||
<translation>我的漫画路径</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<location filename="options_dialog.cpp" line="61"/>
|
||||
<source>Background color</source>
|
||||
<translation>背景颜色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="67"/>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<source>Choose</source>
|
||||
<translation>选择</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="100"/>
|
||||
<location filename="options_dialog.cpp" line="97"/>
|
||||
<source>Quick Navigation Mode</source>
|
||||
<translation>快速导航模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="101"/>
|
||||
<location filename="options_dialog.cpp" line="98"/>
|
||||
<source>Disable mouse over activation</source>
|
||||
<translation>禁用鼠标激活</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="200"/>
|
||||
<location filename="options_dialog.cpp" line="197"/>
|
||||
<source>Restart is needed</source>
|
||||
<translation>需要重启</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="144"/>
|
||||
<location filename="options_dialog.cpp" line="141"/>
|
||||
<source>Brightness</source>
|
||||
<translation>亮度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<location filename="options_dialog.cpp" line="71"/>
|
||||
<source>Scroll behaviour</source>
|
||||
<translation>滚动效果</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="77"/>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<source>Do not turn page using scroll</source>
|
||||
<translation>滚动时不翻页</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="78"/>
|
||||
<location filename="options_dialog.cpp" line="75"/>
|
||||
<source>Use single scroll step to turn page</source>
|
||||
<translation>使用单滚动步骤翻页</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="145"/>
|
||||
<location filename="options_dialog.cpp" line="142"/>
|
||||
<source>Contrast</source>
|
||||
<translation>对比度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="146"/>
|
||||
<location filename="options_dialog.cpp" line="143"/>
|
||||
<source>Gamma</source>
|
||||
<translation>Gamma值</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="150"/>
|
||||
<location filename="options_dialog.cpp" line="147"/>
|
||||
<source>Reset</source>
|
||||
<translation>重置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="155"/>
|
||||
<location filename="options_dialog.cpp" line="152"/>
|
||||
<source>Image options</source>
|
||||
<translation>图片选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="159"/>
|
||||
<location filename="options_dialog.cpp" line="156"/>
|
||||
<source>Fit options</source>
|
||||
<translation>适应项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="161"/>
|
||||
<location filename="options_dialog.cpp" line="158"/>
|
||||
<source>Enlarge images to fit width/height</source>
|
||||
<translation>放大图片以适应宽度/高度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="172"/>
|
||||
<location filename="options_dialog.cpp" line="169"/>
|
||||
<source>Double Page options</source>
|
||||
<translation>双页选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="174"/>
|
||||
<location filename="options_dialog.cpp" line="171"/>
|
||||
<source>Show covers as single page</source>
|
||||
<translation>显示封面为单页</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="192"/>
|
||||
<location filename="options_dialog.cpp" line="189"/>
|
||||
<source>General</source>
|
||||
<translation>常规</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="193"/>
|
||||
<location filename="options_dialog.cpp" line="190"/>
|
||||
<source>Page Flow</source>
|
||||
<translation>页面流</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="194"/>
|
||||
<location filename="options_dialog.cpp" line="191"/>
|
||||
<source>Image adjustment</source>
|
||||
<translation>图像调整</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="209"/>
|
||||
<location filename="options_dialog.cpp" line="206"/>
|
||||
<source>Options</source>
|
||||
<translation>选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="216"/>
|
||||
<location filename="options_dialog.cpp" line="213"/>
|
||||
<source>Comics directory</source>
|
||||
<translation>漫画目录</translation>
|
||||
</message>
|
||||
@ -935,7 +935,7 @@
|
||||
<context>
|
||||
<name>YACReader::WhatsNewDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="104"/>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="95"/>
|
||||
<source>Close</source>
|
||||
<translation>关闭</translation>
|
||||
</message>
|
||||
|
@ -124,17 +124,17 @@
|
||||
<context>
|
||||
<name>HelpAboutDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="25"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="27"/>
|
||||
<source>About</source>
|
||||
<translation>關於</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="28"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="30"/>
|
||||
<source>Help</source>
|
||||
<translation>幫助</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="31"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="33"/>
|
||||
<source>System info</source>
|
||||
<translation>系統資訊</translation>
|
||||
</message>
|
||||
@ -190,112 +190,112 @@
|
||||
<translation>我的漫畫路徑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<location filename="options_dialog.cpp" line="61"/>
|
||||
<source>Background color</source>
|
||||
<translation>背景顏色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="67"/>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<source>Choose</source>
|
||||
<translation>選擇</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="100"/>
|
||||
<location filename="options_dialog.cpp" line="97"/>
|
||||
<source>Quick Navigation Mode</source>
|
||||
<translation>快速導航模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="101"/>
|
||||
<location filename="options_dialog.cpp" line="98"/>
|
||||
<source>Disable mouse over activation</source>
|
||||
<translation>禁用滑鼠啟動</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="200"/>
|
||||
<location filename="options_dialog.cpp" line="197"/>
|
||||
<source>Restart is needed</source>
|
||||
<translation>需要重啟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="144"/>
|
||||
<location filename="options_dialog.cpp" line="141"/>
|
||||
<source>Brightness</source>
|
||||
<translation>亮度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<location filename="options_dialog.cpp" line="71"/>
|
||||
<source>Scroll behaviour</source>
|
||||
<translation>滾動效果</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="77"/>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<source>Do not turn page using scroll</source>
|
||||
<translation>滾動時不翻頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="78"/>
|
||||
<location filename="options_dialog.cpp" line="75"/>
|
||||
<source>Use single scroll step to turn page</source>
|
||||
<translation>使用單滾動步驟翻頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="145"/>
|
||||
<location filename="options_dialog.cpp" line="142"/>
|
||||
<source>Contrast</source>
|
||||
<translation>對比度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="146"/>
|
||||
<location filename="options_dialog.cpp" line="143"/>
|
||||
<source>Gamma</source>
|
||||
<translation>Gamma值</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="150"/>
|
||||
<location filename="options_dialog.cpp" line="147"/>
|
||||
<source>Reset</source>
|
||||
<translation>重置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="155"/>
|
||||
<location filename="options_dialog.cpp" line="152"/>
|
||||
<source>Image options</source>
|
||||
<translation>圖片選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="159"/>
|
||||
<location filename="options_dialog.cpp" line="156"/>
|
||||
<source>Fit options</source>
|
||||
<translation>適應項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="161"/>
|
||||
<location filename="options_dialog.cpp" line="158"/>
|
||||
<source>Enlarge images to fit width/height</source>
|
||||
<translation>放大圖片以適應寬度/高度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="172"/>
|
||||
<location filename="options_dialog.cpp" line="169"/>
|
||||
<source>Double Page options</source>
|
||||
<translation>雙頁選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="174"/>
|
||||
<location filename="options_dialog.cpp" line="171"/>
|
||||
<source>Show covers as single page</source>
|
||||
<translation>顯示封面為單頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="192"/>
|
||||
<location filename="options_dialog.cpp" line="189"/>
|
||||
<source>General</source>
|
||||
<translation>常規</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="193"/>
|
||||
<location filename="options_dialog.cpp" line="190"/>
|
||||
<source>Page Flow</source>
|
||||
<translation>頁面流</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="194"/>
|
||||
<location filename="options_dialog.cpp" line="191"/>
|
||||
<source>Image adjustment</source>
|
||||
<translation>圖像調整</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="209"/>
|
||||
<location filename="options_dialog.cpp" line="206"/>
|
||||
<source>Options</source>
|
||||
<translation>選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="216"/>
|
||||
<location filename="options_dialog.cpp" line="213"/>
|
||||
<source>Comics directory</source>
|
||||
<translation>漫畫目錄</translation>
|
||||
</message>
|
||||
@ -935,7 +935,7 @@
|
||||
<context>
|
||||
<name>YACReader::WhatsNewDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="104"/>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="95"/>
|
||||
<source>Close</source>
|
||||
<translation>關閉</translation>
|
||||
</message>
|
||||
|
@ -124,17 +124,17 @@
|
||||
<context>
|
||||
<name>HelpAboutDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="25"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="27"/>
|
||||
<source>About</source>
|
||||
<translation>關於</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="28"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="30"/>
|
||||
<source>Help</source>
|
||||
<translation>幫助</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="31"/>
|
||||
<location filename="../custom_widgets/help_about_dialog.cpp" line="33"/>
|
||||
<source>System info</source>
|
||||
<translation>系統資訊</translation>
|
||||
</message>
|
||||
@ -190,112 +190,112 @@
|
||||
<translation>我的漫畫路徑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<location filename="options_dialog.cpp" line="61"/>
|
||||
<source>Background color</source>
|
||||
<translation>背景顏色</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="67"/>
|
||||
<location filename="options_dialog.cpp" line="64"/>
|
||||
<source>Choose</source>
|
||||
<translation>選擇</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="100"/>
|
||||
<location filename="options_dialog.cpp" line="97"/>
|
||||
<source>Quick Navigation Mode</source>
|
||||
<translation>快速導航模式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="101"/>
|
||||
<location filename="options_dialog.cpp" line="98"/>
|
||||
<source>Disable mouse over activation</source>
|
||||
<translation>禁用滑鼠啟動</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="200"/>
|
||||
<location filename="options_dialog.cpp" line="197"/>
|
||||
<source>Restart is needed</source>
|
||||
<translation>需要重啟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="144"/>
|
||||
<location filename="options_dialog.cpp" line="141"/>
|
||||
<source>Brightness</source>
|
||||
<translation>亮度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<location filename="options_dialog.cpp" line="71"/>
|
||||
<source>Scroll behaviour</source>
|
||||
<translation>滾動效果</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="77"/>
|
||||
<location filename="options_dialog.cpp" line="74"/>
|
||||
<source>Do not turn page using scroll</source>
|
||||
<translation>滾動時不翻頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="78"/>
|
||||
<location filename="options_dialog.cpp" line="75"/>
|
||||
<source>Use single scroll step to turn page</source>
|
||||
<translation>使用單滾動步驟翻頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="145"/>
|
||||
<location filename="options_dialog.cpp" line="142"/>
|
||||
<source>Contrast</source>
|
||||
<translation>對比度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="146"/>
|
||||
<location filename="options_dialog.cpp" line="143"/>
|
||||
<source>Gamma</source>
|
||||
<translation>Gamma值</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="150"/>
|
||||
<location filename="options_dialog.cpp" line="147"/>
|
||||
<source>Reset</source>
|
||||
<translation>重置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="155"/>
|
||||
<location filename="options_dialog.cpp" line="152"/>
|
||||
<source>Image options</source>
|
||||
<translation>圖片選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="159"/>
|
||||
<location filename="options_dialog.cpp" line="156"/>
|
||||
<source>Fit options</source>
|
||||
<translation>適應項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="161"/>
|
||||
<location filename="options_dialog.cpp" line="158"/>
|
||||
<source>Enlarge images to fit width/height</source>
|
||||
<translation>放大圖片以適應寬度/高度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="172"/>
|
||||
<location filename="options_dialog.cpp" line="169"/>
|
||||
<source>Double Page options</source>
|
||||
<translation>雙頁選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="174"/>
|
||||
<location filename="options_dialog.cpp" line="171"/>
|
||||
<source>Show covers as single page</source>
|
||||
<translation>顯示封面為單頁</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="192"/>
|
||||
<location filename="options_dialog.cpp" line="189"/>
|
||||
<source>General</source>
|
||||
<translation>常規</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="193"/>
|
||||
<location filename="options_dialog.cpp" line="190"/>
|
||||
<source>Page Flow</source>
|
||||
<translation>頁面流</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="194"/>
|
||||
<location filename="options_dialog.cpp" line="191"/>
|
||||
<source>Image adjustment</source>
|
||||
<translation>圖像調整</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="209"/>
|
||||
<location filename="options_dialog.cpp" line="206"/>
|
||||
<source>Options</source>
|
||||
<translation>選項</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="options_dialog.cpp" line="216"/>
|
||||
<location filename="options_dialog.cpp" line="213"/>
|
||||
<source>Comics directory</source>
|
||||
<translation>漫畫目錄</translation>
|
||||
</message>
|
||||
@ -935,7 +935,7 @@
|
||||
<context>
|
||||
<name>YACReader::WhatsNewDialog</name>
|
||||
<message>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="104"/>
|
||||
<location filename="../custom_widgets/whats_new_dialog.cpp" line="95"/>
|
||||
<source>Close</source>
|
||||
<translation>關閉</translation>
|
||||
</message>
|
||||
|
@ -83,6 +83,7 @@ HEADERS += comic_flow.h \
|
||||
db/comic_query_result_processor.h \
|
||||
db/folder_query_result_processor.h \
|
||||
db/query_lexer.h \
|
||||
folder_content_view.h \
|
||||
initial_comic_info_extractor.h \
|
||||
library_comic_opener.h \
|
||||
library_creator.h \
|
||||
@ -123,6 +124,7 @@ HEADERS += comic_flow.h \
|
||||
trayicon_controller.h \
|
||||
xml_info_library_scanner.h \
|
||||
xml_info_parser.h \
|
||||
yacreader_content_views_manager.h \
|
||||
yacreader_local_server.h \
|
||||
yacreader_main_toolbar.h \
|
||||
comics_remover.h \
|
||||
@ -147,7 +149,6 @@ HEADERS += comic_flow.h \
|
||||
empty_reading_list_widget.h \
|
||||
../common/scroll_management.h \
|
||||
../common/opengl_checker.h \
|
||||
yacreader_comics_views_manager.h \
|
||||
info_comics_view.h \
|
||||
yacreader_comics_selection_helper.h \
|
||||
yacreader_comic_info_helper.h \
|
||||
@ -165,6 +166,7 @@ SOURCES += comic_flow.cpp \
|
||||
db/comic_query_result_processor.cpp \
|
||||
db/folder_query_result_processor.cpp \
|
||||
db/query_lexer.cpp \
|
||||
folder_content_view.cpp \
|
||||
initial_comic_info_extractor.cpp \
|
||||
library_comic_opener.cpp \
|
||||
library_creator.cpp \
|
||||
@ -201,6 +203,7 @@ SOURCES += comic_flow.cpp \
|
||||
trayicon_controller.cpp \
|
||||
xml_info_library_scanner.cpp \
|
||||
xml_info_parser.cpp \
|
||||
yacreader_content_views_manager.cpp \
|
||||
yacreader_local_server.cpp \
|
||||
yacreader_main_toolbar.cpp \
|
||||
comics_remover.cpp \
|
||||
@ -227,7 +230,6 @@ SOURCES += comic_flow.cpp \
|
||||
empty_reading_list_widget.cpp \
|
||||
../common/scroll_management.cpp \
|
||||
../common/opengl_checker.cpp \
|
||||
yacreader_comics_views_manager.cpp \
|
||||
info_comics_view.cpp \
|
||||
yacreader_comics_selection_helper.cpp \
|
||||
yacreader_comic_info_helper.cpp\
|
||||
@ -284,7 +286,28 @@ TRANSLATIONS = yacreaderlibrary_es.ts \
|
||||
yacreaderlibrary_zh_TW.ts \
|
||||
yacreaderlibrary_zh_HK.ts \
|
||||
yacreaderlibrary_it.ts \
|
||||
yacreaderlibrary_source.ts
|
||||
yacreaderlibrary_en.ts
|
||||
|
||||
CONFIG += lrelease
|
||||
|
||||
win32 {
|
||||
CONFIG(release, debug|release) {
|
||||
SOURCE_QM_DIR = $$OUT_PWD/release/*.qm
|
||||
}
|
||||
CONFIG(debug, debug|release) {
|
||||
SOURCE_QM_DIR = $$OUT_PWD/debug/*.qm
|
||||
}
|
||||
|
||||
DEPLOYMENT_OUT_QM_DIR = ../release/languages/
|
||||
OUT_QM_DIR = $${DESTDIR}/languages/
|
||||
|
||||
QMAKE_POST_LINK += $(MKDIR) $$shell_path($${OUT_QM_DIR}) 2> NULL & \
|
||||
$(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${OUT_QM_DIR}) & \
|
||||
$(MKDIR) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) 2> NULL & \
|
||||
$(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${DEPLOYMENT_OUT_QM_DIR})
|
||||
} else {
|
||||
LRELEASE_DIR = ../release/languages/
|
||||
}
|
||||
|
||||
#QML/GridView
|
||||
QT += quick qml quickwidgets
|
||||
|
@ -11,18 +11,18 @@ 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.png"), tr("red")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_orange.png"), tr("orange")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_yellow.png"), tr("yellow")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_green.png"), tr("green")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_cyan.png"), tr("cyan")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_blue.png"), tr("blue")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_violet.png"), tr("violet")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_purple.png"), tr("purple")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_pink.png"), tr("pink")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_white.png"), tr("white")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_light.png"), tr("light")));
|
||||
list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_dark.png"), tr("dark")));
|
||||
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")));
|
||||
|
||||
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()));
|
||||
|
@ -466,18 +466,8 @@ void ComicVineDialog::getComicsInfo(QList<QPair<ComicDB, QString>> matchingInfo,
|
||||
|
||||
setLoadingMessage(tr("Retrieving tags for : %1").arg(p.first.getFileName()));
|
||||
}
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
db.open();
|
||||
db.transaction();
|
||||
foreach (ComicDB comic, comics) {
|
||||
DBHelper::update(&(comic.info), db);
|
||||
}
|
||||
db.commit();
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
DBHelper::updateComicsInfo(comics, databasePath);
|
||||
|
||||
emit accepted();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtDebug>
|
||||
#include <QStringBuilder>
|
||||
#include <limits>
|
||||
|
||||
#include "comic_item.h"
|
||||
@ -237,6 +238,7 @@ QHash<int, QByteArray> ComicModel::roleNames() const
|
||||
roles[HasBeenOpenedRole] = "has_been_opened";
|
||||
roles[CoverPathRole] = "cover_path";
|
||||
roles[PublicationDate] = "date";
|
||||
roles[ReadableTitle] = "readable_title";
|
||||
|
||||
return roles;
|
||||
}
|
||||
@ -275,7 +277,13 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const
|
||||
return item->data(Number);
|
||||
else if (role == TitleRole)
|
||||
return item->data(Title).isNull() ? item->data(FileName) : item->data(Title);
|
||||
else if (role == FileNameRole)
|
||||
else if (role == ReadableTitle) {
|
||||
QString title;
|
||||
if (!item->data(Number).isNull()) {
|
||||
title = title % "#" % item->data(Number).toString() % " ";
|
||||
}
|
||||
return QVariant(title % (item->data(Title).isNull() ? item->data(FileName).toString() : item->data(Title).toString()));
|
||||
} else if (role == FileNameRole)
|
||||
return item->data(FileName);
|
||||
else if (role == RatingRole)
|
||||
return item->data(Rating);
|
||||
@ -672,7 +680,8 @@ ComicDB ComicModel::getComic(const QModelIndex &mi)
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
@ -686,7 +695,8 @@ ComicDB ComicModel::_getComic(const QModelIndex &mi)
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
@ -726,7 +736,8 @@ QList<ComicDB> ComicModel::getAllComics()
|
||||
|
||||
int numComics = _data.count();
|
||||
for (int i = 0; i < numComics; i++) {
|
||||
comics.append(DBHelper::loadComic(_data.value(i)->data(ComicModel::Id).toULongLong(), db));
|
||||
bool found;
|
||||
comics.append(DBHelper::loadComic(_data.value(i)->data(ComicModel::Id).toULongLong(), db, found));
|
||||
}
|
||||
|
||||
db.commit();
|
||||
@ -755,7 +766,8 @@ QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> l
|
||||
foreach (QModelIndex mi, list) {
|
||||
if (read == YACReader::Read) {
|
||||
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(true));
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
c.info.read = true;
|
||||
DBHelper::update(&(c.info), db);
|
||||
}
|
||||
@ -763,7 +775,8 @@ QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> l
|
||||
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(false));
|
||||
_data.value(mi.row())->setData(ComicModel::CurrentPage, QVariant(1));
|
||||
_data.value(mi.row())->setData(ComicModel::HasBeenOpened, QVariant(false));
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
c.info.read = false;
|
||||
c.info.currentPage = 1;
|
||||
c.info.hasBeenOpened = false;
|
||||
@ -788,7 +801,8 @@ void ComicModel::setComicsManga(QList<QModelIndex> list, bool isManga)
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
foreach (QModelIndex mi, list) {
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
c.info.manga = isManga;
|
||||
DBHelper::update(&(c.info), db);
|
||||
}
|
||||
@ -808,7 +822,8 @@ qint64 ComicModel::asignNumbers(QList<QModelIndex> list, int startingNumber)
|
||||
idFirst = _data.value(list[0].row())->data(ComicModel::Id).toULongLong();
|
||||
int i = 0;
|
||||
foreach (QModelIndex mi, list) {
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
|
||||
bool found;
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found);
|
||||
c.info.number = startingNumber + i;
|
||||
c.info.edited = true;
|
||||
DBHelper::update(&(c.info), db);
|
||||
@ -864,7 +879,8 @@ void ComicModel::finishTransaction()
|
||||
void ComicModel::removeInTransaction(int row)
|
||||
{
|
||||
auto dbTransaction = QSqlDatabase::database(_databaseConnection);
|
||||
ComicDB c = DBHelper::loadComic(_data.at(row)->data(ComicModel::Id).toULongLong(), dbTransaction);
|
||||
bool found;
|
||||
ComicDB c = DBHelper::loadComic(_data.at(row)->data(ComicModel::Id).toULongLong(), dbTransaction, found);
|
||||
|
||||
DBHelper::removeFromDB(&c, dbTransaction);
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
@ -875,6 +891,32 @@ void ComicModel::removeInTransaction(int row)
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void ComicModel::reloadContinueReading()
|
||||
{
|
||||
setupReadingModelData(_databasePath);
|
||||
}
|
||||
|
||||
void ComicModel::reload()
|
||||
{
|
||||
switch (mode) {
|
||||
case Folder:
|
||||
setupFolderModelData(sourceId, _databasePath);
|
||||
break;
|
||||
case Favorites:
|
||||
setupFavoritesModelData(_databasePath);
|
||||
break;
|
||||
case Reading:
|
||||
setupReadingModelData(_databasePath);
|
||||
break;
|
||||
case Label:
|
||||
setupLabelModelData(sourceId, _databasePath);
|
||||
break;
|
||||
case ReadingList:
|
||||
setupReadingListModelData(sourceId, _databasePath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComicModel::remove(int row)
|
||||
{
|
||||
removeInTransaction(row);
|
||||
|
@ -54,6 +54,7 @@ public:
|
||||
HasBeenOpenedRole,
|
||||
CoverPathRole,
|
||||
PublicationDateRole,
|
||||
ReadableTitle,
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
@ -110,6 +111,8 @@ public:
|
||||
qint64 asignNumbers(QList<QModelIndex> list, int startingNumber);
|
||||
// void remove(ComicDB * comic, int row);
|
||||
void removeInTransaction(int row);
|
||||
void reloadContinueReading();
|
||||
void reload();
|
||||
void reload(const ComicDB &comic);
|
||||
void resetComicRating(const QModelIndex &mi);
|
||||
|
||||
|
@ -54,26 +54,26 @@ void drawMacOSXFinishedFolderIcon()
|
||||
#define ROOT 1
|
||||
|
||||
FolderModel::FolderModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), rootItem(0)
|
||||
: QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr), folderIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg")), folderFinishedIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder_finished.svg"))
|
||||
{
|
||||
}
|
||||
|
||||
FolderModel::FolderModel(QSqlQuery &sqlquery, QObject *parent)
|
||||
: QAbstractItemModel(parent), rootItem(0)
|
||||
: QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr)
|
||||
{
|
||||
// lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n
|
||||
QList<QVariant> rootData;
|
||||
rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
|
||||
rootItem = new FolderItem(rootData);
|
||||
rootItem->id = ROOT;
|
||||
rootItem->parentItem = 0;
|
||||
rootItem->parentItem = nullptr;
|
||||
setupModelData(sqlquery, rootItem);
|
||||
// sqlquery.finish();
|
||||
}
|
||||
|
||||
FolderModel::~FolderModel()
|
||||
{
|
||||
if (rootItem != 0)
|
||||
if (rootItem != nullptr)
|
||||
delete rootItem;
|
||||
}
|
||||
|
||||
@ -81,8 +81,37 @@ int FolderModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return static_cast<FolderItem *>(parent.internalPointer())->columnCount();
|
||||
else
|
||||
else {
|
||||
if (rootItem == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return rootItem->columnCount();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> FolderModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[FinishedRole] = "is_finished";
|
||||
roles[CompletedRole] = "is_completed";
|
||||
roles[IdRole] = "id";
|
||||
roles[MangaRole] = "is_manga";
|
||||
roles[CoverPathRole] = "cover_path";
|
||||
roles[FolderName] = "name";
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
void FolderModel::reload()
|
||||
{
|
||||
setupModelData(_databasePath);
|
||||
}
|
||||
|
||||
void FolderModel::reload(const QModelIndex &index)
|
||||
{
|
||||
// TODO: reload just the content under index for better efficiency
|
||||
setupModelData(_databasePath);
|
||||
}
|
||||
|
||||
QVariant FolderModel::data(const QModelIndex &index, int role) const
|
||||
@ -115,12 +144,16 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
#else
|
||||
if (item->data(FolderModel::Finished).toBool())
|
||||
return QVariant(YACReader::noHighlightedIcon(":/images/sidebar/folder_finished.png"));
|
||||
return QVariant(folderFinishedIcon);
|
||||
else
|
||||
return QVariant(YACReader::noHighlightedIcon(":/images/sidebar/folder.png"));
|
||||
return QVariant(folderIcon);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (role == FolderModel::FolderName) {
|
||||
return item->data(FolderModel::Name);
|
||||
}
|
||||
|
||||
if (role == FolderModel::CompletedRole)
|
||||
return item->data(FolderModel::Completed);
|
||||
|
||||
@ -133,6 +166,9 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
|
||||
if (role == FolderModel::IdRole)
|
||||
return item->id;
|
||||
|
||||
if (role == FolderModel::CoverPathRole)
|
||||
return getCoverUrlPathForComicHash(item->data(FirstChildHash).toString());
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
@ -150,6 +186,10 @@ Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const
|
||||
QVariant FolderModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (rootItem == nullptr) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
return rootItem->data(section);
|
||||
|
||||
@ -176,6 +216,26 @@ QModelIndex FolderModel::index(int row, int column, const QModelIndex &parent)
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex FolderModel::index(qulonglong folderId) const
|
||||
{
|
||||
QModelIndex index;
|
||||
YACReader::iterate(QModelIndex(), this, [&](const QModelIndex &idx) {
|
||||
if (index.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto item = static_cast<FolderItem *>(idx.internalPointer());
|
||||
if (item->id == folderId) {
|
||||
index = idx;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
QModelIndex FolderModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
@ -196,10 +256,14 @@ int FolderModel::rowCount(const QModelIndex &parent) const
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
if (!parent.isValid()) {
|
||||
if (rootItem == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
parentItem = rootItem;
|
||||
else
|
||||
} else {
|
||||
parentItem = static_cast<FolderItem *>(parent.internalPointer());
|
||||
}
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
@ -207,17 +271,17 @@ int FolderModel::rowCount(const QModelIndex &parent) const
|
||||
void FolderModel::setupModelData(QString path)
|
||||
{
|
||||
beginResetModel();
|
||||
if (rootItem != 0)
|
||||
if (rootItem != nullptr)
|
||||
delete rootItem; // TODO comprobar que se libera bien la memoria
|
||||
|
||||
rootItem = 0;
|
||||
rootItem = nullptr;
|
||||
|
||||
// inicializar el nodo ra<72>z
|
||||
QList<QVariant> rootData;
|
||||
rootData << "root"; // id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
|
||||
rootItem = new FolderItem(rootData);
|
||||
rootItem->id = ROOT;
|
||||
rootItem->parentItem = 0;
|
||||
rootItem->parentItem = nullptr;
|
||||
|
||||
// cargar la base de datos
|
||||
_databasePath = path;
|
||||
@ -235,6 +299,13 @@ void FolderModel::setupModelData(QString path)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void FolderModel::fullSetup(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
{
|
||||
rootItem = parent;
|
||||
|
||||
setupModelData(sqlquery, parent);
|
||||
}
|
||||
|
||||
void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
{
|
||||
// 64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
|
||||
@ -252,6 +323,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
int manga = record.indexOf("manga");
|
||||
int id = record.indexOf("id");
|
||||
int parentId = record.indexOf("parentId");
|
||||
int firstChildHash = record.indexOf("firstChildHash");
|
||||
|
||||
while (sqlquery.next()) {
|
||||
QList<QVariant> data;
|
||||
@ -261,6 +333,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
data << sqlquery.value(finished).toBool();
|
||||
data << sqlquery.value(completed).toBool();
|
||||
data << sqlquery.value(manga).toBool();
|
||||
data << sqlquery.value(firstChildHash).toString();
|
||||
auto item = new FolderItem(data);
|
||||
|
||||
item->id = sqlquery.value(id).toULongLong();
|
||||
@ -286,6 +359,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
int manga = record.indexOf("manga");
|
||||
int id = record.indexOf("id");
|
||||
int parentId = record.indexOf("parentId");
|
||||
int firstChildHash = record.indexOf("firstChildHash");
|
||||
|
||||
while (sqlquery.next()) {
|
||||
QList<QVariant> data;
|
||||
@ -295,6 +369,7 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
|
||||
data << sqlquery.value(finished).toBool();
|
||||
data << sqlquery.value(completed).toBool();
|
||||
data << sqlquery.value(manga).toBool();
|
||||
data << sqlquery.value(firstChildHash).toString();
|
||||
auto item = new FolderItem(data);
|
||||
|
||||
item->id = sqlquery.value(id).toULongLong();
|
||||
@ -329,16 +404,18 @@ void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool
|
||||
auto item = static_cast<FolderItem *>(mi.internalPointer());
|
||||
item->setData(FolderModel::Completed, status);
|
||||
|
||||
if (!isSubfolder) {
|
||||
Folder f = DBHelper::loadFolder(item->id, db);
|
||||
f.setCompleted(status);
|
||||
DBHelper::update(f, db);
|
||||
}
|
||||
}
|
||||
db.commit();
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed));
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
|
||||
}
|
||||
|
||||
void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool status)
|
||||
@ -351,16 +428,18 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s
|
||||
auto item = static_cast<FolderItem *>(mi.internalPointer());
|
||||
item->setData(FolderModel::Finished, status);
|
||||
|
||||
if (!isSubfolder) {
|
||||
Folder f = DBHelper::loadFolder(item->id, db);
|
||||
f.setFinished(status);
|
||||
DBHelper::update(f, db);
|
||||
}
|
||||
}
|
||||
db.commit();
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed));
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
|
||||
}
|
||||
|
||||
void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga)
|
||||
@ -383,14 +462,16 @@ void FolderModel::updateFolderManga(const QModelIndexList &list, bool manga)
|
||||
|
||||
setManga(item, manga);
|
||||
|
||||
if (!isSubfolder) {
|
||||
DBHelper::updateFolderTreeManga(item->id, db, manga);
|
||||
}
|
||||
}
|
||||
db.commit();
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Manga));
|
||||
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::FirstChildHash));
|
||||
}
|
||||
|
||||
QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
|
||||
@ -417,6 +498,97 @@ QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
|
||||
return result;
|
||||
}
|
||||
|
||||
FolderModel *FolderModel::getSubfoldersModel(const QModelIndex &mi)
|
||||
{
|
||||
qulonglong id = 1;
|
||||
FolderItem *parent = nullptr;
|
||||
if (mi.isValid()) {
|
||||
auto item = static_cast<FolderItem *>(mi.internalPointer());
|
||||
parent = new FolderItem(item->getData(), item->parent());
|
||||
id = parent->id = item->id;
|
||||
}
|
||||
|
||||
if (id == 1) {
|
||||
if (parent != nullptr) {
|
||||
delete parent;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
auto model = new FolderModel();
|
||||
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
|
||||
QSqlQuery selectQuery(db); // TODO check
|
||||
selectQuery.prepare("SELECT * FROM folder WHERE parentId = :parentId and id <> 1");
|
||||
selectQuery.bindValue(":parentId", id);
|
||||
selectQuery.exec();
|
||||
|
||||
if (parent != nullptr) {
|
||||
model->fullSetup(selectQuery, parent);
|
||||
}
|
||||
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
model->_databasePath = _databasePath;
|
||||
|
||||
model->isSubfolder = true;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
Folder FolderModel::getFolder(const QModelIndex &mi)
|
||||
{
|
||||
auto folderItem = static_cast<FolderItem *>(mi.internalPointer());
|
||||
auto name = folderItem->data(FolderModel::Name).toString();
|
||||
auto parentItem = folderItem->parent();
|
||||
auto folder = Folder(folderItem->id,
|
||||
parentItem->id,
|
||||
name,
|
||||
folderItem->parent()->data(Columns::Path).toString() + "/" + name,
|
||||
folderItem->data(Columns::Completed).toBool(),
|
||||
folderItem->data(Columns::Finished).toBool(),
|
||||
folderItem->data(Columns::Manga).toBool());
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
QModelIndex FolderModel::getIndexFromFolder(const Folder &folder, const QModelIndex &parent)
|
||||
{
|
||||
if (rootItem == nullptr) {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
auto numRows = rowCount(parent);
|
||||
for (auto i = 0; i < numRows; i++) {
|
||||
auto modelIndex = index(i, 0, parent);
|
||||
|
||||
if (modelIndex.isValid()) {
|
||||
auto folderItem = static_cast<FolderItem *>(modelIndex.internalPointer());
|
||||
|
||||
if (folderItem->id == folder.id) {
|
||||
return modelIndex;
|
||||
}
|
||||
|
||||
auto childModelIndex = getIndexFromFolder(folder, modelIndex);
|
||||
|
||||
if (childModelIndex.isValid()) {
|
||||
auto folderItem = static_cast<FolderItem *>(childModelIndex.internalPointer());
|
||||
|
||||
if (folderItem->id == folder.id) {
|
||||
return childModelIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
|
||||
{
|
||||
FolderItem *item;
|
||||
@ -531,6 +703,11 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod
|
||||
return index(destRow, 0, parent);
|
||||
}
|
||||
|
||||
QUrl FolderModel::getCoverUrlPathForComicHash(const QString &hash) const
|
||||
{
|
||||
return QUrl("file:" + _databasePath + "/covers/" + hash + ".jpg");
|
||||
}
|
||||
|
||||
void FolderModel::deleteFolder(const QModelIndex &mi)
|
||||
{
|
||||
beginRemoveRows(mi.parent(), mi.row(), mi.row());
|
||||
|
@ -7,9 +7,12 @@
|
||||
#include <QVariant>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlDatabase>
|
||||
#include <QUrl>
|
||||
#include <QIcon>
|
||||
|
||||
#include "yacreader_global.h"
|
||||
#include "folder.h"
|
||||
#include "folder_query_result_processor.h"
|
||||
#include "yacreader_global.h"
|
||||
|
||||
class FolderItem;
|
||||
|
||||
@ -51,11 +54,15 @@ public:
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex index(qulonglong folderId) const;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
// Convenience methods
|
||||
void reload();
|
||||
void reload(const QModelIndex &index);
|
||||
void setupModelData(QString path);
|
||||
QString getDatabase();
|
||||
QString getFolderPath(const QModelIndex &folder);
|
||||
@ -68,31 +75,44 @@ public:
|
||||
void updateFolderManga(const QModelIndexList &list, bool manga);
|
||||
|
||||
QStringList getSubfoldersNames(const QModelIndex &mi);
|
||||
FolderModel *getSubfoldersModel(const QModelIndex &mi);
|
||||
|
||||
Folder getFolder(const QModelIndex &mi);
|
||||
QModelIndex getIndexFromFolder(const Folder &folder, const QModelIndex &parent = QModelIndex());
|
||||
|
||||
void fetchMoreFromDB(const QModelIndex &parent);
|
||||
|
||||
QModelIndex addFolderAtParent(const QString &folderName, const QModelIndex &parent);
|
||||
|
||||
Q_INVOKABLE QUrl getCoverUrlPathForComicHash(const QString &hash) const;
|
||||
|
||||
enum Columns {
|
||||
Name = 0,
|
||||
Path = 1,
|
||||
Finished = 2,
|
||||
Completed = 3,
|
||||
Manga = 4
|
||||
Manga = 4,
|
||||
FirstChildHash = 5
|
||||
}; // id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL
|
||||
|
||||
enum Roles {
|
||||
FinishedRole = Qt::UserRole + 1,
|
||||
CompletedRole,
|
||||
IdRole,
|
||||
MangaRole
|
||||
MangaRole,
|
||||
CoverPathRole,
|
||||
FolderName,
|
||||
};
|
||||
|
||||
bool isSubfolder;
|
||||
|
||||
public slots:
|
||||
void deleteFolder(const QModelIndex &mi);
|
||||
void updateFolderChildrenInfo(qulonglong folderId);
|
||||
|
||||
private:
|
||||
void fullSetup(QSqlQuery &sqlquery, FolderItem *parent);
|
||||
|
||||
void setupModelData(QSqlQuery &sqlquery, FolderItem *parent);
|
||||
void updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent);
|
||||
|
||||
@ -100,6 +120,9 @@ private:
|
||||
QMap<unsigned long long int, FolderItem *> items; // relación entre folders
|
||||
|
||||
QString _databasePath;
|
||||
|
||||
QIcon folderIcon;
|
||||
QIcon folderFinishedIcon;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@ QIcon SpecialListItem::getIcon() const
|
||||
{
|
||||
if (itemData.count() > Id) {
|
||||
QString id = itemData.at(Id).toString();
|
||||
return YACReader::noHighlightedIcon(QString(":/images/lists/default_%1.png").arg(id));
|
||||
return YACReader::noHighlightedIcon(QString(":/images/lists/default_%1.svg").arg(id));
|
||||
}
|
||||
|
||||
QLOG_WARN() << "Icon for SpecialListItem not available";
|
||||
@ -76,7 +76,7 @@ QIcon LabelItem::getIcon() const
|
||||
{
|
||||
if (itemData.count() > Color) {
|
||||
QString color = itemData.at(Color).toString();
|
||||
return YACReader::noHighlightedIcon(QString(":/images/lists/label_%1.png").arg(color).toLower());
|
||||
return YACReader::noHighlightedIcon(QString(":/images/lists/label_%1.svg").arg(color).toLower());
|
||||
}
|
||||
|
||||
QLOG_WARN() << "Icon for label item not available";
|
||||
@ -127,19 +127,19 @@ qulonglong LabelItem::getId() const
|
||||
//------------------------------------------------------
|
||||
|
||||
ReadingListItem::ReadingListItem(const QList<QVariant> &data, ReadingListItem *p)
|
||||
: ListItem(data), parent(p)
|
||||
: ListItem(data), parent(p), list(YACReader::noHighlightedIcon(":/images/lists/list.svg")), folder(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg"))
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ReadingListItem::getIcon() const
|
||||
{
|
||||
if (parent->getId() == 0)
|
||||
return YACReader::noHighlightedIcon(":/images/lists/list.png"); // top level list
|
||||
return list; // top level list
|
||||
else
|
||||
#ifdef Q_OS_MAC
|
||||
return QFileIconProvider().icon(QFileIconProvider::Folder);
|
||||
#else
|
||||
return YACReader::noHighlightedIcon(":/images/sidebar/folder.png"); // sublist
|
||||
return folder; // sublist
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,9 @@ public:
|
||||
private:
|
||||
QList<ReadingListItem *> childItems;
|
||||
|
||||
QIcon list;
|
||||
QIcon folder;
|
||||
|
||||
enum DataIndexes {
|
||||
Name,
|
||||
Id,
|
||||
|
@ -143,7 +143,8 @@ ComicDB DBHelper::getComicInfo(qulonglong libraryId, qulonglong id)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
||||
|
||||
comic = DBHelper::loadComic(id, db);
|
||||
bool found;
|
||||
comic = DBHelper::loadComic(id, db, found);
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
@ -745,33 +746,27 @@ void DBHelper::propagateFolderUpdatesToParent(const Folder &folder, QSqlDatabase
|
||||
Folder DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase &db)
|
||||
{
|
||||
auto folder = loadFolder(folderId, db);
|
||||
QList<LibraryItem *> subitems;
|
||||
QList<LibraryItem *> subfolders = DBHelper::getFoldersFromParent(folderId, db, false);
|
||||
QList<LibraryItem *> comics = DBHelper::getComicsFromParent(folderId, db, false);
|
||||
QList<LibraryItem *> subfolders = DBHelper::getFoldersFromParent(folderId, db, true);
|
||||
QList<LibraryItem *> comics = DBHelper::getComicsFromParent(folderId, db, true);
|
||||
|
||||
QList<LibraryItem *> updatedSubfolders;
|
||||
for (auto sf : subfolders) {
|
||||
updatedSubfolders.append(new Folder(updateChildrenInfo(static_cast<Folder *>(sf)->id, db)));
|
||||
}
|
||||
|
||||
subitems.append(updatedSubfolders);
|
||||
subitems.append(comics);
|
||||
|
||||
std::sort(subitems.begin(), subitems.end(), naturalSortLessThanCILibraryItem);
|
||||
|
||||
QString coverHash = "";
|
||||
for (auto item : subitems) {
|
||||
if (item->isDir()) {
|
||||
|
||||
if (!comics.isEmpty()) {
|
||||
auto c = static_cast<ComicDB *>(comics[0]);
|
||||
coverHash = c->info.hash;
|
||||
} else {
|
||||
for (auto item : updatedSubfolders) {
|
||||
auto f = static_cast<Folder *>(item);
|
||||
auto firstChildHash = f->getFirstChildHash();
|
||||
if (!firstChildHash.isEmpty()) {
|
||||
coverHash = firstChildHash;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
auto c = static_cast<ComicDB *>(item);
|
||||
coverHash = c->info.hash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -798,7 +793,7 @@ Folder DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase &db)
|
||||
void DBHelper::updateChildrenInfo(QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery selectQuery(db); // TODO check
|
||||
selectQuery.prepare("SELECT id FROM folder f WHERE f.parentId = 1");
|
||||
selectQuery.prepare("SELECT id FROM folder f WHERE f.parentId = 1 AND f.id <> 1");
|
||||
selectQuery.exec();
|
||||
|
||||
while (selectQuery.next()) {
|
||||
@ -813,7 +808,8 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
||||
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
||||
bool found;
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
|
||||
comic.info.currentPage = comicInfo.currentPage;
|
||||
comic.info.hasBeenOpened = comicInfo.currentPage > 0 || comic.info.hasBeenOpened;
|
||||
comic.info.read = comic.info.read || comic.info.currentPage == comic.info.numPages;
|
||||
@ -833,7 +829,8 @@ void DBHelper::setComicAsReading(qulonglong libraryId, const ComicInfo &comicInf
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
||||
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
||||
bool found;
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
|
||||
comic.info.hasBeenOpened = true;
|
||||
comic.info.read = comic.info.read || comic.info.currentPage == comic.info.numPages;
|
||||
|
||||
@ -872,7 +869,8 @@ void DBHelper::updateFromRemoteClient(qulonglong libraryId, const ComicInfo &com
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath + "/.yacreaderlibrary");
|
||||
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
||||
bool found;
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
|
||||
|
||||
if (comic.info.hash == comicInfo.hash) {
|
||||
if (comicInfo.currentPage > 0) {
|
||||
@ -962,7 +960,8 @@ QMap<qulonglong, QList<ComicDB>> DBHelper::updateFromRemoteClient(const QMap<qul
|
||||
" WHERE id = :id ");
|
||||
|
||||
foreach (ComicInfo comicInfo, comics[libraryId]) {
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db);
|
||||
bool found;
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
|
||||
|
||||
if (comic.info.hash == comicInfo.hash) {
|
||||
bool isMoreRecent = false;
|
||||
@ -1176,6 +1175,22 @@ void DBHelper::reasignOrderToComicsInReadingList(qulonglong readingListId, QList
|
||||
db.commit();
|
||||
}
|
||||
|
||||
void DBHelper::updateComicsInfo(QList<ComicDB> &comics, const QString &databasePath)
|
||||
{
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
db.open();
|
||||
db.transaction();
|
||||
foreach (ComicDB comic, comics) {
|
||||
DBHelper::update(&(comic.info), db);
|
||||
}
|
||||
db.commit();
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
}
|
||||
|
||||
// inserts
|
||||
qulonglong DBHelper::insert(Folder *folder, QSqlDatabase &db)
|
||||
{
|
||||
@ -1632,7 +1647,7 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql
|
||||
return folder;
|
||||
}
|
||||
|
||||
ComicDB DBHelper::loadComic(qulonglong id, QSqlDatabase &db)
|
||||
ComicDB DBHelper::loadComic(qulonglong id, QSqlDatabase &db, bool &found)
|
||||
{
|
||||
ComicDB comic;
|
||||
|
||||
@ -1654,6 +1669,9 @@ ComicDB DBHelper::loadComic(qulonglong id, QSqlDatabase &db)
|
||||
comic.name = selectQuery.value(name).toString();
|
||||
comic.path = selectQuery.value(path).toString();
|
||||
comic.info = DBHelper::loadComicInfo(selectQuery.value(hash).toString(), db);
|
||||
found = true;
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
|
||||
return comic;
|
||||
|
@ -82,6 +82,7 @@ public:
|
||||
static void reasignOrderToComicsInFavorites(QList<qulonglong> comicIds, QSqlDatabase &db);
|
||||
static void reasignOrderToComicsInLabel(qulonglong labelId, QList<qulonglong> comicIds, QSqlDatabase &db);
|
||||
static void reasignOrderToComicsInReadingList(qulonglong readingListId, QList<qulonglong> comicIds, QSqlDatabase &db);
|
||||
static void updateComicsInfo(QList<ComicDB> &comics, const QString &databasePath);
|
||||
|
||||
static QList<LibraryItem *> getFoldersFromParent(qulonglong parentId, QSqlDatabase &db, bool sort = true);
|
||||
static QList<ComicDB> getSortedComicsFromParent(qulonglong parentId, QSqlDatabase &db);
|
||||
@ -93,7 +94,7 @@ public:
|
||||
// load
|
||||
static Folder loadFolder(qulonglong id, QSqlDatabase &db);
|
||||
static Folder loadFolder(const QString &folderName, qulonglong parentId, QSqlDatabase &db);
|
||||
static ComicDB loadComic(qulonglong id, QSqlDatabase &db);
|
||||
static ComicDB loadComic(qulonglong id, QSqlDatabase &db, bool &found);
|
||||
static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase &database);
|
||||
static ComicInfo loadComicInfo(QString hash, QSqlDatabase &db);
|
||||
static ComicInfo getComicInfoFromQuery(QSqlQuery &query, const QString &idKey = "id");
|
||||
|
278
YACReaderLibrary/folder_content_view.cpp
Normal file
278
YACReaderLibrary/folder_content_view.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
#include "folder_content_view.h"
|
||||
|
||||
#include "folder_model.h"
|
||||
#include "grid_comics_view.h"
|
||||
#include "yacreader_global_gui.h"
|
||||
#include "yacreader_tool_bar_stretch.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWidget>
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
FolderContentView::FolderContentView(QWidget *parent)
|
||||
: QWidget { parent }, parent(QModelIndex()), comicModel(new ComicModel()), folderModel(new FolderModel())
|
||||
{
|
||||
qmlRegisterType<FolderModel>("com.yacreader.FolderModel", 1, 0, "FolderModel");
|
||||
|
||||
settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat, this);
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
view = new QQuickWidget();
|
||||
|
||||
// QQuickWidget requires rendering into OpenGL framebuffer objects
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
view->quickWindow()->setGraphicsApi(QSGRendererInterface::OpenGL);
|
||||
#endif
|
||||
|
||||
view->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
connect(
|
||||
view, &QQuickWidget::statusChanged,
|
||||
[=](QQuickWidget::Status status) {
|
||||
if (status == QQuickWidget::Error) {
|
||||
QLOG_ERROR() << view->errors();
|
||||
}
|
||||
});
|
||||
|
||||
coverSizeSliderWidget = new QWidget(this);
|
||||
coverSizeSliderWidget->setFixedWidth(200);
|
||||
coverSizeSlider = new QSlider(coverSizeSliderWidget);
|
||||
coverSizeSlider->setOrientation(Qt::Horizontal);
|
||||
coverSizeSlider->setRange(YACREADER_MIN_GRID_ZOOM_WIDTH, YACREADER_MAX_GRID_ZOOM_WIDTH);
|
||||
|
||||
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);
|
||||
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);
|
||||
horizontalLayout->addSpacing(10);
|
||||
horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
coverSizeSliderWidget->setLayout(horizontalLayout);
|
||||
|
||||
connect(coverSizeSlider, &QAbstractSlider::valueChanged, this, &FolderContentView::setCoversSize);
|
||||
|
||||
toolbar = new QToolBar();
|
||||
toolbar->addWidget(new YACReaderToolBarStretch);
|
||||
toolbar->addWidget(coverSizeSliderWidget);
|
||||
|
||||
auto l = new QVBoxLayout;
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
l->setSpacing(0);
|
||||
l->addWidget(view);
|
||||
l->addWidget(toolbar);
|
||||
this->setLayout(l);
|
||||
|
||||
QQmlContext *ctxt = view->rootContext();
|
||||
|
||||
LibraryUITheme theme;
|
||||
#ifdef Q_OS_MAC
|
||||
theme = Light;
|
||||
#else
|
||||
theme = Dark;
|
||||
#endif
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
updateCoversSizeInContext(YACREADER_MIN_COVER_WIDTH, ctxt);
|
||||
|
||||
ctxt->setContextProperty("comicsList", comicModel.get());
|
||||
ctxt->setContextProperty("foldersList", folderModel);
|
||||
|
||||
ctxt->setContextProperty("showCurrentComic", QVariant(false));
|
||||
|
||||
ctxt->setContextProperty("openHelper", this);
|
||||
ctxt->setContextProperty("contextMenuHelper", this);
|
||||
|
||||
view->setSource(QUrl("qrc:/qml/FolderContentView.qml"));
|
||||
}
|
||||
|
||||
void FolderContentView::setModel(const QModelIndex &parent, FolderModel *model)
|
||||
{
|
||||
this->parent = parent;
|
||||
QQmlContext *ctxt = view->rootContext();
|
||||
|
||||
ctxt->setContextProperty("foldersList", model);
|
||||
|
||||
// when the root folder is set, FolderModel just returns itself in `getSubfoldersModel`, I need to measure the performance of create a deep copy...
|
||||
if (folderModel->isSubfolder) {
|
||||
delete folderModel;
|
||||
}
|
||||
folderModel = model;
|
||||
|
||||
auto grid = view->rootObject()->findChild<QQuickItem *>(QStringLiteral("grid"));
|
||||
|
||||
if (grid != nullptr) {
|
||||
grid->setProperty("currentIndex", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderContentView::setContinueReadingModel(ComicModel *model)
|
||||
{
|
||||
QQmlContext *ctxt = view->rootContext();
|
||||
|
||||
ctxt->setContextProperty("comicsList", model);
|
||||
this->comicModel.reset(model);
|
||||
|
||||
auto list = view->rootObject()->findChild<QQuickItem *>(QStringLiteral("list"));
|
||||
|
||||
if (list != nullptr) {
|
||||
list->setProperty("currentIndex", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderContentView::reloadContinueReadingModel()
|
||||
{
|
||||
if (!folderModel->isSubfolder) {
|
||||
comicModel->reloadContinueReading();
|
||||
}
|
||||
}
|
||||
|
||||
void FolderContentView::openFolder(int index)
|
||||
{
|
||||
emit subfolderSelected(this->parent, index);
|
||||
}
|
||||
|
||||
void FolderContentView::openComicFromContinueReadingList(int index)
|
||||
{
|
||||
auto comic = comicModel->getComic(comicModel->index(index, 0));
|
||||
emit openComic(comic, ComicModel::Folder);
|
||||
}
|
||||
|
||||
void FolderContentView::requestedFolderContextMenu(QPoint point, int index)
|
||||
{
|
||||
auto folder = folderModel->getFolder(folderModel->index(index, 0));
|
||||
emit openFolderContextMenu(point, folder);
|
||||
}
|
||||
|
||||
void FolderContentView::requestedContinueReadingComicContextMenu(QPoint point, int index)
|
||||
{
|
||||
auto comic = comicModel->getComic(comicModel->index(index, 0));
|
||||
emit openContinueReadingComicContextMenu(point, comic);
|
||||
}
|
||||
|
||||
void FolderContentView::updateCoversSizeInContext(int width, QQmlContext *ctxt)
|
||||
{
|
||||
int cellBottomMarging = 8 * (1 + 2 * (1 - (float(YACREADER_MAX_GRID_ZOOM_WIDTH - width) / (YACREADER_MAX_GRID_ZOOM_WIDTH - YACREADER_MIN_GRID_ZOOM_WIDTH))));
|
||||
|
||||
ctxt->setContextProperty("cellCustomHeight", ((width * YACREADER_MAX_COVER_HEIGHT) / YACREADER_MIN_COVER_WIDTH) + 51 + cellBottomMarging);
|
||||
ctxt->setContextProperty("cellCustomWidth", (width * YACREADER_MIN_CELL_CUSTOM_WIDTH) / YACREADER_MIN_COVER_WIDTH);
|
||||
|
||||
ctxt->setContextProperty("itemWidth", width);
|
||||
ctxt->setContextProperty("itemHeight", ((width * YACREADER_MAX_COVER_HEIGHT) / YACREADER_MIN_COVER_WIDTH) + 51);
|
||||
|
||||
ctxt->setContextProperty("coverWidth", width);
|
||||
ctxt->setContextProperty("coverHeight", (width * YACREADER_MAX_COVER_HEIGHT) / YACREADER_MIN_COVER_WIDTH);
|
||||
}
|
||||
|
||||
void FolderContentView::setCoversSize(int width)
|
||||
{
|
||||
QQmlContext *ctxt = view->rootContext();
|
||||
|
||||
auto grid = view->rootObject()->findChild<QQuickItem *>(QStringLiteral("grid"));
|
||||
|
||||
if (grid != 0) {
|
||||
QVariant cellCustomWidth = (width * YACREADER_MIN_CELL_CUSTOM_WIDTH) / YACREADER_MIN_GRID_ZOOM_WIDTH;
|
||||
QMetaObject::invokeMethod(grid, "calculateCellWidths",
|
||||
Q_ARG(QVariant, cellCustomWidth));
|
||||
}
|
||||
|
||||
updateCoversSizeInContext(width, ctxt);
|
||||
|
||||
settings->setValue(COMICS_GRID_COVER_SIZES, coverSizeSlider->value());
|
||||
}
|
||||
|
||||
void FolderContentView::showEvent(QShowEvent *event)
|
||||
{
|
||||
QWidget::showEvent(event);
|
||||
|
||||
int coverSize = settings->value(COMICS_GRID_COVER_SIZES, YACREADER_MIN_COVER_WIDTH).toInt();
|
||||
|
||||
coverSizeSlider->setValue(coverSize);
|
||||
setCoversSize(coverSize);
|
||||
}
|
||||
|
||||
void FolderContentView::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
void FolderContentView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
}
|
72
YACReaderLibrary/folder_content_view.h
Normal file
72
YACReaderLibrary/folder_content_view.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef FOLDERCONTENTVIEW_H
|
||||
#define FOLDERCONTENTVIEW_H
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "comic_model.h"
|
||||
|
||||
#include "folder.h"
|
||||
#include "comic_db.h"
|
||||
|
||||
class FolderModel;
|
||||
class ComicModel;
|
||||
class YACReaderToolBarStretch;
|
||||
|
||||
class QQuickWidget;
|
||||
class QQmlContext;
|
||||
|
||||
class FolderContentView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FolderContentView(QWidget *parent = nullptr);
|
||||
void setModel(const QModelIndex &parent, FolderModel *model);
|
||||
void setContinueReadingModel(ComicModel *model);
|
||||
void reloadContinueReadingModel();
|
||||
|
||||
FolderModel *currentFolderModel() { return folderModel; }
|
||||
signals:
|
||||
void subfolderSelected(QModelIndex, int);
|
||||
void openComic(const ComicDB &comic, const ComicModel::Mode mode);
|
||||
|
||||
// Drops
|
||||
void copyComicsToCurrentFolder(QList<QPair<QString, QString>>);
|
||||
void moveComicsToCurrentFolder(QList<QPair<QString, QString>>);
|
||||
|
||||
void openFolderContextMenu(QPoint point, Folder folder);
|
||||
void openContinueReadingComicContextMenu(QPoint point, ComicDB comic);
|
||||
|
||||
protected slots:
|
||||
// void onItemClicked(const QModelIndex &mi);
|
||||
void updateCoversSizeInContext(int width, QQmlContext *ctxt);
|
||||
void setCoversSize(int width);
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
void openFolder(int index);
|
||||
void openComicFromContinueReadingList(int index);
|
||||
void requestedFolderContextMenu(QPoint point, int index);
|
||||
void requestedContinueReadingComicContextMenu(QPoint point, int index);
|
||||
|
||||
protected:
|
||||
QQuickWidget *view;
|
||||
QModelIndex parent;
|
||||
|
||||
std::unique_ptr<ComicModel> comicModel;
|
||||
FolderModel *folderModel;
|
||||
|
||||
// Drop to import
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
private:
|
||||
QSettings *settings;
|
||||
QToolBar *toolbar;
|
||||
YACReaderToolBarStretch *toolBarStretch;
|
||||
QAction *toolBarStretchAction;
|
||||
QWidget *coverSizeSliderWidget;
|
||||
QSlider *coverSizeSlider;
|
||||
QAction *coverSizeSliderAction;
|
||||
QAction *showInfoAction;
|
||||
QAction *showInfoSeparatorAction;
|
||||
};
|
||||
|
||||
#endif // FOLDERCONTENTVIEW_H
|
@ -14,22 +14,6 @@
|
||||
#include "yacreader_comic_info_helper.h"
|
||||
#include "current_comic_view_helper.h"
|
||||
|
||||
// values relative to visible cells
|
||||
const unsigned int YACREADER_MIN_GRID_ZOOM_WIDTH = 156;
|
||||
const unsigned int YACREADER_MAX_GRID_ZOOM_WIDTH = 312;
|
||||
|
||||
// GridView cells
|
||||
const unsigned int YACREADER_MIN_CELL_CUSTOM_HEIGHT = 295;
|
||||
const unsigned int YACREADER_MIN_CELL_CUSTOM_WIDTH = 185;
|
||||
|
||||
// Covers
|
||||
const unsigned int YACREADER_MAX_COVER_HEIGHT = 236;
|
||||
const unsigned int YACREADER_MIN_COVER_WIDTH = YACREADER_MIN_GRID_ZOOM_WIDTH;
|
||||
|
||||
// visible cells (realCell in qml), grid cells size is used to create faux inner margings
|
||||
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;
|
||||
|
||||
GridComicsView::GridComicsView(QWidget *parent)
|
||||
: ComicsView(parent), filterEnabled(false)
|
||||
{
|
||||
@ -161,7 +145,7 @@ 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.png"));
|
||||
showInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/show_comic_info.svg"));
|
||||
showInfoAction->setCheckable(true);
|
||||
showInfoAction->setChecked(showInfo);
|
||||
connect(showInfoAction, &QAction::toggled, this, &GridComicsView::showInfo);
|
||||
@ -195,11 +179,11 @@ void GridComicsView::createCoverSizeSliderWidget()
|
||||
|
||||
auto horizontalLayout = new QHBoxLayout();
|
||||
QLabel *smallLabel = new QLabel();
|
||||
smallLabel->setPixmap(QPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.png"));
|
||||
smallLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.svg", QSize(18, 18)));
|
||||
horizontalLayout->addWidget(smallLabel);
|
||||
horizontalLayout->addWidget(coverSizeSlider, 0, Qt::AlignVCenter);
|
||||
QLabel *bigLabel = new QLabel();
|
||||
bigLabel->setPixmap(QPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.png"));
|
||||
bigLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.svg", QSize(18, 18)));
|
||||
horizontalLayout->addWidget(bigLabel);
|
||||
horizontalLayout->addSpacing(10);
|
||||
horizontalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -422,6 +406,8 @@ void GridComicsView::setCoversSize(int width)
|
||||
}
|
||||
|
||||
updateCoversSizeInContext(width, ctxt);
|
||||
|
||||
settings->setValue(COMICS_GRID_COVER_SIZES, coverSizeSlider->value());
|
||||
}
|
||||
|
||||
void GridComicsView::updateCoversSizeInContext(int width, QQmlContext *ctxt)
|
||||
@ -478,6 +464,15 @@ void GridComicsView::resetScroll()
|
||||
QMetaObject::invokeMethod(scrollView, "scrollToOrigin");
|
||||
}
|
||||
|
||||
void GridComicsView::showEvent(QShowEvent *event)
|
||||
{
|
||||
ComicsView::showEvent(event);
|
||||
int coverSize = settings->value(COMICS_GRID_COVER_SIZES, YACREADER_MIN_COVER_WIDTH).toInt();
|
||||
|
||||
coverSizeSlider->setValue(coverSize);
|
||||
setCoversSize(coverSize);
|
||||
}
|
||||
|
||||
QByteArray GridComicsView::getMimeDataFromSelection()
|
||||
{
|
||||
QByteArray data;
|
||||
@ -504,7 +499,7 @@ void GridComicsView::startDrag()
|
||||
{
|
||||
auto drag = new QDrag(this);
|
||||
drag->setMimeData(model->mimeData(selectionHelper->selectedRows()));
|
||||
drag->setPixmap(QPixmap(":/images/comics_view_toolbar/openInYACReader.png")); // TODO add better image
|
||||
drag->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/openInYACReader.svg", QSize(18, 18))); // TODO add better image
|
||||
|
||||
/*Qt::DropAction dropAction =*/drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
|
||||
}
|
||||
|
@ -16,6 +16,22 @@ class YACReaderToolBarStretch;
|
||||
class YACReaderComicsSelectionHelper;
|
||||
class YACReaderComicInfoHelper;
|
||||
|
||||
// values relative to visible cells
|
||||
const unsigned int YACREADER_MIN_GRID_ZOOM_WIDTH = 156;
|
||||
const unsigned int YACREADER_MAX_GRID_ZOOM_WIDTH = 312;
|
||||
|
||||
// GridView cells
|
||||
const unsigned int YACREADER_MIN_CELL_CUSTOM_HEIGHT = 295;
|
||||
const unsigned int YACREADER_MIN_CELL_CUSTOM_WIDTH = 185;
|
||||
|
||||
// Covers
|
||||
const unsigned int YACREADER_MAX_COVER_HEIGHT = 236;
|
||||
const unsigned int YACREADER_MIN_COVER_WIDTH = YACREADER_MIN_GRID_ZOOM_WIDTH;
|
||||
|
||||
// visible cells (realCell in qml), grid cells size is used to create faux inner margings
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -73,6 +89,8 @@ protected slots:
|
||||
|
||||
void resetScroll();
|
||||
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void onScrollToOrigin();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>../images/accept_shortcut.png</file>
|
||||
<file>../images/clear_shortcut.png</file>
|
||||
<file>../images/accept_shortcut.svg</file>
|
||||
<file>../images/clear_shortcut.svg</file>
|
||||
<file>../images/comic_vine/downArrow.png</file>
|
||||
<file>../images/comic_vine/nextPage.png</file>
|
||||
<file>../images/comic_vine/previousPage.png</file>
|
||||
@ -10,36 +10,21 @@
|
||||
<file>../images/comic_vine/rowDown.png</file>
|
||||
<file>../images/comic_vine/rowUp.png</file>
|
||||
<file>../images/comic_vine/upArrow.png</file>
|
||||
<file>../images/comics_view_toolbar/asignNumber.png</file>
|
||||
<file>../images/comics_view_toolbar/asignNumber@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/big_size_grid_zoom.png</file>
|
||||
<file>../images/comics_view_toolbar/big_size_grid_zoom@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/editComic.png</file>
|
||||
<file>../images/comics_view_toolbar/editComic@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/getInfo.png</file>
|
||||
<file>../images/comics_view_toolbar/getInfo@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/hideComicFlow.png</file>
|
||||
<file>../images/comics_view_toolbar/hideComicFlow@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/openInYACReader.png</file>
|
||||
<file>../images/comics_view_toolbar/openInYACReader@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/selectAll.png</file>
|
||||
<file>../images/comics_view_toolbar/selectAll@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/setReadButton.png</file>
|
||||
<file>../images/comics_view_toolbar/setReadButton@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/setUnread.png</file>
|
||||
<file>../images/comics_view_toolbar/setUnread@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/showMarks.png</file>
|
||||
<file>../images/comics_view_toolbar/showMarks@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/small_size_grid_zoom.png</file>
|
||||
<file>../images/comics_view_toolbar/small_size_grid_zoom@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/trash.png</file>
|
||||
<file>../images/comics_view_toolbar/trash@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/show_comic_info.png</file>
|
||||
<file>../images/comics_view_toolbar/show_comic_info@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/setManga.png</file>
|
||||
<file>../images/comics_view_toolbar/setManga@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/setNormal.png</file>
|
||||
<file>../images/comics_view_toolbar/setNormal@2x.png</file>
|
||||
<file>../images/comics_view_toolbar/asignNumber.svg</file>
|
||||
<file>../images/comics_view_toolbar/big_size_grid_zoom.svg</file>
|
||||
<file>../images/comics_view_toolbar/editComic.svg</file>
|
||||
<file>../images/comics_view_toolbar/getInfo.svg</file>
|
||||
<file>../images/comics_view_toolbar/hideComicFlow.svg</file>
|
||||
<file>../images/comics_view_toolbar/openInYACReader.svg</file>
|
||||
<file>../images/comics_view_toolbar/selectAll.svg</file>
|
||||
<file>../images/comics_view_toolbar/setReadButton.svg</file>
|
||||
<file>../images/comics_view_toolbar/setUnread.svg</file>
|
||||
<file>../images/comics_view_toolbar/showMarks.svg</file>
|
||||
<file>../images/comics_view_toolbar/small_size_grid_zoom.svg</file>
|
||||
<file>../images/comics_view_toolbar/trash.svg</file>
|
||||
<file>../images/comics_view_toolbar/show_comic_info.svg</file>
|
||||
<file>../images/comics_view_toolbar/setManga.svg</file>
|
||||
<file>../images/comics_view_toolbar/setNormal.svg</file>
|
||||
<file>../images/defaultCover.png</file>
|
||||
<file>../images/edit.png</file>
|
||||
<file>../images/empty_current_readings.png</file>
|
||||
@ -64,23 +49,16 @@
|
||||
<file>../images/importingIcon.png</file>
|
||||
<file>../images/importLibrary.png</file>
|
||||
<file>../images/importTopCoversDecoration.png</file>
|
||||
<file>../images/main_toolbar/divider.png</file>
|
||||
<file>../images/menus_icons/editIcon.png</file>
|
||||
<file>../images/menus_icons/editIcon@2x.png</file>
|
||||
<file>../images/menus_icons/exportComicsInfoIcon.png</file>
|
||||
<file>../images/menus_icons/exportComicsInfoIcon@2x.png</file>
|
||||
<file>../images/menus_icons/exportLibraryIcon.png</file>
|
||||
<file>../images/menus_icons/exportLibraryIcon@2x.png</file>
|
||||
<file>../images/menus_icons/importComicsInfoIcon.png</file>
|
||||
<file>../images/menus_icons/importComicsInfoIcon@2x.png</file>
|
||||
<file>../images/menus_icons/importLibraryIcon.png</file>
|
||||
<file>../images/menus_icons/importLibraryIcon@2x.png</file>
|
||||
<file>../images/menus_icons/open.png</file>
|
||||
<file>../images/menus_icons/open@2x.png</file>
|
||||
<file>../images/menus_icons/removeLibraryIcon.png</file>
|
||||
<file>../images/menus_icons/removeLibraryIcon@2x.png</file>
|
||||
<file>../images/menus_icons/updateLibraryIcon.png</file>
|
||||
<file>../images/menus_icons/updateLibraryIcon@2x.png</file>
|
||||
<file>../images/main_toolbar/divider.svg</file>
|
||||
<file>../images/menus_icons/editIcon.svg</file>
|
||||
<file>../images/menus_icons/exportComicsInfoIcon.svg</file>
|
||||
<file>../images/menus_icons/exportLibraryIcon.svg</file>
|
||||
<file>../images/menus_icons/importComicsInfoIcon.svg</file>
|
||||
<file>../images/menus_icons/importLibraryIcon.svg</file>
|
||||
<file>../images/menus_icons/removeLibraryIcon.svg</file>
|
||||
<file>../images/menus_icons/updateLibraryIcon.svg</file>
|
||||
<file>../images/menus_icons/open_containing_folder.svg</file>
|
||||
<file>../images/menus_icons/update_current_folder.svg</file>
|
||||
<file>../images/new.png</file>
|
||||
<file>../images/nextCoverPage.png</file>
|
||||
<file>../images/noLibrariesIcon.png</file>
|
||||
@ -92,28 +70,43 @@
|
||||
<file>../images/readRibbon.png</file>
|
||||
<file>../images/searching_icon.png</file>
|
||||
<file>../images/serverConfigBackground.png</file>
|
||||
<file>../images/shortcuts_group_comics.png</file>
|
||||
<file>../images/shortcuts_group_folders.png</file>
|
||||
<file>../images/shortcuts_group_general.png</file>
|
||||
<file>../images/shortcuts_group_libraries.png</file>
|
||||
<file>../images/shortcuts_group_mglass.png</file>
|
||||
<file>../images/shortcuts_group_page.png</file>
|
||||
<file>../images/shortcuts_group_reading.png</file>
|
||||
<file>../images/shortcuts_group_visualization.png</file>
|
||||
<file>../images/shortcuts_group_comics.svg</file>
|
||||
<file>../images/shortcuts_group_folders.svg</file>
|
||||
<file>../images/shortcuts_group_general.svg</file>
|
||||
<file>../images/shortcuts_group_libraries.svg</file>
|
||||
<file>../images/shortcuts_group_mglass.svg</file>
|
||||
<file>../images/shortcuts_group_page.svg</file>
|
||||
<file>../images/shortcuts_group_reading.svg</file>
|
||||
<file>../images/shortcuts_group_visualization.svg</file>
|
||||
<file>../images/shownCovers.png</file>
|
||||
<file>../images/sidebar/branch-closed.png</file>
|
||||
<file>../images/sidebar/branch-open.png</file>
|
||||
<file>../images/sidebar/branch-closed.svg</file>
|
||||
<file>../images/sidebar/branch-open.svg</file>
|
||||
<file>../images/sidebar/collapsed_branch_osx.png</file>
|
||||
<file>../images/sidebar/collapsed_branch_selected.png</file>
|
||||
<file>../images/sidebar/expanded_branch_osx.png</file>
|
||||
<file>../images/sidebar/expanded_branch_selected.png</file>
|
||||
<file>../images/sidebar/folder.png</file>
|
||||
<file>../images/sidebar/folder_finished.png</file>
|
||||
<file>../images/sidebar/libraryIconSelected.png</file>
|
||||
<file>../images/sidebar/libraryOptions.png</file>
|
||||
<file>../images/sidebar/libraryOptions@2x.png</file>
|
||||
<file>../images/sidebar/folder.svg</file>
|
||||
<file>../images/sidebar/folder_finished.svg</file>
|
||||
<file>../images/sidebar/libraryIconSelected.svg</file>
|
||||
<file>../images/sidebar/libraryOptions.svg</file>
|
||||
<file>../images/updatingIcon.png</file>
|
||||
<file>../images/custom_dialog/custom_close_button.svg</file>
|
||||
<file>../images/whats_new/whatsnew_header.svg</file>
|
||||
|
||||
<file>../images/lists/default_0.svg</file>
|
||||
<file>../images/lists/default_1.svg</file>
|
||||
<file>../images/lists/label_blue.svg</file>
|
||||
<file>../images/lists/label_cyan.svg</file>
|
||||
<file>../images/lists/label_dark.svg</file>
|
||||
<file>../images/lists/label_green.svg</file>
|
||||
<file>../images/lists/label_light.svg</file>
|
||||
<file>../images/lists/label_orange.svg</file>
|
||||
<file>../images/lists/label_pink.svg</file>
|
||||
<file>../images/lists/label_purple.svg</file>
|
||||
<file>../images/lists/label_red.svg</file>
|
||||
<file>../images/lists/label_violet.svg</file>
|
||||
<file>../images/lists/label_white.svg</file>
|
||||
<file>../images/lists/label_yellow.svg</file>
|
||||
<file>../images/lists/list.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -23,37 +23,7 @@
|
||||
<file>../images/iconSearch@2x.png</file>
|
||||
<file>../images/clearSearch.png</file>
|
||||
<file>../images/clearSearch@2x.png</file>
|
||||
<file alias="images/lists/default_0.png">../images/lists/default_0_osx.png</file>
|
||||
<file alias="images/lists/default_1.png">../images/lists/default_1_osx.png</file>
|
||||
<file alias="images/lists/label_blue.png">../images/lists/label_blue_osx.png</file>
|
||||
<file alias="images/lists/label_cyan.png">../images/lists/label_cyan_osx.png</file>
|
||||
<file alias="images/lists/label_dark.png">../images/lists/label_dark_osx.png</file>
|
||||
<file alias="images/lists/label_green.png">../images/lists/label_green_osx.png</file>
|
||||
<file alias="images/lists/label_light.png">../images/lists/label_light_osx.png</file>
|
||||
<file alias="images/lists/label_orange.png">../images/lists/label_orange_osx.png</file>
|
||||
<file alias="images/lists/label_pink.png">../images/lists/label_pink_osx.png</file>
|
||||
<file alias="images/lists/label_purple.png">../images/lists/label_purple_osx.png</file>
|
||||
<file alias="images/lists/label_red.png">../images/lists/label_red_osx.png</file>
|
||||
<file alias="images/lists/label_violet.png">../images/lists/label_violet_osx.png</file>
|
||||
<file alias="images/lists/label_white.png">../images/lists/label_white_osx.png</file>
|
||||
<file alias="images/lists/label_yellow.png">../images/lists/label_yellow_osx.png</file>
|
||||
<file alias="images/lists/list.png">../images/lists/list_osx.png</file>
|
||||
<file alias="images/empty_reading_list.png">../images/empty_reading_list_osx.png</file>
|
||||
<file alias="images/lists/default_0@2x.png">../images/lists/default_0_osx@2x.png</file>
|
||||
<file alias="images/lists/default_1@2x.png">../images/lists/default_1_osx@2x.png</file>
|
||||
<file alias="images/lists/label_blue@2x.png">../images/lists/label_blue_osx@2x.png</file>
|
||||
<file alias="images/lists/label_cyan@2x.png">../images/lists/label_cyan_osx@2x.png</file>
|
||||
<file alias="images/lists/label_dark@2x.png">../images/lists/label_dark_osx@2x.png</file>
|
||||
<file alias="images/lists/label_green@2x.png">../images/lists/label_green_osx@2x.png</file>
|
||||
<file alias="images/lists/label_light@2x.png">../images/lists/label_light_osx@2x.png</file>
|
||||
<file alias="images/lists/label_orange@2x.png">../images/lists/label_orange_osx@2x.png</file>
|
||||
<file alias="images/lists/label_pink@2x.png">../images/lists/label_pink_osx@2x.png</file>
|
||||
<file alias="images/lists/label_purple@2x.png">../images/lists/label_purple_osx@2x.png</file>
|
||||
<file alias="images/lists/label_red@2x.png">../images/lists/label_red_osx@2x.png</file>
|
||||
<file alias="images/lists/label_violet@2x.png">../images/lists/label_violet_osx@2x.png</file>
|
||||
<file alias="images/lists/label_white@2x.png">../images/lists/label_white_osx@2x.png</file>
|
||||
<file alias="images/lists/label_yellow@2x.png">../images/lists/label_yellow_osx@2x.png</file>
|
||||
<file alias="images/lists/list@2x.png">../images/lists/list_osx@2x.png</file>
|
||||
<file alias="images/sidebar/libraryIcon.png">../images/sidebar/libraryIcon_osx.png</file>
|
||||
<file alias="images/sidebar/setRoot.png">../images/sidebar/setRoot_osx.png</file>
|
||||
<file alias="images/sidebar/expand.png">../images/sidebar/expand_osx.png</file>
|
||||
|
@ -1,47 +1,32 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>../images/main_toolbar/back.png</file>
|
||||
<file>../images/main_toolbar/back.svg</file>
|
||||
<file>../images/main_toolbar/back_disabled.png</file>
|
||||
<file>../images/main_toolbar/forward.png</file>
|
||||
<file>../images/main_toolbar/forward.svg</file>
|
||||
<file>../images/main_toolbar/forward_disabled.png</file>
|
||||
<file>../images/main_toolbar/settings.png</file>
|
||||
<file>../images/main_toolbar/server.png</file>
|
||||
<file>../images/main_toolbar/help.png</file>
|
||||
<file>../images/main_toolbar/fullscreen.png</file>
|
||||
<file>../images/sidebar/libraryIcon.png</file>
|
||||
<file>../images/sidebar/setRoot.png</file>
|
||||
<file>../images/sidebar/expand.png</file>
|
||||
<file>../images/sidebar/colapse.png</file>
|
||||
<file>../images/sidebar/newLibraryIcon.png</file>
|
||||
<file>../images/sidebar/openLibraryIcon.png</file>
|
||||
<file>../images/main_toolbar/flow.png</file>
|
||||
<file>../images/main_toolbar/grid.png</file>
|
||||
<file>../images/main_toolbar/info.png</file>
|
||||
<file>../images/main_toolbar/settings.svg</file>
|
||||
<file>../images/main_toolbar/server.svg</file>
|
||||
<file>../images/main_toolbar/help.svg</file>
|
||||
<file>../images/main_toolbar/fullscreen.svg</file>
|
||||
<file>../images/main_toolbar/flow.svg</file>
|
||||
<file>../images/main_toolbar/grid.svg</file>
|
||||
<file>../images/main_toolbar/info.svg</file>
|
||||
<file>../images/sidebar/libraryIcon.svg</file>
|
||||
<file>../images/sidebar/setRoot.svg</file>
|
||||
<file>../images/sidebar/expand.svg</file>
|
||||
<file>../images/sidebar/colapse.svg</file>
|
||||
<file>../images/sidebar/newLibraryIcon.svg</file>
|
||||
<file>../images/sidebar/openLibraryIcon.svg</file>
|
||||
<file>../images/sidebar/addNew_sidebar.svg</file>
|
||||
<file>../images/sidebar/delete_sidebar.svg</file>
|
||||
<file>../images/sidebar/addLabelIcon.svg</file>
|
||||
<file>../images/sidebar/renameListIcon.svg</file>
|
||||
<file>../images/empty_folder.png</file>
|
||||
<file>../images/empty_search.png</file>
|
||||
<file>../images/sidebar/addNew_sidebar.png</file>
|
||||
<file>../images/sidebar/delete_sidebar.png</file>
|
||||
<file alias="images/iconSearch.png">../images/iconSearchNew.png</file>
|
||||
<file alias="images/clearSearch.png">../images/clearSearchNew.png</file>
|
||||
<file>../images/sidebar/addLabelIcon.png</file>
|
||||
<file>../images/sidebar/renameListIcon.png</file>
|
||||
<file>../images/lists/default_0.png</file>
|
||||
<file>../images/lists/default_1.png</file>
|
||||
<file>../images/lists/label_blue.png</file>
|
||||
<file>../images/lists/label_cyan.png</file>
|
||||
<file>../images/lists/label_dark.png</file>
|
||||
<file>../images/lists/label_green.png</file>
|
||||
<file>../images/lists/label_light.png</file>
|
||||
<file>../images/lists/label_orange.png</file>
|
||||
<file>../images/lists/label_pink.png</file>
|
||||
<file>../images/lists/label_purple.png</file>
|
||||
<file>../images/lists/label_red.png</file>
|
||||
<file>../images/lists/label_violet.png</file>
|
||||
<file>../images/lists/label_white.png</file>
|
||||
<file>../images/lists/label_yellow.png</file>
|
||||
<file>../images/lists/list.png</file>
|
||||
<file alias="images/iconSearch.svg">../images/iconSearchNew.svg</file>
|
||||
<file alias="images/clearSearch.svg">../images/clearSearchNew.svg</file>
|
||||
<file>../images/empty_reading_list.png</file>
|
||||
<file>../images/viewer_toolbar/close.png</file>
|
||||
<file>../images/viewer_toolbar/close.svg</file>
|
||||
<file>icon.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -10,8 +10,8 @@ using namespace YACReader;
|
||||
|
||||
bool InitialComicInfoExtractor::crash = false;
|
||||
|
||||
InitialComicInfoExtractor::InitialComicInfoExtractor(QString fileSource, QString target, int coverPage)
|
||||
: _fileSource(fileSource), _target(target), _numPages(0), _coverPage(coverPage), _xmlInfoData()
|
||||
InitialComicInfoExtractor::InitialComicInfoExtractor(QString fileSource, QString target, int coverPage, bool getXMLMetadata)
|
||||
: _fileSource(fileSource), _target(target), _numPages(0), _coverPage(coverPage), getXMLMetadata(getXMLMetadata), _xmlInfoData()
|
||||
{
|
||||
}
|
||||
|
||||
@ -101,8 +101,8 @@ void InitialComicInfoExtractor::extract()
|
||||
|
||||
QList<QString> order = archive.getFileNames();
|
||||
|
||||
if (getXMLMetadata) {
|
||||
// Try to find embeded XML info (ComicRack or ComicTagger)
|
||||
|
||||
auto infoIndex = 0;
|
||||
for (auto &fileName : order) {
|
||||
if (fileName.endsWith(".xml", Qt::CaseInsensitive)) {
|
||||
@ -112,6 +112,7 @@ void InitialComicInfoExtractor::extract()
|
||||
|
||||
infoIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------
|
||||
|
||||
|
@ -9,7 +9,7 @@ class InitialComicInfoExtractor : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InitialComicInfoExtractor(QString fileSource, QString target = "", int coverPage = 1);
|
||||
InitialComicInfoExtractor(QString fileSource, QString target = "", int coverPage = 1, bool getXMLMetadata = false);
|
||||
|
||||
private:
|
||||
QString _fileSource;
|
||||
@ -19,6 +19,7 @@ private:
|
||||
QPair<int, int> _coverSize;
|
||||
QImage _cover;
|
||||
int _coverPage;
|
||||
int getXMLMetadata;
|
||||
static bool crash;
|
||||
QByteArray _xmlInfoData;
|
||||
void saveCover(const QString &path, const QImage &cover);
|
||||
|
@ -26,8 +26,8 @@ using namespace std;
|
||||
using namespace YACReader;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
LibraryCreator::LibraryCreator()
|
||||
: creation(false), partialUpdate(false)
|
||||
LibraryCreator::LibraryCreator(QSettings *settings)
|
||||
: creation(false), partialUpdate(false), settings(settings)
|
||||
{
|
||||
_nameFilter << Comic::comicExtensions;
|
||||
}
|
||||
@ -301,7 +301,7 @@ void LibraryCreator::insertComic(const QString &relativePath, const QFileInfo &f
|
||||
QPair<int, int> originalCoverSize = { 0, 0 };
|
||||
bool exists = checkCover(hash);
|
||||
|
||||
YACReader::InitialComicInfoExtractor ie(QDir::cleanPath(fileInfo.absoluteFilePath()), _target + "/covers/" + hash + ".jpg", comic.info.coverPage.toInt());
|
||||
YACReader::InitialComicInfoExtractor ie(QDir::cleanPath(fileInfo.absoluteFilePath()), _target + "/covers/" + hash + ".jpg", comic.info.coverPage.toInt(), settings->value(IMPORT_COMIC_INFO_XML_METADATA, false).toBool());
|
||||
|
||||
if (!(comic.hasCover() && exists)) {
|
||||
ie.extract();
|
||||
|
@ -22,7 +22,7 @@ class LibraryCreator : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LibraryCreator();
|
||||
LibraryCreator(QSettings *settings);
|
||||
void createLibrary(const QString &source, const QString &target);
|
||||
void updateLibrary(const QString &source, const QString &target);
|
||||
void updateFolder(const QString &source, const QString &target, const QString &folder, const QModelIndex &dest);
|
||||
@ -54,6 +54,7 @@ private:
|
||||
bool creation;
|
||||
bool partialUpdate;
|
||||
QModelIndex folderDestinationModelIndex;
|
||||
QSettings *settings;
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,8 @@
|
||||
#include "folder_query_result_processor.h"
|
||||
|
||||
#include "comic_model.h"
|
||||
#include "comic_db.h"
|
||||
#include "folder.h"
|
||||
|
||||
#include <future>
|
||||
#include <memory>
|
||||
@ -131,7 +133,7 @@ public:
|
||||
//-------------
|
||||
|
||||
YACReaderNavigationController *navigationController;
|
||||
YACReaderComicsViewsManager *comicsViewsManager;
|
||||
YACReaderContentViewsManager *contentViewsManager;
|
||||
|
||||
YACReaderFoldersView *foldersView;
|
||||
YACReaderReadingListsView *listsView;
|
||||
@ -217,6 +219,7 @@ public:
|
||||
QAction *asignOrderAction;
|
||||
QAction *forceCoverExtractedAction;
|
||||
QAction *deleteComicsAction;
|
||||
QAction *deleteMetadataAction;
|
||||
|
||||
QAction *focusSearchLineAction;
|
||||
QAction *focusComicsViewAction;
|
||||
@ -227,6 +230,7 @@ public:
|
||||
|
||||
QAction *updateFolderAction;
|
||||
QAction *updateCurrentFolderAction;
|
||||
QAction *rescanXMLFromCurrentFolderAction;
|
||||
|
||||
// reading lists actions
|
||||
QAction *addReadingListAction;
|
||||
@ -343,6 +347,8 @@ public slots:
|
||||
void removeLibrary();
|
||||
void renameLibrary();
|
||||
void rescanLibraryForXMLInfo();
|
||||
void rescanCurrentFolderForXMLInfo();
|
||||
void rescanFolderForXMLInfo(QModelIndex modelIndex);
|
||||
void rename(QString newName);
|
||||
void cancelCreating();
|
||||
void stopLibraryCreator();
|
||||
@ -374,14 +380,19 @@ public slots:
|
||||
void manageUpdatingError(const QString &error);
|
||||
void manageOpeningLibraryError(const QString &error);
|
||||
QModelIndexList getSelectedComics();
|
||||
void deleteMetadataFromSelectedComics();
|
||||
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);
|
||||
void libraryAlreadyExists(const QString &name);
|
||||
void importLibraryPackage();
|
||||
void updateComicsView(quint64 libraryId, const ComicDB &comic);
|
||||
void updateViewsOnClientSync();
|
||||
void updateViewsOnComicUpdateWithId(quint64 libraryId, quint64 comicId);
|
||||
void updateViewsOnComicUpdate(quint64 libraryId, const ComicDB &comic);
|
||||
void showComicVineScraper();
|
||||
void setRemoveError();
|
||||
void checkRemoveError();
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <QCommandLineParser>
|
||||
|
||||
#include "yacreader_global.h"
|
||||
#include "startup.h"
|
||||
#include "yacreader_http_server.h"
|
||||
#include "yacreader_local_server.h"
|
||||
#include "comic_db.h"
|
||||
#include "db_helper.h"
|
||||
@ -30,7 +30,7 @@
|
||||
#define PICTUREFLOW_QT4 1
|
||||
|
||||
// Server interface
|
||||
Startup *s;
|
||||
YACReaderHttpServer *httpServer;
|
||||
|
||||
using namespace QsLogging;
|
||||
|
||||
@ -164,21 +164,20 @@ int main(int argc, char **argv)
|
||||
logger.addDestination(std::move(fileDestination));
|
||||
|
||||
QTranslator translator;
|
||||
QString sufix = QLocale::system().name();
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
translator.load(QString(DATADIR) + "/yacreader/languages/yacreaderlibrary_" + sufix);
|
||||
translator.load(QLocale(), "yacreaderlibrary", "_", QString(DATADIR) + "/yacreader/languages");
|
||||
#else
|
||||
translator.load(QCoreApplication::applicationDirPath() + "/languages/yacreaderlibrary_" + sufix);
|
||||
translator.load(QLocale(), "yacreaderlibrary", "_", "languages");
|
||||
#endif
|
||||
app.installTranslator(&translator);
|
||||
|
||||
QTranslator viewerTranslator;
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
/*QTranslator viewerTranslator;
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
viewerTranslator.load(QString(DATADIR) + "/yacreader/languages/yacreader_" + sufix);
|
||||
#else
|
||||
#else
|
||||
viewerTranslator.load(QCoreApplication::applicationDirPath() + "/languages/yacreader_" + sufix);
|
||||
#endif
|
||||
app.installTranslator(&viewerTranslator);
|
||||
#endif
|
||||
app.installTranslator(&viewerTranslator);*/
|
||||
|
||||
qRegisterMetaType<ComicDB>("ComicDB");
|
||||
|
||||
@ -244,10 +243,10 @@ int main(int argc, char **argv)
|
||||
QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat);
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
s = new Startup();
|
||||
httpServer = new YACReaderHttpServer();
|
||||
|
||||
if (settings->value(SERVER_ON, true).toBool()) {
|
||||
s->start();
|
||||
httpServer->start();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -255,8 +254,9 @@ int main(int argc, char **argv)
|
||||
|
||||
auto mw = new LibraryWindow();
|
||||
|
||||
mw->connect(localServer, &YACReaderLocalServer::comicUpdated, mw, &LibraryWindow::updateComicsView, Qt::QueuedConnection);
|
||||
|
||||
mw->connect(localServer, &YACReaderLocalServer::comicUpdated, mw, &LibraryWindow::updateViewsOnComicUpdate, Qt::QueuedConnection);
|
||||
mw->connect(httpServer, &YACReaderHttpServer::comicUpdated, mw, &LibraryWindow::updateViewsOnComicUpdateWithId, Qt::QueuedConnection);
|
||||
mw->connect(httpServer, &YACReaderHttpServer::clientSync, mw, &LibraryWindow::updateViewsOnClientSync, Qt::QueuedConnection);
|
||||
// connections to localServer
|
||||
|
||||
// start as tray
|
||||
@ -276,8 +276,8 @@ int main(int argc, char **argv)
|
||||
YACReader::exitCheck(ret);
|
||||
|
||||
// shutdown
|
||||
s->stop();
|
||||
delete s;
|
||||
httpServer->stop();
|
||||
delete httpServer;
|
||||
localServer->close();
|
||||
delete localServer;
|
||||
delete mw;
|
||||
|
@ -50,13 +50,13 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
trayIconCheckbox = new QCheckBox(tr("Close to tray"));
|
||||
startToTrayCheckbox = new QCheckBox(tr("Start into the system tray"));
|
||||
|
||||
connect(trayIconCheckbox, &QCheckBox::clicked,
|
||||
connect(trayIconCheckbox, &QCheckBox::clicked, this,
|
||||
[=](bool checked) {
|
||||
settings->setValue(CLOSE_TO_TRAY, checked);
|
||||
startToTrayCheckbox->setEnabled(checked);
|
||||
emit optionsChanged();
|
||||
});
|
||||
connect(startToTrayCheckbox, &QCheckBox::clicked,
|
||||
connect(startToTrayCheckbox, &QCheckBox::clicked, this,
|
||||
[=](bool checked) {
|
||||
settings->setValue(START_TO_TRAY, checked);
|
||||
});
|
||||
@ -74,6 +74,18 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
|
||||
connect(apiKeyButton, &QAbstractButton::clicked, this, &OptionsDialog::editApiKey);
|
||||
|
||||
auto comicInfoXMLBox = new QGroupBox(tr("ComicInfo.xml legacy support"));
|
||||
|
||||
comicInfoXMLCheckbox = new QCheckBox(tr("Import metada from ComicInfo.xml when adding new comics"));
|
||||
connect(comicInfoXMLCheckbox, &QCheckBox::clicked, this,
|
||||
[=](bool checked) {
|
||||
settings->setValue(IMPORT_COMIC_INFO_XML_METADATA, checked);
|
||||
});
|
||||
|
||||
auto comicInfoXMLBoxLayout = new QVBoxLayout();
|
||||
comicInfoXMLBoxLayout->addWidget(comicInfoXMLCheckbox);
|
||||
comicInfoXMLBox->setLayout(comicInfoXMLBoxLayout);
|
||||
|
||||
// grid view background config
|
||||
useBackgroundImageCheck = new QCheckBox(tr("Enable background image"));
|
||||
|
||||
@ -139,13 +151,14 @@ OptionsDialog::OptionsDialog(QWidget *parent)
|
||||
generalLayout->addWidget(trayIconBox);
|
||||
generalLayout->addWidget(shortcutsBox);
|
||||
generalLayout->addWidget(apiKeyBox);
|
||||
generalLayout->addWidget(comicInfoXMLBox);
|
||||
generalLayout->addStretch();
|
||||
|
||||
tabWidget->addTab(generalW, tr("General"));
|
||||
tabWidget->addTab(comicFlowW, tr("Comic Flow"));
|
||||
#ifndef NO_OPENGL
|
||||
tabWidget->addTab(gridViewW, tr("Grid view"));
|
||||
#endif
|
||||
tabWidget->addTab(generalW, tr("General"));
|
||||
|
||||
layout->addWidget(tabWidget);
|
||||
layout->addLayout(buttons);
|
||||
@ -172,6 +185,8 @@ void OptionsDialog::restoreOptions(QSettings *settings)
|
||||
startToTrayCheckbox->setChecked(settings->value(START_TO_TRAY, false).toBool());
|
||||
startToTrayCheckbox->setEnabled(trayIconCheckbox->isChecked());
|
||||
|
||||
comicInfoXMLCheckbox->setChecked(settings->value(IMPORT_COMIC_INFO_XML_METADATA, false).toBool());
|
||||
|
||||
bool useBackgroundImage = settings->value(USE_BACKGROUND_IMAGE_IN_GRID_VIEW, true).toBool();
|
||||
|
||||
useBackgroundImageCheck->setChecked(useBackgroundImage);
|
||||
|
@ -37,6 +37,7 @@ private:
|
||||
QCheckBox *displayContinueReadingBannerCheck;
|
||||
QCheckBox *trayIconCheckbox;
|
||||
QCheckBox *startToTrayCheckbox;
|
||||
QCheckBox *comicInfoXMLCheckbox;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/GridComicsView.qml</file>
|
||||
<file>qml/FolderContentView.qml</file>
|
||||
<file>qml/tick.png</file>
|
||||
<file>qml/reading.png</file>
|
||||
<file>qml/star_menu.png</file>
|
||||
|
457
YACReaderLibrary/qml/FolderContentView.qml
Normal file
457
YACReaderLibrary/qml/FolderContentView.qml
Normal file
@ -0,0 +1,457 @@
|
||||
import QtQuick 2.15
|
||||
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import com.yacreader.ComicModel 1.0
|
||||
|
||||
import com.yacreader.ComicInfo 1.0
|
||||
import com.yacreader.ComicDB 1.0
|
||||
|
||||
Rectangle {
|
||||
id: main
|
||||
|
||||
property int continuReadingHeight: 430;
|
||||
property int topContentMargin: 20;
|
||||
|
||||
color: backgroundColor
|
||||
anchors.margins: 0
|
||||
|
||||
Component {
|
||||
id: appDelegate
|
||||
Rectangle
|
||||
{
|
||||
id: cell
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
color: "#00000000"
|
||||
|
||||
scale: mouseArea.containsMouse ? 1.025 : 1
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 90 }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: realCell
|
||||
|
||||
property int position : 0
|
||||
|
||||
width: itemWidth
|
||||
height: itemHeight
|
||||
|
||||
color: "transparent"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onDoubleClicked: {
|
||||
openHelper.openFolder(index);
|
||||
}
|
||||
|
||||
onPressed: mouse => {
|
||||
var ci = grid.currentIndex; //save current index
|
||||
|
||||
mouse.accepted = true;
|
||||
|
||||
if(mouse.button === Qt.RightButton) // context menu is requested
|
||||
{
|
||||
var coordinates = main.mapFromItem(realCell,mouseX,mouseY)
|
||||
contextMenuHelper.requestedFolderContextMenu(Qt.point(coordinates.x,coordinates.y), index);
|
||||
mouse.accepted = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
Rectangle {
|
||||
transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: -4}
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "#20000000"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: 3}
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "#88000000"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: coverWidth
|
||||
height: coverHeight
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
id: coverElement
|
||||
|
||||
Image {
|
||||
id: coverImage
|
||||
anchors.fill: parent
|
||||
source: cover_path
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous : true
|
||||
cache: true
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
anchors.fill: parent
|
||||
cached: true
|
||||
maskSource: Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//border
|
||||
Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "transparent"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
//folder name
|
||||
Text {
|
||||
id : titleText
|
||||
anchors { top: coverElement.bottom; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 10; }
|
||||
width: itemWidth - 8
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
text: name
|
||||
elide: Text.ElideRight
|
||||
color: titleColor
|
||||
font.letterSpacing: fontSpacing
|
||||
font.pointSize: fontSize
|
||||
font.family: fontFamily
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: scrollView
|
||||
objectName: "topScrollView"
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
children: grid
|
||||
|
||||
color: "transparent"
|
||||
|
||||
function scrollToOrigin() {
|
||||
grid.contentY = grid.originY
|
||||
grid.contentX = grid.originX
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onEntered: {
|
||||
if(drag.hasUrls)
|
||||
{
|
||||
if(dropManager.canDropUrls(drag.urls, drag.action))
|
||||
{
|
||||
drag.accepted = true;
|
||||
}else
|
||||
drag.accepted = false;
|
||||
}
|
||||
else if (dropManager.canDropFormats(drag.formats)) {
|
||||
drag.accepted = true;
|
||||
} else
|
||||
drag.accepted = false;
|
||||
}
|
||||
|
||||
onDropped: {
|
||||
if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action))
|
||||
{
|
||||
dropManager.droppedFiles(drop.urls, drop.action);
|
||||
}
|
||||
else{
|
||||
if (dropManager.canDropFormats(drop.formats))
|
||||
{
|
||||
var destItem = grid.itemAt(drop.x,drop.y + grid.contentY);
|
||||
var destLocalX = grid.mapToItem(destItem,drop.x,drop.y + grid.contentY).x
|
||||
var realIndex = grid.indexAt(drop.x,drop.y + grid.contentY);
|
||||
|
||||
if(realIndex === -1)
|
||||
realIndex = grid.count - 1;
|
||||
|
||||
var destIndex = destLocalX < (grid.cellWidth / 2) ? realIndex : realIndex + 1;
|
||||
dropManager.droppedComicsForResortingAt(drop.getDataAsString(), destIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Component continueReadingView: Component {
|
||||
id: continueReadingView
|
||||
Rectangle {
|
||||
id: continueReadingTopView
|
||||
color: "#00000000"
|
||||
|
||||
height: list.count > 0 ? main.continuReadingHeight : main.topContentMargin
|
||||
|
||||
Rectangle {
|
||||
color: continueReadingBackgroundColor
|
||||
|
||||
id: continueReadingBackground
|
||||
|
||||
width: main.width
|
||||
height: main.continuReadingHeight - main.topContentMargin
|
||||
|
||||
visible: list.count > 0
|
||||
|
||||
Text {
|
||||
id: continueReadingText
|
||||
text: qsTr("Continue Reading...")
|
||||
color: continueReadingColor
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin: 25
|
||||
anchors.rightMargin: 0
|
||||
font.pointSize: 18
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
objectName: "list"
|
||||
anchors { top: continueReadingText.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; }
|
||||
|
||||
property int previousIndex;
|
||||
property int verticalPadding: 20
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
pixelAligned: true
|
||||
|
||||
model: comicsList
|
||||
|
||||
spacing: 20
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin: 25
|
||||
anchors.rightMargin: 20
|
||||
|
||||
WheelHandler {
|
||||
onWheel: event => {
|
||||
if (list.contentWidth <= list.width) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = Math.min(list.contentWidth - list.width - anchors.leftMargin, (Math.max(list.originX , list.contentX - event.angleDelta.y)));
|
||||
list.contentX = newValue
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Component {
|
||||
|
||||
//cover
|
||||
Rectangle {
|
||||
width: Math.floor((list.height - (list.verticalPadding * 2)) * 0.65);
|
||||
height: list.height - (list.verticalPadding * 2);
|
||||
|
||||
color:"transparent"
|
||||
|
||||
scale: mouseArea.containsMouse ? 1.025 : 1
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 90 }
|
||||
}
|
||||
|
||||
Image {
|
||||
id: coverElement
|
||||
anchors.fill: parent
|
||||
source: cover_path
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous : true
|
||||
cache: true
|
||||
}
|
||||
|
||||
//title
|
||||
Text {
|
||||
id : comicTitleText
|
||||
anchors { top: coverElement.bottom; left: coverElement.left; right: coverElement.right; leftMargin: 4; rightMargin: 4; topMargin: 4; }
|
||||
width: itemWidth - 8
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
text: readable_title
|
||||
elide: Text.ElideRight
|
||||
color: titleColor
|
||||
font.letterSpacing: fontSpacing
|
||||
font.pointSize: fontSize
|
||||
font.family: fontFamily
|
||||
}
|
||||
|
||||
//border
|
||||
Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
anchors.centerIn: coverElement
|
||||
color: "transparent"
|
||||
border {
|
||||
color: "#30FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onDoubleClicked: {
|
||||
list.currentIndex = index;
|
||||
openHelper.openComicFromContinueReadingList(index);
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
list.currentIndex = index;
|
||||
|
||||
if(mouse.button === Qt.RightButton) // context menu is requested
|
||||
{
|
||||
var coordinates = main.mapFromItem(coverElement,mouseX,mouseY)
|
||||
contextMenuHelper.requestedContinueReadingComicContextMenu(Qt.point(coordinates.x,coordinates.y), index);
|
||||
}
|
||||
|
||||
mouse.accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GridView {
|
||||
id:grid
|
||||
objectName: "grid"
|
||||
anchors.fill: parent
|
||||
cellHeight: cellCustomHeight
|
||||
header: continueReadingView
|
||||
focus: true
|
||||
model: foldersList
|
||||
delegate: appDelegate
|
||||
anchors.topMargin: 0
|
||||
anchors.bottomMargin: 10
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
pixelAligned: true
|
||||
highlightFollowsCurrentItem: true
|
||||
|
||||
currentIndex: 0
|
||||
cacheBuffer: 0
|
||||
|
||||
interactive: true
|
||||
|
||||
move: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
remove: Transition {
|
||||
ParallelAnimation {
|
||||
NumberAnimation { property: "opacity"; to: 0; duration: 250 }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
removeDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
displaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
function numCellsPerRow() {
|
||||
return Math.floor(width / cellCustomWidth);
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
calculateCellWidths(cellCustomWidth);
|
||||
}
|
||||
|
||||
function calculateCellWidths(cWidth) {
|
||||
var wholeCells = Math.floor(width / cWidth);
|
||||
var rest = width - (cWidth * wholeCells)
|
||||
|
||||
grid.cellWidth = cWidth + Math.floor(rest / wholeCells);
|
||||
}
|
||||
|
||||
WheelHandler {
|
||||
onWheel: event => {
|
||||
if (grid.contentHeight <= grid.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = Math.min((grid.contentHeight - grid.height - (true ? main.continuReadingHeight : main.topContentMargin)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
|
||||
grid.contentY = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
visible: grid.contentHeight > grid.height
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: 12
|
||||
implicitHeight: 26
|
||||
Rectangle {
|
||||
color: "#88424242"
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 6
|
||||
anchors.leftMargin: 3
|
||||
anchors.rightMargin: 2
|
||||
anchors.bottomMargin: 6
|
||||
border.color: "#AA313131"
|
||||
border.width: 1
|
||||
radius: 3.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
459
YACReaderLibrary/qml/FolderContentView6.qml
Normal file
459
YACReaderLibrary/qml/FolderContentView6.qml
Normal file
@ -0,0 +1,459 @@
|
||||
import QtQuick 2.15
|
||||
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import com.yacreader.ComicModel 1.0
|
||||
|
||||
import com.yacreader.ComicInfo 1.0
|
||||
import com.yacreader.ComicDB 1.0
|
||||
|
||||
import QtQuick.Controls.Basic
|
||||
|
||||
Rectangle {
|
||||
id: main
|
||||
|
||||
property int continuReadingHeight: 430;
|
||||
property int topContentMargin: 20;
|
||||
|
||||
color: backgroundColor
|
||||
anchors.margins: 0
|
||||
|
||||
Component {
|
||||
id: appDelegate
|
||||
Rectangle
|
||||
{
|
||||
id: cell
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
color: "#00000000"
|
||||
|
||||
scale: mouseArea.containsMouse ? 1.025 : 1
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 90 }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: realCell
|
||||
|
||||
property int position : 0
|
||||
|
||||
width: itemWidth
|
||||
height: itemHeight
|
||||
|
||||
color: "transparent"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onDoubleClicked: {
|
||||
openHelper.openFolder(index);
|
||||
}
|
||||
|
||||
onPressed: mouse => {
|
||||
var ci = grid.currentIndex; //save current index
|
||||
|
||||
mouse.accepted = true;
|
||||
|
||||
if(mouse.button === Qt.RightButton) // context menu is requested
|
||||
{
|
||||
var coordinates = main.mapFromItem(realCell,mouseX,mouseY)
|
||||
contextMenuHelper.requestedFolderContextMenu(Qt.point(coordinates.x,coordinates.y), index);
|
||||
mouse.accepted = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
Rectangle {
|
||||
transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: -4}
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "#20000000"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: 3}
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "#88000000"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: coverWidth
|
||||
height: coverHeight
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
id: coverElement
|
||||
|
||||
Image {
|
||||
id: coverImage
|
||||
anchors.fill: parent
|
||||
source: cover_path
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous : true
|
||||
cache: true
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
anchors.fill: parent
|
||||
cached: true
|
||||
maskSource: Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//border
|
||||
Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
radius: 10
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "transparent"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
//folder name
|
||||
Text {
|
||||
id : titleText
|
||||
anchors { top: coverElement.bottom; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 10; }
|
||||
width: itemWidth - 8
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
text: name
|
||||
elide: Text.ElideRight
|
||||
color: titleColor
|
||||
font.letterSpacing: fontSpacing
|
||||
font.pointSize: fontSize
|
||||
font.family: fontFamily
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: scrollView
|
||||
objectName: "topScrollView"
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
children: grid
|
||||
|
||||
color: "transparent"
|
||||
|
||||
function scrollToOrigin() {
|
||||
grid.contentY = grid.originY
|
||||
grid.contentX = grid.originX
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onEntered: {
|
||||
if(drag.hasUrls)
|
||||
{
|
||||
if(dropManager.canDropUrls(drag.urls, drag.action))
|
||||
{
|
||||
drag.accepted = true;
|
||||
}else
|
||||
drag.accepted = false;
|
||||
}
|
||||
else if (dropManager.canDropFormats(drag.formats)) {
|
||||
drag.accepted = true;
|
||||
} else
|
||||
drag.accepted = false;
|
||||
}
|
||||
|
||||
onDropped: {
|
||||
if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action))
|
||||
{
|
||||
dropManager.droppedFiles(drop.urls, drop.action);
|
||||
}
|
||||
else{
|
||||
if (dropManager.canDropFormats(drop.formats))
|
||||
{
|
||||
var destItem = grid.itemAt(drop.x,drop.y + grid.contentY);
|
||||
var destLocalX = grid.mapToItem(destItem,drop.x,drop.y + grid.contentY).x
|
||||
var realIndex = grid.indexAt(drop.x,drop.y + grid.contentY);
|
||||
|
||||
if(realIndex === -1)
|
||||
realIndex = grid.count - 1;
|
||||
|
||||
var destIndex = destLocalX < (grid.cellWidth / 2) ? realIndex : realIndex + 1;
|
||||
dropManager.droppedComicsForResortingAt(drop.getDataAsString(), destIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Component continueReadingView: Component {
|
||||
id: continueReadingView
|
||||
Rectangle {
|
||||
id: continueReadingTopView
|
||||
color: "#00000000"
|
||||
|
||||
height: list.count > 0 ? main.continuReadingHeight : main.topContentMargin
|
||||
|
||||
Rectangle {
|
||||
color: continueReadingBackgroundColor
|
||||
|
||||
id: continueReadingBackground
|
||||
|
||||
width: main.width
|
||||
height: main.continuReadingHeight - main.topContentMargin
|
||||
|
||||
visible: list.count > 0
|
||||
|
||||
Text {
|
||||
id: continueReadingText
|
||||
text: qsTr("Continue Reading...")
|
||||
color: continueReadingColor
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin: 25
|
||||
anchors.rightMargin: 0
|
||||
font.pointSize: 18
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
objectName: "list"
|
||||
anchors { top: continueReadingText.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; }
|
||||
|
||||
property int previousIndex;
|
||||
property int verticalPadding: 20
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
pixelAligned: true
|
||||
|
||||
model: comicsList
|
||||
|
||||
spacing: 20
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 20
|
||||
anchors.leftMargin: 25
|
||||
anchors.rightMargin: 20
|
||||
|
||||
WheelHandler {
|
||||
onWheel: event => {
|
||||
if (list.contentWidth <= list.width) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = Math.min(list.contentWidth - list.width - anchors.leftMargin, (Math.max(list.originX , list.contentX - event.angleDelta.y)));
|
||||
list.contentX = newValue
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Component {
|
||||
|
||||
//cover
|
||||
Rectangle {
|
||||
width: Math.floor((list.height - (list.verticalPadding * 2)) * 0.65);
|
||||
height: list.height - (list.verticalPadding * 2);
|
||||
|
||||
color:"transparent"
|
||||
|
||||
scale: mouseArea.containsMouse ? 1.025 : 1
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: 90 }
|
||||
}
|
||||
|
||||
Image {
|
||||
id: coverElement
|
||||
anchors.fill: parent
|
||||
source: cover_path
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous : true
|
||||
cache: true
|
||||
}
|
||||
|
||||
//title
|
||||
Text {
|
||||
id : comicTitleText
|
||||
anchors { top: coverElement.bottom; left: coverElement.left; right: coverElement.right; leftMargin: 4; rightMargin: 4; topMargin: 4; }
|
||||
width: itemWidth - 8
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
text: readable_title
|
||||
elide: Text.ElideRight
|
||||
color: titleColor
|
||||
font.letterSpacing: fontSpacing
|
||||
font.pointSize: fontSize
|
||||
font.family: fontFamily
|
||||
}
|
||||
|
||||
//border
|
||||
Rectangle {
|
||||
width: coverElement.width
|
||||
height: coverElement.height
|
||||
anchors.centerIn: coverElement
|
||||
color: "transparent"
|
||||
border {
|
||||
color: "#30FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onDoubleClicked: {
|
||||
list.currentIndex = index;
|
||||
openHelper.openComicFromContinueReadingList(index);
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
list.currentIndex = index;
|
||||
|
||||
if(mouse.button === Qt.RightButton) // context menu is requested
|
||||
{
|
||||
var coordinates = main.mapFromItem(coverElement,mouseX,mouseY)
|
||||
contextMenuHelper.requestedContinueReadingComicContextMenu(Qt.point(coordinates.x,coordinates.y), index);
|
||||
}
|
||||
|
||||
mouse.accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GridView {
|
||||
id:grid
|
||||
objectName: "grid"
|
||||
anchors.fill: parent
|
||||
cellHeight: cellCustomHeight
|
||||
header: continueReadingView
|
||||
focus: true
|
||||
model: foldersList
|
||||
delegate: appDelegate
|
||||
anchors.topMargin: 0
|
||||
anchors.bottomMargin: 10
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
pixelAligned: true
|
||||
highlightFollowsCurrentItem: true
|
||||
|
||||
currentIndex: 0
|
||||
cacheBuffer: 0
|
||||
|
||||
interactive: true
|
||||
|
||||
move: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
remove: Transition {
|
||||
ParallelAnimation {
|
||||
NumberAnimation { property: "opacity"; to: 0; duration: 250 }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
removeDisplaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
displaced: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
||||
function numCellsPerRow() {
|
||||
return Math.floor(width / cellCustomWidth);
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
calculateCellWidths(cellCustomWidth);
|
||||
}
|
||||
|
||||
function calculateCellWidths(cWidth) {
|
||||
var wholeCells = Math.floor(width / cWidth);
|
||||
var rest = width - (cWidth * wholeCells)
|
||||
|
||||
grid.cellWidth = cWidth + Math.floor(rest / wholeCells);
|
||||
}
|
||||
|
||||
WheelHandler {
|
||||
onWheel: event => {
|
||||
if (grid.contentHeight <= grid.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = Math.min((grid.contentHeight - grid.height - (true ? main.continuReadingHeight : main.topContentMargin)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
|
||||
grid.contentY = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
visible: grid.contentHeight > grid.height
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: 12
|
||||
implicitHeight: 26
|
||||
Rectangle {
|
||||
color: "#88424242"
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 6
|
||||
anchors.leftMargin: 3
|
||||
anchors.rightMargin: 2
|
||||
anchors.bottomMargin: 6
|
||||
border.color: "#AA313131"
|
||||
border.width: 1
|
||||
radius: 3.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -756,6 +756,17 @@ Rectangle {
|
||||
grid.cellWidth = cWidth + Math.floor(rest / wholeCells);
|
||||
}
|
||||
|
||||
WheelHandler {
|
||||
onWheel: {
|
||||
if (grid.contentHeight <= grid.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = Math.min((grid.contentHeight - grid.height - (showCurrentComic ? 270 : 20)), (Math.max(grid.originY , grid.contentY - event.angleDelta.y)));
|
||||
grid.contentY = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
visible: grid.contentHeight > grid.height
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="qml/GridComicsView.qml">qml/GridComicsView6.qml</file>
|
||||
<file alias="qml/FolderContentView.qml">qml/FolderContentView6.qml</file>
|
||||
<file alias="qml/FlowView.qml">qml/FlowView6.qml</file>
|
||||
<file alias="qml/InfoTick.qml">qml/InfoTick6.qml</file>
|
||||
<file alias="qml/InfoFavorites.qml">qml/InfoFavorites6.qml</file>
|
||||
|
@ -44,7 +44,12 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon
|
||||
DBHelper::setComicAsReading(libraryId, info);
|
||||
}
|
||||
}
|
||||
|
||||
error = false;
|
||||
updatedLibraryId = libraryId;
|
||||
updatedComicId = comicId;
|
||||
} else {
|
||||
error = true;
|
||||
response.setStatus(412, "No comic info received");
|
||||
response.write("", true);
|
||||
return;
|
||||
|
@ -15,6 +15,10 @@ public:
|
||||
|
||||
/** Generates the response */
|
||||
void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override;
|
||||
|
||||
bool error;
|
||||
qulonglong updatedLibraryId;
|
||||
qulonglong updatedComicId;
|
||||
};
|
||||
|
||||
#endif // UPDATECOMICCONTROLLER_H
|
||||
|
@ -0,0 +1,82 @@
|
||||
#include "statuspagecontroller.h"
|
||||
|
||||
#include "template.h"
|
||||
#include "yacreader_global.h"
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
#include "QsLog.h"
|
||||
|
||||
#include <QSysInfo>
|
||||
|
||||
using stefanfrings::HttpRequest;
|
||||
using stefanfrings::HttpResponse;
|
||||
// using stefanfrings::HttpSession;
|
||||
using stefanfrings::Template;
|
||||
|
||||
StatusPageController::StatusPageController() { }
|
||||
|
||||
void StatusPageController::service(HttpRequest &request, HttpResponse &response)
|
||||
{
|
||||
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
||||
response.setHeader("Connection", "close");
|
||||
|
||||
Template StatusPage = Template(
|
||||
QStringLiteral(
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>YACReaderLibrary Server</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n\n"
|
||||
"<center>\n"
|
||||
"<img src='/images/webui/YACLibraryServer.svg' width=15%>\n"
|
||||
"<h1>YACReaderLibraryServer is up and running.</h1>\n"
|
||||
"<p>YACReader {yr.version}<p>\n"
|
||||
"<p>Server {server.version}<p>\n"
|
||||
"<p>OS:\t{os.name} {os.version}</p>\n"
|
||||
"<p>Port:\t{os.port}</p>\n"
|
||||
"<table>\n"
|
||||
"<thead>\n"
|
||||
"<tr>\n"
|
||||
"<th>Library</th>\n"
|
||||
"<th>Path</th>\n"
|
||||
"</tr>\n"
|
||||
"</thead>\n"
|
||||
"{loop Library}"
|
||||
"<tr>\n"
|
||||
"<td>{Library.Name}</td>\n"
|
||||
"<td>{Library.Path}</td>\n"
|
||||
"<tr>\n"
|
||||
"{end Library}"
|
||||
"</p>\n"
|
||||
"</center>\n"
|
||||
"</body>\n"
|
||||
"</html>\n"),
|
||||
|
||||
"StatusPage");
|
||||
|
||||
StatusPage.enableWarnings();
|
||||
|
||||
// Set template variables
|
||||
StatusPage.setVariable("os.name", QSysInfo::prettyProductName());
|
||||
StatusPage.setVariable("os.version", QSysInfo::productVersion());
|
||||
// Getting the port from the request is basically a hack, but should do the trick
|
||||
StatusPage.setVariable("os.port", QString(request.getHeader("host")).split(":")[1]);
|
||||
|
||||
StatusPage.setVariable("server.version", SERVER_VERSION_NUMBER);
|
||||
StatusPage.setVariable("yr.version", VERSION);
|
||||
|
||||
// Get library info
|
||||
YACReaderLibraries libraries = DBHelper::getLibraries();
|
||||
QList<QString> library_names = libraries.getNames();
|
||||
size_t num_libs = libraries.getNames().size();
|
||||
|
||||
// Fill template
|
||||
StatusPage.loop("Library", num_libs);
|
||||
for (size_t i = 0; i < num_libs; i++) {
|
||||
StatusPage.setVariable(QString("Library%1.Name").arg(i), library_names.at(i));
|
||||
StatusPage.setVariable(QString("Library%1.Path").arg(i), libraries.getPath(library_names.at(i)));
|
||||
}
|
||||
|
||||
response.write(StatusPage.toUtf8(), true);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#ifndef STATUSPAGE_CONTROLLER
|
||||
#define STATUSPAGE_CONTROLLER
|
||||
|
||||
#include "httprequest.h"
|
||||
#include "httpresponse.h"
|
||||
#include "httprequesthandler.h"
|
||||
|
||||
class StatusPageController : public stefanfrings::HttpRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(StatusPageController);
|
||||
|
||||
public:
|
||||
StatusPageController();
|
||||
|
||||
void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override;
|
||||
};
|
||||
|
||||
#endif // STATUSPAGE_CONTROLLER
|
@ -41,6 +41,8 @@
|
||||
#include "controllers/v2/comicfullinfocontroller_v2.h"
|
||||
#include "controllers/v2/comiccontrollerinreadinglist_v2.h"
|
||||
|
||||
#include "controllers/webui/statuspagecontroller.h"
|
||||
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
@ -159,11 +161,18 @@ void RequestMapper::service(HttpRequest &request, HttpResponse &response)
|
||||
|
||||
if (path.startsWith("/v2")) {
|
||||
serviceV2(request, response);
|
||||
} else if (path.startsWith("/webui")) {
|
||||
serviceWebUI(request, response);
|
||||
} else {
|
||||
serviceV1(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
void RequestMapper::serviceWebUI(HttpRequest &request, HttpResponse &response)
|
||||
{
|
||||
StatusPageController().service(request, response);
|
||||
}
|
||||
|
||||
void RequestMapper::serviceV1(HttpRequest &request, HttpResponse &response)
|
||||
{
|
||||
QByteArray path = request.getPath();
|
||||
@ -273,6 +282,7 @@ void RequestMapper::serviceV2(HttpRequest &request, HttpResponse &response)
|
||||
VersionController().service(request, response);
|
||||
} else if (sync.exactMatch(path)) {
|
||||
SyncControllerV2().service(request, response);
|
||||
emit clientSync();
|
||||
} else {
|
||||
if (library.indexIn(path) != -1 && DBHelper::getLibraries().contains(library.cap(1).toInt())) {
|
||||
if (folderInfo.exactMatch(path)) {
|
||||
@ -290,7 +300,12 @@ void RequestMapper::serviceV2(HttpRequest &request, HttpResponse &response)
|
||||
} else if (comicPage.exactMatch(path) || comicPageRemote.exactMatch(path)) {
|
||||
PageControllerV2().service(request, response);
|
||||
} else if (comicUpdate.exactMatch(path)) {
|
||||
UpdateComicControllerV2().service(request, response);
|
||||
auto updateController = UpdateComicControllerV2();
|
||||
updateController.service(request, response);
|
||||
|
||||
if (!updateController.error) {
|
||||
emit comicUpdated(updateController.updatedLibraryId, updateController.updatedComicId);
|
||||
}
|
||||
} else if (folderContent.exactMatch(path)) {
|
||||
FolderContentControllerV2().service(request, response);
|
||||
} else if (tags.exactMatch(path)) {
|
||||
|
@ -20,9 +20,14 @@ public:
|
||||
void loadSessionV1(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response);
|
||||
void loadSessionV2(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response);
|
||||
|
||||
signals:
|
||||
void clientSync();
|
||||
void comicUpdated(qulonglong libraryId, qulonglong comicId);
|
||||
|
||||
private:
|
||||
void serviceV1(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response);
|
||||
void serviceV2(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response);
|
||||
void serviceWebUI(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response);
|
||||
|
||||
static QMutex mutex;
|
||||
};
|
||||
|
@ -10,8 +10,8 @@ DEPENDPATH += $$PWD/controllers/v2
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/static.h \
|
||||
$$PWD/startup.h \
|
||||
$$PWD/requestmapper.h \
|
||||
$$PWD/yacreader_http_server.h \
|
||||
$$PWD/yacreader_http_session.h \
|
||||
$$PWD/yacreader_http_session_store.h \
|
||||
$$PWD/yacreader_server_data_helper.h \
|
||||
@ -47,13 +47,15 @@ HEADERS += \
|
||||
$$PWD/controllers/v2/comicfullinfocontroller_v2.h \
|
||||
$$PWD/controllers/v2/readinglistinfocontroller_v2.h \
|
||||
$$PWD/controllers/v2/taginfocontroller_v2.h \
|
||||
$$PWD/controllers/v2/comiccontrollerinreadinglist_v2.h
|
||||
$$PWD/controllers/v2/comiccontrollerinreadinglist_v2.h\
|
||||
#Browser
|
||||
$$PWD/controllers/webui/statuspagecontroller.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/static.cpp \
|
||||
$$PWD/startup.cpp \
|
||||
$$PWD/requestmapper.cpp \
|
||||
$$PWD/yacreader_http_server.cpp \
|
||||
$$PWD/yacreader_http_session.cpp \
|
||||
$$PWD/yacreader_http_session_store.cpp \
|
||||
$$PWD/yacreader_server_data_helper.cpp \
|
||||
@ -89,7 +91,9 @@ SOURCES += \
|
||||
$$PWD/controllers/v2/comicfullinfocontroller_v2.cpp \
|
||||
$$PWD/controllers/v2/readinglistinfocontroller_v2.cpp \
|
||||
$$PWD/controllers/v2/taginfocontroller_v2.cpp \
|
||||
$$PWD/controllers/v2/comiccontrollerinreadinglist_v2.cpp
|
||||
$$PWD/controllers/v2/comiccontrollerinreadinglist_v2.cpp \
|
||||
#WebUI
|
||||
$$PWD/controllers/webui/statuspagecontroller.cpp
|
||||
|
||||
include(../../third_party/QtWebApp/httpserver/httpserver.pri)
|
||||
include(../../third_party/QtWebApp/templateengine/templateengine.pri)
|
||||
|
@ -1,38 +0,0 @@
|
||||
/**
|
||||
@file
|
||||
@author Stefan Frings
|
||||
*/
|
||||
|
||||
#ifndef STARTUP_H
|
||||
#define STARTUP_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace stefanfrings {
|
||||
class HttpListener;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper class to install and run the application as a windows
|
||||
service.
|
||||
*/
|
||||
class Startup
|
||||
{
|
||||
private:
|
||||
// QTcpServer
|
||||
stefanfrings::HttpListener *listener;
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
Startup();
|
||||
/** Start the server */
|
||||
void start(quint16 port = 0);
|
||||
/** Stop the server */
|
||||
void stop();
|
||||
|
||||
QString getPort();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif // STARTUP_H
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "static.h"
|
||||
#include "startup.h"
|
||||
#include "yacreader_http_server.h"
|
||||
//#include "dualfilelogger.h"
|
||||
#include "httplistener.h"
|
||||
#include "requestmapper.h"
|
||||
@ -32,7 +32,7 @@ using stefanfrings::HttpSessionStore;
|
||||
using stefanfrings::StaticFileController;
|
||||
using stefanfrings::TemplateCache;
|
||||
|
||||
void Startup::start(quint16 port)
|
||||
void YACReaderHttpServer::start(quint16 port)
|
||||
{
|
||||
// Initialize the core application
|
||||
QCoreApplication *app = QCoreApplication::instance();
|
||||
@ -53,7 +53,7 @@ void Startup::start(quint16 port)
|
||||
#else
|
||||
templatePath = QFileInfo(QCoreApplication::applicationDirPath(), baseTemplatePath).absoluteFilePath();
|
||||
#endif
|
||||
|
||||
if (!templateSettings->contains("path"))
|
||||
templateSettings->setValue("path", templatePath);
|
||||
|
||||
Static::templateLoader = new TemplateCache(templateSettings, app);
|
||||
@ -84,6 +84,7 @@ void Startup::start(quint16 port)
|
||||
docroot = QFileInfo(QCoreApplication::applicationDirPath(), basedocroot).absoluteFilePath();
|
||||
#endif
|
||||
|
||||
if (!fileSettings->contains("path"))
|
||||
fileSettings->setValue("path", docroot);
|
||||
|
||||
Static::staticFileController = new StaticFileController(fileSettings, app);
|
||||
@ -137,7 +138,11 @@ void Startup::start(quint16 port)
|
||||
testServer.close();
|
||||
}
|
||||
|
||||
listener = new HttpListener(listenerSettings, new RequestMapper(app), app);
|
||||
auto requestMapper = new RequestMapper(app);
|
||||
listener = new HttpListener(listenerSettings, requestMapper, app);
|
||||
|
||||
connect(requestMapper, &RequestMapper::comicUpdated, this, &YACReaderHttpServer::comicUpdated);
|
||||
connect(requestMapper, &RequestMapper::clientSync, this, &YACReaderHttpServer::clientSync);
|
||||
|
||||
if (listener->isListening()) {
|
||||
qDebug("ServiceHelper: Service has started");
|
||||
@ -146,7 +151,7 @@ void Startup::start(quint16 port)
|
||||
}
|
||||
}
|
||||
|
||||
void Startup::stop()
|
||||
void YACReaderHttpServer::stop()
|
||||
{
|
||||
qDebug("ServiceHelper: Service has been stopped");
|
||||
// QCoreApplication destroys all objects that have been created in start().
|
||||
@ -157,12 +162,12 @@ void Startup::stop()
|
||||
}
|
||||
}
|
||||
|
||||
Startup::Startup()
|
||||
: listener(nullptr)
|
||||
YACReaderHttpServer::YACReaderHttpServer()
|
||||
: QObject(nullptr), listener(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
QString Startup::getPort()
|
||||
QString YACReaderHttpServer::getPort()
|
||||
{
|
||||
return QString("%1").arg(listener->serverPort());
|
||||
}
|
30
YACReaderLibrary/server/yacreader_http_server.h
Normal file
30
YACReaderLibrary/server/yacreader_http_server.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef YACREADER_HTTP_SERVER_H
|
||||
#define YACREADER_HTTP_SERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace stefanfrings {
|
||||
class HttpListener;
|
||||
}
|
||||
|
||||
class YACReaderHttpServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderHttpServer();
|
||||
|
||||
void start(quint16 port = 0);
|
||||
void stop();
|
||||
|
||||
QString getPort();
|
||||
|
||||
signals:
|
||||
void clientSync();
|
||||
void comicUpdated(qulonglong libraryId, qulonglong comicId);
|
||||
|
||||
private:
|
||||
stefanfrings::HttpListener *listener;
|
||||
};
|
||||
|
||||
#endif // YACREADER_HTTP_SERVER_H
|
@ -11,7 +11,7 @@
|
||||
#include <QBitmap>
|
||||
#include <QPainter>
|
||||
|
||||
#include "startup.h"
|
||||
#include "yacreader_http_server.h"
|
||||
#include "yacreader_global_gui.h"
|
||||
|
||||
#include "qnaturalsorting.h"
|
||||
@ -78,7 +78,7 @@ QList<QString> addresses()
|
||||
|
||||
#endif
|
||||
|
||||
extern Startup *s;
|
||||
extern YACReaderHttpServer *httpServer;
|
||||
|
||||
ServerConfigDialog::ServerConfigDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
@ -184,11 +184,11 @@ void ServerConfigDialog::enableServer(int status)
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
if (status == Qt::Checked) {
|
||||
s->start();
|
||||
httpServer->start();
|
||||
this->generateQR();
|
||||
settings->setValue(SERVER_ON, true);
|
||||
} else {
|
||||
s->stop();
|
||||
httpServer->stop();
|
||||
qrCode->setPixmap(QPixmap());
|
||||
ip->clear();
|
||||
port->setText("");
|
||||
@ -247,14 +247,14 @@ void ServerConfigDialog::generateQR()
|
||||
|
||||
if (otherAddresses.length() > 0 || !dir.isEmpty()) {
|
||||
if (!dir.isEmpty()) {
|
||||
generateQR(dir + ":" + s->getPort());
|
||||
generateQR(dir + ":" + httpServer->getPort());
|
||||
|
||||
ip->addItem(dir);
|
||||
} else {
|
||||
generateQR(otherAddresses.first() + ":" + s->getPort());
|
||||
generateQR(otherAddresses.first() + ":" + httpServer->getPort());
|
||||
}
|
||||
ip->addItems(otherAddresses);
|
||||
port->setText(s->getPort());
|
||||
port->setText(httpServer->getPort());
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ void ServerConfigDialog::generateQR(const QString &serverAddress)
|
||||
|
||||
void ServerConfigDialog::regenerateQR(const QString &ip)
|
||||
{
|
||||
generateQR(ip + ":" + s->getPort());
|
||||
generateQR(ip + ":" + httpServer->getPort());
|
||||
}
|
||||
|
||||
void ServerConfigDialog::updatePort()
|
||||
@ -291,8 +291,8 @@ void ServerConfigDialog::updatePort()
|
||||
settings->setValue("port", port->text().toInt());
|
||||
settings->endGroup();
|
||||
|
||||
s->stop();
|
||||
s->start();
|
||||
httpServer->stop();
|
||||
httpServer->start();
|
||||
|
||||
generateQR(ip->currentText() + ":" + port->text());
|
||||
}
|
||||
@ -303,6 +303,13 @@ QrEncoder::QrEncoder()
|
||||
QLibrary encoder(QCoreApplication::applicationDirPath() + "/utils/libqrencode.dylib");
|
||||
#else
|
||||
QLibrary encoder("qrencode");
|
||||
#ifdef Q_OS_UNIX
|
||||
encoder.load();
|
||||
// Fallback - this loads libqrencode.4.x.x.so when libqrencode.so is not available
|
||||
if (!encoder.isLoaded()) {
|
||||
encoder.setFileNameAndVersion("qrencode", 4);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
QRcode_encodeString8bit = (_QRcode_encodeString8bit)encoder.resolve("QRcode_encodeString8bit");
|
||||
QRcode_free = (_QRcode_free)encoder.resolve("QRcode_free");
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "initial_comic_info_extractor.h"
|
||||
#include "xml_info_parser.h"
|
||||
#include "yacreader_global.h"
|
||||
#include "folder_item.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
@ -23,6 +24,21 @@ void XMLInfoLibraryScanner::scanLibrary(const QString &source, const QString &ta
|
||||
|
||||
this->stopRunning = false;
|
||||
|
||||
partialUpdate = false;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void XMLInfoLibraryScanner::scanFolder(const QString &source, const QString &target, const QString &folder, const QModelIndex &dest)
|
||||
{
|
||||
this->source = source;
|
||||
this->target = target;
|
||||
|
||||
this->stopRunning = false;
|
||||
|
||||
partialUpdate = true;
|
||||
folderDestinationModelIndex = dest;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
@ -52,36 +68,29 @@ void XMLInfoLibraryScanner::run()
|
||||
|
||||
database.transaction();
|
||||
|
||||
if (!partialUpdate) {
|
||||
QSqlQuery comicsInfo("SELECT * FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)", database);
|
||||
comicsInfo.exec();
|
||||
|
||||
QSqlRecord record = comicsInfo.record();
|
||||
|
||||
int id = record.indexOf("id");
|
||||
// int parentIdIndex = record.indexOf("parentId");
|
||||
int fileNameIndex = record.indexOf("fileName");
|
||||
int pathIndex = record.indexOf("path");
|
||||
|
||||
while (comicsInfo.next()) {
|
||||
if (this->stopRunning) {
|
||||
break;
|
||||
updateFromSQLQuery(database, comicsInfo);
|
||||
} else {
|
||||
if (folderDestinationModelIndex.isValid()) {
|
||||
YACReader::iterate(folderDestinationModelIndex, folderDestinationModelIndex.model(), [&](const QModelIndex &idx) {
|
||||
if (stopRunning) {
|
||||
return false;
|
||||
}
|
||||
/* currentItem.id = selectQuery.value(id).toULongLong();
|
||||
currentItem.parentId = parentId; //selectQuery.value(parentId).toULongLong();
|
||||
currentItem.name = selectQuery.value(fileName).toString(); */
|
||||
auto fileName = comicsInfo.value(fileNameIndex).toString();
|
||||
auto path = comicsInfo.value(pathIndex).toString();
|
||||
|
||||
emit comicScanned(path, fileName);
|
||||
auto item = static_cast<FolderItem *>(idx.internalPointer());
|
||||
|
||||
auto info = DBHelper::getComicInfoFromQuery(comicsInfo, "comicInfoId");
|
||||
QSqlQuery comicsInfo(database);
|
||||
comicsInfo.prepare("SELECT * FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE c.parentId = :parentId");
|
||||
comicsInfo.bindValue(":parentId", item->id);
|
||||
comicsInfo.exec();
|
||||
|
||||
InitialComicInfoExtractor ie(QDir::cleanPath(this->source + path), "None");
|
||||
updateFromSQLQuery(database, comicsInfo);
|
||||
|
||||
ie.extract();
|
||||
|
||||
if (parseXMLIntoInfo(ie.getXMLInfoRawData(), info)) {
|
||||
DBHelper::update(&info, database);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,3 +105,33 @@ void XMLInfoLibraryScanner::stop()
|
||||
{
|
||||
stopRunning = true;
|
||||
}
|
||||
|
||||
void XMLInfoLibraryScanner::updateFromSQLQuery(QSqlDatabase &db, QSqlQuery &query)
|
||||
{
|
||||
QSqlRecord record = query.record();
|
||||
|
||||
int id = record.indexOf("id");
|
||||
// int parentIdIndex = record.indexOf("parentId");
|
||||
int fileNameIndex = record.indexOf("fileName");
|
||||
int pathIndex = record.indexOf("path");
|
||||
|
||||
while (query.next()) {
|
||||
if (this->stopRunning) {
|
||||
break;
|
||||
}
|
||||
auto fileName = query.value(fileNameIndex).toString();
|
||||
auto path = query.value(pathIndex).toString();
|
||||
|
||||
emit comicScanned(path, fileName);
|
||||
|
||||
auto info = DBHelper::getComicInfoFromQuery(query, "comicInfoId");
|
||||
|
||||
InitialComicInfoExtractor ie(QDir::cleanPath(this->source + path), "None", info.coverPage.toInt(), true);
|
||||
|
||||
ie.extract();
|
||||
|
||||
if (parseXMLIntoInfo(ie.getXMLInfoRawData(), info)) {
|
||||
DBHelper::update(&info, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define XMLINFOLIBRARYSCANNER_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QSqlQuery>
|
||||
|
||||
namespace YACReader {
|
||||
|
||||
@ -11,6 +12,7 @@ class XMLInfoLibraryScanner : public QThread
|
||||
public:
|
||||
XMLInfoLibraryScanner();
|
||||
void scanLibrary(const QString &source, const QString &target);
|
||||
void scanFolder(const QString &source, const QString &target, const QString &folder, const QModelIndex &dest);
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
@ -25,6 +27,10 @@ private:
|
||||
QString source;
|
||||
QString target;
|
||||
bool stopRunning;
|
||||
bool partialUpdate;
|
||||
QModelIndex folderDestinationModelIndex;
|
||||
|
||||
void updateFromSQLQuery(QSqlDatabase &db, QSqlQuery &query);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "yacreader_comics_views_manager.h"
|
||||
#include "yacreader_content_views_manager.h"
|
||||
|
||||
#include "library_window.h"
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "grid_comics_view.h"
|
||||
#include "info_comics_view.h"
|
||||
#include "comics_view_transition.h"
|
||||
#include "empty_folder_widget.h"
|
||||
#include "folder_content_view.h"
|
||||
#include "empty_label_widget.h"
|
||||
#include "empty_special_list.h"
|
||||
#include "empty_reading_list_widget.h"
|
||||
@ -18,7 +18,7 @@
|
||||
#include "yacreader_search_line_edit.h"
|
||||
#include "options_dialog.h"
|
||||
|
||||
YACReaderComicsViewsManager::YACReaderComicsViewsManager(QSettings *settings, LibraryWindow *parent)
|
||||
YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, LibraryWindow *parent)
|
||||
: QObject(parent), libraryWindow(parent), classicComicsView(nullptr), gridComicsView(nullptr), infoComicsView(nullptr)
|
||||
{
|
||||
comicsViewStack = new QStackedWidget();
|
||||
@ -29,26 +29,23 @@ YACReaderComicsViewsManager::YACReaderComicsViewsManager(QSettings *settings, Li
|
||||
comicsViewStatus = Flow;
|
||||
break;
|
||||
|
||||
case Grid:
|
||||
comicsView = gridComicsView = new GridComicsView();
|
||||
connect(libraryWindow->optionsDialog, &YACReaderOptionsDialog::optionsChanged, gridComicsView, &GridComicsView::updateBackgroundConfig);
|
||||
comicsViewStatus = Grid;
|
||||
break;
|
||||
|
||||
case Info:
|
||||
comicsView = infoComicsView = new InfoComicsView();
|
||||
comicsViewStatus = Info;
|
||||
break;
|
||||
|
||||
case Grid:
|
||||
default:
|
||||
comicsView = classicComicsView = new ClassicComicsView();
|
||||
comicsViewStatus = Flow;
|
||||
comicsView = gridComicsView = new GridComicsView();
|
||||
connect(libraryWindow->optionsDialog, &YACReaderOptionsDialog::optionsChanged, gridComicsView, &GridComicsView::updateBackgroundConfig);
|
||||
comicsViewStatus = Grid;
|
||||
break;
|
||||
}
|
||||
|
||||
doComicsViewConnections();
|
||||
|
||||
comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition());
|
||||
comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget());
|
||||
comicsViewStack->addWidget(folderContentView = new FolderContentView());
|
||||
comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget());
|
||||
comicsViewStack->addWidget(emptySpecialList = new EmptySpecialListWidget());
|
||||
comicsViewStack->addWidget(emptyReadingList = new EmptyReadingListWidget());
|
||||
@ -59,23 +56,46 @@ YACReaderComicsViewsManager::YACReaderComicsViewsManager(QSettings *settings, Li
|
||||
comicsViewStack->setCurrentWidget(comicsView);
|
||||
|
||||
// connections
|
||||
connect(emptyFolderWidget, &EmptyFolderWidget::copyComicsToCurrentFolder, libraryWindow, &LibraryWindow::copyAndImportComicsToCurrentFolder);
|
||||
connect(emptyFolderWidget, &EmptyFolderWidget::moveComicsToCurrentFolder, libraryWindow, &LibraryWindow::moveAndImportComicsToCurrentFolder);
|
||||
connect(folderContentView, &FolderContentView::copyComicsToCurrentFolder, libraryWindow, &LibraryWindow::copyAndImportComicsToCurrentFolder);
|
||||
connect(folderContentView, &FolderContentView::moveComicsToCurrentFolder, libraryWindow, &LibraryWindow::moveAndImportComicsToCurrentFolder);
|
||||
}
|
||||
|
||||
QWidget *YACReaderComicsViewsManager::containerWidget()
|
||||
QWidget *YACReaderContentViewsManager::containerWidget()
|
||||
{
|
||||
return comicsViewStack;
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::updateCurrentComicView()
|
||||
void YACReaderContentViewsManager::updateCurrentComicView()
|
||||
{
|
||||
if (comicsViewStack->currentWidget() == comicsView) {
|
||||
comicsView->updateCurrentComicView();
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showComicsView()
|
||||
void YACReaderContentViewsManager::updateContinueReadingView()
|
||||
{
|
||||
if (comicsViewStack->currentWidget() == folderContentView) {
|
||||
folderContentView->reloadContinueReadingModel();
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderContentViewsManager::toFullscreen()
|
||||
{
|
||||
if (comicsViewStack->currentWidget() == comicsView) {
|
||||
comicsView->toFullScreen();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderContentViewsManager::toNormal()
|
||||
{
|
||||
if (comicsViewStack->currentWidget() == comicsView) {
|
||||
comicsView->toNormal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderContentViewsManager::showComicsView()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(comicsView);
|
||||
|
||||
@ -84,50 +104,50 @@ void YACReaderComicsViewsManager::showComicsView()
|
||||
libraryWindow->sideBar->update();
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showEmptyFolderView()
|
||||
void YACReaderContentViewsManager::showFolderContentView()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(emptyFolderWidget);
|
||||
comicsViewStack->setCurrentWidget(folderContentView);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showEmptyLabelView()
|
||||
void YACReaderContentViewsManager::showEmptyLabelView()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(emptyLabelWidget);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showEmptySpecialList()
|
||||
void YACReaderContentViewsManager::showEmptySpecialList()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(emptySpecialList);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showEmptyReadingListWidget()
|
||||
void YACReaderContentViewsManager::showEmptyReadingListWidget()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(emptyReadingList);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showNoSearchResultsView()
|
||||
void YACReaderContentViewsManager::showNoSearchResultsView()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(noSearchResultsWidget);
|
||||
}
|
||||
|
||||
// TODO recover the current comics selection and restore it in the destination
|
||||
void YACReaderComicsViewsManager::toggleComicsView()
|
||||
void YACReaderContentViewsManager::toggleComicsView()
|
||||
{
|
||||
if (comicsViewStack->currentWidget() == comicsView) {
|
||||
QTimer::singleShot(0, this, &YACReaderComicsViewsManager::showComicsViewTransition);
|
||||
QTimer::singleShot(100, this, &YACReaderComicsViewsManager::_toggleComicsView);
|
||||
QTimer::singleShot(0, this, &YACReaderContentViewsManager::showComicsViewTransition);
|
||||
QTimer::singleShot(100, this, &YACReaderContentViewsManager::_toggleComicsView);
|
||||
} else {
|
||||
_toggleComicsView();
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::focusComicsViewViaShortcut()
|
||||
void YACReaderContentViewsManager::focusComicsViewViaShortcut()
|
||||
{
|
||||
comicsView->focusComicsNavigation(Qt::ShortcutFocusReason);
|
||||
}
|
||||
|
||||
// PROTECTED
|
||||
|
||||
void YACReaderComicsViewsManager::disconnectComicsViewConnections(ComicsView *widget)
|
||||
void YACReaderContentViewsManager::disconnectComicsViewConnections(ComicsView *widget)
|
||||
{
|
||||
disconnect(widget, &ComicsView::comicRated, libraryWindow->comicsModel, &ComicModel::updateRating);
|
||||
disconnect(libraryWindow->showHideMarksAction, &QAction::toggled, widget, &ComicsView::setShowMarks);
|
||||
@ -140,7 +160,7 @@ void YACReaderComicsViewsManager::disconnectComicsViewConnections(ComicsView *wi
|
||||
disconnect(comicsView, &ComicsView::customContextMenuItemRequested, libraryWindow, &LibraryWindow::showComicsItemContextMenu);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::doComicsViewConnections()
|
||||
void YACReaderContentViewsManager::doComicsViewConnections()
|
||||
{
|
||||
connect(comicsView, &ComicsView::comicRated, libraryWindow->comicsModel, &ComicModel::updateRating);
|
||||
connect(libraryWindow->showHideMarksAction, &QAction::toggled, comicsView, &ComicsView::setShowMarks);
|
||||
@ -156,7 +176,7 @@ void YACReaderComicsViewsManager::doComicsViewConnections()
|
||||
connect(comicsView, &ComicsView::moveComicsToCurrentFolder, libraryWindow, &LibraryWindow::moveAndImportComicsToCurrentFolder);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::switchToComicsView(ComicsView *from, ComicsView *to)
|
||||
void YACReaderContentViewsManager::switchToComicsView(ComicsView *from, ComicsView *to)
|
||||
{
|
||||
// setup views
|
||||
disconnectComicsViewConnections(from);
|
||||
@ -180,17 +200,17 @@ void YACReaderComicsViewsManager::switchToComicsView(ComicsView *from, ComicsVie
|
||||
}
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::showComicsViewTransition()
|
||||
void YACReaderContentViewsManager::showComicsViewTransition()
|
||||
{
|
||||
comicsViewStack->setCurrentWidget(comicsViewTransition);
|
||||
}
|
||||
|
||||
void YACReaderComicsViewsManager::_toggleComicsView()
|
||||
void YACReaderContentViewsManager::_toggleComicsView()
|
||||
{
|
||||
switch (comicsViewStatus) {
|
||||
case Flow: {
|
||||
QIcon icoViewsButton;
|
||||
icoViewsButton.addFile(":/images/main_toolbar/info.png", QSize(), QIcon::Normal);
|
||||
icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/info"), QSize(), QIcon::Normal);
|
||||
libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton);
|
||||
#ifdef Q_OS_MAC
|
||||
libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton);
|
||||
@ -207,7 +227,7 @@ void YACReaderComicsViewsManager::_toggleComicsView()
|
||||
|
||||
case Grid: {
|
||||
QIcon icoViewsButton;
|
||||
icoViewsButton.addFile(":/images/main_toolbar/flow.png", QSize(), QIcon::Normal);
|
||||
icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/flow"), QSize(), QIcon::Normal);
|
||||
libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton);
|
||||
#ifdef Q_OS_MAC
|
||||
libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton);
|
||||
@ -223,7 +243,7 @@ void YACReaderComicsViewsManager::_toggleComicsView()
|
||||
|
||||
case Info: {
|
||||
QIcon icoViewsButton;
|
||||
icoViewsButton.addFile(":/images/main_toolbar/grid.png", QSize(), QIcon::Normal);
|
||||
icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/grid"), QSize(), QIcon::Normal);
|
||||
libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton);
|
||||
#ifdef Q_OS_MAC
|
||||
libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton);
|
@ -1,5 +1,5 @@
|
||||
#ifndef YACREADERCOMICSVIEWSMANAGER_H
|
||||
#define YACREADERCOMICSVIEWSMANAGER_H
|
||||
#ifndef YACREADERCONTENTVIEWSMANAGER_H
|
||||
#define YACREADERCONTENTVIEWSMANAGER_H
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
@ -12,7 +12,7 @@ class ClassicComicsView;
|
||||
class GridComicsView;
|
||||
class InfoComicsView;
|
||||
class ComicsViewTransition;
|
||||
class EmptyFolderWidget;
|
||||
class FolderContentView;
|
||||
class EmptyLabelWidget;
|
||||
class EmptySpecialListWidget;
|
||||
class EmptyReadingListWidget;
|
||||
@ -20,11 +20,11 @@ class NoSearchResultsWidget;
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
class YACReaderComicsViewsManager : public QObject
|
||||
class YACReaderContentViewsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit YACReaderComicsViewsManager(QSettings *settings, LibraryWindow *parent = nullptr);
|
||||
explicit YACReaderContentViewsManager(QSettings *settings, LibraryWindow *parent = nullptr);
|
||||
|
||||
QWidget *containerWidget();
|
||||
|
||||
@ -32,7 +32,7 @@ public:
|
||||
|
||||
ComicsViewTransition *comicsViewTransition;
|
||||
|
||||
EmptyFolderWidget *emptyFolderWidget;
|
||||
FolderContentView *folderContentView;
|
||||
EmptyLabelWidget *emptyLabelWidget;
|
||||
EmptySpecialListWidget *emptySpecialList;
|
||||
EmptyReadingListWidget *emptyReadingList;
|
||||
@ -40,6 +40,10 @@ public:
|
||||
NoSearchResultsWidget *noSearchResultsWidget;
|
||||
|
||||
void updateCurrentComicView();
|
||||
void updateContinueReadingView();
|
||||
|
||||
void toFullscreen();
|
||||
void toNormal();
|
||||
|
||||
protected:
|
||||
QStackedWidget *comicsViewStack;
|
||||
@ -58,7 +62,7 @@ public slots:
|
||||
void focusComicsViewViaShortcut();
|
||||
|
||||
void showComicsView();
|
||||
void showEmptyFolderView();
|
||||
void showFolderContentView();
|
||||
void showEmptyLabelView();
|
||||
void showEmptySpecialList();
|
||||
void showEmptyReadingListWidget();
|
||||
@ -74,4 +78,4 @@ protected slots:
|
||||
void switchToComicsView(ComicsView *from, ComicsView *to);
|
||||
};
|
||||
|
||||
#endif // COMICSVIEWSMANAGER_H
|
||||
#endif // YACREADERCONTENTVIEWSMANAGER_H
|
@ -116,7 +116,7 @@ void YACReaderMainToolBar::resizeEvent(QResizeEvent *event)
|
||||
|
||||
void YACReaderMainToolBar::addDivider()
|
||||
{
|
||||
QPixmap img(":/images/main_toolbar/divider.png");
|
||||
QPixmap img(":/images/main_toolbar/divider.svg");
|
||||
QLabel *divider = new QLabel();
|
||||
divider->setPixmap(img);
|
||||
|
||||
|
@ -11,17 +11,17 @@
|
||||
#include "folder_model.h"
|
||||
#include "reading_list_model.h"
|
||||
#include "comics_view.h"
|
||||
#include "empty_folder_widget.h"
|
||||
#include "folder_content_view.h"
|
||||
#include "yacreader_search_line_edit.h"
|
||||
#include "yacreader_global.h"
|
||||
#include "empty_label_widget.h"
|
||||
#include "empty_special_list.h"
|
||||
#include "yacreader_comics_views_manager.h"
|
||||
#include "yacreader_content_views_manager.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent, YACReaderComicsViewsManager *comicsViewsManager)
|
||||
: QObject(parent), libraryWindow(parent), comicsViewsManager(comicsViewsManager)
|
||||
YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent, YACReaderContentViewsManager *contentViewsManager)
|
||||
: QObject(parent), libraryWindow(parent), contentViewsManager(contentViewsManager)
|
||||
{
|
||||
setupConnections();
|
||||
}
|
||||
@ -61,13 +61,13 @@ void YACReaderNavigationController::loadFolderInfo(const QModelIndex &modelIndex
|
||||
// configure views
|
||||
if (libraryWindow->comicsModel->rowCount() > 0) {
|
||||
// updateView
|
||||
comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
comicsViewsManager->showComicsView();
|
||||
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
contentViewsManager->showComicsView();
|
||||
libraryWindow->disableComicsActions(false);
|
||||
} else {
|
||||
// showEmptyFolder
|
||||
loadEmptyFolderInfo(modelIndex);
|
||||
comicsViewsManager->showEmptyFolderView();
|
||||
contentViewsManager->showFolderContentView();
|
||||
libraryWindow->disableComicsActions(true);
|
||||
}
|
||||
|
||||
@ -110,25 +110,25 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model
|
||||
break;
|
||||
}
|
||||
|
||||
comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
|
||||
if (libraryWindow->comicsModel->rowCount() > 0) {
|
||||
comicsViewsManager->showComicsView();
|
||||
contentViewsManager->showComicsView();
|
||||
libraryWindow->disableComicsActions(false);
|
||||
} else {
|
||||
// setup empty special list widget
|
||||
switch (type) {
|
||||
case ReadingListModel::Favorites:
|
||||
comicsViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png"));
|
||||
comicsViewsManager->emptySpecialList->setText(tr("No favorites"));
|
||||
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png"));
|
||||
contentViewsManager->emptySpecialList->setText(tr("No favorites"));
|
||||
break;
|
||||
case ReadingListModel::Reading:
|
||||
comicsViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png"));
|
||||
comicsViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!"));
|
||||
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png"));
|
||||
contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!"));
|
||||
break;
|
||||
}
|
||||
|
||||
comicsViewsManager->showEmptySpecialList();
|
||||
contentViewsManager->showEmptySpecialList();
|
||||
libraryWindow->disableComicsActions(true);
|
||||
}
|
||||
}
|
||||
@ -138,18 +138,18 @@ void YACReaderNavigationController::loadLabelInfo(const QModelIndex &modelIndex)
|
||||
qulonglong id = modelIndex.data(ReadingListModel::IDRole).toULongLong();
|
||||
// check comics in label with id = id
|
||||
libraryWindow->comicsModel->setupLabelModelData(id, libraryWindow->foldersModel->getDatabase());
|
||||
comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
|
||||
// configure views
|
||||
if (libraryWindow->comicsModel->rowCount() > 0) {
|
||||
// updateView
|
||||
comicsViewsManager->showComicsView();
|
||||
contentViewsManager->showComicsView();
|
||||
libraryWindow->disableComicsActions(false);
|
||||
} else {
|
||||
// showEmptyFolder
|
||||
// loadEmptyLabelInfo(); //there is no info in an empty label by now, TODO design something
|
||||
comicsViewsManager->emptyLabelWidget->setColor((YACReader::LabelColors)modelIndex.data(ReadingListModel::LabelColorRole).toInt());
|
||||
comicsViewsManager->showEmptyLabelView();
|
||||
contentViewsManager->emptyLabelWidget->setColor((YACReader::LabelColors)modelIndex.data(ReadingListModel::LabelColorRole).toInt());
|
||||
contentViewsManager->showEmptyLabelView();
|
||||
libraryWindow->disableComicsActions(true);
|
||||
}
|
||||
}
|
||||
@ -159,15 +159,15 @@ void YACReaderNavigationController::loadReadingListInfo(const QModelIndex &model
|
||||
qulonglong id = modelIndex.data(ReadingListModel::IDRole).toULongLong();
|
||||
// check comics in label with id = id
|
||||
libraryWindow->comicsModel->setupReadingListModelData(id, libraryWindow->foldersModel->getDatabase());
|
||||
comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||
|
||||
// configure views
|
||||
if (libraryWindow->comicsModel->rowCount() > 0) {
|
||||
// updateView
|
||||
comicsViewsManager->showComicsView();
|
||||
contentViewsManager->showComicsView();
|
||||
libraryWindow->disableComicsActions(false);
|
||||
} else {
|
||||
comicsViewsManager->showEmptyReadingListWidget();
|
||||
contentViewsManager->showEmptyReadingListWidget();
|
||||
libraryWindow->disableComicsActions(true);
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,10 @@ void YACReaderNavigationController::loadIndexFromHistory(const YACReaderLibraryS
|
||||
case YACReaderLibrarySourceContainer::Folder: {
|
||||
QModelIndex mi = libraryWindow->foldersModelProxy->mapFromSource(sourceMI);
|
||||
libraryWindow->foldersView->scrollTo(mi, QAbstractItemView::PositionAtTop);
|
||||
// currentIndexChanged is about to be emited, but we don't want it to end in YACReaderHistoryController::updateHistory
|
||||
disconnect(libraryWindow->foldersView, &YACReaderTreeView::currentIndexChanged, this, &YACReaderNavigationController::selectedFolder);
|
||||
libraryWindow->foldersView->setCurrentIndex(mi);
|
||||
connect(libraryWindow->foldersView, &YACReaderTreeView::currentIndexChanged, this, &YACReaderNavigationController::selectedFolder);
|
||||
loadFolderInfo(sourceMI);
|
||||
break;
|
||||
}
|
||||
@ -249,9 +252,18 @@ void YACReaderNavigationController::selectSubfolder(const QModelIndex &sourceMIP
|
||||
|
||||
void YACReaderNavigationController::loadEmptyFolderInfo(const QModelIndex &modelIndex)
|
||||
{
|
||||
QStringList subfolders;
|
||||
subfolders = libraryWindow->foldersModel->getSubfoldersNames(modelIndex);
|
||||
comicsViewsManager->emptyFolderWidget->setSubfolders(modelIndex, subfolders);
|
||||
auto readingComicsModel = new ComicModel();
|
||||
|
||||
auto isRoot = !modelIndex.isValid();
|
||||
|
||||
if (isRoot) {
|
||||
readingComicsModel->setupReadingModelData(libraryWindow->foldersModel->getDatabase());
|
||||
}
|
||||
|
||||
contentViewsManager->folderContentView->setContinueReadingModel(readingComicsModel);
|
||||
|
||||
auto subFolderModel = libraryWindow->foldersModel->getSubfoldersModel(modelIndex);
|
||||
contentViewsManager->folderContentView->setModel(modelIndex, subFolderModel);
|
||||
}
|
||||
|
||||
void YACReaderNavigationController::loadPreviousStatus()
|
||||
@ -262,11 +274,15 @@ void YACReaderNavigationController::loadPreviousStatus()
|
||||
|
||||
void YACReaderNavigationController::setupConnections()
|
||||
{
|
||||
// we need YACReaderTreeView::currentIndexChanged to be able to navigate the folders tree using the keyboard cursors
|
||||
connect(libraryWindow->foldersView, &YACReaderTreeView::currentIndexChanged, this, &YACReaderNavigationController::selectedFolder);
|
||||
connect(libraryWindow->foldersView, &YACReaderTreeView::clicked, this, &YACReaderNavigationController::selectedFolder);
|
||||
connect(libraryWindow->listsView, &QAbstractItemView::clicked, this, &YACReaderNavigationController::selectedList);
|
||||
connect(libraryWindow->historyController, &YACReaderHistoryController::modelIndexSelected, this, &YACReaderNavigationController::selectedIndexFromHistory);
|
||||
connect(comicsViewsManager->emptyFolderWidget, &EmptyFolderWidget::subfolderSelected, this, &YACReaderNavigationController::selectSubfolder);
|
||||
connect(contentViewsManager->folderContentView, &FolderContentView::subfolderSelected, this, &YACReaderNavigationController::selectSubfolder);
|
||||
connect(contentViewsManager->folderContentView, &FolderContentView::openComic, libraryWindow, QOverload<const ComicDB &, const ComicModel::Mode>::of(&LibraryWindow::openComic));
|
||||
connect(contentViewsManager->folderContentView, &FolderContentView::openFolderContextMenu, libraryWindow, &LibraryWindow::showGridFoldersContextMenu);
|
||||
connect(contentViewsManager->folderContentView, &FolderContentView::openContinueReadingComicContextMenu, libraryWindow, &LibraryWindow::showContinueReadingContextMenu);
|
||||
connect(libraryWindow->comicsModel, &ComicModel::isEmpty, this, &YACReaderNavigationController::reselectCurrentSource);
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,13 @@
|
||||
#include <QObject>
|
||||
class LibraryWindow;
|
||||
class YACReaderLibrarySourceContainer;
|
||||
class YACReaderComicsViewsManager;
|
||||
class YACReaderContentViewsManager;
|
||||
|
||||
class YACReaderNavigationController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit YACReaderNavigationController(LibraryWindow *parent, YACReaderComicsViewsManager *comicsViewsManager);
|
||||
explicit YACReaderNavigationController(LibraryWindow *parent, YACReaderContentViewsManager *contentViewsManager);
|
||||
|
||||
signals:
|
||||
|
||||
@ -44,7 +44,7 @@ public slots:
|
||||
private:
|
||||
void setupConnections();
|
||||
LibraryWindow *libraryWindow;
|
||||
YACReaderComicsViewsManager *comicsViewsManager;
|
||||
YACReaderContentViewsManager *contentViewsManager;
|
||||
|
||||
// convenience methods
|
||||
qulonglong folderModelIndexToID(const QModelIndex &mi);
|
||||
|
File diff suppressed because it is too large
Load Diff
2367
YACReaderLibrary/yacreaderlibrary_en.ts
Normal file
2367
YACReaderLibrary/yacreaderlibrary_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@
|
||||
#include "library_creator.h"
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
ConsoleUILibraryCreator::ConsoleUILibraryCreator(QObject *parent)
|
||||
: QObject(parent), numComicsProcessed(0)
|
||||
ConsoleUILibraryCreator::ConsoleUILibraryCreator(QSettings *settings, QObject *parent)
|
||||
: QObject(parent), numComicsProcessed(0), settings(settings)
|
||||
{
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ void ConsoleUILibraryCreator::createLibrary(const QString &name, const QString &
|
||||
}
|
||||
|
||||
QEventLoop eventLoop;
|
||||
LibraryCreator *libraryCreator = new LibraryCreator();
|
||||
LibraryCreator *libraryCreator = new LibraryCreator(settings);
|
||||
QString cleanPath = QDir::cleanPath(pathDir.absolutePath());
|
||||
|
||||
YACReaderLibraries yacreaderLibraries;
|
||||
@ -56,7 +56,7 @@ void ConsoleUILibraryCreator::updateLibrary(const QString &path)
|
||||
}
|
||||
|
||||
QEventLoop eventLoop;
|
||||
LibraryCreator *libraryCreator = new LibraryCreator();
|
||||
LibraryCreator *libraryCreator = new LibraryCreator(settings);
|
||||
QString cleanPath = QDir::cleanPath(pathDir.absolutePath());
|
||||
|
||||
libraryCreator->updateLibrary(cleanPath, QDir::cleanPath(pathDir.absolutePath() + "/.yacreaderlibrary"));
|
||||
|
@ -7,7 +7,7 @@ class ConsoleUILibraryCreator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConsoleUILibraryCreator(QObject *parent = 0);
|
||||
explicit ConsoleUILibraryCreator(QSettings *settings, QObject *parent = 0);
|
||||
void createLibrary(const QString &name, const QString &path);
|
||||
void updateLibrary(const QString &path);
|
||||
void addExistingLibrary(const QString &name, const QString &path);
|
||||
@ -15,6 +15,7 @@ public:
|
||||
|
||||
private:
|
||||
uint numComicsProcessed;
|
||||
QSettings *settings;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "comic_db.h"
|
||||
#include "db_helper.h"
|
||||
#include "startup.h"
|
||||
#include "yacreader_http_server.h"
|
||||
#include "yacreader_global.h"
|
||||
#include "yacreader_libraries.h"
|
||||
#include "yacreader_local_server.h"
|
||||
@ -124,6 +124,9 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini", QSettings::IniFormat);
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
if (command == "start") {
|
||||
parser.clearPositionalArguments();
|
||||
parser.addPositionalArgument("start", "Start YACReaderLibraryServer");
|
||||
@ -190,11 +193,8 @@ int main(int argc, char **argv)
|
||||
|
||||
QLOG_INFO() << "YACReaderLibrary starting";
|
||||
|
||||
QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini", QSettings::IniFormat);
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
// server
|
||||
Startup *s = new Startup();
|
||||
YACReaderHttpServer *httpServer = new YACReaderHttpServer();
|
||||
if (parser.isSet("port")) {
|
||||
bool valid;
|
||||
qint32 port = parser.value("port").toInt(&valid);
|
||||
@ -203,14 +203,14 @@ int main(int argc, char **argv)
|
||||
parser.showHelp();
|
||||
return 0;
|
||||
} else {
|
||||
s->start(port);
|
||||
httpServer->start(port);
|
||||
}
|
||||
|
||||
} else {
|
||||
s->start();
|
||||
httpServer->start();
|
||||
}
|
||||
|
||||
QLOG_INFO() << "Running on port" << s->getPort();
|
||||
QLOG_INFO() << "Running on port" << httpServer->getPort();
|
||||
|
||||
// Update libraries to new versions
|
||||
LibrariesUpdater updater;
|
||||
@ -223,8 +223,8 @@ int main(int argc, char **argv)
|
||||
QLOG_INFO() << "YACReaderLibrary closed with exit code :" << ret;
|
||||
|
||||
// shutdown
|
||||
s->stop();
|
||||
delete s;
|
||||
httpServer->stop();
|
||||
delete httpServer;
|
||||
localServer->close();
|
||||
delete localServer;
|
||||
#ifdef Q_OS_WIN
|
||||
@ -244,7 +244,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator;
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings);
|
||||
libraryCreatorUI->createLibrary(args.at(1), args.at(2));
|
||||
|
||||
return 0;
|
||||
@ -260,7 +260,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator;
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings);
|
||||
libraryCreatorUI->updateLibrary(args.at(1));
|
||||
|
||||
return 0;
|
||||
@ -277,7 +277,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator;
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings);
|
||||
libraryCreatorUI->addExistingLibrary(args.at(1), args.at(2));
|
||||
|
||||
return 0;
|
||||
@ -293,7 +293,7 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator;
|
||||
ConsoleUILibraryCreator *libraryCreatorUI = new ConsoleUILibraryCreator(settings);
|
||||
libraryCreatorUI->removeLibrary(args.at(1));
|
||||
|
||||
return 0;
|
||||
|
@ -54,7 +54,7 @@ jobs:
|
||||
- script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y qtchooser qtbase5-dev-tools qt5-qmake \
|
||||
qtbase5-dev qtmultimedia5-dev libpoppler-qt5-dev \
|
||||
qtbase5-dev qtmultimedia5-dev libpoppler-qt5-dev qttools5-dev-tools \
|
||||
libqt5opengl5-dev libunarr-dev qtdeclarative5-dev libqt5svg5-dev qtquickcontrols2-5-dev
|
||||
displayName: 'Install dependencies'
|
||||
- script: |
|
||||
@ -94,7 +94,7 @@ jobs:
|
||||
- script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y qtchooser qt6-tools-dev qt6-base-dev-tools qmake6 qmake6-bin \
|
||||
qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev \
|
||||
qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev qt6-l10n-tools \
|
||||
libqt6opengl6-dev libunarr-dev qt6-declarative-dev libqt6svg6-dev libqt6core5compat6-dev
|
||||
displayName: 'Install dependencies'
|
||||
- script: |
|
||||
|
@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>com.yacreader.YACReader</id>
|
||||
<metadata_license>FSFAP</metadata_license>
|
||||
<project_license>GPL-3.0-only</project_license>
|
||||
<name>YACReader</name>
|
||||
<developer_name>Luis Ángel San Martín Rodríguez</developer_name>
|
||||
<summary>Yet another comic reader</summary>
|
||||
<description>
|
||||
<p>
|
||||
Read, browse and manage your comics collection.
|
||||
All you need to enjoy your digital comics.
|
||||
</p>
|
||||
<p>
|
||||
Browse your comics collections using beautiful, customizable and smooth "comic flow" transitions.
|
||||
</p>
|
||||
<p>Features:</p>
|
||||
<ul>
|
||||
<li>File support: YACReader supports a wide variety of comic files and image types. rar, zip, cbr, cbz, tar, pdf, 7z and cb7, jpeg, gif, png, tiff and bmp.</li>
|
||||
<li>Configure your reading: Image rotation, double page mode, full size view, fullscreen mode, customizable background color, custom page fitting mode, bookmarks, resume reading, eye candy 'go to' and more.</li>
|
||||
<li>Image improvements: Bring to life your old comics with the image adjustments available in the reading mode. Use the brightness, contrast and gamma sliders and enjoy the new vibrant colors.</li>
|
||||
<li>Track your readings: YACReaderLibrary organizes your comics and keeps track of your reading progress and your collections' status.</li>
|
||||
<li>Tags (comic vine): Download your comics' information from Comic Vine. Title, number, volumen, authors and more.</li>
|
||||
<li>Search: Find your comics quickly using the built-in search engine. No matter how big is your collection, YACReaderLibrary will find anything instantly.</li>
|
||||
</ul>
|
||||
</description>
|
||||
<categories>
|
||||
<category>Graphics</category>
|
||||
<category>Office</category>
|
||||
<category>Viewer</category>
|
||||
</categories>
|
||||
<launchable type="desktop-id">com.yacreader.YACReader.desktop</launchable>
|
||||
<launchable type="desktop-id">com.yacreader.YACReader.YACReaderLibrary.desktop</launchable>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>YACReader & YACReaderLibrary</caption>
|
||||
<image>https://www.yacreader.com/images/features/phoca_thumb_l_ss3b.jpg</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Properties</caption>
|
||||
<image>https://www.yacreader.com/images/features/phoca_thumb_l_properties.jpg</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<url type="homepage">https://www.yacreader.com/</url>
|
||||
<url type="bugtracker">https://github.com/YACReader/yacreader/issues</url>
|
||||
<url type="faq">https://www.yacreader.com/support</url>
|
||||
<url type="help">https://www.yacreader.com/support</url>
|
||||
<url type="donation">https://www.yacreader.com/donation-why</url>
|
||||
<url type="contact">https://www.yacreader.com/contact</url>
|
||||
<provides>
|
||||
<mediatype>application/x-cbz</mediatype>
|
||||
<mediatype>application/x-cbr</mediatype>
|
||||
<mediatype>application/x-cbt</mediatype>
|
||||
<mediatype>application/x-cb7</mediatype>
|
||||
<mediatype>application/x-pdf</mediatype>
|
||||
<mediatype>application/x-zip</mediatype>
|
||||
<mediatype>application/x-rar</mediatype>
|
||||
<mediatype>application/x-7z</mediatype>
|
||||
<mediatype>inode/directory</mediatype>
|
||||
<mediatype>application/vnd.comicbook-rar</mediatype>
|
||||
<mediatype>application/vnd.comicbook+zip</mediatype>
|
||||
<mediatype>application/pdf</mediatype>
|
||||
<mediatype>application/vnd.rar</mediatype>
|
||||
<mediatype>application/x-7z-compressed</mediatype>
|
||||
<mediatype>application/zip</mediatype>
|
||||
<binary>YACReader</binary>
|
||||
<binary>YACReaderLibrary</binary>
|
||||
<binary>YACReaderLibraryServer</binary>
|
||||
</provides>
|
||||
<releases>
|
||||
<release version="9.8.2.2106204" date="2021-06-20">
|
||||
<description>
|
||||
<p>YACReaderLibrary</p>
|
||||
<ul>
|
||||
<li>Fix opening comics from the continue reading banner.</li>
|
||||
<li>Make available next/prev comic covers in the iOS app while reading. (ios app 3.16.1 needed)</li>
|
||||
</ul>
|
||||
<p>Server</p>
|
||||
<ul>
|
||||
<li>Make available next/prev comic covers in the iOS app while reading. (ios app 3.16.1 needed)</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
@ -1,126 +0,0 @@
|
||||
app-id: com.yacreader.YACReader
|
||||
runtime: org.kde.Platform
|
||||
runtime-version: "5.15-21.08"
|
||||
sdk: org.kde.Sdk
|
||||
command: YACReader
|
||||
finish-args:
|
||||
- --share=ipc
|
||||
- --socket=fallback-x11
|
||||
- --socket=wayland
|
||||
- --share=network
|
||||
- --device=dri
|
||||
- --filesystem=xdg-documents
|
||||
- --filesystem=xdg-pictures
|
||||
cleanup:
|
||||
- /bin/gn
|
||||
- /include
|
||||
- /lib/cmake
|
||||
- /lib/pkgconfig
|
||||
- /lib/systemd
|
||||
- /share/doc
|
||||
- /share/man
|
||||
- "*.a"
|
||||
- "*.la"
|
||||
modules:
|
||||
- name: yacreader
|
||||
# https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=yacreader
|
||||
buildsystem: qmake
|
||||
config-opts:
|
||||
- CONFIG+=unarr pdfium server_bundled
|
||||
install-rule: null
|
||||
make-install-args:
|
||||
- sub-YACReader-install_subtargets
|
||||
- sub-YACReaderLibrary-install_subtargets
|
||||
post-install:
|
||||
- mv "$FLATPAK_DEST"/share/applications/{YACReader,com.yacreader.YACReader}.desktop
|
||||
- mv "$FLATPAK_DEST"/share/applications/{YACReaderLibrary,com.yacreader.YACReader.YACReaderLibrary}.desktop
|
||||
- mv "$FLATPAK_DEST"/share/icons/hicolor/scalable/apps/{YACReader,com.yacreader.YACReader}.svg
|
||||
- mv "$FLATPAK_DEST"/share/icons/hicolor/scalable/apps/{YACReaderLibrary,com.yacreader.YACReader.YACReaderLibrary}.svg
|
||||
- sed -i -e 's/^Categories=\(.*\)$/Categories=Office;\1/' -e 's/^Icon=.*$/Icon=com.yacreader.YACReader/' "$FLATPAK_DEST"/share/applications/com.yacreader.YACReader.desktop
|
||||
- sed -i -e 's/^Categories=\(.*\)$/Categories=Office;\1/' -e 's/^Icon=.*$/Icon=com.yacreader.YACReader.YACReaderLibrary/' "$FLATPAK_DEST"/share/applications/com.yacreader.YACReader.YACReaderLibrary.desktop
|
||||
- install -D -m644 com.yacreader.YACReader.appdata.xml "$FLATPAK_DEST"/share/metainfo/com.yacreader.YACReader.appdata.xml
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/YACReader/yacreader.git
|
||||
tag: 9.8.2.2106204
|
||||
commit: 7394944dccd1ee1f9dd8247e878f6ff8a055b7b8
|
||||
- type: file
|
||||
path: com.yacreader.YACReader.appdata.xml
|
||||
modules:
|
||||
- name: unarr
|
||||
buildsystem: cmake
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/selmf/unarr.git
|
||||
commit: cf4deedfdd2b815ae2ad0f24cfda72c3d8083d14
|
||||
- name: pdfium
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=libpdfium-nojs
|
||||
# Fix visibilty for system Freetype
|
||||
- git -C pdfium/build cherry-pick -n bfd6ff0
|
||||
# Patch abseil build to be static
|
||||
- cd "$FLATPAK_BUILDER_BUILDDIR/pdfium/third_party/abseil-cpp"
|
||||
- sed -i -e 's/component(/static_library(/' -e 's/is_component_build(/false/' pdfium/third_party/abseil-cpp/BUILD.gn
|
||||
# Use system provided icu library (unbundling)
|
||||
- mkdir -p pdfium/third_party/icu
|
||||
- ln -sf ../../build/linux/unbundle/icu.gn pdfium/third_party/icu/BUILD.gn
|
||||
# Download and decode shim header script needed to unbundle icu (gittiles is weird)
|
||||
- mkdir -p pdfium/tools/generate_shim_headers
|
||||
- base64 --decode generate_shim_headers.py > pdfium/tools/generate_shim_headers/generate_shim_headers.py
|
||||
# Create fake gclient_args.gni file to satisfy include list for build/config/compiler/compiler.gni
|
||||
- touch pdfium/build/config/gclient_args.gni
|
||||
# Exclude test fonts from build
|
||||
- sed -i '/"\/\/third_party\/test_fonts",/s/^/#/g' pdfium/testing/BUILD.gn
|
||||
# Build
|
||||
- gn --root=pdfium gen pdfium/out/Release --args="is_clang=false use_sysroot=false is_debug=false symbol_level=0 pdf_enable_v8=false pdf_enable_xfa=false treat_warnings_as_errors=false use_system_libjpeg=true use_system_zlib=true pdf_bundle_freetype=false use_system_freetype=true use_system_lcms2=true use_system_libpng=true use_custom_libcxx=false pdf_is_standalone=true use_system_libopenjpeg2=true is_component_build=true use_gold=false"
|
||||
- ninja -C pdfium/out/Release pdfium
|
||||
- sed -e 's/@VERSION@/5005/g' -e 's#^\s*prefix\s*=.*$#prefix='"$FLATPAK_DEST"'#' -i libpdfium.pc
|
||||
# Install
|
||||
- install -D -m644 pdfium/LICENSE "$FLATPAK_DEST/share/licenses/pdfium/LICENSE"
|
||||
- install -D pdfium/public/*.h --target-directory="$FLATPAK_DEST/include/pdfium"
|
||||
- install -D pdfium/public/cpp/* --target-directory="$FLATPAK_DEST/include/pdfium/cpp"
|
||||
- install -D pdfium/docs/* --target-directory="$FLATPAK_DEST/share/doc/pdfium"
|
||||
- install -Dm755 pdfium/out/Release/libpdfium.so --target-directory="$FLATPAK_DEST/lib"
|
||||
- install -Dm644 libpdfium.pc --target-directory="$FLATPAK_DEST/lib/pkgconfig"
|
||||
sources:
|
||||
- type: git
|
||||
url: https://pdfium.googlesource.com/pdfium
|
||||
# curl 'https://omahaproxy.appspot.com/linux?channel=stable' | cut -d'.' -f 3
|
||||
branch: chromium/5005
|
||||
commit: 62ad9af8a9f9494645b659674b64bb51775cde05
|
||||
dest: pdfium
|
||||
- type: git
|
||||
url: https://chromium.googlesource.com/chromium/src/build.git
|
||||
# awk '/build_revision/ {print substr($2,2,40)}' pdfium/DEPS
|
||||
commit: ee10d9605d3bc45e72defd25ce97562e80693655
|
||||
dest: pdfium/build
|
||||
- type: git
|
||||
url: https://chromium.googlesource.com/chromium/src/third_party/abseil-cpp
|
||||
# awk '/abseil_revision/ {print substr($2,2,40)}' pdfium/DEPS
|
||||
branch: a13888fac08a45c938255c7d9d59b1640f1940e0
|
||||
dest: pdfium/third_party/abseil-cpp
|
||||
- type: file
|
||||
url: https://chromium.googlesource.com/chromium/src/+/master/tools/generate_shim_headers/generate_shim_headers.py?format=TEXT
|
||||
dest-filename: generate_shim_headers.py
|
||||
sha256: f95f0d29e3e12b22a7b86455265c87bc0219a25c09a7fa160d34b608992ea6da
|
||||
- type: file
|
||||
url: https://aur.archlinux.org/cgit/aur.git/plain/libpdfium.pc?h=libpdfium-nojs
|
||||
dest-filename: libpdfium.pc
|
||||
sha256: 4e8cf32c09568ae4c59244f0a221eee8f87ea4a31ddb31f796a1d818c967d477
|
||||
modules:
|
||||
- name: gn
|
||||
buildsystem: simple
|
||||
build-options:
|
||||
env:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
build-commands:
|
||||
- ./build/gen.py
|
||||
- ninja -C out
|
||||
- install -D out/gn "$FLATPAK_DEST/bin/gn"
|
||||
sources:
|
||||
- type: git
|
||||
url: https://gn.googlesource.com/gn
|
||||
commit: 80a40b07305373617eba2d5878d353532af77da3
|
||||
disable-shallow-clone: true
|
@ -197,6 +197,50 @@ ComicInfo::ComicInfo(const ComicInfo &comicInfo)
|
||||
ComicInfo::~ComicInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void ComicInfo::deleteMetadata()
|
||||
{
|
||||
title = QVariant();
|
||||
|
||||
coverPage = QVariant();
|
||||
numPages = QVariant();
|
||||
|
||||
number = QVariant();
|
||||
isBis = QVariant();
|
||||
count = QVariant();
|
||||
|
||||
volume = QVariant();
|
||||
storyArc = QVariant();
|
||||
arcNumber = QVariant();
|
||||
arcCount = QVariant();
|
||||
|
||||
genere = QVariant();
|
||||
|
||||
writer = QVariant();
|
||||
penciller = QVariant();
|
||||
inker = QVariant();
|
||||
colorist = QVariant();
|
||||
letterer = QVariant();
|
||||
coverArtist = QVariant();
|
||||
|
||||
date = QVariant();
|
||||
|
||||
day = QVariant();
|
||||
month = QVariant();
|
||||
year = QVariant();
|
||||
|
||||
publisher = QVariant();
|
||||
format = QVariant();
|
||||
color = QVariant();
|
||||
ageRating = QVariant();
|
||||
manga = QVariant();
|
||||
|
||||
synopsis = QVariant();
|
||||
characters = QVariant();
|
||||
notes = QVariant();
|
||||
|
||||
comicVineID = QVariant();
|
||||
}
|
||||
// the default operator= should work
|
||||
ComicInfo &ComicInfo::operator=(const ComicInfo &comicInfo)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ public:
|
||||
ComicInfo(const ComicInfo &comicInfo);
|
||||
~ComicInfo();
|
||||
|
||||
void deleteMetadata();
|
||||
|
||||
ComicInfo &operator=(const ComicInfo &comicInfo);
|
||||
|
||||
bool operator==(const ComicInfo &other) { return id == other.id; }
|
||||
|
@ -20,6 +20,20 @@ Folder::Folder(qulonglong folderId, qulonglong parentId, const QString &folderNa
|
||||
this->path = folderPath;
|
||||
}
|
||||
|
||||
Folder::Folder(qulonglong folderId, qulonglong parentId, const QString &folderName, const QString &folderPath, bool completed, bool finished, bool manga)
|
||||
: knownParent(true),
|
||||
knownId(true),
|
||||
numChildren(-1)
|
||||
{
|
||||
this->id = folderId;
|
||||
this->parentId = parentId;
|
||||
this->name = folderName;
|
||||
this->path = folderPath;
|
||||
this->completed = completed;
|
||||
this->finished = finished;
|
||||
this->manga = manga;
|
||||
}
|
||||
|
||||
Folder::Folder(const Folder &folder)
|
||||
{
|
||||
operator=(folder);
|
||||
|
@ -13,6 +13,7 @@ public:
|
||||
|
||||
Folder();
|
||||
Folder(qulonglong folderId, qulonglong parentId, const QString &folderName, const QString &folderPath);
|
||||
Folder(qulonglong folderId, qulonglong parentId, const QString &folderName, const QString &folderPath, bool completed, bool finished, bool manga);
|
||||
Folder(const QString &folderName, const QString &folderPath);
|
||||
Folder(const Folder &folder);
|
||||
Folder &operator=(const Folder &other);
|
||||
@ -94,8 +95,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool finished;
|
||||
bool completed;
|
||||
bool finished; // finished means read, the user has read all the content in this folder
|
||||
bool completed; // completed means the folder has all the content, e.g. a series got its final issue and the user has collected all of them
|
||||
bool manga;
|
||||
|
||||
qint32 numChildren; //-1 for unknown number of children
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "yacreader_global.h"
|
||||
|
||||
#include <QModelIndex>
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
QString YACReader::getSettingsPath()
|
||||
@ -100,3 +102,20 @@ QDataStream &YACReader::operator>>(QDataStream &stream, OpenComicSource &source)
|
||||
stream >> source.sourceId;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void YACReader::iterate(const QModelIndex &index,
|
||||
const QAbstractItemModel *model,
|
||||
const std::function<bool(const QModelIndex &)> &iteration)
|
||||
{
|
||||
if (index.isValid()) {
|
||||
auto continueIterating = iteration(index);
|
||||
if (!continueIterating) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((index.flags() & Qt::ItemNeverHasChildren) || !model->hasChildren(index))
|
||||
return;
|
||||
auto rows = model->rowCount(index);
|
||||
for (int i = 0; i < rows; ++i)
|
||||
iterate(model->index(i, 0, index), model, iteration);
|
||||
}
|
||||
|
@ -4,10 +4,12 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QDataStream>
|
||||
#include <QMetaType>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#define VERSION "9.9.2"
|
||||
#define VERSION "9.10.0"
|
||||
|
||||
#define REMOTE_BROWSE_PERFORMANCE_WORKAROUND "REMOTE_BROWSE_PERFORMANCE_WORKAROUND"
|
||||
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"
|
||||
|
||||
#define NUM_DAYS_BETWEEN_VERSION_CHECKS "NUM_DAYS_BETWEEN_VERSION_CHECKS"
|
||||
#define LAST_VERSION_CHECK "LAST_VERSION_CHECK"
|
||||
@ -67,6 +69,10 @@ QString getSettingsPath();
|
||||
QString colorToName(LabelColors colors);
|
||||
QString labelColorToRGBString(LabelColors color);
|
||||
|
||||
void iterate(const QModelIndex &index,
|
||||
const QAbstractItemModel *model,
|
||||
const std::function<bool(const QModelIndex &)> &iteration);
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(YACReader::OpenComicSource::Source)
|
||||
|
@ -21,9 +21,10 @@ QAction *YACReader::createSeparator()
|
||||
|
||||
QIcon YACReader::noHighlightedIcon(const QString &path)
|
||||
{
|
||||
QPixmap p(path);
|
||||
QPixmap sp(path);
|
||||
QPixmap p = hdpiPixmap(path, sp.size());
|
||||
|
||||
QIcon icon; //(path);
|
||||
QIcon icon;
|
||||
icon.addFile(path, p.size(), QIcon::Normal);
|
||||
icon.addFile(path, p.size(), QIcon::Selected);
|
||||
return icon;
|
||||
@ -49,3 +50,52 @@ QList<qulonglong> YACReader::mimeDataToComicsIds(const QMimeData *data)
|
||||
in >> comicIds; // deserialize the list of indentifiers
|
||||
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_MAC
|
||||
return path + ".png";
|
||||
#else
|
||||
return path + ".svg";
|
||||
#endif
|
||||
#else
|
||||
return path + ".svg";
|
||||
#endif
|
||||
}
|
||||
|
||||
QString YACReader::addExtensionToIconPathInToolbar(const QString &path)
|
||||
{
|
||||
return path + "_18x18.svg";
|
||||
}
|
||||
|
||||
QAction *YACReader::actionWithCustomIcon(const QIcon &icon, QAction *action)
|
||||
{
|
||||
auto a = new QAction(icon, action->text());
|
||||
|
||||
a->setEnabled(action->isEnabled());
|
||||
a->setCheckable(action->isCheckable());
|
||||
|
||||
a->setChecked(action->isChecked());
|
||||
|
||||
QObject::connect(a, &QAction::triggered, action, &QAction::triggered);
|
||||
|
||||
QObject::connect(action, &QAction::changed, action, [=]() {
|
||||
a->setEnabled(action->isEnabled());
|
||||
a->setCheckable(action->isCheckable());
|
||||
|
||||
a->setChecked(action->isChecked());
|
||||
});
|
||||
QObject::connect(a, &QAction::toggled, action, &QAction::setChecked);
|
||||
QObject::connect(action, &QAction::toggled, a, &QAction::setChecked);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
QPixmap YACReader::hdpiPixmap(const QString &file, QSize size)
|
||||
{
|
||||
return QIcon(file).pixmap(size);
|
||||
}
|
||||
|
@ -110,6 +110,10 @@ QAction *createSeparator();
|
||||
QIcon noHighlightedIcon(const QString &path);
|
||||
void colorize(QImage &img, QColor &col);
|
||||
QList<qulonglong> 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);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user