From 36f91caee528002e8ebeb9a89fdc9cda26f8ab4d Mon Sep 17 00:00:00 2001 From: zvezdochiot Date: Wed, 8 Nov 2023 12:34:23 +0300 Subject: [PATCH] 0.2.14: Scan Tailor Deviant by @noobie-iv --- .gitmodules | 3 - CMakeLists.txt | 574 +++--- COPYING | 2 +- GPL3.txt => LICENSE | 0 cmake/CopyToBuildDir.cmake | 72 - cmake/FindEXIV2.cmake | 43 +- cmake/FindOPENJPEG.cmake | 36 + cmake/LibToDLL.cmake | 22 - cmake/PatchFile.cmake | 42 - cmake/ToNativePath.cmake | 7 - cmake/cmake_uninstall.cmake.in | 21 - cmake/copy_to_build_dir.cmake.in | 20 - cmake/default_cxxflags.cmake | 2 +- cmake/generate_nsi_file.cmake.in | 64 - cmake/move_sym_file.cmake | 14 - cmake/prepare_staging_dir.cmake.in | 84 - debian/changelog | 3 +- src/CMakeLists.txt | 7 - src/app/CMakeLists.txt | 2 + src/app/ExportDialog.cpp | 3 + src/app/MainWindow.cpp | 2 + src/app/NewOpenProjectPanel.cpp | 38 +- src/app/NewOpenProjectPanel.h | 2 + src/app/SettingsDialog.cpp | 2 +- src/app/StartBatchProcessingDialog.cpp | 2 + .../resources/icons/left_page_plus_offcut.png | Bin 207 -> 434 bytes .../icons/left_page_plus_offcut_selected.png | Bin 208 -> 502 bytes .../icons/right_page_plus_offcut.png | Bin 206 -> 427 bytes .../icons/right_page_plus_offcut_selected.png | Bin 208 -> 474 bytes src/app/resources/icons/single_page_uncut.png | Bin 194 -> 386 bytes .../icons/single_page_uncut_selected.png | Bin 188 -> 410 bytes src/app/resources/icons/two_pages.png | Bin 169 -> 415 bytes .../resources/icons/two_pages_selected.png | Bin 214 -> 551 bytes src/app/ui/AboutDialog.ui | 5 +- src/app/ui/ExportDialog.ui | 24 + src/app/ui/FixDpiDialog.ui | 25 +- src/app/ui/LoadFilesStatusDialog.ui | 3 + src/app/ui/MainWindow.ui | 10 + src/app/ui/NewOpenProjectPanel.ui | 7 +- src/app/ui/ProjectFilesDialog.ui | 17 + src/app/ui/RelinkingDialog.ui | 3 + src/app/ui/RemovePagesDialog.ui | 3 + src/app/ui/SettingsDialog.ui | 710 ++++--- src/app_cli/CMakeLists.txt | 6 +- src/core/CMakeLists.txt | 4 +- src/core/TiffReader.cpp | 62 +- src/core/TiffWriter.cpp | 28 +- src/core/filters/output/BlackWhiteOptions.cpp | 30 +- src/core/filters/output/BlackWhiteOptions.h | 2 +- src/core/filters/output/OptionsWidget.cpp | 93 +- src/core/filters/output/OptionsWidget.h | 16 +- src/core/filters/output/OutputGenerator.cpp | 20 + .../filters/output/PictureZonePropDialog.cpp | 2 + .../output/ui/OutputChangeDewarpingWidget.ui | 6 + .../filters/output/ui/OutputOptionsWidget.ui | 218 +-- .../output/ui/PictureZonePropDialog.ui | 13 - .../page_layout/ui/PageLayoutOptionsWidget.ui | 6 +- .../filters/page_layout/ui/alignmentwidget.ui | 15 + .../page_split/ui/PageSplitOptionsWidget.ui | 2 +- .../ui/SelectContentOptionsWidget.ui | 13 + src/core/settings/globalstaticsettings.cpp | 2 +- src/imageproc/Binarize.cpp | 610 ++++++ src/imageproc/Binarize.h | 49 + src/imageproc/CMakeLists.txt | 5 +- src/imageproc/ColorFilter.cpp | 1377 ++++++++++++++ src/imageproc/ColorFilter.h | 133 ++ src/math/CMakeLists.txt | 7 +- src/packaging/linux/README | 26 - src/packaging/linux/README.md | 163 ++ src/packaging/windows/CMakeLists.txt | 164 -- src/packaging/windows/README.md | 625 ++++++ .../windows/build_deps/CMakeLists.txt | 647 ------- .../windows/build_deps/dump_dll_syms.cmake | 13 - .../windows/build_deps/export-vars.cmake.in | 9 - .../build_deps/generate_qt_build_script.cmake | 34 - .../windows/patch_libtiff/CMakeLists.txt | 35 - .../apply_individual_patches.cmake.in | 9 - src/packaging/windows/readme.en.txt | 192 -- src/packaging/windows/readme.ru.txt | 192 -- src/packaging/windows/registerExtension.nsh | 66 - src/packaging/windows/scantailor.nsi.in | 155 -- src/stylesheets/Breeze.qss | 1667 +++++++++++++++++ src/stylesheets/Breeze/LICENSE.md | 26 + src/stylesheets/Breeze/README.md | 23 + src/stylesheets/Breeze/branch_closed-on.svg | 3 + src/stylesheets/Breeze/branch_closed.svg | 3 + src/stylesheets/Breeze/branch_open-on.svg | 3 + src/stylesheets/Breeze/branch_open.svg | 3 + .../Breeze/checkbox_checked-hover.svg | 5 + src/stylesheets/Breeze/checkbox_checked.svg | 5 + .../Breeze/checkbox_checked_disabled.svg | 5 + .../Breeze/checkbox_indeterminate-hover.svg | 7 + .../Breeze/checkbox_indeterminate.svg | 7 + .../checkbox_indeterminate_disabled.svg | 7 + .../Breeze/checkbox_unchecked-hover.svg | 4 + .../Breeze/checkbox_unchecked_disabled.svg | 4 + src/stylesheets/Breeze/close-hover.svg | 3 + src/stylesheets/Breeze/close-pressed.svg | 3 + src/stylesheets/Breeze/close.svg | 3 + src/stylesheets/Breeze/down_arrow-hover.svg | 3 + src/stylesheets/Breeze/down_arrow.svg | 3 + .../Breeze/down_arrow_disabled.svg | 3 + src/stylesheets/Breeze/hmovetoolbar.svg | 5 + src/stylesheets/Breeze/hsepartoolbar.svg | 3 + src/stylesheets/Breeze/left_arrow.svg | 3 + .../Breeze/left_arrow_disabled.svg | 3 + .../Breeze/radio_checked-hover.svg | 5 + src/stylesheets/Breeze/radio_checked.svg | 5 + .../Breeze/radio_checked_disabled.svg | 5 + .../Breeze/radio_unchecked-hover.svg | 4 + .../Breeze/radio_unchecked_disabled.svg | 4 + src/stylesheets/Breeze/right_arrow.svg | 3 + .../Breeze/right_arrow_disabled.svg | 3 + src/stylesheets/Breeze/sizegrip.svg | 3 + src/stylesheets/Breeze/spinup_disabled.svg | 3 + .../Breeze/stylesheet-branch-end-closed.svg | 4 + .../Breeze/stylesheet-branch-end-open.svg | 4 + .../Breeze/stylesheet-branch-end.svg | 4 + .../Breeze/stylesheet-branch-more.svg | 4 + src/stylesheets/Breeze/stylesheet-vline.svg | 3 + src/stylesheets/Breeze/transparent.svg | 1 + src/stylesheets/Breeze/undock-hover.svg | 5 + src/stylesheets/Breeze/undock.svg | 3 + src/stylesheets/Breeze/up_arrow-hover.svg | 3 + src/stylesheets/Breeze/up_arrow.svg | 3 + src/stylesheets/Breeze/up_arrow_disabled.svg | 3 + src/stylesheets/Breeze/vmovetoolbar.svg | 8 + src/stylesheets/Breeze/vsepartoolbars.svg | 7 + src/stylesheets/BreezeDark.qss | 1662 ++++++++++++++++ src/stylesheets/BreezeDark/LICENSE.md | 26 + src/stylesheets/BreezeDark/README.md | 23 + .../BreezeDark/branch_closed-on.svg | 3 + src/stylesheets/BreezeDark/branch_closed.svg | 3 + src/stylesheets/BreezeDark/branch_open-on.svg | 3 + src/stylesheets/BreezeDark/branch_open.svg | 3 + .../BreezeDark/checkbox_checked.svg | 5 + .../BreezeDark/checkbox_checked_disabled.svg | 5 + .../BreezeDark/checkbox_indeterminate.svg | 7 + .../checkbox_indeterminate_disabled.svg | 7 + .../BreezeDark/checkbox_unchecked.svg | 4 + .../checkbox_unchecked_disabled.svg | 4 + src/stylesheets/BreezeDark/close-hover.svg | 3 + src/stylesheets/BreezeDark/close-pressed.svg | 3 + src/stylesheets/BreezeDark/close.svg | 3 + .../BreezeDark/down_arrow-hover.svg | 3 + src/stylesheets/BreezeDark/down_arrow.svg | 3 + .../BreezeDark/down_arrow_disabled.svg | 3 + src/stylesheets/BreezeDark/hmovetoolbar.svg | 4 + src/stylesheets/BreezeDark/hsepartoolbar.svg | 3 + src/stylesheets/BreezeDark/left_arrow.svg | 3 + .../BreezeDark/left_arrow_disabled.svg | 3 + src/stylesheets/BreezeDark/radio_checked.svg | 5 + .../BreezeDark/radio_checked_disabled.svg | 5 + .../BreezeDark/radio_unchecked.svg | 4 + .../BreezeDark/radio_unchecked_disabled.svg | 4 + src/stylesheets/BreezeDark/right_arrow.svg | 3 + .../BreezeDark/right_arrow_disabled.svg | 3 + src/stylesheets/BreezeDark/sizegrip.svg | 3 + .../BreezeDark/spinup_disabled.svg | 3 + .../stylesheet-branch-end-closed.svg | 4 + .../BreezeDark/stylesheet-branch-end-open.svg | 4 + .../BreezeDark/stylesheet-branch-end.svg | 4 + .../BreezeDark/stylesheet-branch-more.svg | 4 + .../BreezeDark/stylesheet-vline.svg | 3 + src/stylesheets/BreezeDark/transparent.svg | 1 + src/stylesheets/BreezeDark/undock-hover.svg | 5 + src/stylesheets/BreezeDark/undock.svg | 3 + src/stylesheets/BreezeDark/up_arrow-hover.svg | 3 + src/stylesheets/BreezeDark/up_arrow.svg | 3 + .../BreezeDark/up_arrow_disabled.svg | 3 + src/stylesheets/BreezeDark/vmovetoolbar.svg | 8 + src/stylesheets/BreezeDark/vsepartoolbars.svg | 7 + src/stylesheets/CMakeLists.txt | 13 - src/stylesheets/dark_blue.qss | 785 ++++++++ .../dark_blue/checkbox_checked.svg | 7 + .../dark_blue/checkbox_checked_disabled.svg | 7 + .../dark_blue/checkbox_indeterminate.svg | 7 + .../checkbox_indeterminate_disabled.svg | 7 + .../checkbox_indeterminate_hover.svg | 7 + .../dark_blue/checkbox_unchecked.svg | 7 + .../dark_blue/checkbox_unchecked_disabled.svg | 7 + .../dark_blue/checkbox_unchecked_hover.svg | 7 + .../dark_blue/combobox_arrow_down.svg | 7 + .../combobox_arrow_down_disabled.svg | 7 + .../dark_blue/radiobutton_checked.svg | 7 + .../radiobutton_checked_disabled.svg | 7 + .../dark_blue/radiobutton_unchecked.svg | 7 + .../radiobutton_unchecked_disabled.svg | 7 + .../dark_blue/radiobutton_unchecked_hover.svg | 7 + .../dark_blue/scrollbar_arrow_down.svg | 7 + .../scrollbar_arrow_down_disabled.svg | 7 + .../dark_blue/scrollbar_arrow_down_hover.svg | 7 + .../dark_blue/scrollbar_arrow_left.svg | 7 + .../scrollbar_arrow_left_disabled.svg | 7 + .../dark_blue/scrollbar_arrow_left_hover.svg | 7 + .../dark_blue/scrollbar_arrow_right.svg | 7 + .../scrollbar_arrow_right_disabled.svg | 7 + .../dark_blue/scrollbar_arrow_right_hover.svg | 7 + .../dark_blue/scrollbar_arrow_up.svg | 7 + .../dark_blue/scrollbar_arrow_up_disabled.svg | 7 + .../dark_blue/scrollbar_arrow_up_hover.svg | 7 + src/stylesheets/dark_blue/sizegrip.svg | 7 + src/stylesheets/dark_blue/sizegrip_hover.svg | 7 + .../dark_blue/spinbox_arrow_down.svg | 7 + .../dark_blue/spinbox_arrow_down_disabled.svg | 7 + .../dark_blue/spinbox_arrow_up.svg | 7 + .../dark_blue/spinbox_arrow_up_disabled.svg | 7 + .../dark_blue/treeview_arrow_down.svg | 7 + .../dark_blue/treeview_arrow_right.svg | 7 + .../treeview_indicator_checked_selected.svg | 7 + .../dark_blue/treeview_line_item.svg | 7 + .../dark_blue/treeview_line_sibling.svg | 7 + .../dark_blue/treeview_line_sibling_item.svg | 7 + src/stylesheets/ubuntu.qss | 4 +- src/translations/scantailor-universal_ru.ts | 1299 +++++++------ 215 files changed, 9604 insertions(+), 3452 deletions(-) delete mode 100644 .gitmodules rename GPL3.txt => LICENSE (100%) delete mode 100644 cmake/CopyToBuildDir.cmake create mode 100644 cmake/FindOPENJPEG.cmake delete mode 100644 cmake/LibToDLL.cmake delete mode 100644 cmake/PatchFile.cmake delete mode 100644 cmake/ToNativePath.cmake delete mode 100644 cmake/cmake_uninstall.cmake.in delete mode 100644 cmake/copy_to_build_dir.cmake.in delete mode 100644 cmake/generate_nsi_file.cmake.in delete mode 100644 cmake/move_sym_file.cmake delete mode 100644 cmake/prepare_staging_dir.cmake.in create mode 100644 src/imageproc/ColorFilter.cpp create mode 100644 src/imageproc/ColorFilter.h delete mode 100644 src/packaging/linux/README create mode 100644 src/packaging/linux/README.md delete mode 100644 src/packaging/windows/CMakeLists.txt create mode 100644 src/packaging/windows/README.md delete mode 100644 src/packaging/windows/build_deps/CMakeLists.txt delete mode 100644 src/packaging/windows/build_deps/dump_dll_syms.cmake delete mode 100644 src/packaging/windows/build_deps/export-vars.cmake.in delete mode 100644 src/packaging/windows/build_deps/generate_qt_build_script.cmake delete mode 100644 src/packaging/windows/patch_libtiff/CMakeLists.txt delete mode 100644 src/packaging/windows/patch_libtiff/apply_individual_patches.cmake.in delete mode 100644 src/packaging/windows/readme.en.txt delete mode 100644 src/packaging/windows/readme.ru.txt delete mode 100644 src/packaging/windows/registerExtension.nsh delete mode 100644 src/packaging/windows/scantailor.nsi.in create mode 100644 src/stylesheets/Breeze.qss create mode 100644 src/stylesheets/Breeze/LICENSE.md create mode 100644 src/stylesheets/Breeze/README.md create mode 100644 src/stylesheets/Breeze/branch_closed-on.svg create mode 100644 src/stylesheets/Breeze/branch_closed.svg create mode 100644 src/stylesheets/Breeze/branch_open-on.svg create mode 100644 src/stylesheets/Breeze/branch_open.svg create mode 100644 src/stylesheets/Breeze/checkbox_checked-hover.svg create mode 100644 src/stylesheets/Breeze/checkbox_checked.svg create mode 100644 src/stylesheets/Breeze/checkbox_checked_disabled.svg create mode 100644 src/stylesheets/Breeze/checkbox_indeterminate-hover.svg create mode 100644 src/stylesheets/Breeze/checkbox_indeterminate.svg create mode 100644 src/stylesheets/Breeze/checkbox_indeterminate_disabled.svg create mode 100644 src/stylesheets/Breeze/checkbox_unchecked-hover.svg create mode 100644 src/stylesheets/Breeze/checkbox_unchecked_disabled.svg create mode 100644 src/stylesheets/Breeze/close-hover.svg create mode 100644 src/stylesheets/Breeze/close-pressed.svg create mode 100644 src/stylesheets/Breeze/close.svg create mode 100644 src/stylesheets/Breeze/down_arrow-hover.svg create mode 100644 src/stylesheets/Breeze/down_arrow.svg create mode 100644 src/stylesheets/Breeze/down_arrow_disabled.svg create mode 100644 src/stylesheets/Breeze/hmovetoolbar.svg create mode 100644 src/stylesheets/Breeze/hsepartoolbar.svg create mode 100644 src/stylesheets/Breeze/left_arrow.svg create mode 100644 src/stylesheets/Breeze/left_arrow_disabled.svg create mode 100644 src/stylesheets/Breeze/radio_checked-hover.svg create mode 100644 src/stylesheets/Breeze/radio_checked.svg create mode 100644 src/stylesheets/Breeze/radio_checked_disabled.svg create mode 100644 src/stylesheets/Breeze/radio_unchecked-hover.svg create mode 100644 src/stylesheets/Breeze/radio_unchecked_disabled.svg create mode 100644 src/stylesheets/Breeze/right_arrow.svg create mode 100644 src/stylesheets/Breeze/right_arrow_disabled.svg create mode 100644 src/stylesheets/Breeze/sizegrip.svg create mode 100644 src/stylesheets/Breeze/spinup_disabled.svg create mode 100644 src/stylesheets/Breeze/stylesheet-branch-end-closed.svg create mode 100644 src/stylesheets/Breeze/stylesheet-branch-end-open.svg create mode 100644 src/stylesheets/Breeze/stylesheet-branch-end.svg create mode 100644 src/stylesheets/Breeze/stylesheet-branch-more.svg create mode 100644 src/stylesheets/Breeze/stylesheet-vline.svg create mode 100644 src/stylesheets/Breeze/transparent.svg create mode 100644 src/stylesheets/Breeze/undock-hover.svg create mode 100644 src/stylesheets/Breeze/undock.svg create mode 100644 src/stylesheets/Breeze/up_arrow-hover.svg create mode 100644 src/stylesheets/Breeze/up_arrow.svg create mode 100644 src/stylesheets/Breeze/up_arrow_disabled.svg create mode 100644 src/stylesheets/Breeze/vmovetoolbar.svg create mode 100644 src/stylesheets/Breeze/vsepartoolbars.svg create mode 100644 src/stylesheets/BreezeDark.qss create mode 100644 src/stylesheets/BreezeDark/LICENSE.md create mode 100644 src/stylesheets/BreezeDark/README.md create mode 100644 src/stylesheets/BreezeDark/branch_closed-on.svg create mode 100644 src/stylesheets/BreezeDark/branch_closed.svg create mode 100644 src/stylesheets/BreezeDark/branch_open-on.svg create mode 100644 src/stylesheets/BreezeDark/branch_open.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_checked.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_checked_disabled.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_indeterminate.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_indeterminate_disabled.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_unchecked.svg create mode 100644 src/stylesheets/BreezeDark/checkbox_unchecked_disabled.svg create mode 100644 src/stylesheets/BreezeDark/close-hover.svg create mode 100644 src/stylesheets/BreezeDark/close-pressed.svg create mode 100644 src/stylesheets/BreezeDark/close.svg create mode 100644 src/stylesheets/BreezeDark/down_arrow-hover.svg create mode 100644 src/stylesheets/BreezeDark/down_arrow.svg create mode 100644 src/stylesheets/BreezeDark/down_arrow_disabled.svg create mode 100644 src/stylesheets/BreezeDark/hmovetoolbar.svg create mode 100644 src/stylesheets/BreezeDark/hsepartoolbar.svg create mode 100644 src/stylesheets/BreezeDark/left_arrow.svg create mode 100644 src/stylesheets/BreezeDark/left_arrow_disabled.svg create mode 100644 src/stylesheets/BreezeDark/radio_checked.svg create mode 100644 src/stylesheets/BreezeDark/radio_checked_disabled.svg create mode 100644 src/stylesheets/BreezeDark/radio_unchecked.svg create mode 100644 src/stylesheets/BreezeDark/radio_unchecked_disabled.svg create mode 100644 src/stylesheets/BreezeDark/right_arrow.svg create mode 100644 src/stylesheets/BreezeDark/right_arrow_disabled.svg create mode 100644 src/stylesheets/BreezeDark/sizegrip.svg create mode 100644 src/stylesheets/BreezeDark/spinup_disabled.svg create mode 100644 src/stylesheets/BreezeDark/stylesheet-branch-end-closed.svg create mode 100644 src/stylesheets/BreezeDark/stylesheet-branch-end-open.svg create mode 100644 src/stylesheets/BreezeDark/stylesheet-branch-end.svg create mode 100644 src/stylesheets/BreezeDark/stylesheet-branch-more.svg create mode 100644 src/stylesheets/BreezeDark/stylesheet-vline.svg create mode 100644 src/stylesheets/BreezeDark/transparent.svg create mode 100644 src/stylesheets/BreezeDark/undock-hover.svg create mode 100644 src/stylesheets/BreezeDark/undock.svg create mode 100644 src/stylesheets/BreezeDark/up_arrow-hover.svg create mode 100644 src/stylesheets/BreezeDark/up_arrow.svg create mode 100644 src/stylesheets/BreezeDark/up_arrow_disabled.svg create mode 100644 src/stylesheets/BreezeDark/vmovetoolbar.svg create mode 100644 src/stylesheets/BreezeDark/vsepartoolbars.svg delete mode 100644 src/stylesheets/CMakeLists.txt create mode 100644 src/stylesheets/dark_blue.qss create mode 100644 src/stylesheets/dark_blue/checkbox_checked.svg create mode 100644 src/stylesheets/dark_blue/checkbox_checked_disabled.svg create mode 100644 src/stylesheets/dark_blue/checkbox_indeterminate.svg create mode 100644 src/stylesheets/dark_blue/checkbox_indeterminate_disabled.svg create mode 100644 src/stylesheets/dark_blue/checkbox_indeterminate_hover.svg create mode 100644 src/stylesheets/dark_blue/checkbox_unchecked.svg create mode 100644 src/stylesheets/dark_blue/checkbox_unchecked_disabled.svg create mode 100644 src/stylesheets/dark_blue/checkbox_unchecked_hover.svg create mode 100644 src/stylesheets/dark_blue/combobox_arrow_down.svg create mode 100644 src/stylesheets/dark_blue/combobox_arrow_down_disabled.svg create mode 100644 src/stylesheets/dark_blue/radiobutton_checked.svg create mode 100644 src/stylesheets/dark_blue/radiobutton_checked_disabled.svg create mode 100644 src/stylesheets/dark_blue/radiobutton_unchecked.svg create mode 100644 src/stylesheets/dark_blue/radiobutton_unchecked_disabled.svg create mode 100644 src/stylesheets/dark_blue/radiobutton_unchecked_hover.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_down.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_down_disabled.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_down_hover.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_left.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_left_disabled.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_left_hover.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_right.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_right_disabled.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_right_hover.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_up.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_up_disabled.svg create mode 100644 src/stylesheets/dark_blue/scrollbar_arrow_up_hover.svg create mode 100644 src/stylesheets/dark_blue/sizegrip.svg create mode 100644 src/stylesheets/dark_blue/sizegrip_hover.svg create mode 100644 src/stylesheets/dark_blue/spinbox_arrow_down.svg create mode 100644 src/stylesheets/dark_blue/spinbox_arrow_down_disabled.svg create mode 100644 src/stylesheets/dark_blue/spinbox_arrow_up.svg create mode 100644 src/stylesheets/dark_blue/spinbox_arrow_up_disabled.svg create mode 100644 src/stylesheets/dark_blue/treeview_arrow_down.svg create mode 100644 src/stylesheets/dark_blue/treeview_arrow_right.svg create mode 100644 src/stylesheets/dark_blue/treeview_indicator_checked_selected.svg create mode 100644 src/stylesheets/dark_blue/treeview_line_item.svg create mode 100644 src/stylesheets/dark_blue/treeview_line_sibling.svg create mode 100644 src/stylesheets/dark_blue/treeview_line_sibling_item.svg diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cb16309..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/stylesheets/BreezeStyleSheets"] - path = src/stylesheets/BreezeStyleSheets - url = https://github.com/trufanov-nok/BreezeStyleSheets-for-STU diff --git a/CMakeLists.txt b/CMakeLists.txt index bcd2bf7..09185c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,10 @@ IF(DEBUG_CLI) ADD_DEFINITIONS(-DDEBUG_CLI) ENDIF(DEBUG_CLI) -ENABLE_TESTING() +OPTION(ENABLE_TESTS "Enable testing. For debug purpose only. Do not enable if you are not a programmer." OFF) +IF(ENABLE_TESTS) + ENABLE_TESTING() +ENDIF() # An undocumented side-effect of CONFIGURE_FILE() is that it makes # the whole project depend on the file we are parsing / copying. @@ -80,13 +83,11 @@ INCLUDE(cmake/FindPthreads.cmake) IF(UNIX AND NOT APPLE) INCLUDE(cmake/FindCanberra.cmake) ENDIF(UNIX AND NOT APPLE) -INCLUDE(cmake/FindEXIV2.cmake) INCLUDE(cmake/SetDefaultBuildType.cmake) INCLUDE(cmake/SetDefaultGccFlags.cmake) -INCLUDE(cmake/ToNativePath.cmake) INCLUDE(cmake/UpdateTranslations.cmake) -INCLUDE(cmake/CopyToBuildDir.cmake) -INCLUDE(cmake/LibToDLL.cmake) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") ST_SET_DEFAULT_BUILD_TYPE(Release) IF(CMAKE_COMPILER_IS_GNUCC) @@ -96,9 +97,6 @@ ENDIF(CMAKE_COMPILER_IS_GNUCC) GET_FILENAME_COMPONENT(source_outer_dir "${PROJECT_SOURCE_DIR}/.." ABSOLUTE) GET_FILENAME_COMPONENT(build_outer_dir "${PROJECT_BINARY_DIR}/.." ABSOLUTE) -SET(STAGING_LIBS_DIR "") - - INCLUDE(FindOpenGL) SET(use_opengl OFF) IF(OPENGL_FOUND AND QT_QTOPENGL_FOUND) @@ -107,62 +105,6 @@ IF(OPENGL_FOUND AND QT_QTOPENGL_FOUND) ENDIF() OPTION(ENABLE_OPENGL "OpenGL may be used for UI acceleration" ${use_opengl}) -IF(WIN32) - FIND_PATH( - DEPS_BUILD_DIR build-qt.bat - HINTS "${build_outer_dir}/scantailor-universal-deps-build" - DOC "Build directory for Scan Tailor dependencies." - ) - IF(NOT DEPS_BUILD_DIR) - MESSAGE( - FATAL_ERROR "The build directory for Scan Tailor dependencies could not be found! " - "You can specify it manually in DEPS_BUILD_DIR variable. Make sure you build the dependencies first!" - ) - ENDIF() - SET(STAGING_LIBS_DIR "${DEPS_BUILD_DIR}/staging/libs") - INCLUDE("${DEPS_BUILD_DIR}/export-vars.cmake") - - IF (NOT QT_SRC_DIR OR NOT EXISTS "${QT_SRC_DIR}") - FILE(GLOB qt_dirs1 "${build_outer_dir}/qt-win-*-5.[0-9]*") - FILE(GLOB qt_dirs2 "${build_outer_dir}/qt-everywhere-*-5.[0-9]*") - FILE(GLOB qt_dirs3 "${source_outer_dir}/qt-win-*-5.[0-9]*") - FILE(GLOB qt_dirs4 "${source_outer_dir}/qt-everywhere-*-5.[0-9]*") - FILE(GLOB qt_dirs5 "C:/Qt/Qt5.*/*/Src") - FIND_PATH( - QT_SRC_DIR qtbase/qtbase.pro - HINTS ${qt_dirs1} ${qt_dirs2} ${qt_dirs3} - ${qt_dirs4} ${qt_dirs5} dummy_dir - DOC "Path to top-level Qt5 source directory. If you installed a binary version, it will be something like C:\\Qt\\Qt5.0.2\\5.0.2\\Src" - ) - ENDIF() - - IF(NOT QT_SRC_DIR OR NOT EXISTS "${QT_SRC_DIR}") - MESSAGE( - FATAL_ERROR "Qt5 could not be found. " - "If it's installed in a non-standard location, specify it QT_SRC_DIR variable." - ) - ENDIF() - - FILE(GLOB qt_possible_prebuilt_dirs "${QT_SRC_DIR}/../*") - FIND_PATH( - QT_PREBUILT_DIR bin/qmake.exe HINTS ${qt_possible_prebuilt_dirs} - DOC "[optional] Installation path of a pre-built version of Qt5. If you installed a binary version, it will be something like C:\\Qt\\Qt5.0.2\\5.0.2\\msvc2012" - ) - - - SET(Qt5Core_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5Core") - SET(Qt5Gui_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5Gui") - SET(Qt5Widgets_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5Widgets") - SET(Qt5Xml_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5Xml") - SET(Qt5Network_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5Network") - SET(Qt5OpenGL_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5OpenGL") - IF(QT_PREBUILT_DIR) - SET(Qt5LinguistTools_DIR "${QT_PREBUILT_DIR}/lib/cmake/Qt5LinguistTools") - ELSE() - SET(Qt5LinguistTools_DIR "${QT_SRC_DIR}/qtbase/lib/cmake/Qt5LinguistTools") - ENDIF() -ENDIF() - SET(CMAKE_AUTOMOC ON) SET(Qt_MIN_VERSION 5.7.0) IF(APPLE) @@ -180,200 +122,49 @@ IF(ENABLE_OPENGL) FIND_PACKAGE(Qt5OpenGL ${Qt_MIN_VERSION} REQUIRED) ENDIF() -FIND_PATH( - JPEG_INCLUDE_DIR jpeglib.h - PATHS /usr/local/include /usr/include - HINTS ${JPEG_DIR} # JPEG_DIR may come from export-vars.cmake - DOC "Path to libjpeg headers." -) -IF(NOT JPEG_INCLUDE_DIR) - MESSAGE( - FATAL_ERROR - "Could not find jpeg headers.\n" - "You may need to install a package named libjpeg62-dev or similarly." - ) -ENDIF() +SET(EXTRA_LIBS "") +FIND_PACKAGE(JPEG REQUIRED) INCLUDE_DIRECTORIES("${JPEG_INCLUDE_DIR}") +LIST(APPEND EXTRA_LIBS ${JPEG_LIBRARY}) -FIND_LIBRARY( - JPEG_LIBRARY NAMES jpeg libjpeg.lib - PATHS /usr/local/lib /usr/lib - HINTS ${STAGING_LIBS_DIR} - DOC "Path to jpeg library." -) -IF(NOT JPEG_LIBRARY) - MESSAGE( - FATAL_ERROR - "Could not find jpeg library.\n" - "You may need to install a package named libjpeg62-dev or similarly." - ) -ENDIF() - -SET (use_openjpeg ON) -OPTION(ENABLE_OPENJPEG "OpenJPEG library may be used to suppoet JPEG 2000 (.jp2) images." ${use_openjpeg}) - +OPTION(ENABLE_OPENJPEG "OpenJPEG library may be used to support JPEG 2000 (.jp2) images." ON) IF (ENABLE_OPENJPEG) - -IF(NOT WIN32) -FIND_PACKAGE(OpenJPEG QUIET) -ELSE(NOT WIN32) - -FIND_PATH( - OPENJPEG_INCLUDE_DIRS openjpeg.h - PATHS /usr/local/include /usr/include - HINTS ${JPEG2000_DIR} # JPEG2000_DIR may come from export-vars.cmake - PATH_SUFFIXES src/lib/openjp2 - DOC "Path to openjpeg headers." -) -IF(NOT OPENJPEG_INCLUDE_DIRS) - MESSAGE( - "Could not find openjpeg headers.\n" - "You may need to install a package openjpeg." - ) -ENDIF() - -INCLUDE_DIRECTORIES("${OPENJPEG_INCLUDE_DIRS}") - -FIND_LIBRARY( - OPENJPEG_LIBRARIES openjp2 openjp2.lib - PATHS /usr/local/lib /usr/lib - HINTS ${STAGING_LIBS_DIR} - PATH_SUFFIXES openjp2 - DOC "Path to openjpeg library." -) - -IF(OPENJPEG_LIBRARIES AND OPENJPEG_INCLUDE_DIRS) -SET (OpenJPEG_FOUND YES) -SET (OPENJPEG_MAJOR_VERSION 2) -ENDIF(OPENJPEG_LIBRARIES AND OPENJPEG_INCLUDE_DIRS) - -ENDIF(NOT WIN32) - -IF(NOT OpenJPEG_FOUND OR OPENJPEG_MAJOR_VERSION VERSION_LESS 2) - message("warning: OpenJPEG library isn't found.\n" - "The JPEG 2000 (*.jp2) images support will be disabled.\n" - "You may install libopenjp2-7-dev to fix this.\n" - "Or disable this massege with -DENABLE_OPENJPEG=OFF") - SET(ENABLE_OPENJPEG OFF) -ENDIF() + find_package(OPENJPEG REQUIRED) + INCLUDE_DIRECTORIES("${OPENJPEG_INCLUDE_DIR}") + LIST(APPEND EXTRA_LIBS ${OPENJPEG_LIBRARY}) ENDIF(ENABLE_OPENJPEG) -FIND_PATH( - ZLIB_INCLUDE_DIR zlib.h - PATHS /usr/local/include /usr/include - HINTS ${ZLIB_DIR} # ZLIB_DIR may come from export-vars.cmake - DOC "Path to zlib headers." -) -IF(NOT ZLIB_INCLUDE_DIR) - MESSAGE( - FATAL_ERROR - "Could not find zlib headers.\n" - "You may need to install a package named zlib1g-dev or similarly." - ) -ENDIF() - +FIND_PACKAGE(ZLIB REQUIRED) INCLUDE_DIRECTORIES("${ZLIB_INCLUDE_DIR}") +LIST(APPEND EXTRA_LIBS ${ZLIB_LIBRARY}) -FIND_LIBRARY( - ZLIB_LIBRARY NAMES z zdll.lib - PATHS /usr/local/lib /usr/lib - HINTS ${STAGING_LIBS_DIR} - DOC "Path to zlib library." -) -IF(NOT ZLIB_LIBRARY) - MESSAGE( - FATAL_ERROR - "Could not find zlib library.\n" - "You may need to install a package named zlib1g-dev or similarly." - ) -ENDIF() - -FIND_PATH( - PNG_INCLUDE_DIR png.h - PATHS /usr/local/include /usr/include - HINTS ${PNG_DIR} # PNG_DIR may come from export-vars.cmake - DOC "Path to libpng headers." -) -IF(NOT PNG_INCLUDE_DIR) - MESSAGE( - FATAL_ERROR - "Could not find libpng headers.\n" - "You may need to install a package named libpng12-dev or similarly." - ) -ENDIF() - +FIND_PACKAGE(PNG REQUIRED) INCLUDE_DIRECTORIES("${PNG_INCLUDE_DIR}") +LIST(APPEND EXTRA_LIBS ${PNG_LIBRARY}) -FIND_LIBRARY( - PNG_LIBRARY NAMES png libpng.lib - PATHS /usr/local/lib /usr/lib - HINTS ${STAGING_LIBS_DIR} - DOC "Path to png library." -) -IF(NOT PNG_LIBRARY) - MESSAGE( - FATAL_ERROR - "Could not find libpng library.\n" - "You may need to install a package named libpng12-dev or similarly." - ) -ENDIF() - - -FIND_PATH( - TIFF_INCLUDE_DIR tiff.h - PATHS /usr/local/include /usr/include - HINTS ${TIFF_DIR} # TIFF_DIR may come from export-vars.cmake - PATH_SUFFIXES libtiff - DOC "Path to libtiff headers." -) -IF(NOT TIFF_INCLUDE_DIR) - MESSAGE( - FATAL_ERROR - "Could not find libtiff headers.\n" - "You may need to install a package named libtiff4-dev or similarly." - ) -ENDIF() - +FIND_PACKAGE(TIFF REQUIRED) INCLUDE_DIRECTORIES("${TIFF_INCLUDE_DIR}") - -FIND_LIBRARY( - TIFF_LIBRARY tiff libtiff.lib - PATHS /usr/local/lib /usr/lib - HINTS ${STAGING_LIBS_DIR} - PATH_SUFFIXES libtiff - DOC "Path to tiff library." -) -IF(NOT TIFF_LIBRARY) - MESSAGE( - FATAL_ERROR - "Could not find libtiff library.\n" - "You may need to install a package named libtiff4-dev or similarly." - ) -ENDIF() - +LIST(APPEND EXTRA_LIBS ${TIFF_LIBRARY}) IF(WIN32) ADD_DEFINITIONS(-DUSE_LIBTIFF_DLL) ENDIF() - IF(WIN32) SET(Boost_USE_STATIC_LIBS ON) ELSE(WIN32) ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) ENDIF(WIN32) -SET(Boost_USE_MULTITHREADED ON) -FIND_PACKAGE(Boost 1.35.0 COMPONENTS unit_test_framework prg_exec_monitor) -IF(NOT Boost_FOUND) - MESSAGE( - FATAL_ERROR - "Could not find boost headers or libraries. " - "You may need to install a package named libboost1.35-dev or similarly. " - "Hint: create a Boost_DEBUG variable in cmake and set it to YES." - ) -ENDIF(NOT Boost_FOUND) +ADD_DEFINITIONS(-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS) +SET(Boost_USE_MULTITHREADED ON) +IF(ENABLE_TESTS) + FIND_PACKAGE(Boost 1.35.0 COMPONENTS unit_test_framework prg_exec_monitor REQUIRED) +ELSE() + FIND_PACKAGE(Boost 1.35.0 REQUIRED) +ENDIF() INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) @@ -384,12 +175,13 @@ if (OPENMP_FOUND) set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") endif() -IF (EXIV2_FOUND) - ADD_DEFINITIONS(-DHAVE_EXIV2) +OPTION(ENABLE_EXIV2 "Exiv2 library may be used to manage image metadata." ON) +IF (ENABLE_EXIV2) + find_package(EXIV2 REQUIRED) INCLUDE_DIRECTORIES("${EXIV2_INCLUDE_DIR}") -ENDIF(EXIV2_FOUND) - -SET(EXTRA_LIBS "") + LIST(APPEND EXTRA_LIBS ${EXIV2_LIBRARY}) + ADD_DEFINITIONS(-DHAVE_EXIV2) +ENDIF() IF(UNIX) FindPthreads() @@ -410,6 +202,7 @@ ENDIF(UNIX) IF(CANBERRA_FOUND) ADD_DEFINITIONS(-DHAVE_CANBERRA) INCLUDE_DIRECTORIES("${CANBERRA_INCLUDE_DIRS}") + LIST(APPEND EXTRA_LIBS ${CANBERRA_LIBRARIES}) ENDIF(CANBERRA_FOUND) @@ -421,18 +214,6 @@ ELSE(NOT HAVE_STDINT_H) FILE(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/stdint.h") ENDIF(NOT HAVE_STDINT_H) -ADD_DEFINITIONS(-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - -LIST(APPEND EXTRA_LIBS ${TIFF_LIBRARY} ${PNG_LIBRARY} ${ZLIB_LIBRARY} ${JPEG_LIBRARY} ${CANBERRA_LIBRARIES}) - -IF (EXIV2_FOUND) - LIST(APPEND EXTRA_LIBS ${EXIV2_LIBRARY}) -ENDIF(EXIV2_FOUND) - -IF(ENABLE_OPENJPEG AND OpenJPEG_FOUND) - INCLUDE_DIRECTORIES(${OPENJPEG_INCLUDE_DIRS}) - LIST(APPEND EXTRA_LIBS ${OPENJPEG_LIBRARIES}) -ENDIF() IF(WIN32) LIST(APPEND EXTRA_LIBS "ws2_32.lib") @@ -455,7 +236,7 @@ ELSEIF(APPLE) ELSE() SET(TRANSLATIONS_DIR_REL "share/scantailor-universal/translations") SET(STYLESHEETS_DIR_REL "share/scantailor-universal/stylesheets") - SET(PIXMAPS_DIR_ABS "${CMAKE_INSTALL_PREFIX}/share/pixmaps/scantailor-universal/stylesheets") + SET(PIXMAPS_DIR_ABS "${CMAKE_INSTALL_PREFIX}/share/scantailor-universal/stylesheets") ENDIF() SET(TRANSLATIONS_DIR_ABS "${CMAKE_INSTALL_PREFIX}/${TRANSLATIONS_DIR_REL}") SET(STYLESHEETS_DIR_ABS "${CMAKE_INSTALL_PREFIX}/${STYLESHEETS_DIR_REL}") @@ -468,39 +249,16 @@ ADD_SUBDIRECTORY(src) IF(NOT WIN32 AND NOT APPLE) - INSTALL(FILES debian/scantailor-universal.svg DESTINATION "${CMAKE_INSTALL_PREFIX}/share/pixmaps/") - INSTALL(FILES debian/scantailor-universal.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications/") + INSTALL(FILES debian/scantailor-universal.svg DESTINATION "share/pixmaps/") + INSTALL(FILES debian/scantailor-universal.desktop DESTINATION "share/applications/") ENDIF(NOT WIN32 AND NOT APPLE) -# uninstall target -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" - IMMEDIATE @ONLY) - -add_custom_target(uninstall - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) - -# Source code packaging -SET(CPACK_CMAKE_GENERATOR "") -SET(CPACK_SOURCE_GENERATOR "TGZ") -SET(CPACK_SOURCE_PACKAGE_FILE_NAME "scantailor-universal-${VERSION}") -SET( - CPACK_SOURCE_IGNORE_FILES - "/\\\\.svn/" - "/\\\\.git/" - "~$" - "\\\\.pcs$" - "TODO.txt" - "CMakeLists.txt.user" - "/doxygen/" - "${CMAKE_BINARY_DIR}" -) -INCLUDE(CPack) - IF(WIN32) - # Copy some DLLs to the staging dir. + # Install Runtime + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) + INCLUDE(InstallRequiredSystemLibraries) + # Install Qt SET( qt5_libs ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} @@ -512,74 +270,196 @@ IF(WIN32) FOREACH(target ${qt5_libs}) GET_TARGET_PROPERTY(debug_loc "${target}" LOCATION_DEBUG) GET_TARGET_PROPERTY(release_loc "${target}" LOCATION_RELEASE) - COPY_TO_BUILD_DIR("${debug_loc}" CONFIGURATIONS Debug) - COPY_TO_BUILD_DIR("${release_loc}" CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${debug_loc}" DESTINATION . CONFIGURATIONS Debug) + install(FILES "${release_loc}" DESTINATION . CONFIGURATIONS Release MinSizeRel RelWithDebInfo) ENDFOREACH() - SET(DLL_DIR "${QT_SRC_DIR}/qtbase/bin") - COPY_TO_BUILD_DIR( - "${DLL_DIR}/libpng.dll" "${DLL_DIR}/libjpeg.dll" - "${DLL_DIR}/libtiff.dll" "${DLL_DIR}/zdll.dll" - ) + # Install Qt's plugins. + CMAKE_PATH(SET Qt5_DIR NORMALIZE "${Qt5Core_DIR}/../../..") + CMAKE_PATH(APPEND Qt5_DIR "plugins" OUTPUT_VARIABLE PLUGINS_DIR) + + # Install system plugin + install(FILES "${PLUGINS_DIR}/platforms/qwindows.dll" DESTINATION ./platforms CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/platforms/qwindowsd.dll" DESTINATION ./platforms CONFIGURATIONS Debug) + + # Install style plugin + install(FILES "${PLUGINS_DIR}/styles/qwindowsvistastyle.dll" DESTINATION ./styles CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/styles/qwindowsvistastyled.dll" DESTINATION ./styles CONFIGURATIONS Debug) + + # Install accessibility plugin + IF (Qt5Widgets_VERSION VERSION_LESS 5.4.0) + install(FILES "${PLUGINS_DIR}/accessible/qtaccessiblewidgets.dll" DESTINATION ./accessible CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/accessible/qtaccessiblewidgetsd.dll" DESTINATION ./accessible CONFIGURATIONS Debug) + ENDIF() -IF(ENABLE_OPENJPEG AND OpenJPEG_FOUND) - COPY_TO_BUILD_DIR( "${DLL_DIR}/openjp2.dll" ) -ENDIF(ENABLE_OPENJPEG AND OpenJPEG_FOUND) + # Install image format plugins + install(FILES "${PLUGINS_DIR}/imageformats/qjpeg.dll" DESTINATION ./imageformats CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/imageformats/qjpegd.dll" DESTINATION ./imageformats CONFIGURATIONS Debug) + + install(FILES "${PLUGINS_DIR}/imageformats/qtiff.dll" DESTINATION ./imageformats CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/imageformats/qtiffd.dll" DESTINATION ./imageformats CONFIGURATIONS Debug) + + # Install image format plugins required to display images in stylesheets + install(FILES "${PLUGINS_DIR}/imageformats/qico.dll" DESTINATION ./imageformats CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/imageformats/qicod.dll" DESTINATION ./imageformats CONFIGURATIONS Debug) + + install(FILES "${PLUGINS_DIR}/imageformats/qsvg.dll" DESTINATION ./imageformats CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/imageformats/qsvgd.dll" DESTINATION ./imageformats CONFIGURATIONS Debug) + + install(FILES "${PLUGINS_DIR}/iconengines/qsvgicon.dll" DESTINATION ./iconengines CONFIGURATIONS Release MinSizeRel RelWithDebInfo) + install(FILES "${PLUGINS_DIR}/iconengines/qsvgicond.dll" DESTINATION ./iconengines CONFIGURATIONS Debug) + + # Install stylesheets + install(DIRECTORY "${CMAKE_SOURCE_DIR}/src/stylesheets" + DESTINATION . + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN ".gitignore" EXCLUDE + PATTERN ".git" EXCLUDE) + + # Install libpng + FIND_FILE(LIBPNG_DLL + NAMES libpng.dll libpng16.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT LIBPNG_DLL) + MESSAGE(SEND_ERROR "Could not find LIBPNG dll. You may specify it manually.") + ENDIF() + install(FILES "${LIBPNG_DLL}" DESTINATION .) + + # Install libjpeg + FIND_FILE(LIBJPEG_DLL + NAMES libjpeg.dll jpeg.dll jpeg62.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT LIBJPEG_DLL) + MESSAGE(SEND_ERROR "Could not find LIBJPEG dll. You may specify it manually.") + ENDIF() + install(FILES "${LIBJPEG_DLL}" DESTINATION .) + + # Install libtigg + FIND_FILE(LIBTIFF_DLL + NAMES libtiff.dll tiff.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT LIBTIFF_DLL) + MESSAGE(SEND_ERROR "Could not find LIBTIFF dll. You may specify it manually.") + ENDIF() + install(FILES "${LIBTIFF_DLL}" DESTINATION .) + + # Install zlib + FIND_FILE(ZLIB_DLL + NAMES zdll.dll zlib.dll zlib1.dll z.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT ZLIB_DLL) + MESSAGE(SEND_ERROR "Could not find ZLIB dll. You may specify it manually.") + ENDIF() + install(FILES "${ZLIB_DLL}" DESTINATION .) + + # Install openjpeg + IF(ENABLE_OPENJPEG) + FIND_FILE(OPENJPEG_DLL + NAMES openjp2.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT OPENJPEG_DLL) + MESSAGE(SEND_ERROR "Could not find OPENJPEG dll. You may specify it manually.") + ENDIF() + install(FILES "${OPENJPEG_DLL}" DESTINATION .) + ENDIF() -IF(EXIV2_FOUND) - COPY_TO_BUILD_DIR( "${DLL_DIR}/exiv2.dll" ) -ENDIF(EXIV2_FOUND) + # Install exiv + IF(ENABLE_EXIV2) + FIND_FILE(EXIV2_DLL + NAMES exiv2.dll + PATHS ${CMAKE_PREFIX_PATH} + PATH_SUFFIXES bin lib + NO_DEFAULT_PATH) + IF(NOT EXIV2_DLL) + MESSAGE(SEND_ERROR "Could not find EXIV2 dll. You may specify it manually.") + ENDIF() + install(FILES "${EXIV2_DLL}" DESTINATION .) + ENDIF() +ELSEIF(APPLE) +ELSE() + INSTALL(DIRECTORY "${CMAKE_SOURCE_DIR}/src/stylesheets" DESTINATION "share/scantailor-universal") + + FIND_PROGRAM(GZIP gzip REQUIRED) + EXECUTE_PROCESS( + COMMAND "${GZIP}" "-9n" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + INPUT_FILE "${CMAKE_SOURCE_DIR}/debian/changelog" + OUTPUT_FILE "changelog.gz" + RESULT_VARIABLE COMMAND_ERROR) + IF(COMMAND_ERROR) + MESSAGE(FATAL_ERROR "Could not gzip changelog") + ENDIF() - # Qt's plugins. - SET(PLUGINS_DIR "${QT_SRC_DIR}/qtbase/plugins") - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/platforms/qwindows.dll" SUBDIR platforms - CONFIGURATIONS Release MinSizeRel RelWithDebInfo - ) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/platforms/qwindowsd.dll" SUBDIR platforms - CONFIGURATIONS Debug - ) - # required to display images in stylesheets - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/imageformats/qico.dll" SUBDIR imageformats - CONFIGURATIONS Release MinSizeRel RelWithDebInfo - ) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/imageformats/qicod.dll" SUBDIR imageformats - CONFIGURATIONS Debug - ) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/imageformats/qsvg.dll" SUBDIR imageformats - CONFIGURATIONS Release MinSizeRel RelWithDebInfo - ) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/imageformats/qsvgd.dll" SUBDIR imageformats - CONFIGURATIONS Debug - ) -# COPY_TO_BUILD_DIR( -# "${PLUGINS_DIR}/iconengines/qsvgicon.dll" SUBDIR iconengines -# CONFIGURATIONS Release MinSizeRel RelWithDebInfo -# ) -# COPY_TO_BUILD_DIR( -# "${PLUGINS_DIR}/iconengines/qsvgicond.dll" SUBDIR iconengines -# CONFIGURATIONS Debug -# ) - - if (Qt5Widgets_VERSION VERSION_LESS 5.4.0) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/accessible/qtaccessiblewidgets.dll" SUBDIR accessible - CONFIGURATIONS Release MinSizeRel RelWithDebInfo - ) - COPY_TO_BUILD_DIR( - "${PLUGINS_DIR}/accessible/qtaccessiblewidgetsd.dll" SUBDIR accessible - CONFIGURATIONS Debug - ) - endif() + INSTALL(FILES "${CMAKE_BINARY_DIR}/changelog.gz" DESTINATION "share/doc/scantailor-universal") + INSTALL(FILES "${CMAKE_SOURCE_DIR}/debian/copyright" DESTINATION "share/doc/scantailor-universal") +ENDIF(WIN32) - # Generate the target that will actually do the copying. - GENERATE_COPY_TO_BUILD_DIR_TARGET(copy_to_build_dir) +SET(CPACK_PACKAGE_NAME "scantailor-universal") +STRING(REGEX + MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" + CPACK_PACKAGE_VERSION ${VERSION}) +SET(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1}) +SET(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2}) +SET(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3}) +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "trufanov-nok ") +SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") +SET(CPACK_PACKAGE_EXECUTABLES "scantailor-universal;${CMAKE_PROJECT_NAME} ${VERSION}") +SET(CPACK_CREATE_DESKTOP_LINKS "scantailor-universal") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Alternative version of ScanTailor: interactive post-processing tool for scanned pages" +) +SET(CPACK_STRIP_FILES YES) - # Installer for Windows. Must go last. - ADD_SUBDIRECTORY(src/packaging/windows) -ENDIF(WIN32) +IF(WIN32) + SET(CPACK_SOURCE_GENERATOR ZIP) + SET(CPACK_GENERATOR NSIS ZIP 7Z) + SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}") + SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/src/app/resources/win32/icon.ico") + SET(CPACK_NSIS_COMPRESSOR "/SOLID lzma") + SET(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) + SET(CPACK_NSIS_MODIFY_PATH ON) + SET(CPACK_NSIS_DISPLAY_NAME "${CMAKE_PROJECT_NAME} ${VERSION}") + SET(CPACK_NSIS_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") + SET(CPACK_NSIS_INSTALLED_ICON_NAME "scantailor-universal.exe") + SET(CPACK_NSIS_EXECUTABLES_DIRECTORY .) +ELSEIF(APPLE) +ELSE() + SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION + "Scan Tailor is an interactive post-processing tool for scanned pages.\n" + " It performs operations such as page splitting, deskewing, adding/removing\n" + " borders, and others. You give it raw scans, and you get pages ready to be\n" + " printed or assembled into a PDF or DJVU file. Scanning, optical character\n" + " recognition, and assembling multi-page documents are out of scope of this\n" + " project.") + STRING(REPLACE ";" "" CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_DEBIAN_PACKAGE_DESCRIPTION}) + SET(CPACK_DEBIAN_PACKAGE_SECTION graphics) + SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/trufanov-nok/scantailor-universal/") +ENDIF() + +SET(CPACK_SOURCE_IGNORE_FILES + "/\\\\.svn/" + "/\\\\.git/" + "~$" + "\\\\.pcs$" + "TODO.txt" + "CMakeLists.txt.user" + "/doxygen/" + "${CMAKE_BINARY_DIR}" +) + +IF(NOT WIN32 AND NOT APPLE) + SET(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +ENDIF() + +INCLUDE(CPack) diff --git a/COPYING b/COPYING index c17cef6..5dda8a9 100644 --- a/COPYING +++ b/COPYING @@ -3,7 +3,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -The GNU General Public License version 3 can be found in GPL3.txt +The GNU General Public License version 3 can be found in LICENSE Some parts of the program are licensed under different, but compatible with GPL3 terms. For more details, see: diff --git a/GPL3.txt b/LICENSE similarity index 100% rename from GPL3.txt rename to LICENSE diff --git a/cmake/CopyToBuildDir.cmake b/cmake/CopyToBuildDir.cmake deleted file mode 100644 index 8eb1b81..0000000 --- a/cmake/CopyToBuildDir.cmake +++ /dev/null @@ -1,72 +0,0 @@ -# Reset variables. -FOREACH(conf_ Debug Release MinSizeRel RelWithDebInfo) - SET( - "COPY_TO_BUILD_DIR_${conf_}" "" CACHE INTERNAL - "Files to copy to ${conf_} build directory" FORCE - ) -ENDFOREACH() - -# Usage: -# COPY_TO_BUILD_DIR(one or more files [SUBDIR subdir] [CONFIGURATIONS] conf1 conf2 ...) -MACRO(COPY_TO_BUILD_DIR) - SET(files_ "") - SET(confs_ "Debug;Release;MinSizeRel;RelWithDebInfo") - SET(subdir_ "") - SET(out_list_ "files_") - FOREACH(arg_ ${ARGV}) - IF("${arg_}" STREQUAL "SUBDIR") - SET(out_list_ "subdir_") - ELSEIF("${arg_}" STREQUAL "CONFIGURATIONS") - SET(out_list_ "confs_") - SET(confs_ "") - ELSE() - LIST(APPEND ${out_list_} "${arg_}") - ENDIF() - ENDFOREACH() - - LIST(LENGTH subdir_ num_subdirs_) - IF("${num_subdirs_}" GREATER 1) - MESSAGE(FATAL_ERROR "Multiple sub-directories aren't allowed!") - ENDIF() - - FOREACH(conf_ ${confs_}) - FOREACH(file_ ${files_}) - IF("${subdir_}" STREQUAL "") - LIST(APPEND "COPY_TO_BUILD_DIR_${conf_}" "${file_}") - ELSE() - LIST(APPEND "COPY_TO_BUILD_DIR_${conf_}" "${file_}=>${subdir_}") - ENDIF() - ENDFOREACH() - - # Force the new value to be written to the cache. - SET( - "COPY_TO_BUILD_DIR_${conf_}" ${COPY_TO_BUILD_DIR_${conf_}} - CACHE INTERNAL "Files to copy to ${conf_} build directory" FORCE - ) - ENDFOREACH() -ENDMACRO() - - -MACRO(GENERATE_COPY_TO_BUILD_DIR_TARGET target_name_) - SET(script_ "${CMAKE_BINARY_DIR}/copy_to_build_dir.cmake") - CONFIGURE_FILE("cmake/copy_to_build_dir.cmake.in" "${script_}" @ONLY) - - SET( - src_files_ - ${COPY_TO_BUILD_DIR_Debug} ${COPY_TO_BUILD_DIR_Release} - ${COPY_TO_BUILD_DIR_MinSizeRel} ${COPY_TO_BUILD_DIR_RelWithDebInfo} - ) - SET(deps_ "") - FOREACH(src_file_ ${src_files_}) - STRING(REGEX REPLACE "(.*)=>.*" "\\1" src_file_ "${src_file_}") - LIST(APPEND deps_ "${src_file_}") - ENDFOREACH() - - # Copy DLLs and other stuff to ${CMAKE_BINARY_DIR}/ - ADD_CUSTOM_TARGET( - "${target_name_}" ALL - COMMAND "${CMAKE_COMMAND}" "-DTARGET_DIR=$" - "-DCFG=$" -P "${script_}" - DEPENDS "${script_}" ${deps_} - ) -ENDMACRO() diff --git a/cmake/FindEXIV2.cmake b/cmake/FindEXIV2.cmake index d46ac4c..34a3b9c 100644 --- a/cmake/FindEXIV2.cmake +++ b/cmake/FindEXIV2.cmake @@ -6,29 +6,28 @@ # and following variables are set: # EXIV2_INCLUDE_DIR # EXIV2_LIBRARY -# -# A copy of https://github.com/qgis/QGIS/blob/master/cmake/FindEXIV2.cmake -# Under GPL-2.0 License -IF(WIN32) -GET_FILENAME_COMPONENT(build_outer_dir "${PROJECT_BINARY_DIR}/.." ABSOLUTE) FIND_PATH( - DEPS_BUILD_DIR build-qt.bat - HINTS "${build_outer_dir}/scantailor-universal-deps-build" - DOC "Build directory for Scan Tailor dependencies." - ) -SET(STAGING_LIBS_DIR "${DEPS_BUILD_DIR}/staging/libs") -INCLUDE("${DEPS_BUILD_DIR}/export-vars.cmake") -ENDIF(WIN32) + EXIV2_INCLUDE_DIR + NAMES exiv2/exiv2.hpp + PATHS "${EXIV2_DIR}/include" $ENV{EXIV2_DIR}/include /usr/local/include /usr/include +) + +FIND_LIBRARY( + EXIV2_LIBRARY + NAMES exiv2 + PATHS "${EXIV2_DIR}/lib" $ENV{LIB_DIR}/lib /usr/local/lib /usr/lib +) -FIND_PATH(EXIV2_INCLUDE_DIR exiv2/exiv2.hpp $ENV{LIB_DIR}/include /usr/local/include /usr/include "${EXIV2_DIR}/include") -FIND_LIBRARY(EXIV2_LIBRARY NAMES exiv2 PATHS $ENV{LIB_DIR}/lib /usr/local/lib /usr/lib HINTS ${STAGING_LIBS_DIR}) +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + EXIV2 + DEFAULT_MSG + EXIV2_LIBRARY + EXIV2_INCLUDE_DIR +) -IF (EXIV2_INCLUDE_DIR AND EXIV2_LIBRARY) - SET(EXIV2_FOUND TRUE) - MESSAGE(STATUS "Found exiv2: ${EXIV2_LIBRARY}") -ELSE (EXIV2_INCLUDE_DIR AND EXIV2_LIBRARY) - MESSAGE(EXIV2_INCLUDE_DIR=${EXIV2_INCLUDE_DIR}) - MESSAGE(EXIV2_LIBRARY=${EXIV2_LIBRARY}) - MESSAGE(WARNING "Could not find exiv2") -ENDIF (EXIV2_INCLUDE_DIR AND EXIV2_LIBRARY) + MARK_AS_ADVANCED( + EXIV2_INCLUDE_DIR + EXIV2_LIBRARY + ) diff --git a/cmake/FindOPENJPEG.cmake b/cmake/FindOPENJPEG.cmake new file mode 100644 index 0000000..a97c3e3 --- /dev/null +++ b/cmake/FindOPENJPEG.cmake @@ -0,0 +1,36 @@ +# Find OPENJPEG +# ~~~~~~~~~~ +# CMake module to search for OPENJPEG library +# +# If it's found it sets OPENJPEG_FOUND to TRUE +# and following variables are set: +# OPENJPEG_INCLUDE_DIR +# OPENJPEG_LIBRARY + +FIND_PATH( + OPENJPEG_INCLUDE_DIR + NAMES openjpeg.h + PATHS "${OPENJPEG_DIR}/include" $ENV{LIB_DIR}/include /usr/local/include /usr/include + PATH_SUFFIXES + openjpeg-2.0 openjpeg-2.1 openjpeg-2.2 openjpeg-2.3 openjpeg-2.4 + openjpeg-2.5 openjpeg-2.6 openjpeg-2.7 openjpeg-2.8 openjpeg-2.9 +) + +FIND_LIBRARY( + OPENJPEG_LIBRARY + NAMES openjp2 + PATHS "${OPENJPEG_DIR}/lib" $ENV{LIB_DIR}/lib /usr/local/lib /usr/lib +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + OPENJPEG + DEFAULT_MSG + OPENJPEG_LIBRARY + OPENJPEG_INCLUDE_DIR +) + + MARK_AS_ADVANCED( + OPENJPEG_INCLUDE_DIR + OPENJPEG_LIBRARY + ) diff --git a/cmake/LibToDLL.cmake b/cmake/LibToDLL.cmake deleted file mode 100644 index bf6a3e0..0000000 --- a/cmake/LibToDLL.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# Usage: -# LIB_TO_DLL(output_list_of_dlls ${list_of_dot_lib_files}) -MACRO(LIB_TO_DLL out_list_) - SET(${out_list_} "") - FOREACH(lib_file_ ${ARGN}) - #STRING(REGEX REPLACE "\\.lib$" ".dll" dll_file_ "${lib_file_}") - #IF(NOT "${dll_file_}" STREQUAL "${lib_file_}") - # LIST(APPEND ${out_list_} "${dll_file_}") - #ENDIF() - GET_FILENAME_COMPONENT(lib_file_name_ "${lib_file_}" NAME) - GET_FILENAME_COMPONENT(dir_ "${lib_file_}" PATH) - - STRING(REGEX REPLACE "^lib(.*)\\.a$" "\\1.dll" dll_file_name_ "${lib_file_name_}") - IF("${dll_file_name_}" STREQUAL "${lib_file_name_}") - STRING(REGEX REPLACE "^(.*)\\.lib$" "\\1.dll" dll_file_name_ "${lib_file_name_}") - ENDIF() - - IF(NOT "${dll_file_name_}" STREQUAL "${lib_file_name_}") - LIST(APPEND ${out_list_} "${dir_}/${dll_file_name_}") - ENDIF() - ENDFOREACH() -ENDMACRO() \ No newline at end of file diff --git a/cmake/PatchFile.cmake b/cmake/PatchFile.cmake deleted file mode 100644 index 257c271..0000000 --- a/cmake/PatchFile.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# Applies a list of search / replace expressions to a file. -# If the file is modified, saves a backup with .orig name -# appended to the original file name. If a backup already -# exists, it's not overwritten. -# Example usage: -# PATCH_FILE("C:/test.txt" "/apple/orange/" "/@([A-Z_]+)@/@\\1_OLD@") -FUNCTION(PATCH_FILE file_) - MESSAGE(STATUS "Patching file ${file_}") - - IF(EXISTS "${file_}.orig") - FILE(READ "${file_}.orig" contents_) - ELSE() - FILE(READ "${file_}" contents_) - ENDIF() - SET(orig_contents "${contents_}") - - FOREACH(search_replace_ ${ARGN}) - IF(search_replace_ STREQUAL "") - MESSAGE(FATAL_ERROR "Empty string passed as a search/replace expression to PATCH_FILE()") - ENDIF() - - # Parse the string of type /search/replace/ into search_ and _replace variables. - # Note that any symbol missing from both search and replace can be used instead of /. - STRING(SUBSTRING "${search_replace_}" 0 1 sep_) - STRING(REGEX REPLACE "^${sep_}([^${sep_}]+)${sep_}.*" "\\1" search_ "${search_replace_}") - STRING(REGEX REPLACE "^${sep_}[^${sep_}]+${sep_}([^${sep_}]*)${sep_}\$" "\\1" replace_ "${search_replace_}") - IF(search_replace_ STREQUAL "${replace_}") - MESSAGE(FATAL_ERROR "Invalid search/replace expression passed to PATCH_FILE()") - ENDIF() - - STRING(REGEX REPLACE "${search_}" "${replace_}" contents_ "${contents_}") - ENDFOREACH() - - IF(NOT "${contents_}" STREQUAL "${orig_contents_}") - # Make a backup copy, if not already there. - IF(NOT EXISTS "${file_}.orig") - CONFIGURE_FILE("${file_}" "${file_}.orig" COPYONLY) - ENDIF() - - FILE(WRITE "${file_}" "${contents_}") - ENDIF() -ENDFUNCTION() diff --git a/cmake/ToNativePath.cmake b/cmake/ToNativePath.cmake deleted file mode 100644 index 15aa4b2..0000000 --- a/cmake/ToNativePath.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# This macro exists because FILE(TO_NATIVE_PATH ...) is broken on MinGW. -MACRO(TO_NATIVE_PATH PATH OUT) - FILE(TO_NATIVE_PATH "${PATH}" "${OUT}") - IF(MINGW) - STRING(REPLACE "/" "\\" "${OUT}" "${${OUT}}") - ENDIF(MINGW) -ENDMACRO(TO_NATIVE_PATH) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in deleted file mode 100644 index 2037e36..0000000 --- a/cmake/cmake_uninstall.cmake.in +++ /dev/null @@ -1,21 +0,0 @@ -if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") -endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - -file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -string(REGEX REPLACE "\n" ";" files "${files}") -foreach(file ${files}) - message(STATUS "Uninstalling $ENV{DESTDIR}${file}") - if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - exec_program( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - if(NOT "${rm_retval}" STREQUAL 0) - message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") - endif(NOT "${rm_retval}" STREQUAL 0) - else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") - message(STATUS "File $ENV{DESTDIR}${file} does not exist.") - endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") -endforeach(file) diff --git a/cmake/copy_to_build_dir.cmake.in b/cmake/copy_to_build_dir.cmake.in deleted file mode 100644 index 47d9a5f..0000000 --- a/cmake/copy_to_build_dir.cmake.in +++ /dev/null @@ -1,20 +0,0 @@ -SET("COPY_TO_BUILD_DIR_Debug" "@COPY_TO_BUILD_DIR_Debug@") -SET("COPY_TO_BUILD_DIR_Release" "@COPY_TO_BUILD_DIR_Release@") -SET("COPY_TO_BUILD_DIR_MinSizeRel" "@COPY_TO_BUILD_DIR_MinSizeRel@") -SET("COPY_TO_BUILD_DIR_RelWithDebInfo" "@COPY_TO_BUILD_DIR_RelWithDebInfo@") - -FOREACH(src_file ${COPY_TO_BUILD_DIR_${CFG}}) - SET(subdir "") - IF(src_file MATCHES ".*=>.*") - STRING(REGEX REPLACE ".*=>(.*)" "/\\1" subdir "${src_file}") - STRING(REGEX REPLACE "(.*)=>.*" "\\1" src_file "${src_file}") - ENDIF() - SET(dst_dir "${TARGET_DIR}${subdir}") - - GET_FILENAME_COMPONENT(dst_file "${src_file}" NAME) - - IF("${src_file}" IS_NEWER_THAN "${dst_dir}/${dst_file}") - MESSAGE(STATUS "Copying ${dst_file} to ${CFG}${subdir}") - CONFIGURE_FILE("${src_file}" "${dst_dir}/${dst_file}" COPYONLY) - ENDIF() -ENDFOREACH() \ No newline at end of file diff --git a/cmake/default_cxxflags.cmake b/cmake/default_cxxflags.cmake index 2bd89c9..8935cfd 100644 --- a/cmake/default_cxxflags.cmake +++ b/cmake/default_cxxflags.cmake @@ -1,7 +1,7 @@ IF(MSVC) # If we want reliable stack traces, we need /Oy- # We do it only for RelWithDebInfo - SET(_common "/FS /wd4267 /std=c++0x") + SET(_common "/FS /wd4267") SET(CMAKE_CXX_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG ${_common}") SET(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 ${_common}") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG /Oy- ${_common}") diff --git a/cmake/generate_nsi_file.cmake.in b/cmake/generate_nsi_file.cmake.in deleted file mode 100644 index 4fb88c5..0000000 --- a/cmake/generate_nsi_file.cmake.in +++ /dev/null @@ -1,64 +0,0 @@ -INCLUDE("@CMAKE_SOURCE_DIR@/cmake/ToNativePath.cmake") - -# Translations -SET(QM_FILES "@QM_FILES@") -SET(INSTALL_TRANSLATIONS "") -FOREACH(file ${QM_FILES}) - TO_NATIVE_PATH("${file}" file) - SET(INSTALL_TRANSLATIONS "${INSTALL_TRANSLATIONS}\n File \"${file}\"") -ENDFOREACH() - -# Imageformat plugins for Qt -SET(IMAGEFORMAT_PLUGINS_Debug "@QT_QJPEG_PLUGIN_DEBUG@") -SET(IMAGEFORMAT_PLUGINS_Release "@QT_QJPEG_PLUGIN_RELEASE@") -SET(IMAGEFORMAT_PLUGINS_MinSizeRel "@QT_QJPEG_PLUGIN_RELEASE@") -SET(IMAGEFORMAT_PLUGINS_RelWithDebInfo "@QT_QJPEG_PLUGIN_RELEASE@") -SET(INSTALL_IMAGEFORMAT_PLUGINS "") -FOREACH(file ${IMAGEFORMAT_PLUGINS_${CFG}}) - TO_NATIVE_PATH("${file}" file) - LIST( - APPEND INSTALL_IMAGEFORMAT_PLUGINS - "${INSTALL_IMAGEFORMAT_PLUGINS}\nFile \"${file}\"" - ) -ENDFOREACH() - -# Extra binaries (DLLs) -SET(COPY_TO_BUILD_DIR_Debug "@COPY_TO_BUILD_DIR_Debug@") -SET(COPY_TO_BUILD_DIR_Release "@COPY_TO_BUILD_DIR_Release@") -SET(COPY_TO_BUILD_DIR_MinSizeRel "@COPY_TO_BUILD_DIR_MinSizeRel@") -SET(COPY_TO_BUILD_DIR_RelWithDebInfo "@COPY_TO_BUILD_DIR_RelWithDebInfo@") - -SET(INSTALL_EXTRA_BINARIES "") -FOREACH(file ${COPY_TO_BUILD_DIR_${CFG}}) - TO_NATIVE_PATH("${file}" file) - SET(INSTALL_EXTRA_BINARIES "${INSTALL_EXTRA_BINARIES}\n File \"${file}\"") -ENDFOREACH() - -SET(REGISTER_EXTENSION_NSH "@CMAKE_SOURCE_DIR@/src/packaging/windows/registerExtension.nsh") -TO_NATIVE_PATH("${REGISTER_EXTENSION_NSH}" REGISTER_EXTENSION_NSH) - -SET(LICENSE_FILE "@LICENSE_FILE@") -TO_NATIVE_PATH("${LICENSE_FILE}" LICENSE_FILE) - -SET(INSTALLER_FILENAME "@INSTALLER_FILENAME@") - -# These are passed at runtime, not at configure time. -IF(SCANTAILOR_EXE) - TO_NATIVE_PATH("${SCANTAILOR_EXE}" SCANTAILOR_EXE) -ENDIF() -IF(SCANTAILOR_CLI_EXE) - TO_NATIVE_PATH("${SCANTAILOR_CLI_EXE}" SCANTAILOR_CLI_EXE) -ENDIF() -IF(CRASHREPORTER_EXE) - TO_NATIVE_PATH("${CRASHREPORTER_EXE}" CRASHREPORTER_EXE) -ENDIF() - -SET(STAGING_DIR "@CMAKE_BINARY_DIR@/staging") -TO_NATIVE_PATH("${STAGING_DIR}" STAGING_DIR) - -SET(SIZEOF_VOID_PTR "@CMAKE_SIZEOF_VOID_P@") - -CONFIGURE_FILE( - "@CMAKE_SOURCE_DIR@/src/packaging/windows/scantailor.nsi.in" - "@CMAKE_BINARY_DIR@/scantailor.nsi" @ONLY -) diff --git a/cmake/move_sym_file.cmake b/cmake/move_sym_file.cmake deleted file mode 100644 index 7a4f395..0000000 --- a/cmake/move_sym_file.cmake +++ /dev/null @@ -1,14 +0,0 @@ -FILE(STRINGS "${SYMBOLS_PATH}/temp.sym" first_line LIMIT_COUNT 1) -SEPARATE_ARGUMENTS(first_line) -LIST(GET first_line 3 module_id) -LIST(GET first_line 4 module_name_pdb) -STRING( - REGEX REPLACE "(.*)\\.pdb" "\\1.sym" - module_name_sym "${module_name_pdb}" -) -CONFIGURE_FILE( - "${SYMBOLS_PATH}/temp.sym" - "${SYMBOLS_PATH}/${module_name_pdb}/${module_id}/${module_name_sym}" - COPYONLY -) -FILE(REMOVE "${SYMBOLS_PATH}/temp.sym") diff --git a/cmake/prepare_staging_dir.cmake.in b/cmake/prepare_staging_dir.cmake.in deleted file mode 100644 index 5c63098..0000000 --- a/cmake/prepare_staging_dir.cmake.in +++ /dev/null @@ -1,84 +0,0 @@ -INCLUDE("@CMAKE_SOURCE_DIR@/cmake/ToNativePath.cmake") - -SET(MINGW "@MINGW@") -SET(STAGING_DIR "@CMAKE_BINARY_DIR@/staging") -FILE(REMOVE_RECURSE "${STAGING_DIR}") -FILE(MAKE_DIRECTORY "${STAGING_DIR}") - -# Translations -SET(QM_FILES "@QM_FILES@") -FOREACH(file ${QM_FILES}) -GET_FILENAME_COMPONENT(fname "${file}" NAME) -CONFIGURE_FILE("${file}" "${STAGING_DIR}/translations/${fname}" COPYONLY) -ENDFOREACH() - -# Imageformat plugins for Qt (required for stylesheets) -FILE(GLOB imageformat_plugins "${CONF_BUILD_DIR}/imageformats/*.dll") -FOREACH(file ${imageformat_plugins}) - GET_FILENAME_COMPONENT(fname "${file}" NAME) - CONFIGURE_FILE("${file}" "${STAGING_DIR}/imageformats/${fname}" COPYONLY) -ENDFOREACH() - -#FILE(GLOB iconengines_plugins "${CONF_BUILD_DIR}/iconengines/*.dll") -#FOREACH(file ${iconengines_plugins}) -# GET_FILENAME_COMPONENT(fname "${file}" NAME) -# CONFIGURE_FILE("${file}" "${STAGING_DIR}/iconengines/${fname}" COPYONLY) -#ENDFOREACH() - -# Stylesheets -SET(QSS_FILES "@QSS_FILES@") -FOREACH(file ${QSS_FILES}) -GET_FILENAME_COMPONENT(fname "${file}" NAME) -CONFIGURE_FILE("${file}" "${STAGING_DIR}/stylesheets/${fname}" COPYONLY) -ENDFOREACH() - -SET(STYLESHEET_PIXMAP_DIRS "@STYLESHEET_PIXMAP_DIRS@") -FOREACH(dir ${STYLESHEET_PIXMAP_DIRS}) -file(COPY "${dir}" DESTINATION "${STAGING_DIR}/stylesheets/") -ENDFOREACH() - - -# Platform plugins for Qt -FILE(GLOB platforms_plugins "${CONF_BUILD_DIR}/platforms/*.dll") -FOREACH(file ${platforms_plugins}) -GET_FILENAME_COMPONENT(fname "${file}" NAME) -CONFIGURE_FILE("${file}" "${STAGING_DIR}/platforms/${fname}" COPYONLY) -ENDFOREACH() - -# Accessibility plugins for Qt -FILE(GLOB accessible_plugins "${CONF_BUILD_DIR}/accessible/*.dll") -FOREACH(file ${accessible_plugins}) -GET_FILENAME_COMPONENT(fname "${file}" NAME) -CONFIGURE_FILE("${file}" "${STAGING_DIR}/accessible/${fname}" COPYONLY) -ENDFOREACH() - -# Extra binaries (DLLs) -SET(COPY_TO_STAGING_DIR_Debug "@COPY_TO_BUILD_DIR_Debug@") -SET(COPY_TO_STAGING_DIR_Release "@COPY_TO_BUILD_DIR_Release@") -SET(COPY_TO_STAGING_DIR_MinSizeRel "@COPY_TO_BUILD_DIR_MinSizeRel@") -SET(COPY_TO_STAGING_DIR_RelWithDebInfo "@COPY_TO_BUILD_DIR_RelWithDebInfo@") -SET(EXTRA_BINARIES ${COPY_TO_STAGING_DIR_${CFG}}) - -# These are passed at runtime, not at configure time. -SET(EXECUTABLES "${SCANTAILOR_EXE}" "${SCANTAILOR_CLI_EXE}" "${CRASHREPORTER_EXE}") - -# Strip executables and DLLs. -FOREACH(src_file ${EXECUTABLES} ${EXTRA_BINARIES}) -SET(subdir "") -IF(src_file MATCHES ".*=>.*") -STRING(REGEX REPLACE ".*=>(.*)" "/\\1" subdir "${src_file}") -STRING(REGEX REPLACE "(.*)=>.*" "\\1" src_file "${src_file}") -ENDIF() -GET_FILENAME_COMPONENT(fname "${src_file}" NAME) -SET(dst_file "${STAGING_DIR}${subdir}/${fname}") - -CONFIGURE_FILE("${src_file}" "${dst_file}" COPYONLY) -ENDFOREACH() - -# Microsoft CRT redistributable -IF(CRT_REDIST_PATH) -EXECUTE_PROCESS( -COMMAND "${CMAKE_COMMAND}" -E copy_directory -"${CRT_REDIST_PATH}" "${STAGING_DIR}" -) -ENDIF() diff --git a/debian/changelog b/debian/changelog index 302bc16..b92bd11 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,8 +5,9 @@ scantailor-universal (0.2.14-0ubuntu1) bionic; urgency=medium * 1200 dpi in the list of default values * Adapt content selection moving approach from STA - -- Alexander Trufanov Sat, 18 Aug 2023 16:00:00 +0300 + -- Alexander Trufanov Fri, 18 Aug 2023 16:00:00 +0300 +scantailor-universal (0.2.13-0ubuntu1) bionic; urgency=medium * Settings: keep ICC profile of original image (off by default, req Ubuntu 19.04+, libexiv2-dev >= 0.26) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52182e7..82dde0a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,6 @@ ADD_SUBDIRECTORY(exporting) ADD_SUBDIRECTORY(core) ADD_SUBDIRECTORY(app_cli) ADD_SUBDIRECTORY(app) -ADD_SUBDIRECTORY(stylesheets) SET(ts_files ${TRANSLATION_FILES}) @@ -42,9 +41,3 @@ INSTALL(FILES ${QM_FILES} DESTINATION "${TRANSLATIONS_DIR_REL}/") # Let QM_FILES be accessable in packaging/windows/ SET (QM_FILES ${QM_FILES} PARENT_SCOPE) - -IF(WIN32) - # Let QSS_FILES and STYLESHEET_PIXMAP_DIRS be accessable in packaging/windows/ - SET (QSS_FILES ${QSS_FILES} PARENT_SCOPE) - SET (STYLESHEET_PIXMAP_DIRS ${STYLESHEET_PIXMAP_DIRS} PARENT_SCOPE) -ENDIF(WIN32) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 2196867..7f4dffc 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -117,6 +117,8 @@ ENDIF() IF(APPLE) INSTALL(TARGETS scantailor-universal BUNDLE DESTINATION . RUNTIME DESTINATION bin) +ELSEIF(WIN32) + INSTALL(TARGETS scantailor-universal RUNTIME DESTINATION .) ELSE(APPLE) INSTALL(TARGETS scantailor-universal RUNTIME DESTINATION bin) ENDIF(APPLE) diff --git a/src/app/ExportDialog.cpp b/src/app/ExportDialog.cpp index 3e22bab..aa76939 100644 --- a/src/app/ExportDialog.cpp +++ b/src/app/ExportDialog.cpp @@ -65,6 +65,9 @@ ExportDialog::ExportDialog(QWidget* parent, const QString& defaultOutDir) ui.UseSepSuffixForPics->setChecked(m_settings.value(_key_export_use_sep_suffix, _key_export_use_sep_suffix_def).toBool()); ui.KeepOriginalColorIllumForeSubscans->setChecked(m_settings.value(_key_export_keep_original_color, _key_export_keep_original_color_def).toBool()); ui.cbMultipageOutput->setChecked(m_settings.value(_key_export_to_multipage, _key_export_to_multipage_def).toBool()); + + QSize size = sizeHint(); + setFixedHeight(size.height()); } ExportDialog::~ExportDialog() diff --git a/src/app/MainWindow.cpp b/src/app/MainWindow.cpp index 4e5dbd9..cac686f 100644 --- a/src/app/MainWindow.cpp +++ b/src/app/MainWindow.cpp @@ -342,6 +342,8 @@ MainWindow::MainWindow() scrollArea->horizontalScrollBar()->setDisabled(true); filterOptions->installEventFilter(this); + + setDockNestingEnabled(true); } MainWindow::~MainWindow() diff --git a/src/app/NewOpenProjectPanel.cpp b/src/app/NewOpenProjectPanel.cpp index 065117f..1070e23 100644 --- a/src/app/NewOpenProjectPanel.cpp +++ b/src/app/NewOpenProjectPanel.cpp @@ -45,12 +45,6 @@ NewOpenProjectPanel::NewOpenProjectPanel(QWidget* parent) setupUi(this); recentProjectsGroup->setLayout(new QVBoxLayout); - newProjectLabel->setText( - Utils::richTextForLink(newProjectLabel->text()) - ); - openProjectLabel->setText( - Utils::richTextForLink(openProjectLabel->text()) - ); RecentProjects rp; rp.read(); @@ -68,11 +62,11 @@ NewOpenProjectPanel::NewOpenProjectPanel(QWidget* parent) } connect( - newProjectLabel, SIGNAL(linkActivated(QString)), + newProjectButton, SIGNAL(clicked(bool)), this, SIGNAL(newProject()) ); connect( - openProjectLabel, SIGNAL(linkActivated(QString)), + openProjectButton, SIGNAL(clicked(bool)), this, SIGNAL(openProject()) ); } @@ -85,19 +79,31 @@ NewOpenProjectPanel::addRecentProject(QString const& file_path) if (base_name.isEmpty()) { base_name = QChar('_'); } - QLabel* label = new QLabel(recentProjectsGroup); - label->setWordWrap(true); - label->setTextFormat(Qt::RichText); - label->setText(Utils::richTextForLink(base_name, file_path)); - label->setToolTip(file_path); - recentProjectsGroup->layout()->addWidget(label); + + const int max_length = 30; + if (base_name.length() > max_length) { + base_name.truncate(max_length); + base_name.append("..."); + } + + QPushButton* button = new QPushButton(recentProjectsGroup); + button->setText(base_name); + button->setToolTip(file_path); + recentProjectsGroup->layout()->addWidget(button); connect( - label, SIGNAL(linkActivated(QString)), - this, SIGNAL(openRecentProject(QString)) + button, SIGNAL(clicked()), + this, SLOT(recentProjectButtonClicked()) ); } +void +NewOpenProjectPanel::recentProjectButtonClicked() +{ + if(QPushButton* button = qobject_cast(sender())) + openRecentProject(button->toolTip()); +} + void NewOpenProjectPanel::paintEvent(QPaintEvent* /*event*/) { diff --git a/src/app/NewOpenProjectPanel.h b/src/app/NewOpenProjectPanel.h index e005eb3..61d874b 100644 --- a/src/app/NewOpenProjectPanel.h +++ b/src/app/NewOpenProjectPanel.h @@ -39,6 +39,8 @@ class NewOpenProjectPanel : public QWidget, private Ui::NewOpenProjectPanel virtual void paintEvent(QPaintEvent* event); private: void addRecentProject(QString const& file_path); +private slots: + void recentProjectButtonClicked(); }; #endif diff --git a/src/app/SettingsDialog.cpp b/src/app/SettingsDialog.cpp index 307841e..522dda7 100644 --- a/src/app/SettingsDialog.cpp +++ b/src/app/SettingsDialog.cpp @@ -261,7 +261,7 @@ SettingsDialog::populateTreeWidget(QTreeWidget* treeWidget) << tr("Despeckling") << tr("Image metadata"); const QResource tree_metadata(":/SettingsTreeData.tsv"); - QStringList tree_data = QString::fromUtf8((char const*)tree_metadata.data(), tree_metadata.size()).split('\n'); + QStringList tree_data = QString::fromUtf8((char const*)tree_metadata.data(), tree_metadata.size()).split(QRegExp("\r?\n")); QTreeWidgetItem* last_top_item = nullptr; QTreeWidgetItem* parent_item = nullptr; diff --git a/src/app/StartBatchProcessingDialog.cpp b/src/app/StartBatchProcessingDialog.cpp index ca7d3d4..5a80a6c 100644 --- a/src/app/StartBatchProcessingDialog.cpp +++ b/src/app/StartBatchProcessingDialog.cpp @@ -12,6 +12,8 @@ StartBatchProcessingDialog::StartBatchProcessingDialog(QWidget* parent, bool isA ui->allPages->setChecked(isAllPages); ui->fromSelected->setChecked(!isAllPages); + + setFixedSize(sizeHint()); } StartBatchProcessingDialog::~StartBatchProcessingDialog() diff --git a/src/app/resources/icons/left_page_plus_offcut.png b/src/app/resources/icons/left_page_plus_offcut.png index b74447602821b85250d4c068667caaa27989985b..d568449620b412691dfb9b45c7c31b6ee4720c40 100644 GIT binary patch delta 419 zcmV;U0bKsi0kQ*-8Gi-<0047(dh`GQ010qNS#tmY4`BcR4`BhQKc{H`000nrR9JLW zX>@F5000P?GX?+vGypV>udC(&00BrzL_t(o!|j(_ii1E9Maw6Ms0+|d=#T!n09~4! zQ8(bHu0vdaASk{v>4pwHwq}G$Ml)D&2}HxaeW=nD-2R}VD1X|##>2rSF2Cse9ypG} z+A4DGet^|aS(cxg5)URomSvD62~<@Dnx=uOs#vH5K>(iTvF3TkW=LJv!8A?Kwk_0k z4W?;A7>3~c{;E0c!36L;4;;sN5FjbHh>#GZNU&!FXb&bpp63h!UDv;b_$>k2<1+}n zx(CippePE61T4#fAP6=I&>l%X$oaof?*h-D9X#H zfc7{ifn^UYr(kLR|9apeur>wggrX?!nu0w9K5Gj05@?zRYtM7wyghKe4X=Mh7l9+D z0G7MjeQUuQhT)-c95+SZM}GU$ZbTpc3i!!W;kq N002ovPDHLkV1iitvZVk3 delta 190 zcmdnQe4cTFWIYoD1H&JQw~K)kV{wqX6T`Z5GB1G~&H|6fVg?3oVGw3ym^DWND9B#o z>FdgVgGWfzRPes(Q4OF_qNj^vh==#vX^vbB3LGrPzy44672tA;;&{7dZmQUETa{I} zKF#ZpIWUjC-}5PB^3z*o=Wn;nlik5w)SsBa9%O#;X-)`>wXbUk3-1BOZ5>?;7%dKn n1qzxlu-k22@#k@y+Za4u{an^LB{Ts5x(Poz diff --git a/src/app/resources/icons/left_page_plus_offcut_selected.png b/src/app/resources/icons/left_page_plus_offcut_selected.png index 1c98e960e77c0959fac1b72f41f811d260a86698..b0d1a51ab63b6545a61c851b9a23a0d06710c9a6 100644 GIT binary patch delta 476 zcmV<20VDp<0rmrsB!3BTNLh0L01sgR01sgSs6VG^0000GdQ@0+RB3cl}|0i)eqbT$=RBf#W#OMc;FlW$ldA`rK5M_c}FAbF;@z0R8?W2zkI{@{DLSfk-5_ z)-@_#pvu#QJaxEQJ7v09%&}U%V?Li@I(42bp=lZn!*B+W&6bf) zUw=inrNBlvAb%|JZT8p%CW?}0_NuC)R4Ta>7z}z20OR6=(7ucCslA>UEr6%Z1zTV>gyZ`ZViNA z!|;zNByjRBC={y5<&>S53dsiMJ; S>!qXs0000 delta 180 zcmeyye1UO-NGZx^prw85kHi3p^r=85p>QL70(Y)*K0-AbW|YuPgfv9${e< z+2WOprvinNJY5_^BHZ6zcI0X>;BmRwSFvR0f6ixqfh>-WyS3gvE03PV<2!HCDzk?- zvc6u-ntfsS?WD?vzmn&_UEufp6zzYh^gGvuY6Fv-k-Bg0vAZ4M2xwpuS-`-m;lRih g(9rahi=%+y?8TrblLZQw1Fd85boFyt=akR{06^|TuK)l5 diff --git a/src/app/resources/icons/right_page_plus_offcut.png b/src/app/resources/icons/right_page_plus_offcut.png index 10a58206807cee5700813be46d3cdfa242bfa9ec..b34bbd9ba0cf72b94b92f0cc7940275e6e560e89 100644 GIT binary patch delta 412 zcmV;N0b~Bo0jmR$8Gi-<0047(dh`GQ010qNS#tmY4`BcR4`BhQKc{H`000nrR9JLW zX>@F5000P?GX?+vGypV>udC(&00BWsL_t(o!|hi~ii9u_Ex#xT9zZ-quLL)G0rdhd zJ&s3k=@Ik*F1?2yKt%+9J(GaaBT+K582jUcA|;7=<)f-%;D5e@Fbwbi0TxaMKMVtQ zzJmc#6b~2oeUC?mVTdEzV-IMK#KHT%j~z|Zz;#`)ZJW43mSvD636y0Cs;Yu4%fN9Q zNRosDK*q8x%=3(GnkM{S+qT%6rXh0hQ4~=rU>FA6Znu?a!9u?G#g9HwfglK|6v*?O zT7gIMx~@M^fq&P{0nhWmvaDSN(lmvlD5w=c^V=NQay*X$x~_xcIEM=SwFNJw3Y<~}aU8D? zf*|ZFfSQMCnm=wrTc4!D*57jQN2FW)W-TpFznq>Pz!evRUmJbb^2GxH0000FdgVgGWffP??>J+1%% diff --git a/src/app/resources/icons/right_page_plus_offcut_selected.png b/src/app/resources/icons/right_page_plus_offcut_selected.png index 80388b62c6681d397d3cfa7eef7e6784ab61d9e3..76395fa9670e9a5d9e626815920e22c95abe5f22 100644 GIT binary patch delta 448 zcmV;x0YCoG0ontQB!3BTNLh0L01sgR01sgSs6VG^0000GdQ@0+RB3cfB(!NA|l0LVd2G~ zr)Pt3z??aAhzbF9brS|>@EG(?3A&`=iLR1Lcym^M`5CB;O zv;5n)&m%AdhJS7v@b~v;u(!9z69T({A@G#w5CF-ervXb#F9u!R!59Lvva$@mzP(_UNuU|hgh>FSp(}2ey4FPJT0T{rS3kGi*7!3j9ashGW0LY@hfB(SCf#H-3 zAmsojCpQrD5FG+TCl`#?hNCT_(GVDrT(D%x5;%vIl{pn>2!IL?O-*x@o)9`4dv6Gp qjS&L)EXC-@u@J9z$aGEz+yMY$)p_7AMJ^Bk0000GZx^prw85kHi3p^r=85p>QL70(Y)*K0-AbW|YuPgfv9${fK zt)EIMAfY5r7srqY_qUUG^Bz#(aoO21anFC2?ZF(ptQQ)eD809e-uCqV<=-oPCWX8? zYTF*WalUpaU)K`zfZw}zn@yJ}c0F>iCwtY~hgaU$>oy2GFp8ic$6x$Q%r7w1wpFN_ T%Xr=ZTF2n&>gTe~DWM4faz#JF diff --git a/src/app/resources/icons/single_page_uncut.png b/src/app/resources/icons/single_page_uncut.png index d5f9c3881dfb9c381bea5ac05f18c6741de3177c..349adec8d147b5b7c610c1d14373925d2cac00cb 100644 GIT binary patch delta 370 zcmV-&0ge8`0fGaN8Gi-<0047(dh`GQ010qNS#tmY4`BcR4`BhQKc{H`000nrR9JLW zX>@F5000P?GX?+vGypV>udC(&009_DL_t(o!|j)A4nsf?fM+QokvM=j3m3p;Ie?$; z!2u8T( zJP$0(;;ahFvTKAiO~Euxa2)601eS7u{y-kiVYGAeZ&h&o95@MV(Ff2_+qTa>@LyHH z`hccsRJS0&Une|IMCXabNu{g-xiDBJ2nU_EgXMsm#F#`j)FbFd;%$g$s6l5>) z^mS#w!6PJKWO0R;GXp3T;_2cT;^F=FnjzN#10I%xF(3Z#Uo+v_S+Qqahj)nyNyRTb zbLMhQ{^p7j$uvIywO&C`%}J>DI>22WQ%mvv4FO#t<=I^X~R diff --git a/src/app/resources/icons/single_page_uncut_selected.png b/src/app/resources/icons/single_page_uncut_selected.png index 5f0931fca03656cb2ede67936d7e850904e6aed6..465d780d54ae82bb284ce5bf5dbd2b2d3ccf231f 100644 GIT binary patch delta 383 zcmV-_0f7Fz0h$AlB!3BTNLh0L01sgR01sgSs6VG^0000GdQ@0+RB3cp z7)+qwAKi?q%P1iNMUR1b zh`=@z1n}Q@40sHO6X^BImIaL2V46p0x4U5sjDH@1^cdgN~2<1FBv(dnrZlHPScp?eZ*L?E>_i+}L< d&1voioB=yaq^$UNnauzI002ovPDHLkV1hvrqb>jd delta 160 zcmbQmyoYguNGZx^prw85kHi3p^r=85p>QL70(Y)*K0-AbW|YuPgfv9${e% zF^_YmfNSPU_qD@h^V?lgI)FRt*P6u7CzGQ}Ubq2KJ0YlkHV4?y@}x8qMJ8>gTe~ HDWM4fe04Py diff --git a/src/app/resources/icons/two_pages.png b/src/app/resources/icons/two_pages.png index 804aa923d8ab36e904e2cb39980b9252c3da85ad..429d00e8cc1da5df8d29f54c799a942fab8621cf 100644 GIT binary patch delta 400 zcmV;B0dM}P0iOeq8Gi-<0047(dh`GQ010qNS#tmY4`BcR4`BhQKc{H`000nrR9JLW zX>@F5000P?GX?+vGypV>udC(&00A{gL_t(o!|hi=jzvHeEHW%a;sD|hR+d}<7jqmA zVCf!2*ohrtM)yR={ORuh|5!+8bn?$3rBR~-PrK;b6^t}p-a#{v#%d!yxegDy=`D+oJ6g8PZF82bSe}o{s zgJHHn(_Xk-w2@c`q9~x%YQXQ`Mk0|!JbpUy@aJq6_dJhcr2?PF120X(<8qD- zXf&JH@%wSbaep|E$A2ae3LPR4*f%QI-wa9W6)1{2tX{Je zz(Xd3H$j-%1J^wQXSSOHQ7l7}KEblPy&kx*Bw#fKrGHutbxFb=%i=PTSX%<-Jup56 zi}t|y6s&U(YzSEEz`Rpnr2}@E0$m4an(0ySEv1A59q_u{@G;CEQNsW9HQf9WZ3wJz z3N&GfL{9WmjgkGp4o*h{Yehg47cLr|h%xT(Fe5N6@FHt8xGfH+D^K7HU-AVklticj Q00000Ne4wvM6N<$f`NVHlK=n! delta 186 zcmZ3^a*c6GZx^prw85kHi3p^r=85p>QL70(Y)*K0-AbW|YuPgfv9${f? zi~XkAvOu8>PZ!6K2=}*>5ArrB2(TQCxb!Xl;J1=v5KoTzhqi@(VK1m^+{>$&Ss_DAKt&3*?3cJ@ Yb~0u#t>}0$5ojrcr>mdKI;Vst0DSa8Hvj+t diff --git a/src/app/ui/AboutDialog.ui b/src/app/ui/AboutDialog.ui index 0e46475..9806158 100644 --- a/src/app/ui/AboutDialog.ui +++ b/src/app/ui/AboutDialog.ui @@ -13,6 +13,9 @@ About Scan Tailor "Universal" + + true + @@ -125,7 +128,7 @@ 0 - -238 + 0 430 593 diff --git a/src/app/ui/ExportDialog.ui b/src/app/ui/ExportDialog.ui index de420d3..341f237 100644 --- a/src/app/ui/ExportDialog.ui +++ b/src/app/ui/ExportDialog.ui @@ -13,6 +13,9 @@ Export + + true + @@ -327,6 +330,27 @@ for content in foreground subscans (lengthy) + + tabWidget + cbExportImage + cbExportForeground + cbExportBackground + cbExportAutomask + cbExportMask + cbExportZones + DefaultOutputFolder + outExportDirLine + outExportDirBrowseBtn + cbExportSelected + btnResetToDefault + ExportButton + OkButton + cbMultipageOutput + GenerateBlankBackSubscans + UseSepSuffixForPics + cbExportWithoutOutputStage + KeepOriginalColorIllumForeSubscans + diff --git a/src/app/ui/FixDpiDialog.ui b/src/app/ui/FixDpiDialog.ui index a8c1ab3..e54c0fb 100644 --- a/src/app/ui/FixDpiDialog.ui +++ b/src/app/ui/FixDpiDialog.ui @@ -13,6 +13,9 @@ Fix DPI + + true + @@ -131,19 +134,6 @@ - - - - Qt::Vertical - - - - 317 - 16 - - - - @@ -156,6 +146,15 @@ + + tabWidget + undefinedDpiView + dpiCombo + xDpi + yDpi + applyBtn + allPagesView + diff --git a/src/app/ui/LoadFilesStatusDialog.ui b/src/app/ui/LoadFilesStatusDialog.ui index 186b02c..40bc289 100644 --- a/src/app/ui/LoadFilesStatusDialog.ui +++ b/src/app/ui/LoadFilesStatusDialog.ui @@ -13,6 +13,9 @@ Some files failed to load + + true + diff --git a/src/app/ui/MainWindow.ui b/src/app/ui/MainWindow.ui index 8605c41..4d42d23 100644 --- a/src/app/ui/MainWindow.ui +++ b/src/app/ui/MainWindow.ui @@ -941,6 +941,16 @@ 1 + + filterList + scrollArea + inverseOrderButton + focusButton + multiselectButton + thumbView + resetSortingBtn + sortOptions + diff --git a/src/app/ui/NewOpenProjectPanel.ui b/src/app/ui/NewOpenProjectPanel.ui index ee0a813..5ca297d 100644 --- a/src/app/ui/NewOpenProjectPanel.ui +++ b/src/app/ui/NewOpenProjectPanel.ui @@ -57,13 +57,10 @@ - + New Project... - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - @@ -83,7 +80,7 @@ - + Open Project... diff --git a/src/app/ui/ProjectFilesDialog.ui b/src/app/ui/ProjectFilesDialog.ui index 377b81a..0f04f41 100644 --- a/src/app/ui/ProjectFilesDialog.ui +++ b/src/app/ui/ProjectFilesDialog.ui @@ -13,6 +13,9 @@ Project Files + + true + @@ -201,6 +204,20 @@ p, li { white-space: pre-wrap; } + + inpDirLine + inpDirBrowseBtn + outDirLine + outDirBrowseBtn + offProjectList + offProjectSelectAllBtn + addToProjectBtn + removeFromProjectBtn + inProjectList + inProjectSelectAllBtn + rtlLayoutCB + forceFixDpi + diff --git a/src/app/ui/RelinkingDialog.ui b/src/app/ui/RelinkingDialog.ui index 4940529..ac210c2 100644 --- a/src/app/ui/RelinkingDialog.ui +++ b/src/app/ui/RelinkingDialog.ui @@ -13,6 +13,9 @@ Relinking + + true + 6 diff --git a/src/app/ui/RemovePagesDialog.ui b/src/app/ui/RemovePagesDialog.ui index dd8b61c..95854a3 100644 --- a/src/app/ui/RemovePagesDialog.ui +++ b/src/app/ui/RemovePagesDialog.ui @@ -13,6 +13,9 @@ Remove Pages + + true + diff --git a/src/app/ui/SettingsDialog.ui b/src/app/ui/SettingsDialog.ui index f324455..512930f 100644 --- a/src/app/ui/SettingsDialog.ui +++ b/src/app/ui/SettingsDialog.ui @@ -45,6 +45,9 @@ + + 6 + @@ -176,19 +179,19 @@ - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -197,19 +200,19 @@ - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -276,8 +279,30 @@ You can add new images (for ex. missing pages) after project is created with Ins Options - + + + + + + + Application language: + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -290,14 +315,63 @@ You can add new images (for ex. missing pages) after project is created with Ins - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Application language: + Application style: - + + + + QComboBox::AdjustToContents + + + + + + + Application stylesheet: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QComboBox::AdjustToContents + + + + + + Batch processing @@ -350,7 +424,7 @@ You can add new images (for ex. missing pages) after project is created with Ins - + Filter existing files in insert new image dialog @@ -360,34 +434,6 @@ You can add new images (for ex. missing pages) after project is created with Ins - - - - Application style: - - - - - - - QComboBox::AdjustToContents - - - - - - - QComboBox::AdjustToContents - - - - - - - Application stylesheet: - - - @@ -396,19 +442,19 @@ You can add new images (for ex. missing pages) after project is created with Ins - 5 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -518,19 +564,19 @@ p, li { white-space: pre-wrap; }</style></head><body> - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -578,19 +624,19 @@ This option allows to increase page view panel size to almost a whole applicatio - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -599,19 +645,19 @@ This option allows to increase page view panel size to almost a whole applicatio - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -766,22 +812,7 @@ This option allows to increase page view panel size to almost a whole applicatio - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + @@ -985,19 +1016,19 @@ This option allows to increase page view panel size to almost a whole applicatio - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1077,19 +1108,19 @@ If project was never saved before this will create UnnamedAutoSave.Scantailor fi - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1098,19 +1129,19 @@ If project was never saved before this will create UnnamedAutoSave.Scantailor fi - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -1307,19 +1338,19 @@ Horizontal differencing predictor - a preprocessing step applied to image data t - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1370,19 +1401,19 @@ Use "Apply To..." dialog to apply changes to a specified range of page - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1394,16 +1425,16 @@ Use "Apply To..." dialog to apply changes to a specified range of page 0 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -1475,19 +1506,19 @@ The dividing line can also be determined/moved automatically or specified manual - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1599,19 +1630,19 @@ The dividing line can also be determined/moved automatically or specified manual - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1623,16 +1654,16 @@ The dividing line can also be determined/moved automatically or specified manual 0 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -1757,19 +1788,19 @@ Images can be rotated by dragging the round handles at the edges. You can also e - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1817,19 +1848,19 @@ The Deviant page on this stage is defined as a page which absolute deskew angle - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -1838,19 +1869,19 @@ The Deviant page on this stage is defined as a page which absolute deskew angle - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -1990,19 +2021,19 @@ If areas are identified incorrectly, you can tweak individual pages manually by - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2050,19 +2081,19 @@ The Deviant page on this stage is defined as a page which content zone square di - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2074,16 +2105,16 @@ The Deviant page on this stage is defined as a page which content zone square di 0 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -2326,19 +2357,19 @@ Everything outside page area is highlighted with yellow in page view panel. - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2347,19 +2378,19 @@ Everything outside page area is highlighted with yellow in page view panel. - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -2422,19 +2453,19 @@ Everything outside page area is highlighted with yellow in page view panel. - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2482,19 +2513,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2503,19 +2534,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -2763,19 +2794,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2790,19 +2821,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -2920,7 +2951,7 @@ The Deviant page on this stage is defined as a page which has no alignment. - + 0 0 @@ -2928,7 +2959,7 @@ The Deviant page on this stage is defined as a page which has no alignment. 156 - 0 + 156 @@ -2962,19 +2993,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -2983,19 +3014,19 @@ The Deviant page on this stage is defined as a page which has no alignment. - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3236,19 +3267,19 @@ Unlike the other stages, the "Output" stage becomes available only aft - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3257,19 +3288,19 @@ Unlike the other stages, the "Output" stage becomes available only aft - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3349,19 +3380,19 @@ Making black and white image from grayscale or color source requires binarizatio - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3370,19 +3401,19 @@ Making black and white image from grayscale or color source requires binarizatio - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3455,19 +3486,19 @@ Equalize illumination option normalizes the background color, bringing it to whi - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3476,19 +3507,19 @@ Equalize illumination option normalizes the background color, bringing it to whi - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3553,7 +3584,20 @@ Automatic picture zones detection works well enough, but if the picture merges s Options - + + + 9 + + + 9 + + + 9 + + + 9 + + @@ -3561,19 +3605,19 @@ Automatic picture zones detection works well enough, but if the picture merges s - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3582,19 +3626,19 @@ Automatic picture zones detection works well enough, but if the picture merges s - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3659,19 +3703,19 @@ This mask can't be changed directly but only switched on/off. User could also cr - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3680,19 +3724,19 @@ This mask can't be changed directly but only switched on/off. User could also cr - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3806,19 +3850,19 @@ In case sensitivity parameter is 100% the picture detection algorithm looks for - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3827,19 +3871,19 @@ In case sensitivity parameter is 100% the picture detection algorithm looks for - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -3922,19 +3966,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -3989,19 +4033,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -4010,19 +4054,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -4105,19 +4149,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -4199,6 +4243,9 @@ As Foreground layer is using binarization to separate content from background it + + 6 + @@ -4260,19 +4307,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 @@ -4281,19 +4328,19 @@ As Foreground layer is using binarization to separate content from background it - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 - 0 + 6 @@ -4404,7 +4451,90 @@ Debug images are saved as png in temporary folder with unique filenames. These f + treeWidget lineEdit + scrollArea_8 + language + cbStyle + cbStyleSheet + startBatchProcessingDlgAllPages + startBatchProcessingDlgFromSelected + showStartBatchProcessingDlg + cbDontUseNativeDlg + scrollArea + btnResetHotKeys + scrollArea_16 + cbThumbsListOrder + gbFixedMaxLogicalThumbSize + sbFixedMaxLogicalThumbSizeHeight + sbFixedMaxLogicalThumbSizeWidth + sbThumbsCacheImgSize + sbThumbsMinSpacing + sbThumbsBoundaryAdjTop + sbThumbsBoundaryAdjLeft + sbThumbsBoundaryAdjBottom + sbThumbsBoundaryAdjRight + btnThumbDefaults + cbOrderHints + sbSavePeriod + scrollArea_2 + cbTiffCompressionBW + cbTiffCompressionColor + cbTiffFilter + useHorizontalPredictor + scrollArea_4 + cbApplyCutDefault + scrollArea_21 + btnColorDeskew + btnColorDeskewReset + scrollArea_5 + btnColorSelectedContent + btnColorSelectedContentReset + scrollArea_9 + gbPageDetectionFineTuneCorners + cbPageDetectionFineTuneCorners + gbPageDetectionTargetSize + pageDetectionTargetWidth + pageDetectionTargetHeight + gbPageDetectionBorders + pageDetectionTopBorder + pageDetectionLeftBorder + pageDetectionRightBorder + pageDetectionBottomBorder + scrollArea_6 + scrollArea_18 + cbMarginUnits + marginDefaultTopVal + marginDefaultLeftVal + marginDefaultRightVal + marginDefaultBottomVal + gbMarginsAuto + cbMarginsAuto + scrollArea_17 + cbAlignmentAuto + cbAlignmentOriginal + scrollArea_7 + dpiDefaultXValue + dpiDefaultYValue + ThresholdMinValue + ThresholdMaxValue + ThresholdDefaultsValue + originalPageDisplayOnKeyHold + scrollArea_11 + disableSmoothingBW + scrollArea_12 + scrollArea_13 + scrollArea_14 + scrollArea_15 + rectangularAreasSensitivityValue + scrollArea_10 + cbForegroundLayerSeparateControl + scrollArea_19 + cbTryVertHalfCorrection + cbTryDeskewAfterDewarp + despecklingDefaultsValue + cbCopyICCProfile + scrollArea_3 diff --git a/src/app_cli/CMakeLists.txt b/src/app_cli/CMakeLists.txt index 8943356..a6832b5 100644 --- a/src/app_cli/CMakeLists.txt +++ b/src/app_cli/CMakeLists.txt @@ -24,9 +24,11 @@ ENDIF() IF(APPLE) INSTALL(TARGETS scantailor-universal-cli BUNDLE DESTINATION . RUNTIME DESTINATION bin) -ELSE(APPLE) +ELSEIF(WIN32) + INSTALL(TARGETS scantailor-universal-cli RUNTIME DESTINATION .) +ELSE() INSTALL(TARGETS scantailor-universal-cli RUNTIME DESTINATION bin) -ENDIF(APPLE) +ENDIF() TRANSLATION_SOURCES( scantailor-universal diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2008cb1..7be9599 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -10,7 +10,9 @@ INCLUDE_DIRECTORIES("${core_ui_sources_BINARY_DIR}") ADD_SUBDIRECTORY(interaction) ADD_SUBDIRECTORY(zones) -ADD_SUBDIRECTORY(tests) +IF(ENABLE_TESTS) + ADD_SUBDIRECTORY(tests) +ENDIF() ADD_SUBDIRECTORY(filters/fix_orientation) ADD_SUBDIRECTORY(filters/page_split) diff --git a/src/core/TiffReader.cpp b/src/core/TiffReader.cpp index 760b44b..45d3196 100644 --- a/src/core/TiffReader.cpp +++ b/src/core/TiffReader.cpp @@ -116,10 +116,10 @@ class TiffReader::TiffBuffer struct TiffReader::TiffInfo { int width; int height; - uint16 bits_per_sample; - uint16 samples_per_pixel; - uint16 sample_format; - uint16 photometric; + uint16_t bits_per_sample; + uint16_t samples_per_pixel; + uint16_t sample_format; + uint16_t photometric; bool host_big_endian; bool file_big_endian; @@ -138,7 +138,7 @@ TiffReader::TiffInfo::TiffInfo(TiffHandle const& tif, TiffHeader const& header) host_big_endian(QSysInfo::ByteOrder == QSysInfo::BigEndian), file_big_endian(header.signature() == TiffHeader::TIFF_BIG_ENDIAN) { - uint16 compression = 1; + uint16_t compression = 1; TIFFGetField(tif.handle(), TIFFTAG_COMPRESSION, &compression); switch (compression) { case COMPRESSION_CCITTFAX3: @@ -278,11 +278,11 @@ TiffReader::readMetadata( return ImageMetadataLoader::LOADED; } -static void convertAbgrToArgb(uint32 const* src, uint32* dst, int count) +static void convertAbgrToArgb(uint32_t const* src, uint32_t* dst, int count) { for (int i = 0; i < count; ++i) { - uint32 const src_word = src[i]; - uint32 dst_word = src_word & 0xFF000000; // A + uint32_t const src_word = src[i]; + uint32_t dst_word = src_word & 0xFF000000; // A dst_word |= (src_word & 0x00FF0000) >> 16; // B dst_word |= src_word & 0x0000FF00; // G dst_word |= (src_word & 0x000000FF) << 16; // R @@ -342,18 +342,18 @@ TiffReader::readImage(QIODevice& device, int const page_num) } // For ABGR -> ARGB conversion. - TiffBuffer tmp_buffer; - uint32 const* src_line = 0; + TiffBuffer tmp_buffer; + uint32_t const* src_line = 0; if (image.bytesPerLine() == 4 * info.width) { // We can avoid creating a temporary buffer in this case. if (!TIFFReadRGBAImageOriented(tif.handle(), info.width, info.height, - (uint32*)image.bits(), ORIENTATION_TOPLEFT, 0)) { + (uint32_t*)image.bits(), ORIENTATION_TOPLEFT, 0)) { return QImage(); } - src_line = (uint32 const*)image.bits(); + src_line = (uint32_t const*)image.bits(); } else { - TiffBuffer(info.width * info.height).swap(tmp_buffer); + TiffBuffer(info.width * info.height).swap(tmp_buffer); if (!TIFFReadRGBAImageOriented(tif.handle(), info.width, info.height, tmp_buffer.data(), ORIENTATION_TOPLEFT, 0)) { return QImage(); @@ -361,7 +361,7 @@ TiffReader::readImage(QIODevice& device, int const page_num) src_line = tmp_buffer.data(); } - uint32* dst_line = (uint32*)image.bits(); + uint32_t* dst_line = (uint32_t*)image.bits(); assert(image.bytesPerLine() % 4 == 0); int const dst_stride = image.bytesPerLine() / 4; for (int y = 0; y < info.height; ++y) { @@ -388,14 +388,14 @@ TiffReader::readHeader(QIODevice& device) return TiffHeader(); } - uint16 const version_byte0 = data[2]; - uint16 const version_byte1 = data[3]; + uint16_t const version_byte0 = data[2]; + uint16_t const version_byte1 = data[3]; if (data[0] == 0x4d && data[1] == 0x4d) { - uint16 const version = (version_byte0 << 8) + version_byte1; + uint16_t const version = (version_byte0 << 8) + version_byte1; return TiffHeader(TiffHeader::TIFF_BIG_ENDIAN, version); } else if (data[0] == 0x49 && data[1] == 0x49) { - uint16 const version = (version_byte1 << 8) + version_byte0; + uint16_t const version = (version_byte1 << 8) + version_byte0; return TiffHeader(TiffHeader::TIFF_LITTLE_ENDIAN, version); } else { return TiffHeader(); @@ -417,9 +417,9 @@ TiffReader::checkHeader(TiffHeader const& header) ImageMetadata TiffReader::currentPageMetadata(TiffHandle const& tif) { - uint32 width = 0, height = 0; + uint32_t width = 0, height = 0; float xres = 0, yres = 0; - uint16 res_unit = 0; + uint16_t res_unit = 0; TIFFGetField(tif.handle(), TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif.handle(), TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tif.handle(), TIFFTAG_XRESOLUTION, &xres); @@ -460,9 +460,9 @@ TiffReader::extractBinaryOrIndexed8Image( image.setColorCount(num_colors); if (info.photometric == PHOTOMETRIC_PALETTE) { - uint16* pr = 0; - uint16* pg = 0; - uint16* pb = 0; + uint16_t* pr = 0; + uint16_t* pg = 0; + uint16_t* pb = 0; TIFFGetField(tif.handle(), TIFFTAG_COLORMAP, &pr, &pg, &pb); if (!pr || !pg || !pb) { return QImage(); @@ -474,10 +474,10 @@ TiffReader::extractBinaryOrIndexed8Image( } double const f = 255.0 / 65535.0; for (int i = 0; i < num_colors; ++i) { - uint32 const r = (uint32)(pr[i] * f + 0.5); - uint32 const g = (uint32)(pg[i] * f + 0.5); - uint32 const b = (uint32)(pb[i] * f + 0.5); - uint32 const a = 0xFF000000; + uint32_t const r = (uint32_t)(pr[i] * f + 0.5); + uint32_t const g = (uint32_t)(pg[i] * f + 0.5); + uint32_t const b = (uint32_t)(pb[i] * f + 0.5); + uint32_t const a = 0xFF000000; image.setColor(i, a | (r << 16) | (g << 8) | b); } } else if (info.photometric == PHOTOMETRIC_MINISBLACK) { @@ -519,7 +519,7 @@ void TiffReader::readAndUnpackLines( TiffHandle const& tif, TiffInfo const& info, QImage& image) { - TiffBuffer buf(TIFFScanlineSize(tif.handle())); + TiffBuffer buf(TIFFScanlineSize(tif.handle())); int const width = image.width(); int const height = image.height(); @@ -532,8 +532,8 @@ TiffReader::readAndUnpackLines( unsigned accum = 0; int bits_in_accum = 0; - uint8 const* src = buf.data(); - uint8* dst = (uint8*)image.scanLine(y); + uint8_t const* src = buf.data(); + uint8_t* dst = (uint8_t*)image.scanLine(y); for (int i = width; i > 0; --i, ++dst) { while (bits_in_accum < bits_per_sample) { @@ -543,7 +543,7 @@ TiffReader::readAndUnpackLines( ++src; } bits_in_accum -= bits_per_sample; - *dst = static_cast((accum >> bits_in_accum) & dst_mask); + *dst = static_cast((accum >> bits_in_accum) & dst_mask); } } } diff --git a/src/core/TiffWriter.cpp b/src/core/TiffWriter.cpp index cbfe7b8..fbbcc99 100644 --- a/src/core/TiffWriter.cpp +++ b/src/core/TiffWriter.cpp @@ -270,7 +270,7 @@ TiffWriter::setDpm(TiffHandle const& tif, Dpm const& dpm) float xres = 0.01 * dpm.horizontal(); // cm float yres = 0.01 * dpm.vertical(); // cm - uint16 unit = RESUNIT_CENTIMETER; + uint16_t unit = RESUNIT_CENTIMETER; // If we have a round (or almost round) DPI, then // write it as DPI rather than dots per cm. @@ -294,10 +294,10 @@ bool TiffWriter::writeBitonalOrIndexed8Image( TiffHandle const& tif, QImage const& image, bool multipage, int compression) { - TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16(1)); + TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16_t(1)); - uint16 bits_per_sample = 8; - uint16 photometric = PHOTOMETRIC_PALETTE; + uint16_t bits_per_sample = 8; + uint16_t photometric = PHOTOMETRIC_PALETTE; if (image.isGrayscale()) { photometric = PHOTOMETRIC_MINISBLACK; } @@ -324,7 +324,7 @@ TiffWriter::writeBitonalOrIndexed8Image( default:; } - TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16(compression)); + TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16_t(compression)); TIFFSetField(tif.handle(), TIFFTAG_BITSPERSAMPLE, bits_per_sample); TIFFSetField(tif.handle(), TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(tif.handle(), TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); @@ -339,9 +339,9 @@ TiffWriter::writeBitonalOrIndexed8Image( if (color_table.size() > num_colors) { color_table.resize(num_colors); } - std::vector pr(num_colors, 0); - std::vector pg(num_colors, 0); - std::vector pb(num_colors, 0); + std::vector pr(num_colors, 0); + std::vector pg(num_colors, 0); + std::vector pb(num_colors, 0); for (int i = 0; i < color_table.size(); ++i) { QRgb const rgb = color_table[i]; pr[i] = (0xFFFF * qRed(rgb) + 128) / 255; @@ -379,9 +379,9 @@ TiffWriter::writeRGB32Image( { assert(image.format() == QImage::Format_RGB32); - TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16(3)); - TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16(compression)); - TIFFSetField(tif.handle(), TIFFTAG_BITSPERSAMPLE, uint16(8)); + TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16_t(3)); + TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16_t(compression)); + TIFFSetField(tif.handle(), TIFFTAG_BITSPERSAMPLE, uint16_t(8)); TIFFSetField(tif.handle(), TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); if (GlobalStaticSettings::m_use_horizontal_predictor) { TIFFSetField(tif.handle(), TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL); @@ -423,9 +423,9 @@ TiffWriter::writeARGB32Image( { assert(image.format() == QImage::Format_ARGB32); - TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16(4)); - TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16(compression)); - TIFFSetField(tif.handle(), TIFFTAG_BITSPERSAMPLE, uint16(8)); + TIFFSetField(tif.handle(), TIFFTAG_SAMPLESPERPIXEL, uint16_t(4)); + TIFFSetField(tif.handle(), TIFFTAG_COMPRESSION, uint16_t(compression)); + TIFFSetField(tif.handle(), TIFFTAG_BITSPERSAMPLE, uint16_t(8)); TIFFSetField(tif.handle(), TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); if (GlobalStaticSettings::m_use_horizontal_predictor) { TIFFSetField(tif.handle(), TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL); diff --git a/src/core/filters/output/BlackWhiteOptions.cpp b/src/core/filters/output/BlackWhiteOptions.cpp index 929c617..029d018 100644 --- a/src/core/filters/output/BlackWhiteOptions.cpp +++ b/src/core/filters/output/BlackWhiteOptions.cpp @@ -99,7 +99,19 @@ BlackWhiteOptions::operator!=(BlackWhiteOptions const& other) const ThresholdFilter BlackWhiteOptions::parseThresholdMethod(QString const& str) { - if (str == "sauvola") + if (str == "mean") + { + return MEANDELTA; + } + else if (str == "niblack") + { + return NIBLACK; + } + else if (str == "gatos") + { + return GATOS; + } + else if (str == "sauvola") { return SAUVOLA; } @@ -123,6 +135,10 @@ BlackWhiteOptions::parseThresholdMethod(QString const& str) { return EDGEDIV; } + else if (str == "multiscale") + { + return MSCALE; + } else { return OTSU; @@ -138,6 +154,15 @@ BlackWhiteOptions::formatThresholdMethod(ThresholdFilter type) case OTSU: str = "otsu"; break; + case MEANDELTA: + str = "mean"; + break; + case NIBLACK: + str = "niblack"; + break; + case GATOS: + str = "gatos"; + break; case SAUVOLA: str = "sauvola"; break; @@ -156,6 +181,9 @@ BlackWhiteOptions::formatThresholdMethod(ThresholdFilter type) case EDGEDIV: str = "edgediv"; break; + case MSCALE: + str = "multiscale"; + break; } return str; } diff --git a/src/core/filters/output/BlackWhiteOptions.h b/src/core/filters/output/BlackWhiteOptions.h index 2f5a724..42503b6 100644 --- a/src/core/filters/output/BlackWhiteOptions.h +++ b/src/core/filters/output/BlackWhiteOptions.h @@ -26,7 +26,7 @@ class QDomElement; namespace output { -enum ThresholdFilter { OTSU, SAUVOLA, WOLF, BRADLEY, EDGEPLUS, BLURDIV, EDGEDIV }; +enum ThresholdFilter { OTSU, MEANDELTA, NIBLACK, GATOS, SAUVOLA, WOLF, BRADLEY, EDGEPLUS, BLURDIV, EDGEDIV, MSCALE }; class BlackWhiteOptions { diff --git a/src/core/filters/output/OptionsWidget.cpp b/src/core/filters/output/OptionsWidget.cpp index 66a7772..78e8889 100644 --- a/src/core/filters/output/OptionsWidget.cpp +++ b/src/core/filters/output/OptionsWidget.cpp @@ -64,12 +64,16 @@ OptionsWidget::OptionsWidget( setupUi(this); thresholdMethodSelector->addItem(tr("Otsu"), OTSU); + thresholdMethodSelector->addItem(tr("Mean"), MEANDELTA); + thresholdMethodSelector->addItem(tr("Niblack"), NIBLACK); + thresholdMethodSelector->addItem(tr("Gatos"), GATOS); thresholdMethodSelector->addItem(tr("Sauvola"), SAUVOLA); thresholdMethodSelector->addItem(tr("Wolf"), WOLF); thresholdMethodSelector->addItem(tr("Bradley"), BRADLEY); thresholdMethodSelector->addItem(tr("EdgePlus"), EDGEPLUS); thresholdMethodSelector->addItem(tr("BlurDiv"), BLURDIV); thresholdMethodSelector->addItem(tr("EdgeDiv"), EDGEDIV); + thresholdMethodSelector->addItem(tr("MultiScale"), MSCALE); setDespeckleLevel(DESPECKLE_NORMAL); @@ -99,6 +103,46 @@ OptionsWidget::OptionsWidget( updateLayersDisplay(); updateDewarpingDisplay(); + connect( + dpiValue, SIGNAL(clicked(bool)), + this, SLOT(dpiValueClicked()) + ); + + connect( + modeValue, SIGNAL(clicked(bool)), + this, SLOT(modeValueClicked()) + ); + + connect( + applyColorsButton, SIGNAL(clicked(bool)), + this, SLOT(applyColorsButtonClicked()) + ); + + connect( + applyThresholdButton, SIGNAL(clicked(bool)), + this, SLOT(applyThresholdButtonClicked()) + ); + + connect( + applyForegroundThresholdButton, SIGNAL(clicked(bool)), + this, SLOT(applyForegroundThresholdButtonClicked()) + ); + + connect( + applyDepthPerception, SIGNAL(clicked(bool)), + this, SLOT(applyDepthPerceptionClicked()) + ); + + connect( + dewarpingStatusButton, SIGNAL(clicked(bool)), + this, SLOT(dewarpingStatusButtonClicked()) + ); + + connect( + applyDespeckleButton, SIGNAL(clicked(bool)), + this, SLOT(applyDespeckleButtonClicked()) + ); + connect( whiteMarginsCB, SIGNAL(clicked(bool)), this, SLOT(whiteMarginsToggled(bool)) @@ -282,8 +326,8 @@ OptionsWidget::thresholdWindowSizeChanged(int value) { blackWhiteOptions.setThresholdWindowSize(value); m_colorParams.setBlackWhiteOptions(blackWhiteOptions); m_ptrSettings->setColorParams(m_pageId, m_colorParams); - if (blackWhiteOptions.thresholdMethod() != OTSU) - emit reloadRequested(); + if (blackWhiteOptions.thresholdMethod() != OTSU && blackWhiteOptions.thresholdMethod() != MEANDELTA) + emit reloadRequested(); } void @@ -292,7 +336,8 @@ OptionsWidget::thresholdCoefChanged(double value) { blackWhiteOptions.setThresholdCoef(value); m_colorParams.setBlackWhiteOptions(blackWhiteOptions); m_ptrSettings->setColorParams(m_pageId, m_colorParams); - emit reloadRequested(); + if (blackWhiteOptions.thresholdMethod() != OTSU && blackWhiteOptions.thresholdMethod() != MEANDELTA) + emit reloadRequested(); } void @@ -523,10 +568,10 @@ OptionsWidget::updateDpiDisplay() QString dpi_label = tr("%1 x %2 dpi") .arg(m_outputDpi.horizontal()) .arg(m_outputDpi.vertical()); - dpiValue->setText(Utils::richTextForLink(dpi_label)); + dpiValue->setText(dpi_label); } else { QString dpi_label = tr("%1 dpi").arg(QString::number(m_outputDpi.horizontal())); - dpiValue->setText(Utils::richTextForLink(dpi_label)); + dpiValue->setText(dpi_label); } StatusBarProvider::setSettingsDPi(m_outputDpi); @@ -537,13 +582,13 @@ OptionsWidget::updateModeValueText() { switch (m_currentMode) { case ColorParams::BLACK_AND_WHITE: - modeValue->setText(Utils::richTextForLink(actionModeBW->toolTip())); + modeValue->setText(actionModeBW->toolTip()); break; case ColorParams::COLOR_GRAYSCALE: - modeValue->setText(Utils::richTextForLink(actionModeColorOrGrayscale->toolTip())); + modeValue->setText(actionModeColorOrGrayscale->toolTip()); break; case ColorParams::MIXED: - modeValue->setText(Utils::richTextForLink(actionModeMixed->toolTip())); + modeValue->setText(actionModeMixed->toolTip()); break; } } @@ -633,7 +678,7 @@ OptionsWidget::updateColorsDisplay() thresholdSlider->setValue(blackWhiteOptions.thresholdAdjustment()); thresholdWindowSize->setValue(blackWhiteOptions.thresholdWindowSize()); thresholdCoef->setValue(blackWhiteOptions.thresholdCoef()); - if (blackWhiteOptions.thresholdMethod() == OTSU) + if (blackWhiteOptions.thresholdMethod() == OTSU || blackWhiteOptions.thresholdMethod() == MEANDELTA) { thresholdWindowSize->setEnabled( false ); thresholdCoef->setEnabled( false ); @@ -678,18 +723,18 @@ OptionsWidget::updateDewarpingDisplay() switch (m_dewarpingMode) { case DewarpingMode::OFF: - dewarpingStatusLabel->setText(Utils::richTextForLink(tr("Off"))); + dewarpingStatusButton->setText(tr("Off")); break; case DewarpingMode::AUTO: - dewarpingStatusLabel->setText(Utils::richTextForLink(tr("Auto"))); + dewarpingStatusButton->setText(tr("Auto")); break; case DewarpingMode::MANUAL: - dewarpingStatusLabel->setText(Utils::richTextForLink(tr("Manual"))); + dewarpingStatusButton->setText(tr("Manual")); break; //begin of modified by monday2000 //Marginal_Dewarping case DewarpingMode::MARGINAL: - dewarpingStatusLabel->setText(Utils::richTextForLink(tr("Marginal"))); + dewarpingStatusButton->setText(tr("Marginal")); break; //end of modified by monday2000 } @@ -735,7 +780,7 @@ void output::OptionsWidget::on_depthPerceptionSlider_valueChanged(int value) emit depthPerceptionChanged(m_depthPerception.value()); } -void output::OptionsWidget::on_applyDepthPerception_linkActivated(const QString& /*link*/) +void output::OptionsWidget::applyDepthPerceptionClicked() { ApplyToDialog* dialog = new ApplyToDialog(this, m_pageId, m_pageSelectionAccessor); dialog->setWindowTitle(tr("Apply Depth Perception")); @@ -750,7 +795,7 @@ void output::OptionsWidget::on_applyDepthPerception_linkActivated(const QString& dialog->show(); } -void output::OptionsWidget::on_dewarpingStatusLabel_linkActivated(const QString& /*link*/) +void output::OptionsWidget::dewarpingStatusButtonClicked() { ApplyToDialog* dialog = new ApplyToDialog( this, m_pageId, m_pageSelectionAccessor); @@ -770,7 +815,7 @@ void output::OptionsWidget::on_dewarpingStatusLabel_linkActivated(const QString& dialog->show(); } -void output::OptionsWidget::on_applyDespeckleButton_linkActivated(const QString& /*link*/) +void output::OptionsWidget::applyDespeckleButtonClicked() { ApplyToDialog* dialog = new ApplyToDialog(this, m_pageId, m_pageSelectionAccessor); dialog->setWindowTitle(tr("Apply Despeckling Level")); @@ -786,7 +831,7 @@ void output::OptionsWidget::on_applyDespeckleButton_linkActivated(const QString& dialog->show(); } -void output::OptionsWidget::on_applyColorsButton_linkActivated(const QString& /*link*/) +void output::OptionsWidget::applyColorsButtonClicked() { ApplyToDialog* dialog = new ApplyToDialog(this, m_pageId, m_pageSelectionAccessor); dialog->setWindowTitle(tr("Apply Mode")); @@ -802,28 +847,28 @@ void output::OptionsWidget::on_applyColorsButton_linkActivated(const QString& /* dialog->show(); } -void output::OptionsWidget::on_modeValue_linkActivated(const QString& /*link*/) +void output::OptionsWidget::modeValueClicked() { m_menuMode.popup(modeValue->mapToGlobal(QPoint(0, modeValue->geometry().height()))); } void output::OptionsWidget::on_actionModeBW_triggered() { - modeValue->setText(Utils::richTextForLink(actionModeBW->toolTip())); + modeValue->setText(actionModeBW->toolTip()); changeColorMode(ColorParams::BLACK_AND_WHITE); emit invalidateThumbnail(m_pageId); } void output::OptionsWidget::on_actionModeColorOrGrayscale_triggered() { - modeValue->setText(Utils::richTextForLink(actionModeColorOrGrayscale->toolTip())); + modeValue->setText(actionModeColorOrGrayscale->toolTip()); changeColorMode(ColorParams::COLOR_GRAYSCALE); emit invalidateThumbnail(m_pageId); } void output::OptionsWidget::on_actionModeMixed_triggered() { - modeValue->setText(Utils::richTextForLink(actionModeMixed->toolTip())); + modeValue->setText(actionModeMixed->toolTip()); changeColorMode(ColorParams::MIXED); emit invalidateThumbnail(m_pageId); } @@ -973,7 +1018,7 @@ void output::OptionsWidget::on_thresholdForegroundSlider_valueChanged() emit invalidateThumbnail(m_pageId); } -void output::OptionsWidget::on_dpiValue_linkActivated(const QString& /*link*/) +void output::OptionsWidget::dpiValueClicked() { ApplyToDialog* dialog = new ApplyToDialog( this, m_pageId, m_pageSelectionAccessor @@ -1013,7 +1058,7 @@ void output::OptionsWidget::applyThresholdConfirmed(std::set const& page } } -void output::OptionsWidget::on_applyThresholdButton_linkActivated(const QString& /*link*/) +void output::OptionsWidget::applyThresholdButtonClicked() { ApplyToDialog* dialog = new ApplyToDialog(this, m_pageId, m_pageSelectionAccessor); dialog->setWindowTitle(tr("Apply Threshold")); @@ -1083,7 +1128,7 @@ void output::OptionsWidget::on_autoLayerCB_toggled(bool checked) } } -void output::OptionsWidget::on_applyForegroundThresholdButton_linkActivated(const QString& /*link*/) +void output::OptionsWidget::applyForegroundThresholdButtonClicked() { ApplyToDialog* dialog = new ApplyToDialog(this, m_pageId, m_pageSelectionAccessor); dialog->setWindowTitle(tr("Apply Foreground layer threshold")); diff --git a/src/core/filters/output/OptionsWidget.h b/src/core/filters/output/OptionsWidget.h index afe78d1..505178b 100644 --- a/src/core/filters/output/OptionsWidget.h +++ b/src/core/filters/output/OptionsWidget.h @@ -99,15 +99,15 @@ private slots: void on_depthPerceptionSlider_valueChanged(int value); - void on_applyDepthPerception_linkActivated(const QString&); + void applyDepthPerceptionClicked(); - void on_dewarpingStatusLabel_linkActivated(const QString&); + void dewarpingStatusButtonClicked(); - void on_applyDespeckleButton_linkActivated(const QString&); + void applyDespeckleButtonClicked(); - void on_applyColorsButton_linkActivated(const QString&); + void applyColorsButtonClicked(); - void on_modeValue_linkActivated(const QString&); + void modeValueClicked(); void on_actionModeBW_triggered(); @@ -127,11 +127,11 @@ private slots: void thresholdCoefChanged(double value); - void on_dpiValue_linkActivated(const QString&); + void dpiValueClicked(); void on_actionReset_to_default_value_triggered(); - void on_applyThresholdButton_linkActivated(const QString&); + void applyThresholdButtonClicked(); void on_pictureZonesLayerCB_toggled(bool checked); @@ -139,7 +139,7 @@ private slots: void on_autoLayerCB_toggled(bool checked); - void on_applyForegroundThresholdButton_linkActivated(const QString& link); + void applyForegroundThresholdButtonClicked(); void on_actionReset_to_default_value_foeground_triggered(); diff --git a/src/core/filters/output/OutputGenerator.cpp b/src/core/filters/output/OutputGenerator.cpp index 64b2a4f..8537ee1 100644 --- a/src/core/filters/output/OutputGenerator.cpp +++ b/src/core/filters/output/OutputGenerator.cpp @@ -2066,6 +2066,21 @@ OutputGenerator::binarize(QImage const& image, BinaryImage const& mask, const in binarized = BinaryImage(image, adjustThreshold(bw_thresh, adjustment)); break; } + case MEANDELTA: + { + binarized = binarizeMean(image, threshold_delta); + break; + } + case NIBLACK: + { + binarized = binarizeNiblack(image, window_size, threshold_coef, threshold_delta); + break; + } + case GATOS: + { + binarized = binarizeGatos(image, window_size, 3.0, threshold_coef, threshold_delta); + break; + } case SAUVOLA: { binarized = binarizeSauvola(image, window_size, threshold_coef, threshold_delta); @@ -2096,6 +2111,11 @@ OutputGenerator::binarize(QImage const& image, BinaryImage const& mask, const in binarized = binarizeEdgeDiv(image, window_size, threshold_coef, threshold_coef, threshold_delta); break; } + case MSCALE: + { + binarized = binarizeMScale(image, window_size, threshold_coef, threshold_delta); + break; + } } } diff --git a/src/core/filters/output/PictureZonePropDialog.cpp b/src/core/filters/output/PictureZonePropDialog.cpp index 9137ffe..43e297e 100644 --- a/src/core/filters/output/PictureZonePropDialog.cpp +++ b/src/core/filters/output/PictureZonePropDialog.cpp @@ -48,6 +48,8 @@ PictureZonePropDialog::PictureZonePropDialog( connect(ui.eraser1, SIGNAL(toggled(bool)), SLOT(itemToggled(bool))); connect(ui.painter2, SIGNAL(toggled(bool)), SLOT(itemToggled(bool))); connect(ui.eraser3, SIGNAL(toggled(bool)), SLOT(itemToggled(bool))); + + setFixedSize(sizeHint()); } void diff --git a/src/core/filters/output/ui/OutputChangeDewarpingWidget.ui b/src/core/filters/output/ui/OutputChangeDewarpingWidget.ui index 8be0b7e..c99e1e9 100644 --- a/src/core/filters/output/ui/OutputChangeDewarpingWidget.ui +++ b/src/core/filters/output/ui/OutputChangeDewarpingWidget.ui @@ -102,6 +102,12 @@ + + offRB + autoRB + marginalRB + manualRB + diff --git a/src/core/filters/output/ui/OutputOptionsWidget.ui b/src/core/filters/output/ui/OutputOptionsWidget.ui index 511379f..3040108 100644 --- a/src/core/filters/output/ui/OutputOptionsWidget.ui +++ b/src/core/filters/output/ui/OutputOptionsWidget.ui @@ -49,15 +49,9 @@ - - - - 75 - true - - + - value + value @@ -73,7 +67,7 @@ - + 0 0 @@ -81,30 +75,30 @@ 0 - 168 + 0 16777215 - 168 + 16777215 - 3 + 6 0 - 3 + 0 0 - 3 + 0 @@ -135,21 +129,9 @@ - - - - 75 - true - - - - Qt::NoContextMenu - + - value - - - Qt::RichText + value @@ -159,7 +141,7 @@ - 0 + 3 6 @@ -194,7 +176,7 @@ - 0 + 3 6 @@ -235,19 +217,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -264,20 +233,9 @@ - - - - true - - - - Qt::NoContextMenu - + - <a href="#">Apply To...</a> - - - Qt::RichText + Apply To... @@ -308,16 +266,22 @@ + + + 0 + 0 + + 0 - 164 + 0 16777215 - 164 + 16777215 @@ -340,13 +304,13 @@ - 3 + 6 0 - 3 + 0 0 @@ -355,7 +319,11 @@ 0 - + + + 11 + + @@ -469,13 +437,6 @@ - - - - Coef: - - - @@ -492,6 +453,13 @@ + + + + Coef: + + + @@ -513,20 +481,9 @@ - - - - true - - - - Qt::NoContextMenu - + - <a href="#">Apply To...</a> - - - Qt::RichText + Apply To... @@ -562,13 +519,13 @@ - 3 + 6 0 - 3 + 0 0 @@ -685,20 +642,9 @@ - - - - true - - - - Qt::NoContextMenu - + - <a href="#">Apply To...</a> - - - Qt::RichText + Apply To... @@ -731,19 +677,19 @@ - 3 + 6 0 - 3 + 0 0 - 3 + 0 @@ -830,20 +776,9 @@ - - - - true - - - - Qt::NoContextMenu - + - <a href="#">Apply To...</a> - - - Qt::RichText + Apply To... @@ -908,21 +843,9 @@ - - - - 75 - true - - - - Qt::NoContextMenu - + - value - - - Qt::RichText + value @@ -939,7 +862,7 @@ - 0 + 6 0 @@ -1148,20 +1071,9 @@ - - - - true - - - - Qt::NoContextMenu - + - <a href="#">Apply To...</a> - - - Qt::RichText + Apply To... @@ -1274,6 +1186,32 @@ + + dpiValue + modeValue + whiteMarginsCB + equalizeIlluminationCB + autoLayerCB + pictureZonesLayerCB + foregroundLayerCB + applyColorsButton + thresholdMethodSelector + thresholdSlider + thresholdWindowSize + thresholdCoef + applyThresholdButton + thresholdForegroundSlider + applyForegroundThresholdButton + depthPerceptionSlider + applyDepthPerception + dewarpingStatusButton + despeckleOffBtn + despeckleCautiousBtn + despeckleNormalBtn + despeckleAggressiveBtn + applyDespeckleButton + despeckleSlider + diff --git a/src/core/filters/output/ui/PictureZonePropDialog.ui b/src/core/filters/output/ui/PictureZonePropDialog.ui index 6e7da64..fb23e97 100644 --- a/src/core/filters/output/ui/PictureZonePropDialog.ui +++ b/src/core/filters/output/ui/PictureZonePropDialog.ui @@ -35,19 +35,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/core/filters/page_layout/ui/PageLayoutOptionsWidget.ui b/src/core/filters/page_layout/ui/PageLayoutOptionsWidget.ui index aa1e559..6e7f76d 100644 --- a/src/core/filters/page_layout/ui/PageLayoutOptionsWidget.ui +++ b/src/core/filters/page_layout/ui/PageLayoutOptionsWidget.ui @@ -439,12 +439,14 @@ - topBottomLink + unitsComboBox topMarginSpinBox + topBottomLink bottomMarginSpinBox - leftRightLink leftMarginSpinBox + leftRightLink rightMarginSpinBox + autoMargins applyMarginsBtn applyAlignmentBtn diff --git a/src/core/filters/page_layout/ui/alignmentwidget.ui b/src/core/filters/page_layout/ui/alignmentwidget.ui index ed98ba9..4ecae67 100644 --- a/src/core/filters/page_layout/ui/alignmentwidget.ui +++ b/src/core/filters/page_layout/ui/alignmentwidget.ui @@ -510,6 +510,21 @@
filters/page_layout/alignmentwidget.h
+ + alignWithOthersCB + alignTopLeftBtn + alignTopBtn + alignTopRightBtn + alignLeftBtn + alignCenterBtn + alignRightBtn + alignBottomLeftBtn + alignBottomBtn + alignBottomRightBtn + cbAutoMagnet + cbOriginalProp + btnResetAdvAlignment + diff --git a/src/core/filters/page_split/ui/PageSplitOptionsWidget.ui b/src/core/filters/page_split/ui/PageSplitOptionsWidget.ui index 3a7db9a..2342ca8 100644 --- a/src/core/filters/page_split/ui/PageSplitOptionsWidget.ui +++ b/src/core/filters/page_split/ui/PageSplitOptionsWidget.ui @@ -11,7 +11,7 @@
- + 0 0 diff --git a/src/core/filters/select_content/ui/SelectContentOptionsWidget.ui b/src/core/filters/select_content/ui/SelectContentOptionsWidget.ui index b3566d4..b4f6bd8 100644 --- a/src/core/filters/select_content/ui/SelectContentOptionsWidget.ui +++ b/src/core/filters/select_content/ui/SelectContentOptionsWidget.ui @@ -293,6 +293,19 @@
+ + pageDetectDisableBtn + pageDetectAutoBtn + fineTuneBtn + leftBorder + topBorder + rightBorder + bottomBorder + disableBtn + autoBtn + manualBtn + applyToBtn + diff --git a/src/core/settings/globalstaticsettings.cpp b/src/core/settings/globalstaticsettings.cpp index 06484af..c72d9b7 100644 --- a/src/core/settings/globalstaticsettings.cpp +++ b/src/core/settings/globalstaticsettings.cpp @@ -131,7 +131,7 @@ void GlobalStaticSettings::applyAppStyle(const QSettings& settings) int idx = new_qss.indexOf("@path_to_pics@"); if (idx != -1) { -#if defined(_WIN32) or defined(Q_OS_MAC) +#if defined(_WIN32) || defined(Q_OS_MAC) QFileInfo fi(qss_fname); const QString path_to_pix = fi.absolutePath(); diff --git a/src/imageproc/Binarize.cpp b/src/imageproc/Binarize.cpp index 01cbf86..d6d4ccd 100644 --- a/src/imageproc/Binarize.cpp +++ b/src/imageproc/Binarize.cpp @@ -20,7 +20,9 @@ #include "BinaryImage.h" #include "BinaryThreshold.h" #include "Grayscale.h" +#include "GrayImage.h" #include "IntegralImage.h" +#include "ColorFilter.h" #include #include #include @@ -52,6 +54,434 @@ BinaryImage binarizeMokji( return BinaryImage(src, threshold); } +static inline void binarySetBW(uint32_t* bw_line, unsigned int x, bool black) +{ + static uint32_t const msb = uint32_t(1) << 31; + uint32_t const mask = msb >> (x & 31); + if (black) + { + // black + bw_line[x >> 5] |= mask; + } + else + { + // white + bw_line[x >> 5] &= ~mask; + } +} + +BinaryImage binarizeMean(QImage const& src, int const delta) +{ + if (src.isNull()) + { + return BinaryImage(); + } + + GrayImage gray(src); + + unsigned int const w = gray.width(); + unsigned int const h = gray.height(); + uint8_t const* gray_line = gray.data(); + unsigned int const gray_bpl = gray.stride(); + unsigned long int count = 0, countb = 0; + double meanl = 0, mean = 0.0, meanw = 0.0, countw = 0.0; + double dist, dist_mean = 0, threshold = 128; + + for (unsigned int y = 0; y < h; ++y) + { + meanl = 0.0; + for (unsigned int x = 0; x < w; ++x) + { + double const pixel = gray_line[x]; + meanl += pixel; + count++; + } + mean += meanl; + gray_line += gray_bpl; + } + mean = (count > 0) ? (mean / count) : 128.0; + + gray_line = gray.data(); + for (unsigned int y = 0; y < h; ++y) + { + meanl = 0.0; + for (unsigned int x = 0; x < w; ++x) + { + double const pixel = gray_line[x]; + dist = (pixel > mean) ? (pixel - mean) : (mean - pixel); + dist++; + dist = 256.0 / dist; + meanl += (pixel * dist); + countw += dist; + } + meanw += meanl; + gray_line += gray_bpl; + } + meanw = (countw > 0.0) ? (meanw / countw) : 128.0; + + gray_line = gray.data(); + for (unsigned int y = 0; y < h; ++y) + { + meanl = 0.0; + for (unsigned int x = 0; x < w; ++x) + { + double const pixel = gray_line[x]; + dist = (pixel > meanw) ? (pixel - meanw) : (meanw - pixel); + dist *= dist; + meanl += dist; + } + dist_mean += meanl; + gray_line += gray_bpl; + } + dist_mean = (count > 0) ? (dist_mean / count) : 64.0 * 64.0; + threshold = sqrt(dist_mean); + + gray_line = gray.data(); + for (unsigned int y = 0; y < h; ++y) + { + for (unsigned int x = 0; x < w; ++x) + { + double const pixel = gray_line[x]; + dist = (pixel > meanw) ? (pixel - meanw) : (meanw - pixel); + if (dist < threshold) + { + // white + countb++; + } + } + gray_line += gray_bpl; + } + countb += countb; + + BinaryImage bw_img(w, h); + uint32_t* bw_line = bw_img.data(); + unsigned int const bw_wpl = bw_img.wordsPerLine(); + + gray_line = gray.data(); + threshold *= (count < countb) ? (1.0 - (double) delta * 0.02) : (1.0 + (double) delta * 0.02); + for (unsigned int y = 0; y < h; ++y) + { + for (unsigned int x = 0; x < w; ++x) + { + double const pixel = gray_line[x]; + dist = (pixel > meanw) ? (pixel - meanw) : (meanw - pixel); + binarySetBW(bw_line, x, ((dist < threshold) ^ (count < countb))); + } + gray_line += gray_bpl; + bw_line += bw_wpl; + } + + return bw_img; +} // binarizeMean + +BinaryImage binarizeFromMap(GrayImage const& src, GrayImage const& threshold, + unsigned char const lower_bound, unsigned char const upper_bound, int const delta) +{ + if (src.isNull() || threshold.isNull()) + { + return BinaryImage(); + } + + unsigned int const w = src.width(); + unsigned int const h = src.height(); + unsigned int const wt = threshold.width(); + unsigned int const ht = threshold.height(); + + if ((w != wt) || (h != ht)) + { + return BinaryImage(); + } + + uint8_t const* src_line = src.data(); + unsigned int const src_bpl = src.stride(); + uint8_t const* threshold_line = threshold.data(); + unsigned int const threshold_bpl = threshold.stride(); + + BinaryImage bw_img(w, h); + uint32_t* bw_line = bw_img.data(); + unsigned int const bw_wpl = bw_img.wordsPerLine(); + + for (unsigned int y = 0; y < h; ++y) + { + for (unsigned int x = 0; x < w; ++x) + { + binarySetBW(bw_line, x, (src_line[x] < lower_bound || (src_line[x] <= upper_bound && ((int)src_line[x] < ((int)threshold_line[x] + delta))))); + } + src_line += src_bpl; + threshold_line += threshold_bpl; + bw_line += bw_wpl; + } + + return bw_img; +} + +GrayImage binarizeNiblackMap( + GrayImage const& src, QSize const window_size, double const k) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeNiblackMap: invalid window_size"); + } + + if (src.isNull()) + { + return GrayImage(); + } + + GrayImage gray = GrayImage(src); + int const w = src.width(); + int const h = src.height(); + uint8_t const* src_line = src.data(); + int const src_stride = src.stride(); + uint8_t* gray_line = gray.data(); + int const gray_stride = gray.stride(); + + IntegralImage integral_image(w, h); + IntegralImage integral_sqimage(w, h); + + for (int y = 0; y < h; ++y) + { + integral_image.beginRow(); + integral_sqimage.beginRow(); + for (int x = 0; x < w; ++x) + { + uint32_t const pixel = src_line[x]; + integral_image.push(pixel); + integral_sqimage.push(pixel * pixel); + } + src_line += src_stride; + } + + int const window_lower_half = window_size.height() >> 1; + int const window_upper_half = window_size.height() - window_lower_half; + int const window_left_half = window_size.width() >> 1; + int const window_right_half = window_size.width() - window_left_half; + + src_line = src.data(); + for (int y = 0; y < h; ++y) + { + int const top = std::max(0, y - window_lower_half); + int const bottom = std::min(h, y + window_upper_half); // exclusive + + for (int x = 0; x < w; ++x) + { + int const left = std::max(0, x - window_left_half); + int const right = std::min(w, x + window_right_half); // exclusive + int const area = (bottom - top) * (right - left); + assert(area > 0); // because window_size > 0 and w > 0 and h > 0 + + QRect const rect(left, top, right - left, bottom - top); + double const window_sum = integral_image.sum(rect); + double const window_sqsum = integral_sqimage.sum(rect); + + double const r_area = 1.0 / area; + double const mean = window_sum * r_area; + double const sqmean = window_sqsum * r_area; + + double const variance = sqmean - mean * mean; + double const stddev = sqrt(fabs(variance)); + + double threshold = mean - k * stddev; + + threshold = (threshold < 0.0) ? 0.0 : ((threshold < 255.0) ? threshold : 255.0); + gray_line[x] = (uint8_t) threshold; + } + src_line += src_stride; + gray_line += gray_stride; + } + + return gray; +} + +BinaryImage binarizeNiblack( + QImage const& src, QSize const window_size, + double const k, int const delta) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeNiblack: invalid window_size"); + } + + if (src.isNull()) + { + return BinaryImage(); + } + + GrayImage gray(src); + + GrayImage threshold_map(binarizeNiblackMap(gray, window_size, k)); + BinaryImage bw_img(binarizeFromMap(gray, threshold_map, 0, 255, delta)); + + return bw_img; +} + +BinaryImage binarizeGatosCleaner( + GrayImage& wiener, BinaryImage const& niblack, + QSize const window_size) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeGatosPostfilter: invalid window_size"); + } + + if (wiener.isNull() || niblack.isNull()) + { + return niblack; + } + + int const w = wiener.width(); + int const h = wiener.height(); + int const wb = niblack.width(); + int const hb = niblack.height(); + + if ((w != wb) || (h != hb)) + { + return niblack; + } + + IntegralImage niblack_bg_ii(w, h); + IntegralImage wiener_bg_ii(w, h); + + uint32_t const* niblack_line = niblack.data(); + int const niblack_stride = niblack.wordsPerLine(); + uint8_t* wiener_line = wiener.data(); + int const wiener_stride = wiener.stride(); + + for (int y = 0; y < h; ++y) + { + niblack_bg_ii.beginRow(); + wiener_bg_ii.beginRow(); + for (int x = 0; x < w; ++x) + { + // bg: 1, fg: 0 + uint32_t const niblack_inverted_pixel = + (~niblack_line[x >> 5] >> (31 - (x & 31))) & uint32_t(1); + uint32_t const wiener_pixel = wiener_line[x]; + niblack_bg_ii.push(niblack_inverted_pixel); + + // bg: wiener_pixel, fg: 0 + wiener_bg_ii.push(wiener_pixel & ~(niblack_inverted_pixel - uint32_t(1))); + } + wiener_line += wiener_stride; + niblack_line += niblack_stride; + } + + std::vector windows; + for (int scale = 1;; ++scale) + { + windows.emplace_back(0, 0, window_size.width() * scale, window_size.height() * scale); + if (windows.back().width() > w*2 && windows.back().height() > h * 2) + { + // Such a window is enough to cover the whole image when centered + // at any of its corners. + break; + } + } + + // sum(background - original) for foreground pixels according to Niblack. + uint32_t sum_diff = 0; + + // sum(background) pixels for background pixels according to Niblack. + uint32_t sum_bg = 0; + + QRect const image_rect(wiener.rect()); + GrayImage background(wiener); + uint8_t* background_line = background.data(); + int const background_stride = background.stride(); + niblack_line = niblack.data(); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + for (QRect window : windows) + { + window.moveCenter(QPoint(x, y)); + window &= image_rect; + uint32_t const niblack_sum_bg = niblack_bg_ii.sum(window); + if (niblack_sum_bg == 0) + { + // No background pixels in this window. Try a larger one. + continue; + } + + static uint32_t const msb = uint32_t(1) << 31; + if (niblack_line[x >> 5] & (msb >> (x & 31))) + { + // Foreground pixel. Interpolate from background pixels in window. + uint32_t const wiener_sum_bg = wiener_bg_ii.sum(window); + uint32_t const bg = (wiener_sum_bg + (niblack_sum_bg >> 1)) / niblack_sum_bg; + sum_diff += bg - background_line[x]; + background_line[x] = bg; + } + else + { + sum_bg += background_line[x]; + } + + break; + } + } + background_line += background_stride; + niblack_line += niblack_stride; + } + + double const delta = double(sum_diff) / (w*h - niblack_bg_ii.sum(image_rect)); + double const b = double(sum_bg) / niblack_bg_ii.sum(image_rect); + + double const q = 0.6; + double const p1 = 0.5; + double const p2 = 0.8; + + double const exp_scale = -4.0 / (b * (1.0 - p1)); + double const exp_bias = 2.0 * (1.0 + p1) / (1.0 - p1); + double const threshold_scale = q * delta * (1.0 - p2); + double const threshold_bias = q * delta * p2; + + wiener_line = wiener.data(); + background_line = background.data(); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + uint8_t& wiener_pixel = wiener_line[x]; + uint8_t const bg_pixel = background_line[x]; + double const threshold = threshold_scale / + (1.0 + exp(double(bg_pixel) * exp_scale + exp_bias)) + threshold_bias; + wiener_pixel = double(bg_pixel) - double(wiener_pixel) > threshold ? 0x00 : 0xff; + } + wiener_line += wiener_stride; + background_line += background_stride; + } + + return BinaryImage(wiener); +} + +BinaryImage binarizeGatos( + QImage const& src, QSize const window_size, + double const noise_sigma, double const k, int const delta) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeGatos: invalid window_size"); + } + + if (src.isNull()) + { + return BinaryImage(); + } + + GrayImage gray(src); + + int const w = src.width(); + int const h = src.height(); + + GrayImage wiener(wienerFilter(gray, QSize(5, 5), noise_sigma)); + BinaryImage niblack(binarizeNiblack(wiener, window_size, k, delta)); + BinaryImage bw_img(binarizeGatosCleaner(wiener, niblack, window_size)); + + return bw_img; +} + BinaryImage binarizeSauvola(QImage const& src, QSize const window_size, double const k, int const delta) { if (window_size.isEmpty()) { @@ -410,4 +840,184 @@ peakThreshold(QImage const& image) return BinaryImage(image, BinaryThreshold::peakThreshold(image)); } +GrayImage binarizeMScaleMap( + GrayImage const& src, QSize const window_size, double const coef) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeMScaleMap: invalid window_size"); + } + + if (src.isNull()) + { + return GrayImage(); + } + + GrayImage gray = GrayImage(src); + int const w = src.width(); + int const h = src.height(); + uint8_t const* src_line = src.data(); + int const src_bpl = src.stride(); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + unsigned int whcp, l, i, j, blsz, rsz, radius; + double immean, kover, sensitivity, sensdiv, senspos, sensinv; + unsigned int pim, immin, immax, imt, cnth, cntw, level = 0; + unsigned int maskbl, maskover, tim, threshold = 0; + unsigned long int idx; + + radius = (window_size.height() + window_size.width()) >> 1; + whcp = (h + w) >> 1; + blsz = 1; + while (blsz < whcp) + { + level++; + blsz <<= 1; + } + blsz >>= 1; + rsz = 1; + while ((rsz < radius) && (level > 1)) + { + level--; + rsz <<= 1; + } + + gray_line = gray.data(); + immin = gray_line[0]; + immax = immin; + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + pim = gray_line[x]; + if (pim < immin) + { + immin = pim; + } + if (pim > immax) + { + immax = pim; + } + } + gray_line += gray_bpl; + } + immean = (double) (immax + immin); + immean *= 0.5; + immean += 0.5; + tim = (unsigned int) immean; + + gray_line = gray.data(); + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + gray_line[x] = tim; + } + gray_line += gray_bpl; + } + + kover = 1.5; + + if (coef < 0.0) + { + sensitivity = -coef; + sensdiv = sensitivity; + sensdiv += 1.0; + sensinv = 1.0 / sensdiv; + senspos = sensitivity / sensdiv; + } + else + { + sensitivity = coef; + sensdiv = sensitivity; + sensdiv += 1.0; + senspos = 1.0 / sensdiv; + sensinv = sensitivity / sensdiv; + } + + src_line = src.data(); + gray_line = gray.data(); + for (l = 0; l < level; l++) + { + cnth = (h + blsz - 1) / blsz; + cntw = (w + blsz - 1) / blsz; + maskbl = blsz; + maskover = (unsigned int) (kover * maskbl); + for (i = 0; i < cnth; i++) + { + int y0 = i * maskbl; + int y1 = y0 + maskover; + y1 = (y1 < h) ? y1 : h; + for (j = 0; j < cntw; j++) + { + int x0 = j * maskbl; + int x1 = x0 + maskover; + x1 = (x1 < w) ? x1 : w; + + idx = y0 * src_bpl + x0; + immin = src_line[idx]; + immax = immin; + for (int y = y0; y < y1; y++) + { + for (int x = x0; x < x1; x++) + { + idx = y * src_bpl + x; + pim = src_line[idx]; + if (pim < immin) + { + immin = pim; + } + if (pim > immax) + { + immax = pim; + } + } + } + immean = (double) (immax + immin); + immean *= 0.5; + immean *= sensinv; + for (int y = y0; y < y1; y++) + { + for (int x = x0; x < x1; x++) + { + idx = y * gray_bpl + x; + imt = gray_line[idx]; + imt *= senspos; + imt += immean; + imt += 0.5; + imt = (imt < 0.0) ? 0.0 : ((imt < 255.0) ? imt : 255.0); + gray_line[idx] = (uint8_t) imt; + } + } + } + } + blsz >>= 1; + } + + return gray; +} // binarizeMScaleMap + +BinaryImage binarizeMScale( + QImage const& src, QSize const window_size, + double const coef, int const delta) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("binarizeMScale: invalid window_size"); + } + + if (src.isNull()) + { + return BinaryImage(); + } + + GrayImage gray = GrayImage(src); + + GrayImage threshold_map(binarizeMScaleMap(gray, window_size, coef)); + BinaryImage bw_img(binarizeFromMap(gray, threshold_map, 0, 255, delta)); + + return bw_img; +} // binarizeMScale + } // namespace imageproc diff --git a/src/imageproc/Binarize.h b/src/imageproc/Binarize.h index 5e2f35f..99eb396 100644 --- a/src/imageproc/Binarize.h +++ b/src/imageproc/Binarize.h @@ -27,6 +27,7 @@ namespace imageproc { class BinaryImage; +class GrayImage; /** * \brief Image binarization using Otsu's global thresholding method. @@ -36,6 +37,12 @@ class BinaryImage; */ BinaryImage binarizeOtsu(QImage const& src, int delta = 0); +/** + * \brief Image binarization using DeltaMean global thresholding method. + */ +BinaryImage binarizeMean( + QImage const& src, int const delta = 0); + /** * \brief Image binarization using Mokji's global thresholding method. * @@ -53,6 +60,35 @@ BinaryImage binarizeMokji( QImage const& src, unsigned max_edge_width = 3, unsigned min_edge_magnitude = 20); +/** + * \brief Image binarization using Niblack's local thresholding method. + * + * Niblack, Wayne. An introduction to digital image processing. + * Englewood Cliffs, N. J., Prentice Hall (1986) 115-116 + */ +GrayImage binarizeNiblackMap( + GrayImage const& src, QSize window_size, double k = 0.20); +BinaryImage binarizeNiblack( + QImage const& src, QSize window_size, + double k = 0.20, int delta = 0); + +/** + * \brief Image binarization using Gatos' local thresholding method. + * + * This implementation doesn't include the post-processing steps from + * the above paper. + * + * Gatos, Basilios, Ioannis Pratikakis, and Stavros J. Perantonis. + * "An adaptive binarization technique for low quality historical documents." + * Document Analysis Systems VI. Springer Berlin Heidelberg, 2004. 102-113. + */ +BinaryImage binarizeGatosCleaner( + GrayImage& wiener, BinaryImage const& niblack, + QSize const window_size); +BinaryImage binarizeGatos( + QImage const& src, QSize window_size, + double noise_sigma = 3.0, double k = 0.2, int delta = 0); + /** * \brief Image binarization using Sauvola's local thresholding method. * @@ -100,6 +136,19 @@ BinaryImage binarizeEdgeDiv( double kep = 0.5, double kdb = 0.5, int delta = 0); BinaryImage peakThreshold(QImage const& image); + +/** + * \brief Image binarization using MultiScale thresholding method. + * + * MultiScale thresholding method. + */ +GrayImage binarizeMScaleMap( + GrayImage const& src, QSize window_size, + double coef = 0.5); +BinaryImage binarizeMScale( + QImage const& src, QSize window_size, + double coef = 0.5, int delta = 0); + } // namespace imageproc #endif diff --git a/src/imageproc/CMakeLists.txt b/src/imageproc/CMakeLists.txt index 6f72617..a2ee4af 100644 --- a/src/imageproc/CMakeLists.txt +++ b/src/imageproc/CMakeLists.txt @@ -35,6 +35,7 @@ SET( PolynomialSurface.cpp PolynomialSurface.h SavGolKernel.cpp SavGolKernel.h SavGolFilter.cpp SavGolFilter.h + ColorFilter.cpp ColorFilter.h DrawOver.cpp DrawOver.h AdjustBrightness.cpp AdjustBrightness.h SEDM.cpp SEDM.h @@ -54,4 +55,6 @@ SOURCE_GROUP(Sources FILES ${sources}) ADD_LIBRARY(imageproc STATIC ${sources}) QT5_USE_MODULES(imageproc Core Gui) -ADD_SUBDIRECTORY(tests) +IF(ENABLE_TESTS) + ADD_SUBDIRECTORY(tests) +ENDIF() diff --git a/src/imageproc/ColorFilter.cpp b/src/imageproc/ColorFilter.cpp new file mode 100644 index 0000000..f142684 --- /dev/null +++ b/src/imageproc/ColorFilter.cpp @@ -0,0 +1,1377 @@ +/* + Scan Tailor - Interactive post-processing tool for scanned pages. + Copyright (C) 2015 Joseph Artsimovich + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define _USE_MATH_DEFINES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Grayscale.h" +#include "GrayImage.h" +#include "BinaryImage.h" +#include "IntegralImage.h" +#include "BinaryThreshold.h" +#include "ColorFilter.h" + +namespace imageproc +{ + +GrayImage wienerFilter( + GrayImage const& image, QSize const& window_size, float const noise_sigma) +{ + GrayImage dst(image); + wienerFilterInPlace(dst, window_size, noise_sigma); + return dst; +} + +void wienerFilterInPlace( + GrayImage& image, QSize const& window_size, float const noise_sigma) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("wienerFilter: empty window_size"); + } + if (image.isNull()) + { + return; + } + + if (noise_sigma > 0.0f) + { + int const w = image.width(); + int const h = image.height(); + float const noise_variance = noise_sigma * noise_sigma; + + IntegralImage integral_image(w, h); + IntegralImage integral_sqimage(w, h); + + uint8_t* image_line = image.data(); + int const image_stride = image.stride(); + + for (int y = 0; y < h; ++y) + { + integral_image.beginRow(); + integral_sqimage.beginRow(); + for (int x = 0; x < w; ++x) + { + uint32_t const pixel = image_line[x]; + integral_image.push(pixel); + integral_sqimage.push(pixel * pixel); + } + image_line += image_stride; + } + + int const window_lower_half = window_size.height() >> 1; + int const window_upper_half = window_size.height() - window_lower_half; + int const window_left_half = window_size.width() >> 1; + int const window_right_half = window_size.width() - window_left_half; + + image_line = image.data(); + for (int y = 0; y < h; ++y) + { + int const top = ((y - window_lower_half) < 0) ? 0 : (y - window_lower_half); + int const bottom = ((y + window_upper_half) < h) ? (y + window_upper_half) : h; // exclusive + + for (int x = 0; x < w; ++x) + { + int const left = ((x - window_left_half) < 0) ? 0 : (x - window_left_half); + int const right = ((x + window_right_half) < w) ? (x + window_right_half) : w; // exclusive + int const area = (bottom - top) * (right - left); + assert(area > 0); // because window_size > 0 and w > 0 and h > 0 + + QRect const rect(left, top, right - left, bottom - top); + float const window_sum = integral_image.sum(rect); + float const window_sqsum = integral_sqimage.sum(rect); + + float const r_area = 1.0f / area; + float const mean = window_sum * r_area; + float const sqmean = window_sqsum * r_area; + float const variance = sqmean - mean * mean; + + float const src_pixel = (float) image_line[x]; + float const delta_pixel = src_pixel - mean; + float const delta_variance = variance - noise_variance; + float dst_pixel = mean; + if (delta_variance > 0.0f) + { + dst_pixel += delta_pixel * delta_variance / variance; + } + image_line[x] = (uint8_t) (dst_pixel + 0.5f); + } + image_line += image_stride; + } + } +} + +QImage wienerColorFilter( + QImage const& image, QSize const& window_size, float const coef) +{ + QImage dst(image); + wienerColorFilterInPlace(dst, window_size, coef); + return dst; +} + +void wienerColorFilterInPlace( + QImage& image, QSize const& window_size, float const coef) +{ + if (image.isNull()) + { + return; + } + if (window_size.isEmpty()) + { + throw std::invalid_argument("wienerFilter: empty window_size"); + } + + if (coef > 0.0f) + { + int const w = image.width(); + int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + GrayImage wiener(wienerFilter(gray, window_size, 255.0f * coef)); + uint8_t* wiener_line = wiener.data(); + int const wiener_bpl = wiener.stride(); + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + float const origin = gray_line[x]; + float color = wiener_line[x]; + // color = coef * color + (1.0 - coef) * origin; + + float const colscale = (color + 1.0f) / (origin + 1.0f); + float const coldelta = color - origin * colscale; + for (unsigned int c = 0; c < cnum; ++c) + { + int const indx = x * cnum + c; + float origcol = image_line[indx]; + float val = origcol * colscale + coldelta; + val = (val < 0.0f) ? 0.0f : (val < 255.0f) ? val : 255.0f; + image_line[indx] = (uint8_t) (val + 0.5f); + } + } + image_line += image_bpl; + gray_line += gray_bpl; + wiener_line += wiener_bpl; + } + } +} + +QImage knnDenoiserFilter( + QImage const& image, int const radius, float const coef) +{ + QImage dst(image); + knnDenoiserFilterInPlace(dst, radius, coef); + return dst; +} + +void knnDenoiserFilterInPlace( + QImage& image, int const radius, float const coef) +{ + if (image.isNull()) + { + return; + } + + if ((radius > 0) && (coef > 0.0)) + { + float const threshold_weight = 0.02f; + float const threshold_lerp = 0.66f; + float const noise_eps = 0.0000001f; + float const noise_lerpc = 0.16f; + + int const w = image.width(); + int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + IntegralImage integral_image(w, h); + + for (int y = 0; y < h; ++y) + { + integral_image.beginRow(); + for (int x = 0; x < w; ++x) + { + uint32_t const pixel = gray_line[x]; + integral_image.push(pixel); + } + gray_line += gray_bpl; + } + + int const noise_area = ((2 * radius + 1) * (2 * radius + 1)); + float const noise_area_inv = (1.0f / (float) noise_area); + float const noise_weight = (1.0f / (coef * coef)); + float const pixel_weight = (1.0f / 255.0f); + + gray_line = gray.data(); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + float const origin = gray_line[x]; + float f_count = noise_area_inv; + float sum_weights = 1.0f; + float color = origin; + + for (int r = 1; r <= radius; r++) + { + int const top = ((y - r) < 0) ? 0 : (y - r); + int const bottom = ((y + r) < h) ? (y + r) : h; + int const left = ((x - r) < 0) ? 0 : (x - r); + int const right = ((x + r) < w) ? (x + r) : w; + int const area = (bottom - top) * (right - left); + QRect const rect(left, top, right - left, bottom - top); + float const window_sum = integral_image.sum(rect); + float const r_area = 1.0f / area; + float const mean = window_sum * r_area; + float const delta = (origin - mean) * pixel_weight * r; + float const deltasq = delta * delta; + + // Denoising + float r2 = r * r; + float weight_f = expf(-(r2 * noise_area_inv + deltasq * noise_weight)); + float weight_r = (r << 3); + float weight_fr = weight_f * weight_r; + color += mean * weight_fr; + sum_weights += weight_fr; + f_count += (weight_f > threshold_weight) ? (noise_area_inv * weight_r) : 0.0f; + } + + // Normalize result color + sum_weights = (sum_weights > 0.0f) ? (1.0f / sum_weights) : 1.0f; + color *= sum_weights; + + float lerp_q = (f_count > threshold_lerp) ? noise_lerpc : (1.0f - noise_lerpc); + color = color + (origin - color) * lerp_q; + + // Result to memory + color = (color < 0.0f) ? 0.0f : ((color < 255.0f) ? color : 255.0f); + + float const colscale = (color + 1.0f) / (origin + 1.0f); + float const coldelta = color - origin * colscale; + for (unsigned int c = 0; c < cnum; ++c) + { + int const indx = x * cnum + c; + float origcol = image_line[indx]; + float val = origcol * colscale + coldelta; + val = (val < 0.0f) ? 0.0f : (val < 255.0f) ? val : 255.0f; + image_line[indx] = (uint8_t) (val + 0.5f); + } + } + image_line += image_bpl; + gray_line += gray_bpl; + } + } +} + +QImage blurFilter( + QImage const& image, QSize const& window_size, float const coef) +{ + QImage dst(image); + blurFilterInPlace(dst, window_size, coef); + return dst; +} + +void blurFilterInPlace( + QImage& image, QSize const& window_size, float const coef) +{ + if (window_size.isEmpty()) + { + throw std::invalid_argument("blurFilter: empty window_size"); + } + + if (coef != 0.0f) + { + int const w = image.width(); + int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + IntegralImage integral_image(w, h); + + for (int y = 0; y < h; ++y) + { + integral_image.beginRow(); + for (int x = 0; x < w; ++x) + { + uint32_t const pixel = gray_line[x]; + integral_image.push(pixel); + } + gray_line += gray_bpl; + } + + int const window_lower_half = window_size.height() >> 1; + int const window_upper_half = window_size.height() - window_lower_half; + int const window_left_half = window_size.width() >> 1; + int const window_right_half = window_size.width() - window_left_half; + + gray_line = gray.data(); + for (int y = 0; y < h; ++y) + { + int const top = ((y - window_lower_half) < 0) ? 0 : (y - window_lower_half); + int const bottom = ((y + window_upper_half) < h) ? (y + window_upper_half) : h; + for (int x = 0; x < w; ++x) + { + int const left = ((x - window_left_half) < 0) ? 0 : (x - window_left_half); + int const right = ((x + window_right_half) < w) ? (x + window_right_half) : w; + int const area = (bottom - top) * (right - left); + assert(area > 0); // because windowSize > 0 and w > 0 and h > 0 + QRect const rect(left, top, right - left, bottom - top); + float const window_sum = integral_image.sum(rect); + + float const r_area = 1.0 / area; + float const mean = window_sum * r_area; + + float const origin = gray_line[x]; + float retval = coef * mean + (1.0 - coef) * origin; + float const colscale = (retval + 1.0f) / (origin + 1.0f); + float const coldelta = retval - origin * colscale; + for (unsigned int c = 0; c < cnum; ++c) + { + int const indx = x * cnum + c; + float origcol = image_line[indx]; + float val = origcol * colscale + coldelta; + val = (val < 0.0f) ? 0.0f : (val < 255.0f) ? val : 255.0f; + image_line[indx] = (uint8_t) (val + 0.5f); + } + } + image_line += image_bpl; + gray_line += gray_bpl; + } + } +} + +QImage screenFilter( + QImage const& image, QSize const& window_size, float const coef) +{ + QImage dst(image); + screenFilterInPlace(dst, window_size, coef); + return dst; +} + +void screenFilterInPlace( + QImage& image, QSize const& window_size, float const coef) +{ + if (image.isNull()) + { + return; + } + if (window_size.isEmpty()) + { + throw std::invalid_argument("screenFilter: empty window_size"); + } + + if (coef != 0.0f) + { + int const w = image.width(); + int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + IntegralImage integral_image(w, h); + + for (int y = 0; y < h; ++y) + { + integral_image.beginRow(); + for (int x = 0; x < w; ++x) + { + uint32_t const pixel = gray_line[x]; + integral_image.push(pixel); + } + gray_line += gray_bpl; + } + + int const window_lower_half = window_size.height() >> 1; + int const window_upper_half = window_size.height() - window_lower_half; + int const window_left_half = window_size.width() >> 1; + int const window_right_half = window_size.width() - window_left_half; + + size_t histogram[256] = {0}; + size_t szi = (h * w) >> 8; + gray_line = gray.data(); + for (int y = 0; y < h; ++y) + { + int const top = ((y - window_lower_half) < 0) ? 0 : (y - window_lower_half); + int const bottom = ((y + window_upper_half) < h) ? (y + window_upper_half) : h; + for (int x = 0; x < w; ++x) + { + int const left = ((x - window_left_half) < 0) ? 0 : (x - window_left_half); + int const right = ((x + window_right_half) < w) ? (x + window_right_half) : w; + int const area = (bottom - top) * (right - left); + assert(area > 0); // because windowSize > 0 and w > 0 and h > 0 + QRect const rect(left, top, right - left, bottom - top); + float const window_sum = integral_image.sum(rect); + + float const r_area = 1.0f / area; + float const mean = window_sum * r_area; + gray_line[x] = mean; + unsigned int indx = (unsigned int) (mean + 0.5f); + histogram[indx]++; + } + gray_line += gray_bpl; + } + + for (unsigned int i = 1; i < 256; i++) + { + histogram[i] += histogram[i - 1]; + } + for (unsigned int i = 0; i < 256; i++) + { + histogram[i] += (szi >> 1); + histogram[i] /= szi; + histogram[i] = (histogram[i] < 255) ? histogram[i] : 255; + } + + gray_line = gray.data(); + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + float const origin = gray_line[x]; + float const remap = histogram[gray_line[x]]; + float const colscale = (remap + 1.0f) / (origin + 1.0f); + float const coldelta = remap - origin * colscale; + for (unsigned int c = 0; c < cnum; ++c) + { + int const indx = x * cnum + c; + float origcol = image_line[indx]; + float valpos = origcol * colscale + coldelta; + float valneg = 255.0f - valpos; + float retval = origcol * valneg; + retval /= 255.0f; + retval += valpos; + retval = coef * retval + (1.0f - coef) * origcol; + retval = (retval < 0.0f) ? 0.0f : (retval < 255.0f) ? retval : 255.0f; + image_line[indx] = (uint8_t) retval; + } + } + image_line += image_bpl; + gray_line += gray_bpl; + } + } +} + +QImage colorCurveFilter( + QImage& image, float const coef) +{ + QImage dst(image); + colorCurveFilterInPlace(dst, coef); + return dst; +} + +void colorCurveFilterInPlace( + QImage& image, float const coef) +{ + if (image.isNull()) + { + return; + } + + if (coef != 0.0f) + { + int icoef = (int) (coef * 256.0f + 0.5f); + unsigned int const w = image.width(); + unsigned int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + uint8_t pix_replace[256]; + + int thres = BinaryThreshold::otsuThreshold(image); + thres <<= 8; + for (unsigned int j = 0; j < 256; j++) + { + int val = (j << 8); + int delta = (val - thres); + int dsqr = delta * delta; + dsqr = (delta < 0) ? -(dsqr / thres) : (dsqr / (65280 - thres)); + delta -= dsqr; + delta *= icoef; + delta += 128; + delta >>= 8; + val += delta; + val += 128; + val >>= 8; + pix_replace[j] = (uint8_t) val; + } + + for (size_t i = 0; i < (h * image_bpl); i++) + { + uint8_t val = image_line[i]; + image_line[i] = pix_replace[val]; + } + } +} + +QImage colorSqrFilter( + QImage& image, float const coef) +{ + QImage dst(image); + colorSqrFilterInPlace(dst, coef); + return dst; +} + +void colorSqrFilterInPlace( + QImage& image, float const coef) +{ + if (image.isNull()) + { + return; + } + + if (coef != 0.0f) + { + int icoef = (int) (coef * 256.0f + 0.5f); + unsigned int const w = image.width(); + unsigned int const h = image.height(); + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + uint8_t pix_replace[256]; + + for (unsigned int j = 0; j < 256; j++) + { + unsigned int val = j; + val++; + val *= val; + val += 255; + val >>= 8; + val--; + val = icoef * val + (256 - icoef) * j; + val += 128; + val >>= 8; + pix_replace[j] = (uint8_t) val; + } + + for (size_t i = 0; i < (h * image_bpl); i++) + { + uint8_t val = image_line[i]; + image_line[i] = pix_replace[val]; + } + } +} + +GrayImage coloredSignificanceFilter( + QImage const& image, float const coef) +{ + GrayImage dst(image); + coloredSignificanceFilterInPlace(image, dst, coef); + return dst; +} + +void coloredSignificanceFilterInPlace( + QImage const& image, GrayImage& gray, float const coef) +{ + if (image.isNull()) + { + return; + } + if (gray.isNull()) + { + gray = GrayImage(image); + } + + unsigned int const w = image.width(); + unsigned int const h = image.height(); + unsigned int const wg = gray.width(); + unsigned int const hg = gray.height(); + uint8_t const* image_line = (uint8_t const*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + if ((coef != 0.0f) && (w == wg) && (h == hg)) + { + for (unsigned int y = 0; y < h; y++) + { + for (unsigned int x = 0; x < w; x++) + { + QRgb pixel = image.pixel(x, y); + int r = qRed(pixel); + int g = qGreen(pixel); + int b = qBlue(pixel); + int hsv_s, hsv_si; + int max = 0, min = 255; + max = (r < g) ? g : r; + max = (max < b) ? b : max; + min = (r > g) ? g : r; + min = (min > b) ? b : min; + hsv_s = max - min; + hsv_si = 255 - hsv_s; + float retval = coef * (float) hsv_si + (1.0f - coef) * 255.0f; + retval = (retval < 0.0f) ? 0.0f : (retval < 255.0f) ? retval : 255.0f; + gray_line[x] = (uint8_t) retval; + } + gray_line += gray_bpl; + } + } + else + { + for (unsigned int y = 0; y < hg; ++y) + { + for (unsigned int x = 0; x < wg; ++x) + { + gray_line[x] = (uint8_t) 255; + } + gray_line += gray_bpl; + } + } +} + +QImage coloredDimmingFilter( + QImage& image, GrayImage& gray) +{ + QImage dst(image); + coloredSignificanceFilterInPlace(dst, gray); + return dst; +} + +void coloredDimmingFilterInPlace( + QImage& image, GrayImage& gray) +{ + if (image.isNull() || gray.isNull()) + { + return; + } + + unsigned int const w = image.width(); + unsigned int const h = image.height(); + unsigned int const wg = gray.width(); + unsigned int const hg = gray.height(); + + if ((w == wg) && (h == hg)) + { + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + uint8_t const* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + for (unsigned int y = 0; y < h; ++y) + { + for (unsigned int x = 0; x < w; ++x) + { + float ycbcr = gray_line[x]; + for (unsigned int c = 0; c < cnum; ++c) + { + unsigned int const indx = x * cnum + c; + float const origin = image_line[indx]; + float retval = origin; + retval *= (ycbcr + 1.0f); + retval /= 256.0f; + retval = (retval < 0.0f) ? 0.0f : (retval < 255.0f) ? retval : 255.0f; + image_line[indx] = (uint8_t) retval; + } + } + image_line += image_bpl; + gray_line += gray_bpl; + } + } +} + +void coloredMaskInPlace( + QImage& image, BinaryImage content, BinaryImage mask) +{ + if (image.isNull() || content.isNull() || mask.isNull()) + { + return; + } + + unsigned int const w = image.width(); + unsigned int const h = image.height(); + unsigned int const wc = content.width(); + unsigned int const hc = content.height(); + unsigned int const wm = mask.width(); + unsigned int const hm = mask.height(); + + if ((w == wc) && (h == hc) && (w == wm) && (h == hm)) + { + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + uint32_t const* content_line = content.data(); + int const content_wpl = content.wordsPerLine(); + uint32_t const* mask_line = mask.data(); + int const mask_wpl = mask.wordsPerLine(); + + uint32_t const msb = uint32_t(1) << 31; + for (unsigned int y = 0; y < h; ++y) + { + for (unsigned int x = 0; x < w; ++x) + { + if (content_line[x >> 5] & (msb >> (x & 31))) + { + if (!(mask_line[x >> 5] & (msb >> (x & 31)))) + { + for (unsigned int c = 0; c < cnum; ++c) + { + unsigned int const indx = x * cnum + c; + image_line[indx] = (uint8_t) 0; + } + } + } + } + image_line += image_bpl; + content_line += content_wpl; + mask_line += mask_wpl; + } + } +} + +void hsvKMeansInPlace( + QImage& dst, QImage const& image, BinaryImage const& mask, int const ncount, float const coef_sat, float const coef_norm, float const coef_bg) +{ + if (dst.isNull() || image.isNull() || mask.isNull()) + { + return; + } + + if ((ncount > 0) && (ncount < 256)) + { + unsigned int const w = dst.width(); + unsigned int const h = dst.height(); + unsigned int const wi = image.width(); + unsigned int const hi = image.height(); + unsigned int const wm = mask.width(); + unsigned int const hm = mask.height(); + + if ((w != wi) || (h != hi) || (w != wm) || (h != hm)) + { + return; + } + + uint8_t* dst_line = (uint8_t*) dst.bits(); + int const dst_bpl = dst.bytesPerLine(); + unsigned int const dnum = dst_bpl / w; + uint8_t const* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const inum = image_bpl / w; + uint32_t const* mask_line = mask.data(); + int const mask_wpl = mask.wordsPerLine(); + + QImage hsv_img(w, h, QImage::Format_RGB32); + uint8_t* hsv_line = (uint8_t*) hsv_img.bits(); + int const hsv_bpl = hsv_img.bytesPerLine(); + unsigned int const hnum = hsv_bpl / w; + + unsigned long mean_len[256] = {0}; + double mean_h0[256] = {0.0}; + double mean_s0[256] = {0.0}; + double mean_h[256] = {0.0}; + double mean_s[256] = {0.0}; + double mean_v[256] = {0.0}; + + float ctorad = (float)(2.0 * M_PI / 256.0); + uint32_t const msb = uint32_t(1) << 31; + + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + QRgb pixel = image.pixel(x, y); + int r = qRed(pixel); + int g = qGreen(pixel); + int b = qBlue(pixel); + float hsv_h, hsv_s, hsv_v; + int max = 0, min = 255; + max = (r < g) ? g : r; + max = (max < b) ? b : max; + min = (r > g) ? g : r; + min = (min > b) ? b : min; + hsv_h = max - min; + if (hsv_h > 0.0f) + { + if (max == r) + { + hsv_h = (256.0f * (g - b) / hsv_h) / 6.0f; + if (hsv_h < 0.0f) + { + hsv_h += 256.0f; + } + } + else if (max == g) + { + hsv_h = (256.0f * (2.0f + (float) (b - r) / hsv_h)) / 6.0f; + } + else + { + hsv_h = (256.0f * (4.0f + (float) (r - g) / hsv_h)) / 6.0f; + } + } + hsv_s = max - min; + if (max > 0) + { + hsv_s *= 256.0f; + hsv_s /= max; + } + hsv_v = max; + r = (int) (128.0f + 0.5f * hsv_s * cos(hsv_h * ctorad)); // +0.5f for round + r = (r < 0) ? 0 : (r < 255) ? r : 255; + g = (int) (128.0f + 0.5f * hsv_s * sin(hsv_h * ctorad)); // +0.5f for round + g = (g < 0) ? 0 : (g < 255) ? g : 255; + b = (int) (0.5f + hsv_v); // +0.5f for round + b = (b < 0) ? 0 : (b < 255) ? b : 255; + if (!(mask_line[x >> 5] & (msb >> (x & 31)))) + { + mean_h[0] += r; + mean_s[0] += g; + mean_v[0] += b; + mean_len[0]++; + } + rowh[x] = qRgb(r, g, b); + } + mask_line += mask_wpl; + } + + if (mean_len[0] > 0) + { + double mean_bg_part = 1.0 / (double) mean_len[0]; + mean_h[0] *= mean_bg_part; + mean_s[0] *= mean_bg_part; + mean_v[0] *= mean_bg_part; + } + + GrayImage clusters(image); + uint8_t* clusters_line = clusters.data(); + int const clusters_bpl = clusters.stride(); + + float const fk = (ncount > 0) ? (256.0f / (float) ncount) : 0.0f; + for (int i = 1; i <= ncount; i++) + { + float const hsv_h = ((float) i - 0.5f) * fk; + mean_h0[i] = 128.0 * (1.0 + cos(hsv_h * ctorad)); + mean_s0[i] = 128.0 * (1.0 + sin(hsv_h * ctorad)); + mean_h[i] = mean_h0[i]; + mean_s[i] = mean_s0[i]; + mean_v[i] = 255.0; + } + + mask_line = mask.data(); + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + float const hsv_h = qRed(rowh[x]); + float const hsv_s = qGreen(rowh[x]); + float const hsv_v = qBlue(rowh[x]); + float dist_min = 196608.0f; + int indx_min = 0; + for (int k = 1; k <= ncount; k++) + { + float const delta_h = hsv_h - mean_h[k]; + float const delta_s = hsv_s - mean_s[k]; + float const delta_v = hsv_v - mean_v[k]; + float const dist = delta_h * delta_h + delta_s * delta_s + delta_v * delta_v; + if (dist < dist_min) + { + indx_min = k; + dist_min = dist; + } + } + clusters_line[x] = indx_min; + } + } + mask_line += mask_wpl; + clusters_line += clusters_bpl; + } + + for (unsigned int itr = 0; itr < 50; itr++) + { + for (int i = 1; i <= ncount; i++) + { + mean_h[i] = 0.0; + mean_s[i] = 0.0; + mean_v[i] = 0.0; + mean_len[i] = 0; + } + + mask_line = mask.data(); + clusters_line = clusters.data(); + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + int const cluster = clusters_line[x]; + float const hsv_h = qRed(rowh[x]); + float const hsv_s = qGreen(rowh[x]); + float const hsv_v = qBlue(rowh[x]); + mean_h[cluster] += hsv_h; + mean_s[cluster] += hsv_s; + mean_v[cluster] += hsv_v; + mean_len[cluster]++; + } + } + mask_line += mask_wpl; + clusters_line += clusters_bpl; + } + unsigned long changes = 0; + for (int i = 1; i <= ncount; i++) + { + if (mean_len[i] > 0) + { + float const mean_lr = 1.0f / (float) mean_len[i]; + mean_h[i] *= mean_lr; + mean_s[i] *= mean_lr; + mean_v[i] *= mean_lr; + } + else + { + float const hsv_hmc = mean_h0[i]; + float const hsv_hms = mean_s0[i]; + mean_h[i] = hsv_hmc; + mean_s[i] = hsv_hms; + mean_v[i] = 255.0; + + mask_line = mask.data(); + float dist_min = 196608.0f; + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + float const hsv_h = qRed(rowh[x]); + float const hsv_s = qGreen(rowh[x]); + float const hsv_v = qBlue(rowh[x]); + float const delta_h = hsv_h - hsv_hmc; + float const delta_s = hsv_s - hsv_hms; + float const delta_v = 255.0f - hsv_v; + float const dist = delta_h * delta_h + delta_s * delta_s + delta_v * delta_v; + if (dist < dist_min) + { + mean_h[i] = hsv_h; + mean_s[i] = hsv_s; + mean_v[i] = hsv_v; + dist_min = dist; + } + } + } + mask_line += mask_wpl; + } + mean_len[i] = 1; + changes++; + } + } + + mask_line = mask.data(); + clusters_line = clusters.data(); + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + float const hsv_h = qRed(rowh[x]); + float const hsv_s = qGreen(rowh[x]); + float const hsv_v = qBlue(rowh[x]); + float dist_min = 196608.0f; + int indx_min = 0; + for (int k = 1; k <= ncount; k++) + { + float const delta_h = hsv_h - mean_h[k]; + float const delta_s = hsv_s - mean_s[k]; + float const delta_v = hsv_v - mean_v[k]; + float const dist = delta_h * delta_h + delta_s * delta_s + delta_v * delta_v; + if (dist < dist_min) + { + indx_min = k; + dist_min = dist; + } + } + if (indx_min != clusters_line[x]) + { + clusters_line[x] = indx_min; + changes++; + } + } + } + mask_line += mask_wpl; + clusters_line += clusters_bpl; + } + + if (changes == 0) + { + break; + } + } + + for (int k = 0; k <= ncount; k++) + { + float const hsv_hsc = (mean_h[k] - 128.0f) * 2.0f; + float const hsv_hss = (mean_s[k] - 128.0f) * 2.0f; + float const hsv_v = mean_v[k]; + float hsv_h = atan2(hsv_hss, hsv_hsc) / ctorad; + hsv_h = (hsv_h < 0.0f) ? (hsv_h + 256.0f) : hsv_h; + float const hsv_s = sqrt(hsv_hsc * hsv_hsc + hsv_hss * hsv_hss); + mean_h[k] = hsv_h; + mean_s[k] = hsv_s; + } + float min_sat = 512.0f; + float max_sat = 0.0f; + float min_vol = 512.0f; + float max_vol = 0.0f; + for (int k = 0; k <= ncount; k++) + { + min_sat = (mean_s[k] < min_sat) ? mean_s[k] : min_sat; + max_sat = (mean_s[k] > max_sat) ? mean_s[k] : max_sat; + min_vol = (mean_v[k] < min_vol) ? mean_v[k] : min_vol; + max_vol = (mean_v[k] > max_vol) ? mean_v[k] : max_vol; + } + float d_sat = max_sat - min_sat; + float d_vol = max_vol - min_vol; + for (int k = 0; k <= ncount; k++) + { + double sat_new = (d_sat > 0.0f) ? ((mean_s[k] - min_sat) * 255.0f / d_sat) : 255.0f; + sat_new = sat_new * coef_sat + mean_s[k] * (1.0f - coef_sat); + double vol_new = (d_vol > 0.0f) ? ((mean_v[k] - min_vol) * 255.0f / d_vol) : 0.0f; + vol_new = vol_new * coef_norm + mean_v[k] * (1.0f - coef_norm); + mean_s[k] = sat_new; + mean_v[k] = vol_new; + } + for (int k = 0; k <= ncount; k++) + { + int r, g, b; + float const hsv_h = mean_h[k]; + float const hsv_s = mean_s[k]; + float const hsv_v = mean_v[k]; + r = g = b = (int) (hsv_v + 0.5f); + int const i = (int) (hsv_h * 6.0f / 256.0f) % 6; + int const vm = (int) ((256.0f - hsv_s) * hsv_v + 127)/ 256; + int const va = (int) ((hsv_v - vm) * (6.0f * hsv_h - i * 256.0f) + 127)/ 256; + int const vi = vm + va; + int const vd = hsv_v - va; + if (hsv_s > 0.0f) + { + switch (i) + { + default: + case 0: + g = vi; + b = vm; + break; + case 1: + r = vd; + b = vm; + break; + case 2: + r = vm; + b = vi; + break; + case 3: + r = vm; + g = vd; + break; + case 4: + r = vi; + g = vm; + break; + case 5: + g = vm; + b = vd; + break; + } + } + r = (r < 0) ? 0 : (r < 255) ? r : 255; + g = (g < 0) ? 0 : (g < 255) ? g : 255; + b = (b < 0) ? 0 : (b < 255) ? b : 255; + mean_h[k] = r; + mean_s[k] = g; + mean_v[k] = b; + } + mean_h[0] *= coef_bg; + mean_s[0] *= coef_bg; + mean_v[0] *= coef_bg; + mean_h[0] += ((1.0f - coef_bg) * 255.0f); + mean_s[0] += ((1.0f - coef_bg) * 255.0f); + mean_v[0] += ((1.0f - coef_bg) * 255.0f); + + mask_line = mask.data(); + clusters_line = clusters.data(); + for (unsigned int y = 0; y < h; y++) + { + QRgb *rowh = (QRgb*)hsv_img.constScanLine(y); + for (unsigned int x = 0; x < w; x++) + { + int r, g, b; + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + int const cluster = clusters_line[x]; + r = mean_h[cluster]; + g = mean_s[cluster]; + b = mean_v[cluster]; + } + else + { + QRgb const pixel = dst.pixel(x, y); + r = qRed(pixel); + g = qGreen(pixel); + b = qBlue(pixel); + if ((r == 255) && (g == 255) && (b == 255)) + { + r = mean_h[0]; + g = mean_s[0]; + b = mean_v[0]; + } + } + rowh[x] = qRgb(r, g, b); + } + mask_line += mask_wpl; + clusters_line += clusters_bpl; + } + + dst = hsv_img; + } +} + +void maskMorphologicalErode( + QImage& image, BinaryImage const& mask, int const radius) +{ + if (image.isNull() || mask.isNull()) + { + return; + } + + int const w = image.width(); + int const h = image.height(); + + int const wm = mask.width(); + int const hm = mask.height(); + + if ((w != wm) || (h != hm)) + { + return; + } + + if (radius > 0) + { + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + uint32_t const* mask_line = mask.data(); + int const mask_wpl = mask.wordsPerLine(); + uint32_t const msb = uint32_t(1) << 31; + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + int origin = gray_line[x]; + for (int yf = (y - radius); yf <= (y + radius); yf++) + { + if ((yf >= 0) && (yf < h)) + { + uint32_t const* mask_line_f = mask.data(); + mask_line_f += (mask_wpl * yf); + uint8_t* gray_line_f = gray.data(); + gray_line_f += (gray_bpl * yf); + uint8_t* image_line_f = (uint8_t*) image.bits(); + image_line_f += (image_bpl * yf); + for (int xf = (x - radius); xf <= (x + radius); xf++) + { + if ((xf >= 0) && (xf < w)) + { + int const refer = gray_line_f[xf]; + if (mask_line_f[xf >> 5] & (msb >> (xf & 31))) + { + if (origin > refer) + { + for (unsigned int c = 0; c < cnum; c++) + { + image_line[x * cnum + c] = image_line_f[xf * cnum + c]; + } + origin = refer; + } + } + } + } + } + } + } + } + image_line += image_bpl; + gray_line += gray_bpl; + mask_line += mask_wpl; + } + } +} + +void maskMorphologicalDilate( + QImage& image, BinaryImage const& mask, int const radius) +{ + if (image.isNull() || mask.isNull()) + { + return; + } + + int const w = image.width(); + int const h = image.height(); + + int const wm = mask.width(); + int const hm = mask.height(); + + if ((w != wm) || (h != hm)) + { + return; + } + + if (radius > 0) + { + GrayImage gray = GrayImage(image); + uint8_t* gray_line = gray.data(); + int const gray_bpl = gray.stride(); + + uint8_t* image_line = (uint8_t*) image.bits(); + int const image_bpl = image.bytesPerLine(); + unsigned int const cnum = image_bpl / w; + uint32_t const* mask_line = mask.data(); + int const mask_wpl = mask.wordsPerLine(); + uint32_t const msb = uint32_t(1) << 31; + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + if (mask_line[x >> 5] & (msb >> (x & 31))) + { + int origin = gray_line[x]; + for (int yf = (y - radius); yf <= (y + radius); yf++) + { + if ((yf >= 0) && (yf < h)) + { + uint32_t const* mask_line_f = mask.data(); + mask_line_f += (mask_wpl * yf); + uint8_t* gray_line_f = gray.data(); + gray_line_f += (gray_bpl * yf); + uint8_t* image_line_f = (uint8_t*) image.bits(); + image_line_f += (image_bpl * yf); + for (int xf = (x - radius); xf <= (x + radius); xf++) + { + if ((xf >= 0) && (xf < w)) + { + int const refer = gray_line_f[xf]; + if (mask_line_f[xf >> 5] & (msb >> (xf & 31))) + { + if (origin < refer) + { + for (unsigned int c = 0; c < cnum; c++) + { + image_line[x * cnum + c] = image_line_f[xf * cnum + c]; + } + origin = refer; + } + } + } + } + } + } + } + } + image_line += image_bpl; + gray_line += gray_bpl; + mask_line += mask_wpl; + } + } +} + +void maskMorphologicalOpen( + QImage& image, BinaryImage const& mask, int const radius) +{ + if (image.isNull() || mask.isNull()) + { + return; + } + maskMorphologicalErode(image, mask, radius); + maskMorphologicalDilate(image, mask, radius); +} + +void maskMorphologicalClose( + QImage& image, BinaryImage const& mask, int const radius) +{ + if (image.isNull() || mask.isNull()) + { + return; + } + maskMorphologicalDilate(image, mask, radius); + maskMorphologicalErode(image, mask, radius); +} + +void maskMorphological( + QImage& image, BinaryImage const& mask, int const radius) +{ + if (image.isNull() || mask.isNull()) + { + return; + } + if (radius < 0) + { + maskMorphologicalClose(image, mask, -radius); + maskMorphologicalOpen(image, mask, -radius); + } + else + { + maskMorphologicalOpen(image, mask, radius); + maskMorphologicalClose(image, mask, radius); + } +} + +} // namespace imageproc diff --git a/src/imageproc/ColorFilter.h b/src/imageproc/ColorFilter.h new file mode 100644 index 0000000..e3b7764 --- /dev/null +++ b/src/imageproc/ColorFilter.h @@ -0,0 +1,133 @@ +/* + Scan Tailor - Interactive post-processing tool for scanned pages. + Copyright (C) 2015 Joseph Artsimovich + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef IMAGEPROC_COLOR_FILTER_H_ +#define IMAGEPROC_COLOR_FILTER_H_ + +#include + +class QImage; + +namespace imageproc +{ + +class GrayImage; + +/** + * @brief Applies the Wiener filter to a grayscale image. + * + * @param image The image to apply the filter to. A null image is allowed. + * @param window_size The local neighbourhood around a pixel to use. + * @param noise_sigma The standard deviation of noise in the image. + * @return The filtered image. + */ +GrayImage wienerFilter( + GrayImage const& image, QSize const& window_size, float noise_sigma); + +/** + * @brief An in-place version of wienerFilter(). + * @see wienerFilter() + */ +void wienerFilterInPlace( + GrayImage& image, QSize const& window_size, float noise_sigma); + +QImage wienerColorFilter( + QImage const& image, QSize const& window_size, float coef = 0.0f); + +void wienerColorFilterInPlace( + QImage& image, QSize const& window_size, float coef = 0.0f); + +QImage knnDenoiserFilter( + QImage const& image, int radius = 1, float coef = 0.0f); + +void knnDenoiserFilterInPlace( + QImage& image, int radius = 1, float coef = 0.0f); + +QImage blurFilter( + QImage const& image, QSize const& window_size, float coef = 0.0f); + +void blurFilterInPlace( + QImage& image, QSize const& window_size, float coef = 0.0f); + +/** + * @brief Applies the Screen filter to a image. + * + * @param image The image to apply the filter to. A null image is allowed. + * @param window_size The local neighbourhood around a pixel to use. + * @param coef The part of filter in the result. + * @return The filtered image. + */ +QImage screenFilter( + QImage const& image, QSize const& window_size, float coef = 0.0f); + +/** + * @brief An in-place version of screenFilter(). + * @see screenFilter() + */ +void screenFilterInPlace( + QImage& image, QSize const& window_size, float coef = 0.0f); + +QImage colorCurveFilter( + QImage& image, float coef = 0.5f); + +void colorCurveFilterInPlace( + QImage& image, float coef = 0.5f); + +QImage colorSqrFilter( + QImage& image, float coef = 0.5f); + +void colorSqrFilterInPlace( + QImage& image, float coef = 0.5f); + +GrayImage coloredSignificanceFilter( + QImage const& image, float coef = 0.0f); + +void coloredSignificanceFilterInPlace( + QImage const& image, GrayImage& gray, float coef = 0.0f); + +QImage coloredDimmingFilter( + QImage& image, GrayImage& gray); + +void coloredDimmingFilterInPlace( + QImage& image, GrayImage& gray); + +void coloredMaskInPlace( + QImage& image, BinaryImage content, BinaryImage mask); + +void hsvKMeansInPlace( + QImage& dst, QImage const& image, BinaryImage const& mask, int const ncount, + float coef_sat = 0.0f, float coef_norm = 0.0f, float coef_bg = 0.0f); + +void maskMorphologicalErode( + QImage& image, BinaryImage const& mask, int radius = 0); + +void maskMorphologicalDilate( + QImage& image, BinaryImage const& mask, int radius = 0); + +void maskMorphologicalOpen( + QImage& image, BinaryImage const& mask, int radius = 0); + +void maskMorphologicalClose( + QImage& image, BinaryImage const& mask, int radius = 0); + +void maskMorphological( + QImage& image, BinaryImage const& mask, int radius = 0); + +} // namespace imageproc + +#endif diff --git a/src/math/CMakeLists.txt b/src/math/CMakeLists.txt index 77caba9..6d9de5c 100644 --- a/src/math/CMakeLists.txt +++ b/src/math/CMakeLists.txt @@ -45,6 +45,7 @@ SOURCE_GROUP("Sources\\Differentiation Framework" FILES ${ADIFF_SOURCES}) ADD_LIBRARY(math STATIC ${GENERIC_SOURCES} ${SPFIT_SOURCES} ${ADIFF_SOURCES}) QT5_USE_MODULES(math Core) -ADD_SUBDIRECTORY(spfit/tests) -ADD_SUBDIRECTORY(adiff/tests) - +IF(ENABLE_TESTS) + ADD_SUBDIRECTORY(spfit/tests) + ADD_SUBDIRECTORY(adiff/tests) +ENDIF() diff --git a/src/packaging/linux/README b/src/packaging/linux/README deleted file mode 100644 index f0bfa90..0000000 --- a/src/packaging/linux/README +++ /dev/null @@ -1,26 +0,0 @@ -We switched on building deb packets for Linux according to Ubuntu instructions. -In particular: -https://packaging.ubuntu.com/html/getting-set-up.html -https://packaging.ubuntu.com/html/packaging-new-software.html - -Deb packets are supposed to be published on launchpad: https://launchpad.net/~truf/+archive/ubuntu/scantailor-universal - -You can update your system with packages from this untrusted PPA by adding ppa:truf/scantailor-universal to your system's Software Sources: - -sudo add-apt-repository ppa:truf/scantailor-universal -sudo apt-get update - -If you want to build deb packet by himself you may follow instructions. -I'm leaving some key steps here just as a reminder for myself: - -bzr dh-make scantailor-universal 0.2.9 scantailor-universal-0.2.9.tar.gz -cd scantailor-universal/debian/ -rm *.ex *.EX README.* *.docs -cd .. -bzr builddeb -- -us -uc -bzr builddeb -S -cd ../build-area/ -pbuilder-dist bionic build scantailor-universal_0.2.9-0ubuntu1.dsc -gpg --list-secret-keys -debsign -k 2B79FA6A519BF20289519BBCA2F3EBCE5C719A67 scantailor-universal_0.2.9-0ubuntu1_source.changes -dput ppa:truf/scantailor-universal scantailor-universal_0.2.9-0ubuntu1_source.changes diff --git a/src/packaging/linux/README.md b/src/packaging/linux/README.md new file mode 100644 index 0000000..7f24d8d --- /dev/null +++ b/src/packaging/linux/README.md @@ -0,0 +1,163 @@ +# Ho to build the Linux version of Scan Tailor + +## Install Prerequisites + +First, install the following software. +Unless stated otherwise, take the latest stable version. + +Here are the versions with which the 2023 release was built on ubuntu-20.04.6: + +### Required software + +1. **Base build tools** + + ~~~ text + sudo apt install build-essential + ~~~ + +2. **CMake** + + ~~~ text + sudo apt install cmake + ~~~ + +3. **Boost** + + ~~~ text + sudo apt install libboost1.71-dev + sudo apt install libboost-test1.71-dev + ~~~ + +4. **Qt5** + + ~~~ text + sudo apt install qtbase5-dev + sudo apt install qttools5-dev + sudo apt install libqt5svg5-dev + ~~~ + +5. **zlib** + + ~~~ text + sudo apt install zlib1g-dev + ~~~ + +6. **libjpeg** + + ~~~ text + sudo apt install libjpeg-dev + ~~~ + +7. **libpng** + + ~~~ text + sudo apt install libpng-dev + ~~~ + +8. **libtiff** + + ~~~ text + sudo apt install libtiff-dev + ~~~ + +9. **libcanberra** + + ~~~ text + sudo apt install libcanberra-dev + ~~~ + +### Optional software + +1. **OpenJPEG** + + ~~~ text + sudo apt install libopenjp2-7-dev + ~~~ + +2. **Exiv2** + + ~~~ text + sudo apt install libexiv2-dev + ~~~ + +3. **CMake GUI** + + ~~~ text + sudo apt install cmake-qt-gui + ~~~ + +## Build Scan Tailor + +### Create a build directory + +Goto /scantailor directory. + +Unpack scantailor archive to /src subdirectory. + +You should get the following directory structure: + +~~~ text +scantailor/ + └─ src/ + ├─ cmake/ + ├─ debian/ + ├─ src/ + ... + ├─ CMakeLists.txt + ... +~~~ + +From /scantailor directory run commands: + +### Configure + +Configure if optional libraries were installed: + +~~~ text +cmake -S ./src -B ./build -DENABLE_EXIV2:BOOL=ON -DENABLE_OPENJPEG:BOOL=ON +~~~ + +Configure if optional libraries were not installed: + +~~~ text +cmake -S ./src -B ./build -DENABLE_EXIV2:BOOL=OFF -DENABLE_OPENJPEG:BOOL=OFF +~~~ + +You can also configure build using GUI if it is installed: + +~~~ text +cmake-gui +~~~ + +### Build + +~~~ text +cmake --build ./build --config Release --target scantailor-universal --parallel 4 +cmake --build ./build --config Release --target scantailor-universal-cli --parallel 4 +~~~ + +### Build installation package + +You can create a deb installation package: + +~~~ text +cpack -G DEB --config ./build/CPackConfig.cmake -B $(pwd)/pkg +~~~ + +When finished, package will be located in the /pkg directory. + +### Install + +You can also install the program directly: + +~~~ text +cmake --build ./build --config Release --target install +~~~ + +### Build source packages + +~~~ text +cpack -G "TGZ;TXZ" --config ./build/CPackSourceConfig.cmake -B $(pwd)/pkg +~~~ + +When finished, source archives will be located in the /pkg directory. diff --git a/src/packaging/windows/CMakeLists.txt b/src/packaging/windows/CMakeLists.txt deleted file mode 100644 index 210aa51..0000000 --- a/src/packaging/windows/CMakeLists.txt +++ /dev/null @@ -1,164 +0,0 @@ -FIND_PROGRAM( - MAKENSIS_EXE makensis - PATHS "[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\NSIS;InstallLocation]" -) -IF(NOT MAKENSIS_EXE) - MESSAGE( - FATAL_ERROR - "makensis.exe could not be found.\n" - "makensis.exe is a part of NSIS. Get NSIS from http://nsis.sf.net/" - ) -ENDIF(NOT MAKENSIS_EXE) - -IF(MSVC) - GET_FILENAME_COMPONENT(linker_dir "${CMAKE_LINKER}" PATH) - FIND_FILE( - VC_REDIST_DIR VC/redist PATHS "${linker_dir}" - PATH_SUFFIXES .. ../.. ../../../ DOC "VC/redist directory." - ) - IF(VC_REDIST_DIR) - # Get rid of .. components in the path. - GET_FILENAME_COMPONENT(VC_REDIST_DIR "${VC_REDIST_DIR}" ABSOLUTE) - SET(VC_REDIST_DIR "${VC_REDIST_DIR}" CACHE PATH "VC/redist directory." FORCE) - - # x86 vs x64 - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(arch "x64") - ELSE() - SET(arch "x86") - ENDIF() - - # Find CRT redistributables. - FILE(GLOB crt_redist_dirs "${VC_REDIST_DIR}/${arch}/Microsoft.VC*.CRT") - IF(crt_redist_dirs) - LIST(GET crt_redist_dirs 0 CRT_REDIST_PATH) - ENDIF(crt_redist_dirs) - ENDIF(VC_REDIST_DIR) - - IF (NOT CRT_REDIST_PATH) - MESSAGE( - FATAL_ERROR - "Could not find Visual Studio redistributables.\n" - "They are typically located in a directory like:\n" - "C:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\redist\n" - "Please set VC_REDIST_DIR accordinally.\n" - "Specifically, we are after redist\\x86\\Microsoft.VC*.CRT" - ) - ENDIF(NOT CRT_REDIST_PATH) -ENDIF() - -MATH(EXPR bits "${CMAKE_SIZEOF_VOID_P} * 8") -SET(LICENSE_FILE "${CMAKE_SOURCE_DIR}/GPL3.txt") -SET(INSTALLER_FILENAME "scantailor-universal-${VERSION}-${bits}bit-install.exe") -SET(REGISTER_EXTENSION_NSH "${CMAKE_CURRENT_SOURCE_DIR}/registerExtension.nsh") - -SET( - SOURCES - scantailor.nsi.in "${CMAKE_SOURCE_DIR}/cmake/generate_nsi_file.cmake.in" - "${CMAKE_SOURCE_DIR}/cmake/prepare_staging_dir.cmake.in" -) - -SOURCE_GROUP("Sources" FILES ${SOURCES}) -SOURCE_GROUP("Generated" FILES "${CMAKE_BINARY_DIR}/scantailor.nsi") - -CONFIGURE_FILE( - "${CMAKE_SOURCE_DIR}/cmake/prepare_staging_dir.cmake.in" - "${CMAKE_BINARY_DIR}/prepare_staging_dir.cmake" @ONLY -) - -SET(MAYBE_CRASHREPORTER_EXE "") -IF(ENABLE_CRASH_REPORTER) - SET(MAYBE_CRASHREPORTER_EXE "-DCRASHREPORTER_EXE=$") -ENDIF() - -SET(MAYBE_CRT_REDIST_PATH "") -IF(CRT_REDIST_PATH) - SET(MAYBE_CRT_REDIST_PATH "-DCRT_REDIST_PATH=${CRT_REDIST_PATH}") -ENDIF() -ADD_CUSTOM_TARGET( - prepare_staging_dir - COMMAND "${CMAKE_COMMAND}" ARGS -DCFG=$ - "-DCONF_BUILD_DIR=$" - "-DSCANTAILOR_EXE=$" - "-DSCANTAILOR_CLI_EXE=$" - ${MAYBE_CRASHREPORTER_EXE} - ${MAYBE_CRT_REDIST_PATH} - -P "${CMAKE_BINARY_DIR}/prepare_staging_dir.cmake" - DEPENDS "${CMAKE_SOURCE_DIR}/cmake/prepare_staging_dir.cmake.in" - VERBATIM -) -ADD_DEPENDENCIES( - prepare_staging_dir - scantailor-universal scantailor-universal-cli compile_translations -) -IF(ENABLE_CRASH_REPORTER) - ADD_DEPENDENCIES(prepare_staging_dir CrashReporter) -ENDIF() - -SET(extra_deps scantailor compile_translations) - -SET(DUMP_SYMBOLS_COMMANDS "") -IF(ENABLE_CRASH_REPORTER) - LIST(APPEND extra_deps CrashReporter) - SET( - DUMP_SYMBOLS_COMMANDS - COMMAND "${CMAKE_COMMAND}" ARGS -E echo "Dumping symbols..." - - COMMAND "${DUMP_SYMS_EXECUTABLE}" ARGS "$" - ">" "${SYMBOLS_PATH}/temp.sym" - COMMAND "${CMAKE_COMMAND}" ARGS "-DSYMBOLS_PATH=${SYMBOLS_PATH}" - -P "${CMAKE_SOURCE_DIR}/cmake/move_sym_file.cmake" - - COMMAND "${DUMP_SYMS_EXECUTABLE}" ARGS "$" - ">" "${SYMBOLS_PATH}/temp.sym" - COMMAND "${CMAKE_COMMAND}" ARGS "-DSYMBOLS_PATH=${SYMBOLS_PATH}" - -P "${CMAKE_SOURCE_DIR}/cmake/move_sym_file.cmake" - ) -ENDIF(ENABLE_CRASH_REPORTER) - -CONFIGURE_FILE( - "${CMAKE_SOURCE_DIR}/cmake/generate_nsi_file.cmake.in" - "${CMAKE_BINARY_DIR}/generate_nsi_file.cmake" @ONLY -) - -SET( - scantailor_nsi_command - OUTPUT "${CMAKE_BINARY_DIR}/scantailor.nsi" - COMMAND "${CMAKE_COMMAND}" "-DCFG=$" -) -IF(ENABLE_CRASH_REPORTER) - LIST( - APPEND scantailor_nsi_command - "-DCRASHREPORTER_EXE=$" - ) -ENDIF() -LIST( - APPEND scantailor_nsi_command - -P "${CMAKE_BINARY_DIR}/generate_nsi_file.cmake" - DEPENDS scantailor.nsi.in - "${CMAKE_SOURCE_DIR}/cmake/generate_nsi_file.cmake.in" - VERBATIM -) -ADD_CUSTOM_COMMAND(${scantailor_nsi_command}) - -ADD_CUSTOM_COMMAND( - OUTPUT "${INSTALLER_FILENAME}" - ${DUMP_SYMBOLS_COMMANDS} - COMMAND "${MAKENSIS_EXE}" /V2 scantailor.nsi - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - MAIN_DEPENDENCY "${CMAKE_BINARY_DIR}/scantailor.nsi" - DEPENDS ${extra_deps} - VERBATIM -) - -OPTION(BUILD_INSTALLER_BY_DEFAULT "Whether the \"installer\" target gets built by default" ON) -SET(maybe_all "") -IF(BUILD_INSTALLER_BY_DEFAULT) - SET(maybe_all ALL) -ENDIF() -ADD_CUSTOM_TARGET( - installer ${maybe_all} - SOURCES ${SOURCES} - DEPENDS "${INSTALLER_FILENAME}" -) -ADD_DEPENDENCIES(installer prepare_staging_dir) diff --git a/src/packaging/windows/README.md b/src/packaging/windows/README.md new file mode 100644 index 0000000..167ae11 --- /dev/null +++ b/src/packaging/windows/README.md @@ -0,0 +1,625 @@ +# Ho to build the Windows version of Scan Tailor + +## Downloading Prerequisites + +First, download the following software. +Unless stated otherwise, take the latest stable version. + +Here are the versions with which the 2023 release was built: + +### Required software: + +1. **Visual Studio С++ Native Desktop** + + Site: https://visualstudio.microsoft.com/ + + File: Visual Studio Community 2022 + +2. **CMake** + + Site: https://cmake.org/ + + File: cmake-3.27.4-windows-x86_64.msi + +3. **Perl** + + Site: https://strawberryperl.com/ + + File: strawberry-perl-5.32.1.1-64bit.msi + +4. **Jom** + + Site: https://wiki.qt.io/Jom + + File: jom_1_1_4.zip + +5. **Qt5** + + Site: https://www.qt.io/ + + File: qt-everywhere-src-5.12.12.tar.xz + +6. **Boost** + + Site: https://www.boost.org/ + + File: boost_1_83_0.7z + +7. **zlib** + + Site: https://zlib.net/ + + File: zlib-1.3.tar.xz + +8. **libjpeg-turbo** + + Site: https://libjpeg-turbo.org/ + + File: libjpeg-turbo-3.0.0.tar.gz + +9. **libpng** + + Site: http://www.libpng.org/ + + File: libpng-1.6.40.tar.xz + +10. **libtiff** + + Site: http://www.libtiff.org/ + + File: tiff-4.6.0.tar.xz + +### Optional software: + +1. **OpenJPEG** + + Site: https://www.openjpeg.org/ + + File: openjpeg-2.5.0.zip + +2. **Exiv2** + + Site: https://exiv2.org/ + + File: exiv2-0.27.7.zip + +3. **NSIS** + + Site: http://nsis.sourceforge.net/ + + File: nsis-3.09-setup.exe + +## Build Dependencies + +1. **Install software** + + Install **Visual Studio** , **CMake**, **Perl** + Instal **NSIS** (optional) + +2. **Create a build folder** + + From now on this document will be assuming the build folder is D:\Prog\. + + Create folders for all dependencies and for Scan Tailor. + Create version subfolders within dependency folders. + Dependencies will be installed into these subfolders. + You should get a directory structure like this: + + ~~~ text + D:\ + └─ Prog\ + ├─ boost\ + │ └─ 1.83.0\ + ├─ exiv2\ + │ └─ 0.27.7\ + ├─ libjpeg-turbo\ + │ └─ 3.0.0\ + ├─ libpng\ + │ └─ 1.6.40\ + ├─ openjpeg\ + │ └─ 2.5.0\ + ├─ Qt\ + │ └─ 5.12.12\ + ├─ scantailor\ + ├─ tiff\ + │ └─ 4.6.0\ + └─ zlib\ + └─ 1.3\ + ~~~ + +3. **Build boost** + + Unpack boost to his install subfolder. + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ boost\ + └─ 1.83.0\ + ├─ boost\ + ├─ doc\ + ├─ libs\ + ... + ├─ bootstrap.bat + ... + ~~~ + + Go to \boost\1.83.0 directory and run commands: + + ~~~ text + bootstrap.bat + b2.exe variant=release + ~~~ + + After the build is complete, the \bin.v2 folder can be deleted. + +4. **Build Qt** + + Goto \Qt\5.12.12 folder. + + Unpack Qt archive to \src subfolder. + + Unpack jom archive to \jom subfolder. + + Create \build subfolder. + + In the build subfolder, create a build.cmd file with the following contents: + + ~~~ text + @EM Set paths + SET PATH=%CD%\qtbase\bin;%CD%\gnuwin32\bin;%PATH% + + @REM Congigure Qt + ..\src\configure -prefix %CD%\.. -opensource -confirm-license -platform win32-msvc -release -mp -opengl desktop -nomake examples -nomake tests + + @REM Build packages: Core Gui Widgets Xml Network OpenGL Svg + ..\jom\jom module-qtbase + + @REM Build packages: LinguistTools + ..\jom\jom module-qttools + + @REM Build additional image formats + ..\jom\jom module-qtimagefo + + @REM Install packages: Core Gui Widgets Xml Network OpenGL + ..\jom\jom module-qtbase-install_subtargets + + @REM Install packages: LinguistTools + ..\jom\jom module-qttools-install_subtargets + + @REM Install additional image formats + ..\jom\jom module-qtimageformats-install_subtargets + ~~~ + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ Qt\ + └─ 5.12.12\ + ├─ build\ + │ └─ build.cmd + ├─ jom\ + │ └─ jom.exe + └─ src\ + ├─ coin\ + ├─ gnuwin32\ + ... + ├─ qtbase\ + ... + ├─ configure.bat + ... + ~~~ + + From the Start menu, launch the shortcut + "x64 Native Tools Command Prompt for VS 2022". + When the developer console opens, + go to the Qt build folder and run the batch file. + + ~~~ text + D: + CD D:\Prog\Qt\5.12.12\build\ + build.cmd + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ Qt\ + └─ 5.12.12\ + ├─ bin\ + ├─ build\ + ├─ doc\ + ├─ include\ + ├─ jom\ + ├─ lib\ + ├─ mkspecs\ + ├─ phrasebooks\ + ├─ plugins\ + ├─ qml\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +5. Build **zlib** + + Goto \zlib\1.3 folder. + + Unpack zlib archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ zlib\ + └─ 1.3\ + └─ src\ + ├─ amiga\ + ├─ contrib\ + ├─ doc\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From \zlib\1.3 folder folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ zlib\ + └─ 1.3\ + ├─ bin\ + │ └─ zlib.dll + ├─ build\ + ├─ include\ + │ └─ *.h + ├─ lib\ + │ └─ *.lib + ├─ share\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +6. Build **libjpeg-turbo** + + Goto \libjpeg-turbo\3.0.0 folder. + + Unpack \libjpeg-turbo archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ libjpeg-turbo\ + └─ 3.0.0\ + └─ src\ + ├─ cmakescripts\ + ├─ doc\ + ├─ fuzz\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From libjpeg-turbo\3.0.0 folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ libjpeg-turbo\ + └─ 3.0.0\ + ├─ bin\ + │ ├─ jpeg62.dll + │ ... + ├─ build\ + ├─ include\ + │ └─ *.h + ├─ lib\ + │ └─ *.lib + ├─ share\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +7. Build **libpng** + + Goto \libpng\1.6.40 folder. + + Unpack libpng archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ libpng\ + └─ 1.6.40\ + └─ src\ + ├─ arm\ + ├─ ci\ + ├─ contrib\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From \libpng\1.6.40 folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% -DCMAKE_PREFIX_PATH:PATH="d:\Prog\zlib\1.3" + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ libpng + └─ 1.6.40\ + ├─ bin\ + │ ├─ libpng16.dll + │ ... + ├─ build\ + ├─ include\ + │ └─ *.h + ├─ lib\ + │ └─ *.lib + ├─ share\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +8. Build **libtiff** + + Goto \tiff\4.6.0 folder. + + Unpack tiff archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ tiff\ + └─ 4.6.0\ + └─ src\ + ├─ build\ + ├─ cmake\ + ├─ config\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From \tiff\4.6.0 folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% -DCMAKE_PREFIX_PATH:PATH="d:\Prog\zlib\1.3;d:\Prog\libjpeg-turbo\3.0.0" + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ tiff\ + └─ 4.6.0\ + ├─ bin\ + │ ├─ tiff.dll + │ ... + ├─ build\ + ├─ include\ + │ └─ *.h + ├─ lib\ + │ └─ *.lib + ├─ share\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +9. Build **OpenJPEG** (optional) + + Goto \openjpeg\2.5.0 folder. + + Unpack tiff archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ openjpeg\ + └─ 2.5.0\ + └─ src\ + ├─ cmake\ + ├─ doc\ + ├─ scripts\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From \openjpeg\2.5.0 folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% -DBUILD_CODEC:BOOL=FALSE -DCMAKE_PREFIX_PATH:PATH="d:\Prog\zlib\1.3;d:\Prog\libpng\1.6.40;d:\Prog\tiff\4.6.0" + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ openjpeg\ + └─ 2.5.0\ + ├─ bin\ + │ ├─ openjp2.dll + │ ... + ├─ build\ + ├─ include\ + │ └─ openjpeg-2.5\ + │ └─ *.h + ├─ lib\ + │ └─ *.lib + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +10. Build **Exiv2** (optional) + + Goto \exiv2\0.27.7 folder. + + Unpack exiv2 archive to \src subfolder. + + You should get the following folder structure: + + ~~~ text + D:\ + └─ Prog\ + └─ exiv2\ + └─ 0.27.7\ + └─ src\ + ├─ ci\ + ├─ cmake\ + ├─ contrib\ + ... + ├─ CMakeLists.txt + ... + ~~~ + + From \exiv2\0.27.7 folder run commands: + + ~~~ text + cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD% -DEXIV2_ENABLE_WIN_UNICODE:BOOL=ON -DEXIV2_ENABLE_XMP:BOOL=OFF -DEXIV2_ENABLE_PRINTUCS2=OFF -DEXIV2_ENABLE_LENSDATA=OFF -DCMAKE_PREFIX_PATH:PATH="d:\Prog\zlib\1.3" + cmake --build .\build --config Release --target install --parallel 4 + ~~~ + + When finished, the folder structure will look like this: + + ~~~ text + D:\ + └─ Prog\ + └─ exiv2\ + └─ 0.27.7\ + ├─ bin\ + │ ├─ exiv2.dll + │ ... + ├─ build\ + ├─ include\ + │ └─ exiv2 + │ └─ *.h + ├─ lib\ + │ └─ *.lib + ├─ share\ + └─ src\ + ~~~ + + The \build and \src folders can be deleted. + +## Build Scan Tailor + +### Create a build folder + +Goto \scantailor folder. + +Unpack scantailor archive to \src subfolder. + +You should get the following folder structure: + +~~~ text +D:\ +└─ Prog\ + └─ scantailor\ + └─ src\ + ├─ cmake\ + ├─ debian\ + ├─ src\ + ... + ├─ CMakeLists.txt + ... +~~~ + +From \scantailor folder run commands: + +### Configure + +Configure if all libraries were installed: + +~~~ text +cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD%\install -DENABLE_EXIV2:BOOL=ON -DENABLE_OPENGL:BOOL=ON -DENABLE_OPENJPEG:BOOL=ON -DCMAKE_PREFIX_PATH:PATH="d:\Prog\boost\1.83.0;d:\Prog\exiv2\0.27.7;d:\Prog\libjpeg-turbo\3.0.0;d:\Prog\libpng\1.6.40;d:\Prog\openjpeg\2.5.0;d:\Prog\Qt\5.12.12;d:\Prog\tiff\4.6.0;d:\Prog\zlib\1.3" +~~~ + +Configure if optional libraries were not installed: + +~~~ text +cmake -S .\src -B .\build -DCMAKE_INSTALL_PREFIX:PATH=%CD%\install -DENABLE_EXIV2:BOOL=OFF -DENABLE_OPENGL:BOOL=ON -DENABLE_OPENJPEG:BOOL=OFF -DCMAKE_PREFIX_PATH:PATH="d:\Prog\boost\1.83.0;d:\Prog\libjpeg-turbo\3.0.0;d:\Prog\libpng\1.6.40;d:\Prog\Qt\5.12.12;d:\Prog\tiff\4.6.0;d:\Prog\zlib\1.3" +~~~ + +### Build + +~~~ text +cmake --build .\build --config Release --target scantailor-universal --parallel 4 +cmake --build .\build --config Release --target scantailor-universal-cli --parallel 4 +~~~ + +### Install + +~~~ text +cmake --build .\build --config Release --target install --parallel 4 +~~~ + +When finished, the ready-to-use program will be located in the \install folder. + +### Build installation packages + +If NSIS was installed: + +~~~ text +cpack -G "NSIS;ZIP;7Z" --config ./build/CPackConfig.cmake -B %CD%\pkg +~~~ + +If NSIS was not installed: + +~~~ text +cpack -G "ZIP;7Z" --config ./build/CPackConfig.cmake -B %CD%\pkg +~~~ + +When finished, packages will be located in the \pkg folder. + +### Build source package + +~~~ text +cpack -G "ZIP" --config ./build/CPackSourceConfig.cmake -B %CD%\pkg +~~~ + +When finished, source archive will be located in the \pkg folder. diff --git a/src/packaging/windows/build_deps/CMakeLists.txt b/src/packaging/windows/build_deps/CMakeLists.txt deleted file mode 100644 index a85cb3d..0000000 --- a/src/packaging/windows/build_deps/CMakeLists.txt +++ /dev/null @@ -1,647 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.9) - -SET( - CMAKE_USER_MAKE_RULES_OVERRIDE - "${CMAKE_SOURCE_DIR}/../../../../cmake/default_cflags.cmake" -) -SET( - CMAKE_USER_MAKE_RULES_OVERRIDE_CXX - "${CMAKE_SOURCE_DIR}/../../../../cmake/default_cxxflags.cmake" -) - -PROJECT("Scan Tailor Dependencies") - - -INCLUDE(../../../../cmake/SetDefaultBuildType.cmake) -INCLUDE(../../../../cmake/SetDefaultGccFlags.cmake) -INCLUDE(../../../../cmake/ToNativePath.cmake) -INCLUDE(../../../../cmake/PatchFile.cmake) -INCLUDE(TestCXXAcceptsFlag) - -ST_SET_DEFAULT_BUILD_TYPE(Release) -ST_SET_DEFAULT_GCC_FLAGS() - -GET_FILENAME_COMPONENT(source_outer_dir "${PROJECT_SOURCE_DIR}/../../../../.." ABSOLUTE) -GET_FILENAME_COMPONENT(build_outer_dir "${PROJECT_BINARY_DIR}/../.." ABSOLUTE) - -FILE(GLOB jpeg_dirs1 "${build_outer_dir}/jpeg-[0-9]*") -FILE(GLOB jpeg_dirs2 "${source_outer_dir}/jpeg-[0-9]*") -FILE(GLOB zlib_dirs1 "${build_outer_dir}/zlib-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB zlib_dirs2 "${source_outer_dir}/zlib-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB png_dirs1 "${build_outer_dir}/libpng-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB png_dirs2 "${source_outer_dir}/libpng-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB png_dirs3 "${build_outer_dir}/lpng[0-9]*") -FILE(GLOB png_dirs4 "${source_outer_dir}/lpng[0-9]*") -FILE(GLOB tiff_dirs1 "${build_outer_dir}/tiff-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB tiff_dirs2 "${source_outer_dir}/tiff-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB qt_dirs1 "${build_outer_dir}/qt-win-*-5.[0-9]*") -FILE(GLOB qt_dirs2 "${build_outer_dir}/qt-everywhere-*-5.[0-9]*") -FILE(GLOB qt_dirs3 "${source_outer_dir}/qt-win-*-5.[0-9]*") -FILE(GLOB qt_dirs4 "${source_outer_dir}/qt-everywhere-*-5.[0-9]*") -FILE(GLOB qt_dirs5 "C:/Qt/Qt5.*/*/Src") -FILE(GLOB boost_dirs1 "${build_outer_dir}/boost_1_[0-9]*_[0-9]*") -FILE(GLOB boost_dirs2 "${source_outer_dir}/boost_1_[0-9]*_[0-9]*") -FILE(GLOB jpeg2000_dirs1 "${build_outer_dir}/openjpeg-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB jpeg2000_dirs2 "${source_outer_dir}/openjpeg-[0-9]*.[0-9]*.[0-9]*") -FILE(GLOB exiv2_dirs1 "${build_outer_dir}/exiv2-[0-9]*.[0-9]*") -FILE(GLOB exiv2_dirs2 "${source_outer_dir}/exiv2-[0-9]*.[0-9]*") - -FIND_PATH( - JPEG_DIR jpeglib.h HINTS ${jpeg_dirs1} ${jpeg_dirs2} - DOC "Path to jpeg source directory." -) -FIND_PATH( - ZLIB_DIR zlib.h HINTS ${zlib_dirs1} ${zlib_dirs2} - DOC "Path to zlib source directory." -) -FIND_PATH( - PNG_DIR png.h HINTS ${png_dirs1} ${png_dirs2} ${png_dirs3} ${png_dirs4} - DOC "Path to libpng source directory." -) -FIND_PATH( - TIFF_DIR libtiff/tiff.h HINTS ${tiff_dirs1} ${tiff_dirs2} - DOC "Path to top-level tiff source directory." -) -FIND_PATH( - QT_SRC_DIR NAMES qtbase/qtbase.pro HINTS ${qt_dirs1} ${qt_dirs2} - ${qt_dirs3} ${qt_dirs4} ${qt_dirs5} - DOC "Path to top-level Qt5 source directory. If you installed a binary version, it will be something like C:\\Qt\\Qt5.0.2\\5.0.2\\Src" -) -FIND_PATH( - BOOST_DIR boost/foreach.hpp HINTS ${boost_dirs1} ${boost_dirs2} - DOC "Path to top-level Boost source directory." -) -FIND_PATH( - JPEG2000_DIR src/lib/openjp2/openjpeg.h HINTS ${jpeg2000_dirs1} ${jpeg2000_dirs2} - DOC "Path to OpenJPEG source directory." -) -FIND_PATH( - EXIV2_DIR /include/exiv2/exiv2.hpp HINTS ${exiv2_dirs1} ${exiv2_dirs2} - DOC "Path to exiv2 source directory." -) - -IF(NOT JPEG_DIR) - MESSAGE(FATAL_ERROR "JPEG source directory not found. You may specify it manually.") -ELSEIF(NOT ZLIB_DIR) - MESSAGE(FATAL_ERROR "ZLIB source directory not found. You may specify it manually.") -ELSEIF(NOT PNG_DIR) - MESSAGE(FATAL_ERROR "LibPNG source directory not found. You may specify it manually.") -ELSEIF(NOT TIFF_DIR) - MESSAGE(FATAL_ERROR "TIFF source directory not found. You may specify it manually.") -ELSEIF(NOT JPEG2000_DIR) - MESSAGE(FATAL_ERROR "OpenJPEG source directory not found. You may specify it manually.") -ELSEIF(NOT EXIV2_DIR) - MESSAGE(WARNING "Exiv2 source directory not found. You may specify it manually.") -ELSEIF(NOT QT_SRC_DIR) - MESSAGE(FATAL_ERROR "Qt5 source directory not found. You may specify it manually. If you installed a binary version, it will be something like C:\\Qt\\Qt5.0.2\\5.0.2\\Src") -ELSEIF(NOT BOOST_DIR) - MESSAGE(FATAL_ERROR "Boost source directory not found. You may specify it manually.") -ENDIF() - -SET(QTBASE_DIR "${QT_SRC_DIR}/qtbase") - -FILE(GLOB qt_possible_prebuilt_dirs "${QT_SRC_DIR}/../*") -FIND_PATH( - QT_PREBUILT_DIR bin/qmake.exe HINTS ${qt_possible_prebuilt_dirs} - DOC "[optional] Installation path of a pre-built version of Qt5. If you installed a binary version, it will be something like C:\\Qt\\Qt5.0.2\\5.0.2\\msvc2012" -) - -SET(ZLIB_LIBRARY_NAME zdll) -SET(PNG_LIBRARY_NAME libpng) -SET(JPEG_LIBRARY_NAME libjpeg) -SET(TIFF_LIBRARY_NAME libtiff) -SET(JPEG2000_LIBRARY_NAME openjp2) -SET(EXIV2_LIBRARY_NAME exiv2) - -MACRO(LIST_ITEMS_PREPEND LIST PREFIX) - SET(tmp_list_) - FOREACH(item ${${LIST}}) - LIST(APPEND tmp_list_ "${PREFIX}${item}") - ENDFOREACH(item) - SET(${LIST} ${tmp_list_}) -ENDMACRO(LIST_ITEMS_PREPEND) - - -#=================================== JPEG ===================================# - -# Patch jmorecfg.h to: -# 1. Prevent double definition of INT32. -# 2. Build a DLL rather than a static library. -IF(NOT EXISTS "${JPEG_DIR}/jmorecfg.h.orig") - FILE(READ "${JPEG_DIR}/jmorecfg.h" jmorecfg_h_orig) - STRING(REPLACE "XMD_H" "_BASETSD_H" jmorecfg_h "${jmorecfg_h_orig}") - STRING( - REGEX REPLACE "#define[ \t]+GLOBAL\\(type\\)[^\n]*" - "#ifdef JPEG_BUILD\n#define GLOBAL(type) __declspec(dllexport) type\n#else\n#define GLOBAL(type) __declspec(dllimport) type\n#endif" - jmorecfg_h "${jmorecfg_h}" - ) - STRING( - REGEX REPLACE "#define[ \t]+EXTERN\\(type\\)[^\n]*" - "#ifdef JPEG_BUILD\n#define EXTERN(type) extern __declspec(dllexport) type\n#else\n#define EXTERN(type) extern __declspec(dllimport) type\n#endif" - jmorecfg_h "${jmorecfg_h}" - ) - FILE(WRITE "${JPEG_DIR}/jmorecfg.h" "${jmorecfg_h}") - FILE(WRITE "${JPEG_DIR}/jmorecfg.h.orig" "${jmorecfg_h_orig}") - SET(jmorecfg_h "") - SET(jmorecfg_h_orig "") -ENDIF(NOT EXISTS "${JPEG_DIR}/jmorecfg.h.orig") - -SET( - libjpeg_sources - jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c - jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c - jcomapi.c jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c - jdapistd.c jdarith.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c - jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c - jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c - jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c - jquant2.c jutils.c jmemmgr.c jmemnobs.c -) -LIST_ITEMS_PREPEND(libjpeg_sources "${JPEG_DIR}/") - -CONFIGURE_FILE("${JPEG_DIR}/jconfig.vc" "${JPEG_DIR}/jconfig.h" COPYONLY) - -ADD_LIBRARY(${JPEG_LIBRARY_NAME} SHARED ${libjpeg_sources}) -SET_TARGET_PROPERTIES( - ${JPEG_LIBRARY_NAME} PROPERTIES - DEFINE_SYMBOL JPEG_BUILD - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) - - -#=================================== ZLIB ===================================# - -SET( - zlib_sources - adler32.c compress.c crc32.c deflate.c inffast.c inflate.c - inftrees.c trees.c uncompr.c zutil.c -) -LIST_ITEMS_PREPEND(zlib_sources "${ZLIB_DIR}/") - -ADD_LIBRARY(${ZLIB_LIBRARY_NAME} SHARED ${zlib_sources}) -SET_TARGET_PROPERTIES( - ${ZLIB_LIBRARY_NAME} PROPERTIES - DEFINE_SYMBOL ZLIB_DLL - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) - - -#================================== LIBPNG ==================================# - -IF(NOT EXISTS "${PNG_DIR}/pnglibconf.h") - IF(EXISTS "${PNG_DIR}/scripts/pnglibconf.h.prebuilt") - CONFIGURE_FILE( - "${PNG_DIR}/scripts/pnglibconf.h.prebuilt" - "${PNG_DIR}/pnglibconf.h" COPYONLY - ) - ENDIF() -ENDIF() - -INCLUDE_DIRECTORIES(${ZLIB_DIR}) - -SET( - libpng_sources - png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c pngread.c - pngrio.c pngwio.c pngwrite.c pngrtran.c pngwtran.c pngmem.c - pngerror.c pngpread.c -) -LIST_ITEMS_PREPEND(libpng_sources "${PNG_DIR}/") - -ADD_DEFINITIONS(-DPNG_NO_MODULEDEF) -ADD_LIBRARY(${PNG_LIBRARY_NAME} SHARED ${libpng_sources}) -TARGET_LINK_LIBRARIES(${PNG_LIBRARY_NAME} ${ZLIB_LIBRARY_NAME}) -SET_TARGET_PROPERTIES( - ${PNG_LIBRARY_NAME} PROPERTIES - DEFINE_SYMBOL PNG_BUILD_DLL - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) - - -#=================================== TIFF ===================================# - -INCLUDE_DIRECTORIES("${JPEG_DIR}") # ZLIB_DIR already included above - -SET( - libtiff_sources - tif_aux.c tif_close.c tif_codec.c tif_color.c tif_compress.c - tif_dir.c tif_dirinfo.c tif_dirread.c tif_dirwrite.c - tif_dumpmode.c tif_error.c tif_extension.c tif_fax3.c - tif_fax3sm.c tif_getimage.c tif_jpeg.c tif_ojpeg.c tif_flush.c - tif_luv.c tif_lzw.c tif_next.c tif_open.c tif_packbits.c - tif_pixarlog.c tif_predict.c tif_print.c tif_read.c tif_swab.c - tif_strip.c tif_thunder.c tif_tile.c tif_version.c - tif_warning.c tif_write.c tif_zip.c tif_unix.c libtiff.def -) -LIST_ITEMS_PREPEND(libtiff_sources "${TIFF_DIR}/libtiff/") - -SET(tiff_vc_config "${TIFF_DIR}/libtiff/tif_config.vc.h") -IF(EXISTS "${TIFF_DIR}/libtiff/tif_config.h.vc") - SET(tiff_vc_config "${TIFF_DIR}/libtiff/tif_config.h.vc") -ENDIF(EXISTS "${TIFF_DIR}/libtiff/tif_config.h.vc") -CONFIGURE_FILE( - "${tiff_vc_config}" "${TIFF_DIR}/libtiff/tif_config.h" COPYONLY -) -IF(EXISTS "${TIFF_DIR}/libtiff/tiffconf.vc.h") - CONFIGURE_FILE( - "${TIFF_DIR}/libtiff/tiffconf.vc.h" - "${TIFF_DIR}/libtiff/tiffconf.h" COPYONLY - ) -ENDIF(EXISTS "${TIFF_DIR}/libtiff/tiffconf.vc.h") - -SET( - libport_snprintf_sources - dummy.c snprintf.c -) -LIST_ITEMS_PREPEND(libport_snprintf_sources "${TIFF_DIR}/port/") - -ADD_LIBRARY(${TIFF_LIBRARY_NAME} SHARED ${libtiff_sources} ${libport_snprintf_sources}) -TARGET_LINK_LIBRARIES( - ${TIFF_LIBRARY_NAME} - ${PNG_LIBRARY_NAME} ${JPEG_LIBRARY_NAME} ${ZLIB_LIBRARY_NAME} -) -SET_TARGET_PROPERTIES( - ${TIFF_LIBRARY_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) - -target_compile_definitions(${TIFF_LIBRARY_NAME} PRIVATE CCITT_SUPPORT=1 - PACKBITS_SUPPORT=1 - LZW_SUPPORT=1 - THUNDER_SUPPORT=1 - NEXT_SUPPORT=1 - LOGLUV_SUPPORT=1 - MDI_SUPPORT=1 # tries to open MS MDI as Tiff - ZIP_SUPPORT=1 - PIXARLOG_SUPPORT=1 - JPEG_SUPPORT=1 - OJPEG_SUPPORT=1 - #JBIG_SUPPORT=1 - #LZMA_SUPPORT=1 -) - -#=================================== OpenJPEG ===================================# - -SET( - jpeg2000_sources - thread.c bio.c cio.c dwt.c event.c image.c invert.c j2k.c - jp2.c mct.c mqc.c openjpeg.c opj_clock.c pi.c t1.c t2.c - tcd.c tgt.c function_list.c opj_malloc.c sparse_array.c - ) - -LIST_ITEMS_PREPEND(jpeg2000_sources "${JPEG2000_DIR}/src/lib/openjp2/") - -ADD_LIBRARY(${JPEG2000_LIBRARY_NAME} SHARED ${jpeg2000_sources}) -TARGET_LINK_LIBRARIES( ${JPEG2000_LIBRARY_NAME} - ${TIFF_LIBRARY_NAME} ${PNG_LIBRARY_NAME} ${ZLIB_LIBRARY_NAME} -) -SET_TARGET_PROPERTIES( - ${JPEG2000_LIBRARY_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) -set(OPENJPEG_VERSION_MAJOR 2) -set(OPENJPEG_VERSION_MINOR 4) -set(OPENJPEG_VERSION_BUILD 0) -CONFIGURE_FILE(${JPEG2000_DIR}/src/lib/openjp2/opj_config.h.cmake.in "${JPEG2000_DIR}/src/lib/openjp2/opj_config.h" @ONLY) -set(PACKAGE_VERSION - "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}") -set(OPJ_HAVE_INTTYPES_H YES) - -# x86 vs x64 -IF(CMAKE_GENERATOR_TOOLSET EQUAL "x86") -set(_FILE_OFFSET_BITS 32) -ELSE() -set(_FILE_OFFSET_BITS 64) -ENDIF() - -set(OPJ_HAVE_FSEEKO YES) -CONFIGURE_FILE(${JPEG2000_DIR}/src/lib/openjp2/opj_config_private.h.cmake.in "${JPEG2000_DIR}/src/lib/openjp2/opj_config_private.h" @ONLY) - - -#=================================== EXIV2 ===================================# - -SET( - exiv2_cpp_sources - actions.cpp i18n.h rw2image.cpp - actions.hpp image.cpp rw2image_int.cpp - asfvideo.cpp image_int.cpp rw2image_int.hpp - basicio.cpp image_int.hpp safe_op.hpp - bmffimage.cpp ini.cpp samsungmn_int.cpp - bmpimage.cpp iptc.cpp samsungmn_int.hpp - canonmn_int.cpp jp2image.cpp sigmamn_int.cpp - canonmn_int.hpp jpgimage.cpp sigmamn_int.hpp - casiomn_int.cpp makernote_int.cpp sonymn_int.cpp - casiomn_int.hpp makernote_int.hpp sonymn_int.hpp - matroskavideo.cpp ssh.cpp - convert.cpp metadatum.cpp tags.cpp - cr2header_int.cpp minoltamn_int.cpp tags_int.cpp - cr2header_int.hpp minoltamn_int.hpp tags_int.hpp - cr2image.cpp mrwimage.cpp tgaimage.cpp - crwimage.cpp nikonmn_int.cpp tiffcomposite_int.cpp - crwimage_int.cpp nikonmn_int.hpp tiffcomposite_int.hpp - crwimage_int.hpp olympusmn_int.cpp tifffwd_int.hpp - datasets.cpp olympusmn_int.hpp tiffimage.cpp - orfimage.cpp tiffimage_int.cpp - easyaccess.cpp orfimage_int.cpp tiffimage_int.hpp - enforce.hpp orfimage_int.hpp tiffvisitor_int.cpp - epsimage.cpp panasonicmn_int.cpp tiffvisitor_int.hpp - error.cpp panasonicmn_int.hpp timegm.h - exif.cpp pentaxmn_int.cpp - exiv2.cpp pentaxmn_int.hpp types.cpp - exiv2app.hpp pgfimage.cpp tzfile.h - fff.h pngchunk_int.cpp unused.h - fujimn_int.cpp pngchunk_int.hpp utils.cpp - fujimn_int.hpp pngimage.cpp utils.hpp - futils.cpp preview.cpp utilsvideo.cpp - getopt.cpp private.h value.cpp - getopt.hpp properties.cpp version.cpp - gifimage.cpp psdimage.cpp webpimage.cpp - helper_functions.cpp quicktimevideo.cpp xmp.cpp - helper_functions.hpp rafimage.cpp xmpsidecar.cpp - http.cpp riffvideo.cpp -) - -LIST_ITEMS_PREPEND(exiv2_cpp_sources "${EXIV2_DIR}/src/") - -SET( - exiv2_incl_sources - - asfvideo.hpp exif.hpp orfimage.hpp tags.hpp - basicio.hpp exiv2.hpp pgfimage.hpp tgaimage.hpp - bmffimage.hpp futils.hpp pngimage.hpp tiffimage.hpp - bmpimage.hpp gifimage.hpp preview.hpp types.hpp - http.hpp properties.hpp utilsvideo.hpp - config.h image.hpp psdimage.hpp value.hpp - convert.hpp ini.hpp quicktimevideo.hpp version.hpp - cr2image.hpp iptc.hpp rafimage.hpp webpimage.hpp - crwimage.hpp jp2image.hpp riffvideo.hpp xmp_exiv2.hpp - datasets.hpp jpgimage.hpp rw2image.hpp xmpsidecar.hpp - easyaccess.hpp matroskavideo.hpp rwlock.hpp - epsimage.hpp metadatum.hpp slice.hpp - error.hpp mrwimage.hpp ssh.hpp - - -) - -LIST_ITEMS_PREPEND(exiv2_incl_sources "${EXIV2_DIR}/include/exiv2/") - -INCLUDE_DIRECTORIES("${EXIV2_DIR}/include/") -INCLUDE_DIRECTORIES("${EXIV2_DIR}/include/exiv2/") -INCLUDE_DIRECTORIES("${EXIV2_DIR}/contrib/vs2019/solution/") - -SET (exiv2_sources ${exiv2_cpp_sources} ${exiv2_incl_sources}) - -ADD_LIBRARY(${EXIV2_LIBRARY_NAME} SHARED ${exiv2_sources}) -SET_TARGET_PROPERTIES( - ${EXIV2_LIBRARY_NAME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/staging/libs" - ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/staging/libs" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${QTBASE_DIR}/bin" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${QTBASE_DIR}/bin" -) - -TARGET_LINK_LIBRARIES( - ${EXIV2_LIBRARY_NAME} ${ZLIB_LIBRARY_NAME} "psapi.lib" "ws2_32.lib" -) - -target_compile_definitions(${EXIV2_LIBRARY_NAME} PRIVATE _WINDOWS NOMINMAX WIN32_LEAN_AND_MEAN PSAPI_VERSION=1 - BUILD_SHARED_LIBS=1 EXIV2_ENABLE_DYNAMIC_RUNTIME=1 exiv2lib_EXPORTS) - -#================================= Boost ================================# - -IF(MSVC) - SET(boost_toolset msvc) -ELSE() - MESSAGE(FATAL_ERROR "Unsupported platform. Only Visual Studio is currently supported") -ENDIF() - -SET(boost_64bit_flags "") -IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - LIST(APPEND boost_64bit_flags "address-model=64") -ENDIF() - -ADD_CUSTOM_TARGET( - boost ALL - COMMAND cmd /c bootstrap - COMMAND b2 --with-test toolset=${boost_toolset} - threading=multi link=static variant=debug,release ${boost_64bit_flags} - stage - WORKING_DIRECTORY "${BOOST_DIR}" - VERBATIM -) - - -#=================================== Qt ===================================# - -# Backward compatibility. We used to patch projects.pro, but now we achieve -# the same result by other means. -IF(EXISTS "${QTBASE_DIR}/projects.pro.orig") - CONFIGURE_FILE( - "${QTBASE_DIR}/projects.pro.orig" - "${QTBASE_DIR}/projects.pro" COPYONLY - ) - FILE(REMOVE "${QTBASE_DIR}/projects.pro.orig") -ENDIF(EXISTS "${QTBASE_DIR}/projects.pro.orig") - - -TO_NATIVE_PATH("${JPEG_DIR}" JPEG_INCLUDE_DIR) -TO_NATIVE_PATH("${ZLIB_DIR}" ZLIB_INCLUDE_DIR) -TO_NATIVE_PATH("${PNG_DIR}" PNG_INCLUDE_DIR) -TO_NATIVE_PATH("${QTBASE_DIR}" QTBASE_DIR_NATIVE) - - -# Find all *.conf files under mkspecs that mention -Zc:wchar_t- and remove -# that minus at the end. That's necessary to make Qt compatible with other -# libraries that use wchar_t stuff. -FILE(GLOB_RECURSE conf_files "${QTBASE_DIR}/mkspecs/*.conf") -FOREACH(conf_file ${conf_files}) - FILE(READ "${conf_file}" contents) - STRING(REGEX REPLACE "-Zc:wchar_t-" "-Zc:wchar_t" new_contents "${contents}") - IF(NOT "${contents}" STREQUAL "${new_contents}") - # Make a backup copy, if not already there. - IF(NOT EXISTS "${conf_file}.orig") - CONFIGURE_FILE("${conf_file}" "${conf_file}.orig" COPYONLY) - ENDIF() - - FILE(WRITE "${conf_file}" "${new_contents}") - ENDIF() -ENDFOREACH() - -IF(MSVC) - SET(make_command nmake) - IF(MSVC60 OR MSVC70 OR MSVC71 OR MSVC80 OR MSVC90 OR MSVC10 OR MSVC11) - MESSAGE(FATAL_ERROR "This Visual Studio version is too old and is not supported. Supported versions are Visual Studio 2013 or above") - ELSEIF(MSVC12) - SET(platform win32-msvc2013) - SET(force_frame_pointer TRUE) - ELSE() - MESSAGE("A new and unsupported version of Visual Studio was detected. You may proceed, but it may not work. Visual Studio 2013 is strongly recommended") - SET(platform win32-msvc2013) - SET(force_frame_pointer TRUE) - ENDIF() -ELSE() - MESSAGE(FATAL_ERROR "Unsupported compiler. Only Visual Studio 2013 is currently supported.") -ENDIF() - - -IF(MSVC) - # Disable frame pointer ommission in release mode to ensure - # good stack traces from our built-in crash reporter. - PATCH_FILE( - "${QTBASE_DIR}/mkspecs/${platform}/qmake.conf" - - # Add the flag. - "/(QMAKE_CFLAGS_RELEASE[ \t]*=)/\\1 -Oy-/" - - # Get rid of duplicates, in case it was already there. - "/( -Oy-)+/ -Oy-/" - ) -ENDIF() - - -# Force debugging symbols even for release builds. -# Qt5 has a -force-debug-info configure option -# but I had to do the following to make it actually work: -PATCH_FILE( - "${QTBASE_DIR}/.qmake.conf" - - # Put "CONFIG += force_debug_info" at the end. - "/(.)$/\\1\nCONFIG += force_debug_info\n/" -) - - -SET(qt_build_script "${CMAKE_BINARY_DIR}/build-qt.bat") - -SET(maybe_skip_building_tools "") -IF(QT_PREBUILT_DIR) - SET(maybe_skip_building_tools "goto exit") -ENDIF() - - -ADD_CUSTOM_COMMAND( - OUTPUT "${qt_build_script}" - COMMAND "${CMAKE_COMMAND}" - "-DPROJECT_ROOT=${CMAKE_SOURCE_DIR}/../../../.." - "-DTARGET_FILE=${qt_build_script}" - "-DPLATFORM=${platform}" - "-DMAYBE_SKIP_BUILDING_TOOLS=${maybe_skip_building_tools}" - "-DMAKE_COMMAND=${make_command}" - "-DJPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIR}" - "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}" - "-DPNG_INCLUDE_DIR=${PNG_INCLUDE_DIR}" - "-DJPEG_LINK_DIR=$" - "-DZLIB_LINK_DIR=$" - "-DPNG_LINK_DIR=$" - -P "${CMAKE_SOURCE_DIR}/generate_qt_build_script.cmake" - DEPENDS "generate_qt_build_script.cmake" - VERBATIM -) - -ADD_CUSTOM_TARGET( - Qt ALL - COMMAND "${qt_build_script}" - DEPENDS "${qt_build_script}" - WORKING_DIRECTORY "${QTBASE_DIR}" -) - -# boost added so that boost is built before Qt. That's helpful if build -# errors occur, as rebuilding boost is much faster than rebuilding Qt. -ADD_DEPENDENCIES( - Qt ${ZLIB_LIBRARY_NAME} ${JPEG_LIBRARY_NAME} - ${PNG_LIBRARY_NAME} ${TIFF_LIBRARY_NAME} -) - -# If you have multiple versions of Qt installed, this script -# can easily pick the wrong one. -MESSAGE(STATUS "----------------------------") -MESSAGE(STATUS "QT_SRC_DIR is ${QT_SRC_DIR}") -IF(QT_PREBUILT_DIR) - MESSAGE(STATUS "QT_PREBUILT_DIR is ${QT_PREBUILT_DIR}") -ELSE() - MESSAGE(STATUS "QT_PREBUILT_DIR is not set. Using a source-only version of Qt? Fine, but building will take longer.") -ENDIF() -MESSAGE(STATUS "If you've got multiple versions of Qt installed, check we've got the right one.") -MESSAGE(STATUS "----------------------------") - - -# Dump symbols of all DLLs we are going to link to. -OPTION(DUMP_DLL_SYMBOLS "Enable if you are going to build crash reporter." OFF) -IF(DUMP_DLL_SYMBOLS) - FIND_PATH( - SYMBOLS_PATH . PATHS "${build_outer_dir}/symbols" - "${source_outer_dir}/symbols" NO_DEFAULT_PATH - DOC "The directory to write symbol information into." - ) - IF(NOT SYMBOLS_PATH) - MESSAGE(FATAL_ERROR "SYMBOLS_PATH directory is not set.") - ENDIF(NOT SYMBOLS_PATH) - - # We can't build it, because it requires ATL, which is not part - # of the Visual Studio Express Edition, so we rely on a pre-built - # version which can be found in the Mozilla repository. - FIND_PROGRAM( - DUMP_SYMS_EXECUTABLE dump_syms PATHS "${build_outer_dir}" "${source_outer_dir}" - DOC "Path to dump_syms.exe, which can be found in Mozilla repository." - ) - IF(NOT DUMP_SYMS_EXECUTABLE) - MESSAGE( - FATAL_ERROR "dump_syms.exe wasn't found. Specify its location manually by setting the DUMP_SYMS_EXECUTABLE variable. dump_syms.exe may be found in the Mozilla repository under /toolkit/crashreporter/tools/win32" - ) - ENDIF(NOT DUMP_SYMS_EXECUTABLE) - - ADD_CUSTOM_TARGET( - dump_dll_symbols ALL - COMMAND "${CMAKE_COMMAND}" "-DSYMBOLS_PATH=${SYMBOLS_PATH}" - "-DDUMP_SYMS_EXECUTABLE=${DUMP_SYMS_EXECUTABLE}" - "-DMOVE_SYMBOLS_SCRIPT=../../../../cmake/move_sym_file.cmake" - -P "dump_dll_syms.cmake" - DEPENDS "dump_dll_syms.cmake" - WORKING_DIRECTORY "${QTBASE_DIR}/bin" - VERBATIM - ) - - # Qt depends on the rest of them. - ADD_DEPENDENCIES(dump_dll_symbols Qt) -ENDIF() - -#==========================================================================# - -CONFIGURE_FILE(export-vars.cmake.in "${CMAKE_BINARY_DIR}/export-vars.cmake" @ONLY) diff --git a/src/packaging/windows/build_deps/dump_dll_syms.cmake b/src/packaging/windows/build_deps/dump_dll_syms.cmake deleted file mode 100644 index 21e2bba..0000000 --- a/src/packaging/windows/build_deps/dump_dll_syms.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# We are operating on files from the current directory. -FILE(GLOB DLL_FILES "*.dll" "*.DLL") -FOREACH(dll_file ${DLL_FILES}) - MESSAGE(STATUS "Dumping symbols from ${dll_file}") - EXECUTE_PROCESS( - COMMAND "${DUMP_SYMS_EXECUTABLE}" "${dll_file}" - OUTPUT_FILE "${SYMBOLS_PATH}/temp.sym" - ) - EXECUTE_PROCESS( - COMMAND "${CMAKE_COMMAND}" "-DSYMBOLS_PATH=${SYMBOLS_PATH}" - -P "${MOVE_SYMBOLS_SCRIPT}" - ) -ENDFOREACH() diff --git a/src/packaging/windows/build_deps/export-vars.cmake.in b/src/packaging/windows/build_deps/export-vars.cmake.in deleted file mode 100644 index a5b052e..0000000 --- a/src/packaging/windows/build_deps/export-vars.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -SET(JPEG_DIR "@JPEG_DIR@") -SET(ZLIB_DIR "@ZLIB_DIR@") -SET(PNG_DIR "@PNG_DIR@") -SET(TIFF_DIR "@TIFF_DIR@") -SET(JPEG2000_DIR "@JPEG2000_DIR@") -SET(EXIV2_DIR "@EXIV2_DIR@") -SET(BOOST_ROOT "@BOOST_DIR@") -SET(QT_SRC_DIR "@QT_SRC_DIR@") -SET(QT_PREBUILT_DIR "@QT_PREBUILT_DIR@") diff --git a/src/packaging/windows/build_deps/generate_qt_build_script.cmake b/src/packaging/windows/build_deps/generate_qt_build_script.cmake deleted file mode 100644 index 040a9bf..0000000 --- a/src/packaging/windows/build_deps/generate_qt_build_script.cmake +++ /dev/null @@ -1,34 +0,0 @@ -FILE( - WRITE "${TARGET_FILE}" - # Without .gitignore Qt 5 assumes configure.exe is present. - "if not exist configure.exe type nul >>.gitignore" - "\n" - # cmd /c is used because it may be configure.bat, which otherwise wouldn't return control. - "cmd /c configure -platform ${PLATFORM} -debug-and-release -shared -force-debug-info" - " -no-gif -system-zlib -system-libpng -system-libjpeg -qt-imageformat-jpeg -no-openssl" - " -opengl desktop -nomake examples -opensource -confirm-license -no-ltcg -mp" - " -I \"${JPEG_INCLUDE_DIR}\" -I \"${ZLIB_INCLUDE_DIR}\"" - " -I \"${PNG_INCLUDE_DIR}\" -L \"${JPEG_LINK_DIR}\" -L \"${ZLIB_LINK_DIR}\"" - " -L \"${PNG_LINK_DIR}\"" - " -D _BIND_TO_CURRENT_VCLIBS_VERSION=1" - "\n" - "if errorlevel 1 goto exit\n" - "set CL=/MP\n" - "if errorlevel 1 goto exit\n" - "${MAKE_COMMAND}\n" - "if errorlevel 1 goto exit\n" - "cd ..\\qtsvg\n" - "if errorlevel 1 goto exit\n" - "..\\qtbase\\bin\\qmake.exe -makefile -after \"CONFIG += release force_debug_info\" qtsvg.pro\n" - "if errorlevel 1 goto exit\n" - "${MAKE_COMMAND}\n" - "if errorlevel 1 goto exit\n" -# "${MAYBE_SKIP_BUILDING_TOOLS}\n" - "if errorlevel 1 goto exit\n" - "cd ..\\qttools\n" - "if errorlevel 1 goto exit\n" - "..\\qtbase\\bin\\qmake.exe -makefile -after \"CONFIG += release force_debug_info\" qttools.pro\n" - "if errorlevel 1 goto exit\n" - "${MAKE_COMMAND}\n" - ":exit\n" -) diff --git a/src/packaging/windows/patch_libtiff/CMakeLists.txt b/src/packaging/windows/patch_libtiff/CMakeLists.txt deleted file mode 100644 index a57dfe3..0000000 --- a/src/packaging/windows/patch_libtiff/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0) - -PROJECT(patch_libtiff) - -GET_FILENAME_COMPONENT(outer_dir "${PROJECT_SOURCE_DIR}/../../../.." ABSOLUTE) - -FILE(GLOB tiff_dirs "${outer_dir}/tiff-[0-9]*.[0-9]*.[0-9]*") -FIND_PATH( - TIFF_DIR libtiff/tiff.h PATHS ${tiff_dirs} - DOC "Path to top-level tiff source directory." -) - -FIND_PROGRAM( - PATCH_EXE patch - PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32;InstallPath]/bin" - DOC "Full path to patch.exe" -) - -IF(NOT TIFF_DIR) - MESSAGE(FATAL_ERROR "TIFF source directory not found. You may specify it manually.") -ELSEIF(NOT PATCH_EXE) - MESSAGE(FATAL_ERROR "The patch utility wasn't found.") -ENDIF(NOT TIFF_DIR) - -CONFIGURE_FILE( - apply_individual_patches.cmake.in - "${CMAKE_BINARY_DIR}/apply_individual_patches.cmake" @ONLY -) - -ADD_CUSTOM_TARGET( - apply_patches ALL - COMMAND "${CMAKE_COMMAND}" -P - "${CMAKE_BINARY_DIR}/apply_individual_patches.cmake" - WORKING_DIRECTORY "${TIFF_DIR}" -) diff --git a/src/packaging/windows/patch_libtiff/apply_individual_patches.cmake.in b/src/packaging/windows/patch_libtiff/apply_individual_patches.cmake.in deleted file mode 100644 index bcd62dd..0000000 --- a/src/packaging/windows/patch_libtiff/apply_individual_patches.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -FILE(STRINGS "@TIFF_DIR@/debian/patches/series" patch_list) - -FOREACH(patch_file ${patch_list}) - EXECUTE_PROCESS( - COMMAND "@PATCH_EXE@" -p1 --binary -i - "@TIFF_DIR@/debian/patches/${patch_file}" - WORKING_DIRECTORY "@TIFF_DIR@" - ) -ENDFOREACH(patch_file) diff --git a/src/packaging/windows/readme.en.txt b/src/packaging/windows/readme.en.txt deleted file mode 100644 index 5391fac..0000000 --- a/src/packaging/windows/readme.en.txt +++ /dev/null @@ -1,192 +0,0 @@ -This document describes building the Windows version of Scan Tailor. - -Earlier versions of Scan Tailor supported both Visual Studio and MinGW -compilers. MinGW support was dropped at some point, in order to reduce -maintenance effort. Furthermore, Scan Tailor started to use some C++11 -features, making Visual Studio versions below 2013 not supported. - - - Downloading Prerequisites - -First, download the following software. Unless stated otherwise, take the -latest stable version. - -1. Visual Studio Express 2013 for Windows Desktop. (You'll need Update 5 version or upgrade - VS 2013 to Update 5 version. As this update fixes some bugs that could lead to failure while - boost library compilation). - Homepage: http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products -2. CMake >= 2.8.9 - Homepage: http://www.cmake.org -3. jpeg library - Homepage: http://www.ijg.org/ - The file we need will be named jpegsrc.v9.tar.gz or similarly. -4. zlib - Homepage: http://www.zlib.net/ - We need a file named like zlib-x.x.x.tar.gz, where x.x.x represents - the version number. -5. libpng - Homepage: http://www.libpng.org/pub/png/libpng.html - We need a file named like libpng-x.x.x.tar.gz, where x.x.x represents - the version number. -6. libtiff - Homepage: http://www.remotesensing.org/libtiff/ - Because libtiff is updated rarely, but vulnerabilities in it are found often, - it's better to patch it right away. In that case, take it from here: - http://packages.debian.org/source/sid/tiff - There you will find both the original libtiff and a set of patches for it. - The process of patching libtiff is described later in this document. - If you aren't going to distribute your Scan Tailor build and aren't going - to open files from untrusted sources, then you don't really need patching it. -7. Qt 5.x.x (tested with 5.7.1) - Homepage: http://qt-project.org/ - Either a source-only or any of the binary versions will do. In either case - a custom build of Qt will be made, though a binary version will result in - less things to build. -8. ActivePerl (necessary to build Qt5) - Homepage: http://www.activestate.com/activeperl/downloads - A 32-bit version is suggested. Whether or not 64-bit version would work - is unclear. When installing make sure that "Add Perl to the PATH environment - variable" option is set. -9. Boost (tested with 1.70.0) - Homepage: http://boost.org/ - You can download it in any file format, provided you know how to unpack it. -10. NSIS 2.x (tested with 2.46) - Homepage: http://nsis.sourceforge.net/ - - - Instructions - -1. Create a build directory. Its full path should have no spaces. From now on - this document will be assuming the build directory is C:\build - -2. Unpack jpeg, libpng, libtiff, zlib, boost, boost jam, and scantailor - itself to the build directory. You should get a directory structure like - this: - C:\build - | boost_1_70_0 - | jpeg-9c - | libpng-1.6.37 - | scantailor-0.10.0 - | tiff-4.0.10 - | zlib-1.2.11 - - If you went for a source-only version of Qt, unpack it here as well. - Otherwise, install Qt into whatever directory its installer suggests. - IMPORTANT: Tell the installer to install Source Components as well. - - If you don't know how to unpack .tar.gz files, try this tool: - http://www.7-zip.org/ - -3. Install Visual Studio, ActivePerl and CMake. - -4. Create two more subdirectories there: - | scantailor-universal-build - | scantailor-universal-deps-build - -5. Launch CMake and specify the following: - - Where is the source code: C:\build\scantailor-universal\src\packaging\windows\build-deps - Where to build the binaries: C:\build\scantailor-universal-deps-build - - Click "Configure". Select the project type "Visual Studio 12" or - "Visual Studio 12 Win64" for 64-bit builds. Keep in mind that 64-bit - builds are only possible on a 64-bit version of Windows. Visual Studio 12 - is the same as Visual Studio 2013. If any of the paths weren't found, - enter them manually, then click "Configure" again. If everything went right, - the "Generate" button will become clickable. Click it. Sometimes it's - necessary to click "Configure" more than once before "Generate" becomes - clickable. - -6. We will be building Scan Tailor's dependencies here. This step is the - longest one (may take a few hours), but fortunately it only has to be done - once. When building newer versions of Scan Tailor, you won't need to - redo this step. - - Go to C:\build\scantailor-universal-deps-build and open file - "Scan Tailor Dependencies.sln". It will open in Visual Studio. - IMPORTANT: Set the build type to RelWithDebInfo. If you leave Debug - (which is the default), your builds won't run on other computers. - Even with build type set to RelWithDebInfo, some libraries (Qt, boost) - will be built in both debug and release configurations. When building - Scan Tailor itself, the appropriate library configuration will be - selected automatically. - - Now do Build -> Build Solution. - - Make sure the building process finishes without errors. Warnings may - be ignored. - -7. Launch CMake again and specify following: - - Where is the source code: C:\build\scantailor-universal - Where to build the binaries: C:\build\scantailor-universal-build - - Click "Configure", then "Generate", just like on step 5. - - Alternatively from command line (mingw): - cmake -A x64 -S /c/build/scantailor-universal -B /c/build/scantailor-universal-build - or cmake -A win32 -S /c/build/scantailor-universal -B /c/build/scantailor-universal-build - -8. Now we are going to build Scan Tailor itself. On subsequent build of the - same (possiblity modified) version, you can start right from this step. - For building a different version, start from step 7. - - Go to C:\build\scantailor-universal-build and open file "Scan Tailor.sln". - It will open in Visual Studio. Select the desired build type. Debug builds - won't work on other computers. - - Now do Build -> Build Solution - - Make sure the building process finishes without errors. Warnings may - be ignored. - - If everything went right, the installer named scantailor-universal-VERSION-install.exe - will appear in C:\build\scantailor-universal-build. The VERSION part of the name will - be replaced by the actual version, taken from the version.h file in the root - of the source directory. - - - Patching libtiff - -These instructions assume you've got Debian's patches for libtiff from: -http://packages.debian.org/source/sid/tiff -There you will find both the original libtiff sources (filename like -tiff_4.0.10orig.tar.gz) and a patch set for it (filename like -tiff_4.0.10-6.debian.tar.gz). Download both and follow the instructions: - -1. Get the command line patch utility from here: - http://gnuwin32.sourceforge.net/packages/patch.htm - - Better use the version with the installer. In that case CMake will - find the location of patch.exe by itself. - -2. Extract the original libtiff sources into C:\build to get a directory - structure like this: - C:\build - | tiff-4.0.10 - +-- build - | config - | contrib - | ... - - Then extract the patchset inside the tiff directory, to get the "debian" - directory on the same level as "build", "config" and "contrib". - -3. Create another subdirectory under C:\build - Call it "tiff-patch-dir". - -4. Launch CMake and specify the following: - - Where is the source code: C:\build\scantailor-universal\src\packaging\windows\patch_libtiff - Where to build the binaries: C:\build\tiff-patch-dir - - Click "Configure" then "Generate", just like in previous section, step 5. - -5. Go to C:\build\tiff-patch-dir and open file "patch_libtiff.sln". - It will open in Visual Studio. The build type doesn't matter in this case. - - Now do Build -> Build Solution. - - If no errors were reported, you have successfully patched your libtiff. - If you ever need to patch it again, first revert it to the original version, - the one from the .tar.gz file and delete the "debian" subdirectory. diff --git a/src/packaging/windows/readme.ru.txt b/src/packaging/windows/readme.ru.txt deleted file mode 100644 index 37cb3d8..0000000 --- a/src/packaging/windows/readme.ru.txt +++ /dev/null @@ -1,192 +0,0 @@ -This file is in UTF-8 encoding. - -Этот документ описывает процесс сборки Scan Tailor под Windows. - -Ранние версии Scan Tailor поддерживали как Visual Studio так и MinGW. -С какого-то момента времени, поддержка MinGW была убрана, с целью снизить -усилия по сопровождению кода. Кроме того Scan Tailor начал использовать -некоторые возможности стандарта C++11, из-за чего версии Visual Studio -до 2013 перестали поддерживаться. - - - Скачиваем необходимый софт - -Первым делом, нам понадобится нижеследующий софт. Если не указано обратного, -всегда берите последние стабильные версии. - -1. Visual Studio Express 2013 for Windows Desktop. (Требуется версия Update 5 или VS 2013 - должна быть обновлена до неё. В этой версии исправлен баг, который может привести к - невозможности скомпилировать библиотеку boost) - Сайт: http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products -2. CMake >= 2.8.9 - Сайт: http://www.cmake.org -3. jpeg library - Сайт: http://www.ijg.org/ - Нам нужен файл jpegsrc.v9.tar.gz или с похожим именем. -4. zlib - Сайт: http://www.zlib.net/ - Нам нужен файл вида zlib-x.x.x.tar.gz, где x.x.x - номер версии. -5. libpng - Сайт: http://www.libpng.org/pub/png/libpng.html - Нам нужен файл вида libpng-x.x.x.tar.gz, где x.x.x - номер версии. -6. libtiff - Сайт: http://www.remotesensing.org/libtiff/ - Из-за того, что libtiff обновляется редко, а дыры в нем находят часто, лучше - всего будет его сразу же пропатчить. В таком случае брать его нужно отсюда: - http://packages.debian.org/source/sid/tiff - Там и сам libtiff и набор патчей для него. Процесс наложения патчей описан - далее в этом документе. Если вы не собираетесь распространять ваши сборки - Scan Tailor'а и не собираетесь открывать им файлы из сомнительных источников, - тогда можете и не патчить libtiff. -7. Qt 5.x.x (протестировано с Qt 5.7.1) - Cайт: http://download.qt.io/ - Скачивать можно любую бинарную версию (используемый компилятор не важен), - или даже версию только с исходниками. В любом случае будет сделана - специальная сборка Qt, но в первом случае надо будет собирать не так - много вещей, как во втором. -8. ActivePerl (нужно для сборки Qt5) - Сайт: http://www.activestate.com/activeperl/downloads - Рекомендуется ставить 32-битную версию. Будет или нет работать 64-битная - - никто не проверял. При установке убедитесь, что опция "Add Perl to the PATH - environment variable" включена. -8. Boost (протестировано с 170.0) - Сайт: http://boost.org/ - Качайте boost в любом формате, при условии что вы знаете, как этот формат - распаковывать. -9. NSIS 2.x (протестировано с 2.46) - Сайт: http://nsis.sourceforge.net/ - - - Инструкции - -1. Создать директорию сборки. В ее полном пути не должно быть пробелов. - Далее в документе будет предполагаться директория C:\build - -2. Распаковать jpeg-{версия}, libpng, libtiff, zlib, boost, boost jam, и сам - scantailor в директорию сборки. В результате должна получиться примерно - такая структура директорий: - C:\build - | boost_1_70_0 - | jpeg-9c - | libpng-1.6.37 - | scantailor-0.10.0 - | tiff-4.0.10 - | zlib-1.2.11 - - Если брали версию Qt без инсталлятора, распаковываем ее сюда же. - В противном случае ставим Qt в директорию, предлагаемую инсталлятором. - ВАЖНО: инсталлятору нужно указать, чтобы ставил также и исходники - (Source Components). - - Установите также Visual Studio и ActivePerl. - - Если не знаете, чем распаковывать .tar.gz файлы, попробуйте вот этим: - http://www.7-zip.org/ - -3. Установить Visual Studio, ActivePerl и CMake. - -4. Создать там еще пару директорий: - | scantailor-universal-build - | scantailor-universal-deps-build - -5. Запустить CMake и указать следующее: - - Where is the source code: C:\build\scantailor-universal\src\packaging\windows\build-deps - Where to build the binaries: C:\build\scantailor-universal-deps-build - - Жмем "Configure". Выбираем тип проекта "Visual Studio 12" или - "Visual Studio 12 Win64" для 64-битной сборки. Имейте в виду, что 64-битную - сборку можно собрать только на 64-битной версии Windows. Visual Studio 12 - - это то же самое, что Visual Studio 2013. Если какие-то пути не были найдены, - указываем их вручную и жмем "Configure" опять. Если все прошло нормально, - кнопка "Generate" станет активной. Жмем на нее. Имейте в виду, что иногда - нужно нажимать "Configure" несколько раз, прежде чем кнопка "Generate" - станет активной. - -6. На этом шаге мы соберем зависимости Scan Tailor'а. Этот шаг самый длинный - (может занять несколько часов), но к счастью его нужно сделать только один раз, - то есть вам не придется переделывать этот шаг для сборки других версий - Scan Tailor'а. - - Идем в C:\build\scantailor-universal-deps-build и открываем файл - "Scan Tailor Dependencies.sln". Он откроется в Visual Studio. - ВАЖНО: Установите тип сборки в RelWithDebInfo. Если оставите Debug - (выбор по умолчанию), ваши сборки не будут запускаться на других - компьютерах. Несмотря на выставленный RelWithDebInfo, некоторые библиотеки - (Qt, boost) будут собраны и в отладочной и в оптимизированной конфиругации. - При сборке самого Scan Tailor'а, нужная конфигурация библиотек будет выбрана - автоматически. - - Теперь делаем Build -> Build Solution - - Убедитесь, что сборка прошла успещно, то есть количество ошибок (errors) - должно быть нулевым. На предупреждения (warnings) можно не обращать внимания. - -7. Опять запускаем CMake и указываем следующее: - - Where is the source code: C:\build\scantailor-universal - Where to build the binaries: C:\build\scantailor-universal-build - - Жмем "Configure", потом "Generate" - так же, как на шаге 5. - -8. Теперь соберем сам Scan Tailor. При повторной сборки той же версии - (возможно измененной), начинать можно сразу с этот шага (он же и последний). - Для сборки другой версии, начинаем с шага 7. - - Идем в C:\build\scantailor-universal-build и открываем файл "Scan Tailor.sln". - Он откроется в Visual Studio. Выбераем желаемый тип сборки. Сборки типа - Debug не будут запускаться на других компьютерах. - - Теперь делаем Build -> Build Solution - - Если все прошло как надо, в директории C:\build\scantailor-universal-build появится - готовый файл инсталлятора, под именем scantailor-universal-VERSION-install.exe, где - вместо VERSION будет версия сборки, которая берется из файла version.h - в корне дерева исходников. - - - Патчим libtiff - -Эти инструкции предполагают, что вы взяли Debian'овские патчи к libtiff: -http://packages.debian.org/source/sid/tiff -Там вы найдете и оригинальные исходники libtiff (имя файла типа -tiff_4.0.2.orig.tar.gz) и набор патчей для него (имя файла типа -tiff_4.0.2-6.debian.tar.gz). Скачайте оба и следуйте инструкциям: - -1. Скачать и установить утилиту коммандной строки Patch: - http://gnuwin32.sourceforge.net/packages/patch.htm - - Лучше берите версию с инсталлятором. В этом случае CMake сможет - самостоятельно найти путь к patch.exe - -2. Распаковать оригинальные исходники libtiff в C:\build, чтобы получилась - такая структура директорий: - C:\build - | tiff-4.0.10 - +-- build - | config - | contrib - | ... - - Набор патчей распаковываем внутрь директории "tiff-*.*.*", чтобы получить - директорию "debian" на одном уровне с "build", "config" и "contrib". - -3. Создать еще одну поддиректорию в C:\build - Назовем ее "tiff-patch-dir". - -4. Запустить CMake и указать следующее: - - Where is the source code: C:\build\scantailor-universal\src\packaging\windows\patch_libtiff - Where to build the binaries: C:\build\tiff-patch-dir - - Жмем "Configure", затем "Generate", как описано в предыдущей секции, пункт 5. - -5. Идем в C:\build\tiff-patch-dir и открываем файл "patch_libtiff.sln". - Он откроется в Visual Studio. Тип сборки в данном случае значения не имеет. - - Теперь делаем Build -> Build Solution - - Если ошибок не было, значит вы успешно пропатчили libtiff. Если когда-либо - вам понадобится пропатчить его снова, сначала придется привести его в - исходное состояние, то есть заново распаковать его из .tar.gz файла и - снести директорию "debian". diff --git a/src/packaging/windows/registerExtension.nsh b/src/packaging/windows/registerExtension.nsh deleted file mode 100644 index f203008..0000000 --- a/src/packaging/windows/registerExtension.nsh +++ /dev/null @@ -1,66 +0,0 @@ -; From http://nsis.sourceforge.net/File_Association -; Added a parameter to set icon for association -Brendan Kidwell - -!define registerExtension "!insertmacro registerExtension" -!define unregisterExtension "!insertmacro unregisterExtension" - -!macro registerExtension executable extension description icon - Push "${executable}" ; "full path to my.exe" - Push "${extension}" ; ".mkv" - Push "${description}" ; "MKV File" - Push "${icon}" ; "name.ico" - Call registerExtension -!macroend - -; back up old value of .opt -Function registerExtension -!define Index "Line${__LINE__}" - pop $R3 ; icon path - pop $R0 ; ext name - pop $R1 - pop $R2 - push $1 - push $0 - ReadRegStr $1 HKCR $R1 "" - StrCmp $1 "" "${Index}-NoBackup" - StrCmp $1 "OptionsFile" "${Index}-NoBackup" - WriteRegStr HKCR $R1 "backup_val" $1 -"${Index}-NoBackup:" - WriteRegStr HKCR $R1 "" $R0 - ReadRegStr $0 HKCR $R0 "" - StrCmp $0 "" 0 "${Index}-Skip" - WriteRegStr HKCR $R0 "" $R0 - WriteRegStr HKCR "$R0\shell" "" "open" - WriteRegStr HKCR "$R0\DefaultIcon" "" "$R3,0" -"${Index}-Skip:" - WriteRegStr HKCR "$R0\shell\open\command" "" '"$R2" "%1"' - WriteRegStr HKCR "$R0\shell\edit" "" "Edit $R0" - WriteRegStr HKCR "$R0\shell\edit\command" "" '"$R2" "%1"' - pop $0 - pop $1 -!undef Index -FunctionEnd - -!macro unregisterExtension extension description - Push "${extension}" ; ".mkv" - Push "${description}" ; "MKV File" - Call un.unregisterExtension -!macroend - -Function un.unregisterExtension - pop $R1 ; description - pop $R0 ; extension -!define Index "Line${__LINE__}" - ReadRegStr $1 HKCR $R0 "" - StrCmp $1 $R1 0 "${Index}-NoOwn" ; only do this if we own it - ReadRegStr $1 HKCR $R0 "backup_val" - StrCmp $1 "" 0 "${Index}-Restore" ; if backup="" then delete the whole key - DeleteRegKey HKCR $R0 - Goto "${Index}-NoOwn" -"${Index}-Restore:" - WriteRegStr HKCR $R0 "" $1 - DeleteRegValue HKCR $R0 "backup_val" - DeleteRegKey HKCR $R1 ;Delete key with association name settings -"${Index}-NoOwn:" -!undef Index -FunctionEnd \ No newline at end of file diff --git a/src/packaging/windows/scantailor.nsi.in b/src/packaging/windows/scantailor.nsi.in deleted file mode 100644 index 0357105..0000000 --- a/src/packaging/windows/scantailor.nsi.in +++ /dev/null @@ -1,155 +0,0 @@ -!define VERSION "@VERSION@" -!define VERSION_QUAD "@VERSION_QUAD@" -!define LICENSE_FILE "@LICENSE_FILE@" -!define INSTALLER_FILENAME "@INSTALLER_FILENAME@" -!define STAGING_DIR "@STAGING_DIR@" -!define UNINST_REGKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Scan Tailor Universal" - -# The window identifier of the main Scan Tailor window. -!define WNDCLASS "ScanTailor_Window" - -!include "@REGISTER_EXTENSION_NSH@" -!include "x64.nsh" -!include "MUI2.nsh" -!include "LogicLib.nsh" - -BrandingText " " # To remove the mention of NullSoft. -#LoadLanguageFile "${NSISDIR}\Contrib\Language files\Russian.nlf" - -Name "Scan Tailor Universal version ${VERSION}" - -OutFile "${INSTALLER_FILENAME}" - -!if "@SIZEOF_VOID_PTR@" == "8" -InstallDir "$PROGRAMFILES64\Scan Tailor Universal" -!else -InstallDir "$PROGRAMFILES\Scan Tailor Universal" -!endif - -InstallDirRegKey HKLM "${UNINST_REGKEY}" "InstallLocation" - -RequestExecutionLevel admin - -XPStyle on - -AllowSkipFiles off - -SetCompressor /SOLID /FINAL lzma - -!if "${VERSION_QUAD}" != "" - VIAddVersionKey "ProductName" "Scan Tailor Universal" - VIAddVersionKey "ProductVersion" "${VERSION}" - VIAddVersionKey "Comments" "Interactive post-processing tool for scanned pages." - VIAddVersionKey "CompanyName" "Joseph Artsimovich" - VIAddVersionKey "LegalTrademarks" "" - VIAddVersionKey "LegalCopyright" "� Joseph Artsimovich et al." - VIAddVersionKey "FileDescription" "Post-processing tool for scanned pages." - VIAddVersionKey "FileVersion" "${VERSION}" - VIProductVersion "${VERSION_QUAD}" -!endif - -!define MUI_ABORTWARNING - -# Installer Pages -!insertmacro MUI_PAGE_LICENSE "${LICENSE_FILE}" -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES - -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -!insertmacro MUI_LANGUAGE "English" - -!if "@SIZEOF_VOID_PTR@" == "8" -Function .onInit - ${IfNot} ${RunningX64} - MessageBox MB_ICONSTOP|MB_OK "A 64-bit version of Scan Tailor Universal won't work on a 32-bit version of Windows." - Abort - ${EndIf} -FunctionEnd -!endif - -Section - SetOutPath $INSTDIR - File /r "${STAGING_DIR}\*" - - WriteUninstaller $INSTDIR\Uninstaller.exe - - # Write uninstall registry records. - WriteRegStr HKLM "${UNINST_REGKEY}" "DisplayName" "Scan Tailor Universal" - WriteRegStr HKLM "${UNINST_REGKEY}" "UninstallString" "$INSTDIR\Uninstaller.exe" - - # Create menu shortcuts. - SetShellVarContext all - CreateDirectory "$SMPROGRAMS\Scan Tailor Universal" - CreateShortcut "$SMPROGRAMS\Scan Tailor Universal\Scan Tailor Universal.lnk" "$INSTDIR\scantailor-universal.exe" - CreateShortcut "$SMPROGRAMS\Scan Tailor Universal\Uninstall.lnk" "$INSTDIR\Uninstaller.exe" - - # Register the ".ScanTailor" file extension. - ${registerExtension} "$INSTDIR\scantailor-universal.exe" ".ScanTailor" \ - "Scan Tailor Universal Project" "$INSTDIR\scantailor-universal.exe" -SectionEnd - - -Function un.onInit - FindWindow $0 "${WNDCLASS}" "" - StrCmp $0 0 continueInstall - MessageBox MB_ICONSTOP|MB_OK "The application you are trying to remove is running. Close it and try again." - Abort - continueInstall: -FunctionEnd - - -Section "Uninstall" - # Unregister the ".ScanTailor" file extension. - ${unregisterExtension} ".ScanTailor" "Scan Tailor Universal Project" - - # Remove program files. - Delete "$INSTDIR\scantailor-universal.exe" - Delete "$INSTDIR\scantailor-universal-cli.exe" - Delete "$INSTDIR\mingwm10.dll" - Delete "$INSTDIR\libgcc_*.dll" - Delete "$INSTDIR\CrashReporter.exe" - Delete "$INSTDIR\Qt*.dll" - Delete "$INSTDIR\libz.dll" - Delete "$INSTDIR\zdll.dll" - Delete "$INSTDIR\libpng.dll" - Delete "$INSTDIR\libjpeg.dll" - Delete "$INSTDIR\libtiff.dll" - Delete "$INSTDIR\openjp2.dll" - Delete "$INSTDIR\msvc*.dll" - Delete "$INSTDIR\vccorlib*.dll" - Delete "$INSTDIR\libstdc++-6.dll" - Delete "$INSTDIR\libwinpthread-1.dll" - Delete "$INSTDIR\Uninstaller.exe" - RMDir /r "$INSTDIR\Microsoft.VC80.CRT" - RMDir /r "$INSTDIR\Microsoft.VC90.CRT" - RMDir /r "$INSTDIR\Microsoft.VC100.CRT" - - # Remove translations. - Delete "$INSTDIR\translations\*.qm" - RMDir "$INSTDIR\translations" - - # Remove imageformats plugins. - # We no longer ship any, but it's a good idea to cleanup after previous version. - Delete "$INSTDIR\imageformats\*.dll" - RMDir "$INSTDIR\imageformats" - - # Remove platform plugins. - Delete "$INSTDIR\platforms\*.dll" - RMDir "$INSTDIR\platforms" - - # Remove accessible plugins. - Delete "$INSTDIR\accessible\*.dll" - RMDir "$INSTDIR\accessible" - - # Remove the installation directory. - RMDir "$INSTDIR" - - # Remove the uninstall record from the registry. - DeleteRegKey HKLM "${UNINST_REGKEY}" - - # Remove menu entries - SetShellVarContext all - RMDir /r "$SMPROGRAMS\Scan Tailor Universal" -SectionEnd diff --git a/src/stylesheets/Breeze.qss b/src/stylesheets/Breeze.qss new file mode 100644 index 0000000..cf4bbd9 --- /dev/null +++ b/src/stylesheets/Breeze.qss @@ -0,0 +1,1667 @@ +/* + * Breeze stylesheet. + * + * :author: Colin Duquesnoy + * :editor: Alex Huszagh + * :license: MIT, see LICENSE.md + * + * This is originally a fork of QDarkStyleSheet, and is based on Breeze/ + * BreezeDark color scheme, but is in no way affiliated with KDE. + * + * --------------------------------------------------------------------- + * The MIT License (MIT) + * + * Copyright (c) <2013-2014> + * Copyright (c) <2015-2016> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * --------------------------------------------------------------------- + */ + +/* This is an adaptation for ScanTailor Universal + * @path_to_pics@ will be replaced at load time with folder where qss is stored for Win + * or with $CMAKE_INSTALLPREFIX/share/pixmaps/scantailor-universal/stylesheets/ for Linux + */ + +QGraphicsView { + background-color: #bcbfc2; +} + +QToolTip +{ + background-color: black; + color: white; + padding: 0.5ex; +} + +QWidget +{ + color: #31363B; + background-color: #EFF0F1; + selection-background-color:#33A4DF; + selection-color: #31363B; + background-clip: border; + border-image: none; + border: 0px transparent black; + outline: 0; +} + +QWidget:item:hover +{ + background-color: #33A4DF; + color: #31363B; +} + +QWidget:item:selected +{ + background-color: #33A4DF; +} + + +QCheckBox +{ + spacing: 0.5ex; + outline: none; + color: #31363B; + margin-bottom: 0.2ex; + opacity: 200; +} + +QCheckBox:disabled +{ + color: #BAB9B8; +} + +QGroupBox::indicator +{ + margin-left: 0.2ex; + margin-left: 0.2ex; +} + +QCheckBox::indicator:unchecked, +QCheckBox::indicator:unchecked:focus +{ + border-image: url("@path_to_pics@/Breeze/checkbox_unchecked_disabled.svg"); +} + +QCheckBox::indicator:unchecked:hover, +QCheckBox::indicator:unchecked:pressed, +QGroupBox::indicator:unchecked:hover, +QGroupBox::indicator:unchecked:focus, +QGroupBox::indicator:unchecked:pressed +{ + border: none; + border-image: url("@path_to_pics@/Breeze/checkbox_unchecked-hover.svg"); +} + +QCheckBox::indicator:checked +{ + border-image: url("@path_to_pics@/Breeze/checkbox_checked.svg"); +} + +QCheckBox::indicator:checked:focus, +QCheckBox::indicator:checked:pressed, +QGroupBox::indicator:checked:focus, +QGroupBox::indicator:checked:pressed +{ + border: none; + border-image: url("@path_to_pics@/Breeze/checkbox_checked.svg"); +} + +QCheckBox::indicator:checked:hover, +QGroupBox::indicator:checked:hover +{ + border-image: url("@path_to_pics@/Breeze/checkbox_checked-hover.svg"); +} + +QCheckBox::indicator:indeterminate +{ + border-image: url("@path_to_pics@/Breeze/checkbox_indeterminate.svg"); +} + +QCheckBox::indicator:indeterminate:hover +{ + border-image: url("@path_to_pics@/Breeze/checkbox_indeterminate-hover.svg"); +} + +QCheckBox::indicator:indeterminate:focus, +QCheckBox::indicator:indeterminate:pressed +{ +} + +QCheckBox::indicator:indeterminate:disabled +{ + border-image: url("@path_to_pics@/Breeze/checkbox_indeterminate_disabled.svg"); +} + +QCheckBox::indicator:checked:disabled, +QGroupBox::indicator:checked:disabled +{ + border-image: url("@path_to_pics@/Breeze/checkbox_checked_disabled.svg"); +} + +QCheckBox::indicator:unchecked:disabled, +QGroupBox::indicator:unchecked:disabled +{ + border-image: url("@path_to_pics@/Breeze/checkbox_unchecked_disabled.svg"); +} + +QRadioButton +{ + spacing: 0.5ex; + outline: none; + color: #31363B; + margin-bottom: 0.2ex; +} + +QRadioButton:disabled +{ + color: #BAB9B8; +} + +QRadioButton::indicator:unchecked, +QRadioButton::indicator:unchecked:focus +{ + border-image: url("@path_to_pics@/Breeze/radio_unchecked_disabled.svg"); +} + +QRadioButton::indicator:unchecked:hover, +QRadioButton::indicator:unchecked:pressed +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/Breeze/radio_unchecked-hover.svg"); +} + +QRadioButton::indicator:checked +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/Breeze/radio_checked.svg"); +} + +QRadioButton::indicator:checked:focus, +QRadioButton::indicator:checked:pressed +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/Breeze/radio_checked.svg"); +} + +QRadioButton::indicator:checked:hover +{ + border-image: url("@path_to_pics@/Breeze/radio_checked-hover.svg"); +} + +QRadioButton::indicator:checked:disabled +{ + outline: none; + border-image: url("@path_to_pics@/Breeze/radio_checked_disabled.svg"); +} + +QRadioButton::indicator:unchecked:disabled +{ + border-image: url("@path_to_pics@/Breeze/radio_unchecked_disabled.svg"); +} + +QMenuBar +{ + background-color: #EFF0F1; + color: #31363B; +} + +QMenuBar::item +{ + background: transparent; +} + +QMenuBar::item:selected +{ + background: transparent; + border: 1px solid #BAB9B8; +} + +QMenuBar::item:pressed +{ + border: 1px solid #BAB9B8; + background-color: #33A4DF; + color: #31363B; + margin-bottom: -0.1ex; + padding-bottom: 0.1ex; +} + +QMenu +{ + border: 1px solid #BAB9B8; + color: #31363B; + margin: 0.2ex; +} + +QMenu::icon +{ + margin: 0.5ex; +} + +QMenu::item +{ + padding: 0.5ex 3ex 0.5ex 3ex; + margin-left: 0.5ex; + border: 1px solid transparent; /* reserve space for selection border */ +} + +QMenu::item:selected +{ + color: #31363B; +} + +QMenu::separator +{ + height: 0.2ex; + background: lightblue; + margin-left: 1ex; + margin-right: 0.5ex; +} + +/* non-exclusive indicator = check box style indicator + (see QActionGroup::setExclusive) */ +QMenu::indicator:non-exclusive:unchecked +{ + border-image: url("@path_to_pics@/Breeze/checkbox_unchecked_disabled.svg"); +} + +QMenu::indicator:non-exclusive:unchecked:selected +{ + border-image: url("@path_to_pics@/Breeze/checkbox_unchecked_disabled.svg"); +} + +QMenu::indicator:non-exclusive:checked +{ + border-image: url("@path_to_pics@/Breeze/checkbox_checked.svg"); +} + +QMenu::indicator:non-exclusive:checked:selected +{ + border-image: url("@path_to_pics@/Breeze/checkbox_checked.svg"); +} + +/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +QMenu::indicator:exclusive:unchecked +{ + border-image: url("@path_to_pics@/Breeze/radio_unchecked_disabled.svg"); +} + +QMenu::indicator:exclusive:unchecked:selected +{ + border-image: url("@path_to_pics@/Breeze/radio_unchecked_disabled.svg"); +} + +QMenu::indicator:exclusive:checked +{ + border-image: url("@path_to_pics@/Breeze/radio_checked.svg"); +} + +QMenu::indicator:exclusive:checked:selected +{ + border-image: url("@path_to_pics@/Breeze/radio_checked.svg"); +} + +QMenu::right-arrow +{ + margin: 0.5ex; + border-image: url("@path_to_pics@/Breeze/right_arrow.svg"); + width: 0.6ex; + height: 0.9ex; +} + + +QWidget:disabled +{ + color: #454545; + background-color: #EFF0F1; +} + +QAbstractItemView +{ + alternate-background-color: #EFF0F1; + color: #31363B; + border: 1px solid 3A3939; + border-radius: 0.2ex; +} + +QWidget:focus, +QMenuBar:focus +{ + border: 1px solid #33A4DF; +} + +QTabWidget:focus, +QCheckBox:focus, +QRadioButton:focus, +QSlider:focus +{ + border: none; +} + +QLineEdit +{ + background-color: #FCFCFC; + padding: 0.5ex; + border-style: solid; + border: 1px solid #BAB9B8; + border-radius: 0.2ex; + color: #31363B; +} + +QGroupBox +{ + border: 1px solid #BAB9B8; + border-radius: 0.2ex; + padding-top: 1ex; + margin-top: 1ex; +} + +QGroupBox::title +{ + subcontrol-origin: margin; + subcontrol-position: top center; + padding-left: 0.1ex; + padding-right: 0.1ex; + margin-top: -0.7ex; +} + +QAbstractScrollArea +{ + border-radius: 0.2ex; + border: 1px solid #BAB9B8; + background-color: transparent; +} + +QScrollBar:horizontal +{ + height: 1.5ex; + margin: 0.3ex 1.5ex 0.3ex 1.5ex; + border: 1px transparent #2A2929; + border-radius: 0.4ex; + background-color: #2A2929; +} + +QScrollBar::handle:horizontal +{ + background-color: #605F5F; + min-width: 0.5ex; + border-radius: 0.4ex; +} + +QScrollBar::add-line:horizontal +{ + margin: 0ex 0.3ex 0ex 0.3ex; + border-image: url("@path_to_pics@/Breeze/right_arrow_disabled.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal +{ + margin: 0px 0.3ex 0px 0.3ex; + border-image: url("@path_to_pics@/Breeze/left_arrow_disabled.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on +{ + border-image: url("@path_to_pics@/Breeze/right_arrow.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: right; + subcontrol-origin: margin; +} + + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on +{ + border-image: url("@path_to_pics@/Breeze/left_arrow.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal +{ + background: none; +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; +} + +QScrollBar:vertical +{ + background-color: #2A2929; + width: 1.5ex; + margin: 1.5ex 0.3ex 1.5ex 0.3ex; + border: 1px transparent #2A2929; + border-radius: 0.4ex; +} + +QScrollBar::handle:vertical +{ + background-color: #605F5F; + min-height: 0.5ex; + border-radius: 0.4ex; +} + +QScrollBar::sub-line:vertical +{ + margin: 0.3ex 0ex 0.3ex 0ex; + border-image: url("@path_to_pics@/Breeze/up_arrow_disabled.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical +{ + margin: 0.3ex 0ex 0.3ex 0ex; + border-image: url("@path_to_pics@/Breeze/down_arrow_disabled.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, +QScrollBar::sub-line:vertical:on +{ + + border-image: url("@path_to_pics@/Breeze/up_arrow.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: top; + subcontrol-origin: margin; +} + + +QScrollBar::add-line:vertical:hover, +QScrollBar::add-line:vertical:on +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:vertical, +QScrollBar::down-arrow:vertical +{ + background: none; +} + + +QScrollBar::add-page:vertical, +QScrollBar::sub-page:vertical +{ + background: none; +} + +QTextEdit +{ + background-color: #EFF0F1; + color: #31363B; + border: 1px solid #BAB9B8; +} + +QPlainTextEdit +{ + background-color: #EFF0F1; + color: #31363B; + border-radius: 0.2ex; + border: 1px solid #BAB9B8; +} + +QHeaderView::section +{ + background-color: #BAB9B8; + color: #31363B; + padding: 0.5ex; + border: 1px solid #BAB9B8; +} + +QSizeGrip +{ + border-image: url("@path_to_pics@/Breeze/sizegrip.svg"); + width: 1.2ex; + height: 1.2ex; +} + +QMainWindow::separator +{ + background-color: #EFF0F1; + color: white; + padding-left: 0.4ex; + spacing: 0.2ex; + border: 1px dashed #BAB9B8; +} + +QMainWindow::separator:hover +{ + + background-color: #787876; + color: white; + padding-left: 0.4ex; + border: 1px solid #BAB9B8; + spacing: 0.2x; +} + +QMenu::separator +{ + height: 0.1ex; + background-color: #BAB9B8; + color: white; + padding-left: 0.4ex; + margin-left: 1ex; + margin-right: 0.5ex; +} + +QFrame[frameShape="2"], /* QFrame::Panel == 0x0003 */ +QFrame[frameShape="3"], /* QFrame::WinPanel == 0x0003 */ +QFrame[frameShape="4"], /* QFrame::HLine == 0x0004 */ +QFrame[frameShape="5"], /* QFrame::VLine == 0x0005 */ +QFrame[frameShape="6"] /* QFrame::StyledPanel == 0x0006 */ +{ + border-width: 1px; + padding: 0.1ex; + border-style: solid; + border-color: #EFF0F1; + background-color: #bcbfc2; + border-radius: 0.5ex; +} + +QStackedWidget +{ + border: 1px transparent black; +} + +QToolBar +{ + border: 1px transparent #393838; + background: 0.1ex solid #EFF0F1; + font-weight: bold; +} + +QToolBar::handle:horizontal +{ + border-image: url("@path_to_pics@/Breeze/hmovetoolbar.svg"); + width = 1.6ex; + height = 6.4ex; +} + +QToolBar::handle:vertical +{ + border-image: url("@path_to_pics@/Breeze/vmovetoolbar.svg"); + width = 5.4ex; + height = 1ex; +} + +QToolBar::separator:horizontal +{ + border-image: url("@path_to_pics@/Breeze/hsepartoolbar.svg"); + width = 0.7ex; + height = 6.3ex; +} + +QToolBar::separator:vertical +{ + border-image: url("@path_to_pics@/Breeze/vsepartoolbars.svg"); + width = 6.3ex; + height = 0.7ex; +} + +QPushButton +{ + color: #31363B; + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #EFF0F1, stop: 0.5 #eaebec); + border-width: 1px; + border-color: #BAB9B8; + border-style: solid; + padding: 0.5ex; + border-radius: 0.2ex; + outline: none; +} + +QPushButton:disabled +{ + background-color: #e0e1e2; + border-width: 1px; + border-color: #b4b4b4; + border-style: solid; + padding-top: 0.5ex; + padding-bottom: 0.5ex; + padding-left: 1ex; + padding-right: 1ex; + border-radius: 0.2ex; + color: #b4b4b4; +} + +QPushButton:focus +{ + color: black; +} + +QComboBox +{ + selection-background-color: #33A4DF; + border-style: solid; + border: 1px solid #BAB9B8; + border-radius: 0.2ex; + padding: 0.5ex; + min-width: 7.5ex; +} + +QPushButton:checked +{ + background-color: #BAB9B8; + border-color: #6A6969; +} + +QComboBox:hover, +QAbstractSpinBox:hover, +QLineEdit:hover, +QTextEdit:hover, +QPlainTextEdit:hover, +QAbstractView:hover, +QTreeView:hover +{ + border: 1px solid #33A4DF; + color: #31363B; +} + +QComboBox:hover:pressed, +QPushButton:hover:pressed, +QAbstractSpinBox:hover:pressed, +QLineEdit:hover:pressed, +QTextEdit:hover:pressed, +QPlainTextEdit:hover:pressed, +QAbstractView:hover:pressed, +QTreeView:hover:pressed +{ + background-color: #EFF0F1; +} + +QComboBox:on +{ + padding-top: 0.3ex; + padding-left: 0.4ex; + selection-background-color: #4a4a4a; +} + +QComboBox QAbstractItemView +{ + background-color: #FCFCFC; + border-radius: 0.2ex; + border: 1px solid #BAB9B8; + selection-background-color: #33A4DF; +} + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 1.5ex; + + border-left-width: 0ex; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 0.3ex; + border-bottom-right-radius: 0.3ex; +} + +QComboBox::down-arrow +{ + border-image: url("@path_to_pics@/Breeze/down_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QComboBox::down-arrow:on, +QComboBox::down-arrow:hover, +QComboBox::down-arrow:focus +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox +{ + padding: 0.5ex; + border: 1px solid #BAB9B8; + background-color: #D9D8D7; + color: #31363B; + border-radius: 0.2ex; + min-width: 7.5ex; +} + +QAbstractSpinBox:up-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: center right; +} + +QAbstractSpinBox:down-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: center left; +} + +QAbstractSpinBox::up-arrow, +QAbstractSpinBox::up-arrow:disabled, +QAbstractSpinBox::up-arrow:off +{ + border-image: url("@path_to_pics@/Breeze/up_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::up-arrow:hover +{ + border-image: url("@path_to_pics@/Breeze/up_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::down-arrow, +QAbstractSpinBox::down-arrow:disabled, +QAbstractSpinBox::down-arrow:off +{ + border-image: url("@path_to_pics@/Breeze/down_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::down-arrow:hover +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QLabel +{ + border: 0ex solid black; +} + +QTabWidget{ + border: 1px solid #BAB9B8; +} + +/* BORDERS */ +QTabWidget::pane +{ + padding: 0.5ex; + margin: 0.1ex; +} + +QTabWidget::pane:top +{ + border: 1px solid #BAB9B8; + top: -0.1ex; +} + +QTabWidget::pane:bottom +{ + border: 1px solid #BAB9B8; + bottom: -0.1ex; +} + +QTabWidget::pane:left +{ + border: 1px solid #BAB9B8; + right: -0.1ex; +} + +QTabWidget::pane:right +{ + border: 1px solid #BAB9B8; + left: -0.1ex; +} + +QTabBar +{ + qproperty-drawBase: 0; + left: 0.5ex; /* move to the right by 0.5ex */ + border-radius: 0.3ex; +} + +QTabBar:focus +{ + border: 0ex transparent black; +} + +QTabBar::close-button +{ + border-image: url("@path_to_pics@/Breeze/close.svg"); + width: 1.2ex; + height: 1.2ex; + background: transparent; +} + +QTabBar::close-button:hover +{ + border-image: url("@path_to_pics@/Breeze/close-hover.svg"); + width: 1.2ex; + height: 1.2ex; + background: transparent; +} + +QTabBar::close-button:pressed +{ + border-image: url("@path_to_pics@/Breeze/close-pressed.svg"); + width: 1.2ex; + height: 1.2ex; + background: transparent; +} + +/* TOP TABS */ +QTabBar::tab:top +{ + color: #31363B; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-top: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + min-width: 5ex; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:last, +QTabBar::tab:top:only-one +{ + color: #31363B; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-right: 1px solid #BAB9B8; + border-top: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + min-width: 5ex; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:!selected +{ + color: #31363B; + background-color: #D9D8D7; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:first:!selected +{ + color: #31363B; + background-color: #D9D8D7; + border: 1px transparent black; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); + border-left: 1px solid #BAB9B8; +} + +QTabBar::tab:top:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); +} + +/* BOTTOM TABS */ +QTabBar::tab:bottom +{ + color: #31363B; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-bottom: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-width: 5ex; +} + +QTabBar::tab:bottom:last, +QTabBar::tab:bottom:only-one +{ + color: #31363B; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-right: 1px solid #BAB9B8; + border-bottom: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-width: 5ex; +} + +QTabBar::tab:bottom:!selected +{ + color: #31363B; + background-color: #D9D8D7; + border: 1px transparent black; + border-left: 1px solid #BAB9B8; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; +} + +QTabBar::tab:bottom:first:!selected +{ + color: #31363B; + background-color: #D9D8D7; + border: 1px transparent black; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; +} + +QTabBar::tab:bottom:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); + border-left: 1px solid #BAB9B8; +} + +QTabBar::tab:bottom:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); +} + +/* LEFT TABS */ +QTabBar::tab:left +{ + color: #31363B; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-right: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-height: 5ex; +} + +QTabBar::tab:left:last, +QTabBar::tab:left:only-one +{ + color: #31363B; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-bottom: 1px solid #BAB9B8; + border-right: 1px solid #BAB9B8; + background-color: #EFF0F1; + padding: 0.5ex; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-height: 5ex; +} + +QTabBar::tab:left:!selected +{ + color: #31363B; + background-color: #D9D8D7; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; +} + +QTabBar::tab:left:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); + border-top: 1px solid #BAB9B8; +} + +QTabBar::tab:left:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); +} + +/* RIGHT TABS */ +QTabBar::tab:right +{ + color: #31363B; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-left: 1px solid #BAB9B8; + background-color: #D9D8D7; + padding: 0.5ex; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; + min-height: 5ex; +} + +QTabBar::tab:right:last, +QTabBar::tab:right:only-one +{ + color: #31363B; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-bottom: 1px solid #BAB9B8; + border-left: 1px solid #BAB9B8; + background-color: #D9D8D7; + padding: 0.5ex; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; + min-height: 5ex; +} + +QTabBar::tab:right:!selected +{ + color: #31363B; + background-color: #54575B; + border: 1px transparent black; + border-top: 1px solid #BAB9B8; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; +} + +QTabBar::tab:right:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); + border-top: 1px solid #BAB9B8; +} + +QTabBar::tab:right:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.1); + border: 1px rgba(61, 173, 232, 0.1); +} + +QTabBar QToolButton::right-arrow:enabled +{ + border-image: url("@path_to_pics@/Breeze/right_arrow.svg"); +} + +QTabBar QToolButton::left-arrow:enabled +{ + border-image: url("@path_to_pics@/Breeze/left_arrow.svg"); +} + +QTabBar QToolButton::right-arrow:disabled +{ + border-image: url("@path_to_pics@/Breeze/right_arrow_disabled.svg"); +} + +QTabBar QToolButton::left-arrow:disabled +{ + border-image: url("@path_to_pics@/Breeze/left_arrow_disabled.svg"); +} + +QDockWidget +{ + background: #EFF0F1; + border: 1px solid #403F3F; + titlebar-close-icon: url("@path_to_pics@/Breeze/transparent.svg"); + titlebar-normal-icon: url("@path_to_pics@/Breeze/transparent.svg"); +} + +QDockWidget::close-button, +QDockWidget::float-button +{ + border: 1px solid transparent; + border-radius: 0.2ex; + background: transparent; +} + + +QDockWidget::float-button +{ + border-image: url("@path_to_pics@/dark/undock.svg"); +} + +QDockWidget::float-button:hover +{ + border-image: url("@path_to_pics@/dark/undock-hover.svg") ; +} + +QDockWidget::close-button +{ + border-image: url("@path_to_pics@/dark/close.svg") ; +} + +QDockWidget::close-button:hover +{ + border-image: url("@path_to_pics@/dark/close-hover.svg") ; +} + +QDockWidget::close-button:pressed +{ + border-image: url("@path_to_pics@/dark/close-pressed.svg") ; +} + +QTreeView, +QListView +{ + border: 1px solid #BAB9B8; + background-color: #FCFCFC; +} + + +QTreeView::branch:has-siblings:!adjoins-item +{ + border-image: url("@path_to_pics@/Breeze/stylesheet-vline.svg") 0; +} + +QTreeView::branch:has-siblings:adjoins-item +{ + border-image: url("@path_to_pics@/Breeze/stylesheet-branch-more.svg") 0; +} + +QTreeView::branch:!has-children:!has-siblings:adjoins-item +{ + border-image: url("@path_to_pics@/Breeze/stylesheet-branch-end.svg") 0; +} + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings +{ + border-image: url("@path_to_pics@/Breeze/stylesheet-branch-end-closed.svg") 0; + image: url("@path_to_pics@/Breeze/branch_closed.svg"); +} + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings +{ + border-image: url("@path_to_pics@/Breeze/stylesheet-branch-end-open.svg") 0; + image: url("@path_to_pics@/Breeze/branch_open.svg"); +} + +QTableView::item, +QListView::item, +QTreeView::item +{ + padding: 0.3ex; +} + +QTableView::item:!selected:hover, +QListView::item:!selected:hover, +QTreeView::item:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.1); + outline: 0; + color: #31363B; + padding: 0.3ex; +} + +QSlider::groove:horizontal +{ + border: 1px solid #EFF0F1; + height: 0.4ex; + background: #9CA0A4; + margin: 0px; + border-radius: 0.2ex; +} + +QSlider::handle:horizontal +{ + background: #D9D8D7; + border: 1px solid #BABEC2; + width: 1.6ex; + height: 1.6ex; + margin: -0.8ex 0; + border-radius: 0.9ex; +} + +QSlider::groove:vertical +{ + border: 1px solid #EFF0F1; + width: 0.4ex; + background: #9CA0A4; + margin: 0ex; + border-radius: 0.3ex; +} + +QSlider::handle:vertical +{ + background: #D9D8D7; + border: 1px solid #BABEC2; + width: 1.6ex; + height: 1.6ex; + margin: 0 -0.8ex; + border-radius: 0.9ex; +} + +QSlider::handle:horizontal:focus, +QSlider::handle:vertical:focus +{ + border: 1px solid #33A4DF; +} + +QSlider::handle:horizontal:hover, +QSlider::handle:vertical:hover +{ + border: 1px solid #51c2fc; +} + +QSlider::sub-page:horizontal, +QSlider::add-page:vertical +{ + background: #33A4DF; + border-radius: 0.3ex; +} + +QSlider::add-page:horizontal, +QSlider::sub-page:vertical +{ + background: #BABEC2; + border-radius: 0.3ex; +} + +QToolButton +{ + background-color: transparent; + border: 1px solid #BAB9B8; + border-radius: 0.2ex; + margin: 0.3ex; + padding: 0.5ex; +} + +QToolButton[popupMode="1"] /* only for MenuButtonPopup */ +{ + padding-right: 2ex; /* make way for the popup button */ +} + +QToolButton[popupMode="2"] /* only for InstantPopup */ +{ + padding-right: 1ex; /* make way for the popup button */ +} + +QToolButton::menu-indicator +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + top: -0.7ex; left: -0.2ex; /* shift it a bit */ + width = 0.9ex; + height = 0.6ex; +} + +QToolButton::menu-arrow +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + width = 0.9ex; + height = 0.6ex; +} + +QToolButton:hover, +QToolButton::menu-button:hover +{ + background-color: transparent; + border: 1px solid #33A4DF; +} + +QToolButton:checked, +QToolButton:pressed, +QToolButton::menu-button:pressed +{ + background-color: #47b8fc; + border: 1px solid #47b8fc; + padding: 0.5ex; +} + +QToolButton::menu-button +{ + border: 1px solid #BAB9B8; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + /* 1ex width + 0.4ex for border + no text = 2ex allocated above */ + width: 1ex; + padding: 0.5ex; + outline: none; +} + +QToolButton::menu-arrow:open +{ + border: 1px solid #BAB9B8; +} + +QPushButton::menu-indicator +{ + subcontrol-origin: padding; + subcontrol-position: bottom right; + left: 0.8ex; +} + +QTableView +{ + border: 1px solid #BAB9B8; + gridline-color: #BAB9B8; + background-color: #FCFCFC; +} + + +QTableView, +QHeaderView +{ + border-radius: 0px; +} + +QTableView::item:pressed +{ + background: #33A4DF; + color: #31363B; +} + +QTableView::item:selected:active +{ + background: #33A4DF; + color: #31363B; +} + +QTableView::item:selected:hover +{ + background-color: #47b8f3; + color: #31363B; +} + +QListView::item:pressed, +QTreeView::item:pressed +{ + background: #3daee9; + color: #31363B; +} + +QTreeView::item:selected:active, +QListView::item:selected:active +{ + background: #3daee9; + color: #31363B; +} + +QListView::item:selected:hover, +QTreeView::item:selected:hover +{ + background-color: #51c2fc; + color: #31363B; +} + + +QHeaderView +{ + background-color: #EFF0F1; + border: 1px transparent; + border-radius: 0px; + margin: 0px; + padding: 0px; + +} + +QHeaderView::section +{ + background-color: #EFF0F1; + color: #31363B; + padding: 0.5ex; + border: 1px solid #BAB9B8; + border-radius: 0px; + text-align: center; +} + +QHeaderView::section::vertical::first, +QHeaderView::section::vertical::only-one +{ + border-top: 1px solid #BAB9B8; +} + +QHeaderView::section::vertical +{ + border-top: transparent; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one +{ + border-left: 1px solid #BAB9B8; +} + +QHeaderView::section::horizontal +{ + border-left: transparent; +} + + +QHeaderView::section:checked + + { + color: black; + background-color: #b9dae7; + } + + /* style the sort indicator */ +QHeaderView::down-arrow +{ + image: url("@path_to_pics@/Breeze/down_arrow.svg"); +} + +QHeaderView::up-arrow +{ + image: url("@path_to_pics@/Breeze/up_arrow.svg"); +} + +QTableCornerButton::section +{ + background-color: #EFF0F1; + border: 1px transparent #BAB9B8; + border-radius: 0px; +} + +QToolBox +{ + padding: 0.5ex; + border: 1px transparent black; +} + +QToolBox:selected +{ + background-color: #EFF0F1; + border-color: #33A4DF; +} + +QToolBox:hover +{ + border-color: #33A4DF; +} + +QStatusBar::item +{ + border: 0px transparent dark; +} + +QSplitter::handle +{ + border: 1px dashed #BAB9B8; +} + +QSplitter::handle:hover +{ + background-color: #787876; + border: 1px solid #BAB9B8; +} + +QSplitter::handle:horizontal +{ + width: 0.1ex; +} + +QSplitter::handle:vertical +{ + height: 0.1ex; +} + +QProgressBar:horizontal +{ + background-color: #BABEC2; + border: 1px solid #EFF0F1; + border-radius: 0.3ex; + height: 0.5ex; + text-align: right; + margin-top: 0.5ex; + margin-bottom: 0.5ex; + margin-right: 5ex; + padding: 0px; +} + +QProgressBar::chunk:horizontal +{ + background-color: #33A4DF; + border: 1px transparent; + border-radius: 0.3ex; +} + +QAbstractSpinBox +{ + background-color: #EFF0F1; +} + +QSpinBox, +QDoubleSpinBox +{ + padding-right: 1.5ex; +} + +QSpinBox::up-button, +QDoubleSpinBox::up-button +{ + subcontrol-origin: content; + subcontrol-position: right top; + + width: 1.6ex; + border-width: 1px; +} + +QSpinBox::up-arrow, +QDoubleSpinBox::up-arrow +{ + border-image: url("@path_to_pics@/Breeze/up_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::up-arrow:hover, +QSpinBox::up-arrow:pressed, +QDoubleSpinBox::up-arrow:hover, +QDoubleSpinBox::up-arrow:pressed +{ + border-image: url("@path_to_pics@/Breeze/up_arrow-hover.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::up-arrow:disabled, +QSpinBox::up-arrow:off, +QDoubleSpinBox::up-arrow:disabled, +QDoubleSpinBox::up-arrow:off +{ + border-image: url("@path_to_pics@/Breeze/up_arrow_disabled.svg"); +} + +QSpinBox::down-button, +QDoubleSpinBox::down-button +{ + subcontrol-origin: content; + subcontrol-position: right bottom; + + width: 1.6ex; + border-width: 1px; +} + +QSpinBox::down-arrow, +QDoubleSpinBox::down-arrow +{ + border-image: url("@path_to_pics@/Breeze/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::down-arrow:hover, +QSpinBox::down-arrow:pressed, +QDoubleSpinBox::down-arrow:hover, +QDoubleSpinBox::down-arrow:pressed +{ + border-image: url("@path_to_pics@/Breeze/down_arrow-hover.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::down-arrow:disabled, +QSpinBox::down-arrow:off, +QDoubleSpinBox::down-arrow:disabled, +QDoubleSpinBox::down-arrow:off +{ + border-image: url("@path_to_pics@/Breeze/down_arrow_disabled.svg"); +} + +QPushButton:hover +{ + border: 1px solid #3daef3; + color: #31363B; +} + +QPushButton:focus +{ + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #4cbdff, stop: 0.5 #33a4e8); + color: white; +} + +QPushButton:focus:hover +{ + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #bedfec, stop: 0.5 #b9dae7); + color: #31363B; +} + +QPushButton:focus:pressed, +QPushButton:pressed +{ + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #bedfec, stop: 0.5 #b9dae7); + color: #31363B; +} + +RelinkingDialog QListView::item +{ + margin-right: 1.8em; +} diff --git a/src/stylesheets/Breeze/LICENSE.md b/src/stylesheets/Breeze/LICENSE.md new file mode 100644 index 0000000..ef01015 --- /dev/null +++ b/src/stylesheets/Breeze/LICENSE.md @@ -0,0 +1,26 @@ +The MIT License (MIT) +===================== + +Copyright © `<2013-2014>` `` +Copyright © `<2015-2016>` `` + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/stylesheets/Breeze/README.md b/src/stylesheets/Breeze/README.md new file mode 100644 index 0000000..33b930a --- /dev/null +++ b/src/stylesheets/Breeze/README.md @@ -0,0 +1,23 @@ +BreezeStyleSheets for STU +================= + +Breeze and BreezeDark-like stylesheets adapted for [Scan Tailor Universal](https://github.com/trufanov-nok/scantailor-universal) + +License +======= + +MIT, see [license](/LICENSE.md). + +Acknowledgements +================ + +*BreezeStyleSheets for STU* is a fork of [BreezeStyleSheets](https://github.com/trufanov-nok/BreezeStyleSheets). +[BreezeStyleSheets](https://github.com/trufanov-nok/BreezeStyleSheets) is a fork of [QDarkStyleSheet](https://github.com/ColinDuquesnoy/QDarkStyleSheet). + +Contacts of BreezeStyleSheets author +======= + +Alexander Huszagh +Email: ahuszagh@gmail.com +Twitter: KardOnIce + diff --git a/src/stylesheets/Breeze/branch_closed-on.svg b/src/stylesheets/Breeze/branch_closed-on.svg new file mode 100644 index 0000000..23c5421 --- /dev/null +++ b/src/stylesheets/Breeze/branch_closed-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/branch_closed.svg b/src/stylesheets/Breeze/branch_closed.svg new file mode 100644 index 0000000..286c1a9 --- /dev/null +++ b/src/stylesheets/Breeze/branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/branch_open-on.svg b/src/stylesheets/Breeze/branch_open-on.svg new file mode 100644 index 0000000..9e75927 --- /dev/null +++ b/src/stylesheets/Breeze/branch_open-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/branch_open.svg b/src/stylesheets/Breeze/branch_open.svg new file mode 100644 index 0000000..514a312 --- /dev/null +++ b/src/stylesheets/Breeze/branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/checkbox_checked-hover.svg b/src/stylesheets/Breeze/checkbox_checked-hover.svg new file mode 100644 index 0000000..64d6667 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_checked-hover.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/checkbox_checked.svg b/src/stylesheets/Breeze/checkbox_checked.svg new file mode 100644 index 0000000..f3acb63 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_checked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/checkbox_checked_disabled.svg b/src/stylesheets/Breeze/checkbox_checked_disabled.svg new file mode 100644 index 0000000..b7be04b --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_checked_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/checkbox_indeterminate-hover.svg b/src/stylesheets/Breeze/checkbox_indeterminate-hover.svg new file mode 100644 index 0000000..def9596 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_indeterminate-hover.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/Breeze/checkbox_indeterminate.svg b/src/stylesheets/Breeze/checkbox_indeterminate.svg new file mode 100644 index 0000000..a619ab0 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_indeterminate.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/Breeze/checkbox_indeterminate_disabled.svg b/src/stylesheets/Breeze/checkbox_indeterminate_disabled.svg new file mode 100644 index 0000000..74d7168 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_indeterminate_disabled.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/Breeze/checkbox_unchecked-hover.svg b/src/stylesheets/Breeze/checkbox_unchecked-hover.svg new file mode 100644 index 0000000..8f0bb01 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_unchecked-hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/checkbox_unchecked_disabled.svg b/src/stylesheets/Breeze/checkbox_unchecked_disabled.svg new file mode 100644 index 0000000..0ef4300 --- /dev/null +++ b/src/stylesheets/Breeze/checkbox_unchecked_disabled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/close-hover.svg b/src/stylesheets/Breeze/close-hover.svg new file mode 100644 index 0000000..cb44c78 --- /dev/null +++ b/src/stylesheets/Breeze/close-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/close-pressed.svg b/src/stylesheets/Breeze/close-pressed.svg new file mode 100644 index 0000000..a0dc249 --- /dev/null +++ b/src/stylesheets/Breeze/close-pressed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/close.svg b/src/stylesheets/Breeze/close.svg new file mode 100644 index 0000000..07b50c9 --- /dev/null +++ b/src/stylesheets/Breeze/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/down_arrow-hover.svg b/src/stylesheets/Breeze/down_arrow-hover.svg new file mode 100644 index 0000000..408397f --- /dev/null +++ b/src/stylesheets/Breeze/down_arrow-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/down_arrow.svg b/src/stylesheets/Breeze/down_arrow.svg new file mode 100644 index 0000000..34c5d6a --- /dev/null +++ b/src/stylesheets/Breeze/down_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/down_arrow_disabled.svg b/src/stylesheets/Breeze/down_arrow_disabled.svg new file mode 100644 index 0000000..af74a30 --- /dev/null +++ b/src/stylesheets/Breeze/down_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/hmovetoolbar.svg b/src/stylesheets/Breeze/hmovetoolbar.svg new file mode 100644 index 0000000..57e54c9 --- /dev/null +++ b/src/stylesheets/Breeze/hmovetoolbar.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/hsepartoolbar.svg b/src/stylesheets/Breeze/hsepartoolbar.svg new file mode 100644 index 0000000..a446425 --- /dev/null +++ b/src/stylesheets/Breeze/hsepartoolbar.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/left_arrow.svg b/src/stylesheets/Breeze/left_arrow.svg new file mode 100644 index 0000000..f77acf4 --- /dev/null +++ b/src/stylesheets/Breeze/left_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/left_arrow_disabled.svg b/src/stylesheets/Breeze/left_arrow_disabled.svg new file mode 100644 index 0000000..2d749e7 --- /dev/null +++ b/src/stylesheets/Breeze/left_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/radio_checked-hover.svg b/src/stylesheets/Breeze/radio_checked-hover.svg new file mode 100644 index 0000000..f3d5c98 --- /dev/null +++ b/src/stylesheets/Breeze/radio_checked-hover.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/radio_checked.svg b/src/stylesheets/Breeze/radio_checked.svg new file mode 100644 index 0000000..86ff6bf --- /dev/null +++ b/src/stylesheets/Breeze/radio_checked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/radio_checked_disabled.svg b/src/stylesheets/Breeze/radio_checked_disabled.svg new file mode 100644 index 0000000..269ae12 --- /dev/null +++ b/src/stylesheets/Breeze/radio_checked_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/radio_unchecked-hover.svg b/src/stylesheets/Breeze/radio_unchecked-hover.svg new file mode 100644 index 0000000..f5fc943 --- /dev/null +++ b/src/stylesheets/Breeze/radio_unchecked-hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/radio_unchecked_disabled.svg b/src/stylesheets/Breeze/radio_unchecked_disabled.svg new file mode 100644 index 0000000..41f503d --- /dev/null +++ b/src/stylesheets/Breeze/radio_unchecked_disabled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/right_arrow.svg b/src/stylesheets/Breeze/right_arrow.svg new file mode 100644 index 0000000..a43ea2b --- /dev/null +++ b/src/stylesheets/Breeze/right_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/right_arrow_disabled.svg b/src/stylesheets/Breeze/right_arrow_disabled.svg new file mode 100644 index 0000000..4940025 --- /dev/null +++ b/src/stylesheets/Breeze/right_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/sizegrip.svg b/src/stylesheets/Breeze/sizegrip.svg new file mode 100644 index 0000000..3388f07 --- /dev/null +++ b/src/stylesheets/Breeze/sizegrip.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/spinup_disabled.svg b/src/stylesheets/Breeze/spinup_disabled.svg new file mode 100644 index 0000000..838436d --- /dev/null +++ b/src/stylesheets/Breeze/spinup_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/stylesheet-branch-end-closed.svg b/src/stylesheets/Breeze/stylesheet-branch-end-closed.svg new file mode 100644 index 0000000..a31f5c0 --- /dev/null +++ b/src/stylesheets/Breeze/stylesheet-branch-end-closed.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/stylesheet-branch-end-open.svg b/src/stylesheets/Breeze/stylesheet-branch-end-open.svg new file mode 100644 index 0000000..a31f5c0 --- /dev/null +++ b/src/stylesheets/Breeze/stylesheet-branch-end-open.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/stylesheet-branch-end.svg b/src/stylesheets/Breeze/stylesheet-branch-end.svg new file mode 100644 index 0000000..a1c0a42 --- /dev/null +++ b/src/stylesheets/Breeze/stylesheet-branch-end.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/stylesheet-branch-more.svg b/src/stylesheets/Breeze/stylesheet-branch-more.svg new file mode 100644 index 0000000..ebef839 --- /dev/null +++ b/src/stylesheets/Breeze/stylesheet-branch-more.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/Breeze/stylesheet-vline.svg b/src/stylesheets/Breeze/stylesheet-vline.svg new file mode 100644 index 0000000..688177e --- /dev/null +++ b/src/stylesheets/Breeze/stylesheet-vline.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/transparent.svg b/src/stylesheets/Breeze/transparent.svg new file mode 100644 index 0000000..3a8ca5c --- /dev/null +++ b/src/stylesheets/Breeze/transparent.svg @@ -0,0 +1 @@ + diff --git a/src/stylesheets/Breeze/undock-hover.svg b/src/stylesheets/Breeze/undock-hover.svg new file mode 100644 index 0000000..6bddbd7 --- /dev/null +++ b/src/stylesheets/Breeze/undock-hover.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/Breeze/undock.svg b/src/stylesheets/Breeze/undock.svg new file mode 100644 index 0000000..9ab2197 --- /dev/null +++ b/src/stylesheets/Breeze/undock.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/up_arrow-hover.svg b/src/stylesheets/Breeze/up_arrow-hover.svg new file mode 100644 index 0000000..dd1271a --- /dev/null +++ b/src/stylesheets/Breeze/up_arrow-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/up_arrow.svg b/src/stylesheets/Breeze/up_arrow.svg new file mode 100644 index 0000000..b02bb26 --- /dev/null +++ b/src/stylesheets/Breeze/up_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/up_arrow_disabled.svg b/src/stylesheets/Breeze/up_arrow_disabled.svg new file mode 100644 index 0000000..742e1c5 --- /dev/null +++ b/src/stylesheets/Breeze/up_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/Breeze/vmovetoolbar.svg b/src/stylesheets/Breeze/vmovetoolbar.svg new file mode 100644 index 0000000..0a30d45 --- /dev/null +++ b/src/stylesheets/Breeze/vmovetoolbar.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/stylesheets/Breeze/vsepartoolbars.svg b/src/stylesheets/Breeze/vsepartoolbars.svg new file mode 100644 index 0000000..00e91ab --- /dev/null +++ b/src/stylesheets/Breeze/vsepartoolbars.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/BreezeDark.qss b/src/stylesheets/BreezeDark.qss new file mode 100644 index 0000000..9481c76 --- /dev/null +++ b/src/stylesheets/BreezeDark.qss @@ -0,0 +1,1662 @@ +/* + * BreezeDark stylesheet. + * + * :author: Colin Duquesnoy + * :editor: Alex Huszagh + * :license: MIT, see LICENSE.md + * + * This is originally a fork of QDarkStyleSheet, and is based on Breeze/ + * BreezeDark color scheme, but is in no way affiliated with KDE. + * + * --------------------------------------------------------------------- + * The MIT License (MIT) + * + * Copyright (c) <2013-2014> + * Copyright (c) <2015-2016> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * --------------------------------------------------------------------- + */ + +/* This is an adaptation for ScanTailor Universal + * @path_to_pics@ will be replaced at load time with folder where qss is stored for Win + * or with $CMAKE_INSTALLPREFIX/share/pixmaps/scantailor-universal/stylesheets/ for Linux + */ + +QGraphicsView { + background-color: #76797c; +} + +QToolTip +{ + border: 1px solid #eff0f1; + background-color: #31363b; + alternate-background-color: #3b4045; + color: #eff0f1; + padding: 0.5ex; + opacity: 200; +} + +QWidget +{ + color: #eff0f1; + background-color: #31363b; + selection-background-color:#3daee9; + selection-color: #eff0f1; + background-clip: border; + border-image: none; + border: 0px transparent black; + outline: 0; +} + +QWidget:item:hover +{ + background-color: #3daee9; + color: #eff0f1; +} + +QWidget:item:selected +{ + background-color: #3daee9; +} + + +QCheckBox +{ + spacing: 0.5ex; + outline: none; + color: #eff0f1; + margin-bottom: 0.2ex; + opacity: 200; +} + +QCheckBox:disabled +{ + color: #76797c; +} + +QGroupBox::indicator +{ + margin-left: 0.2ex; +} + +QCheckBox::indicator:unchecked, +QCheckBox::indicator:unchecked:focus +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_unchecked_disabled.svg"); +} + +QCheckBox::indicator:unchecked:hover, +QCheckBox::indicator:unchecked:pressed, +QGroupBox::indicator:unchecked:hover, +QGroupBox::indicator:unchecked:focus, +QGroupBox::indicator:unchecked:pressed +{ + border: none; + border-image: url("@path_to_pics@/BreezeDark/checkbox_unchecked.svg"); +} + +QCheckBox::indicator:checked +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_checked.svg"); +} + +QCheckBox::indicator:checked:hover, +QCheckBox::indicator:checked:focus, +QCheckBox::indicator:checked:pressed, +QGroupBox::indicator:checked:hover, +QGroupBox::indicator:checked:focus, +QGroupBox::indicator:checked:pressed +{ + border: none; + border-image: url("@path_to_pics@/BreezeDark/checkbox_checked.svg"); +} + +QCheckBox::indicator:indeterminate +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_indeterminate.svg"); +} + +QCheckBox::indicator:indeterminate:focus, +QCheckBox::indicator:indeterminate:hover, +QCheckBox::indicator:indeterminate:pressed +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_indeterminate.svg"); +} + +QCheckBox::indicator:indeterminate:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_indeterminate_disabled.svg"); +} + +QCheckBox::indicator:checked:disabled, +QGroupBox::indicator:checked:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_checked_disabled.svg"); +} + +QCheckBox::indicator:unchecked:disabled, +QGroupBox::indicator:unchecked:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_unchecked_disabled.svg"); +} + +QRadioButton +{ + spacing: 0.5ex; + outline: none; + color: #eff0f1; + margin-bottom: 0.2ex; +} + +QRadioButton:disabled +{ + color: #76797c; +} + +QRadioButton::indicator:unchecked, +QRadioButton::indicator:unchecked:focus +{ + border-image: url("@path_to_pics@/BreezeDark/radio_unchecked_disabled.svg"); +} + + +QRadioButton::indicator:unchecked:hover, +QRadioButton::indicator:unchecked:pressed +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/BreezeDark/radio_unchecked.svg"); +} + + +QRadioButton::indicator:checked +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/BreezeDark/radio_checked.svg"); +} + +QRadioButton::indicator:checked:hover, +QRadioButton::indicator:checked:focus, +QRadioButton::indicator:checked:pressed +{ + border: none; + outline: none; + border-image: url("@path_to_pics@/BreezeDark/radio_checked.svg"); +} + +QRadioButton::indicator:checked:disabled +{ + outline: none; + border-image: url("@path_to_pics@/BreezeDark/radio_checked_disabled.svg"); +} + +QRadioButton::indicator:unchecked:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/radio_unchecked_disabled.svg"); +} + +QMenuBar +{ + background-color: #31363b; + color: #eff0f1; +} + +QMenuBar::item +{ + background: transparent; +} + +QMenuBar::item:selected +{ + background: transparent; + border: 1px solid #76797c; +} + +QMenuBar::item:pressed +{ + border: 1px solid #76797c; + background-color: #3daee9; + color: #eff0f1; + margin-bottom: -0.1ex; + padding-bottom: 0.1ex; +} + +QMenu +{ + border: 1px solid #76797c; + color: #eff0f1; + margin: 0.2ex; +} + +QMenu::icon +{ + margin: 0.5ex; +} + +QMenu::item +{ + padding: 0.5ex 3ex 0.5ex 3ex; + margin-left: 0.5ex; + border: 1px solid transparent; /* reserve space for selection border */ +} + +QMenu::item:selected +{ + color: #eff0f1; +} + +QMenu::separator +{ + height: 0.2ex; + background: lightblue; + margin-left: 1ex; + margin-right: 0.5ex; +} + +/* non-exclusive indicator = check box style indicator + (see QActionGroup::setExclusive) */ +QMenu::indicator:non-exclusive:unchecked +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_unchecked_disabled.svg"); +} + +QMenu::indicator:non-exclusive:unchecked:selected +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_unchecked_disabled.svg"); +} + +QMenu::indicator:non-exclusive:checked +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_checked.svg"); +} + +QMenu::indicator:non-exclusive:checked:selected +{ + border-image: url("@path_to_pics@/BreezeDark/checkbox_checked.svg"); +} + +/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +QMenu::indicator:exclusive:unchecked +{ + border-image: url("@path_to_pics@/BreezeDark/radio_unchecked_disabled.svg"); +} + +QMenu::indicator:exclusive:unchecked:selected +{ + border-image: url("@path_to_pics@/BreezeDark/radio_unchecked_disabled.svg"); +} + +QMenu::indicator:exclusive:checked +{ + border-image: url("@path_to_pics@/BreezeDark/radio_checked.svg"); +} + +QMenu::indicator:exclusive:checked:selected +{ + border-image: url("@path_to_pics@/BreezeDark/radio_checked.svg"); +} + +QMenu::right-arrow +{ + margin: 0.5ex; + border-image: url("@path_to_pics@/light/right_arrow.svg"); + width: 0.6ex; + height: 0.9ex; +} + + +QWidget:disabled +{ + color: #454545; + background-color: #31363b; +} + +QAbstractItemView +{ + alternate-background-color: #31363b; + color: #eff0f1; + border: 1px solid 3A3939; + border-radius: 0.2ex; +} + +QWidget:focus, +QMenuBar:focus +{ + border: 1px solid #3daee9; +} + +QTabWidget:focus, +QCheckBox:focus, +QRadioButton:focus, +QSlider:focus +{ + border: none; +} + +QLineEdit +{ + background-color: #232629; + padding: 0.5ex; + border-style: solid; + border: 1px solid #76797c; + border-radius: 0.2ex; + color: #eff0f1; +} + +QGroupBox +{ + border: 1px solid #76797c; + border-radius: 0.2ex; + padding-top: 1ex; + margin-top: 1ex; +} + +QGroupBox::title +{ + subcontrol-origin: margin; + subcontrol-position: top center; + padding-left: 0.1ex; + padding-right: 0.1ex; + margin-top: -0.7ex; +} + +QAbstractScrollArea +{ + border-radius: 0.2ex; + border: 1px solid #76797c; + background-color: transparent; +} + +QScrollBar:horizontal +{ + height: 1.5ex; + margin: 0.3ex 1.5ex 0.3ex 1.5ex; + border: 1px transparent #2A2929; + border-radius: 0.4ex; + background-color: #2A2929; +} + +QScrollBar::handle:horizontal +{ + background-color: #3daee9; + min-width: 0.5ex; + border-radius: 0.4ex; +} + +QScrollBar::add-line:horizontal +{ + margin: 0px 0.3ex 0px 0.3ex; + border-image: url("@path_to_pics@/BreezeDark/right_arrow_disabled.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal +{ + margin: 0ex 0.3ex 0ex 0.3ex; + border-image: url("@path_to_pics@/BreezeDark/left_arrow_disabled.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, +QScrollBar::add-line:horizontal:on +{ + border-image: url("@path_to_pics@/BreezeDark/right_arrow.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: right; + subcontrol-origin: margin; +} + + +QScrollBar::sub-line:horizontal:hover, +QScrollBar::sub-line:horizontal:on +{ + border-image: url("@path_to_pics@/BreezeDark/left_arrow.svg"); + width: 1ex; + height: 1ex; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, +QScrollBar::down-arrow:horizontal +{ + background: none; +} + + +QScrollBar::add-page:horizontal, +QScrollBar::sub-page:horizontal +{ + background: none; +} + +QScrollBar:vertical +{ + background-color: #2A2929; + width: 1.5ex; + margin: 1.5ex 0.3ex 1.5ex 0.3ex; + border: 1px transparent #2A2929; + border-radius: 0.4ex; +} + +QScrollBar::handle:vertical +{ + background-color: #3daee9; + min-height: 0.5ex; + border-radius: 0.4ex; +} + +QScrollBar::sub-line:vertical +{ + margin: 0.3ex 0ex 0.3ex 0ex; + border-image: url("@path_to_pics@/BreezeDark/up_arrow_disabled.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical +{ + margin: 0.3ex 0ex 0.3ex 0ex; + border-image: url("@path_to_pics@/BreezeDark/down_arrow_disabled.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, +QScrollBar::sub-line:vertical:on +{ + + border-image: url("@path_to_pics@/BreezeDark/up_arrow.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: top; + subcontrol-origin: margin; +} + + +QScrollBar::add-line:vertical:hover, +QScrollBar::add-line:vertical:on +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); + height: 1ex; + width: 1ex; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical +{ + background: none; +} + + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; +} + +QTextEdit +{ + background-color: #232629; + color: #eff0f1; + border: 1px solid #76797c; +} + +QPlainTextEdit +{ + background-color: #232629;; + color: #eff0f1; + border-radius: 0.2ex; + border: 1px solid #76797c; +} + +QHeaderView::section +{ + background-color: #76797c; + color: #eff0f1; + padding: 0.5ex; + border: 1px solid #76797c; +} + +QSizeGrip +{ + border-image: url("@path_to_pics@/BreezeDark/sizegrip.svg"); + width: 1.2ex; + height: 1.2ex; +} + +QMainWindow::separator +{ + background-color: #31363b; + color: white; + padding-left: 0.4ex; + spacing: 0.2ex; + border: 1px dashed #76797c; +} + +QMainWindow::separator:hover +{ + + background-color: #787876; + color: white; + padding-left: 0.4ex; + border: 1px solid #76797c; + spacing: 0.2ex; +} + +QMenu::separator +{ + height: 0.1ex; + background-color: #76797c; + color: white; + padding-left: 0.4ex; + margin-left: 1ex; + margin-right: 0.5ex; +} + +QFrame[frameShape="2"], /* QFrame::Panel == 0x0003 */ +QFrame[frameShape="3"], /* QFrame::WinPanel == 0x0003 */ +QFrame[frameShape="4"], /* QFrame::HLine == 0x0004 */ +QFrame[frameShape="5"], /* QFrame::VLine == 0x0005 */ +QFrame[frameShape="6"] /* QFrame::StyledPanel == 0x0006 */ +{ + border-width: 1px; + padding: 0.1ex; + border-style: solid; + border-color: #31363b; + background-color: #76797c; + border-radius: 0.5ex; +} + +QStackedWidget +{ + border: 1px transparent black; +} + +QToolBar +{ + border: 1px transparent #393838; + background: 0.1ex solid #31363b; + font-weight: bold; +} + +QToolBar::handle:horizontal +{ + border-image: url("@path_to_pics@/BreezeDark/hmovetoolbar.svg"); + width = 1.6ex; + height = 6.4ex; +} + +QToolBar::handle:vertical +{ + border-image: url("@path_to_pics@/BreezeDark/vmovetoolbar.svg"); + width = 5.4ex; + height = 1ex; +} + +QToolBar::separator:horizontal +{ + border-image: url("@path_to_pics@/BreezeDark/hsepartoolbar.svg"); + width = 0.7ex; + height = 6.3ex; +} + +QToolBar::separator:vertical +{ + border-image: url("@path_to_pics@/BreezeDark/vsepartoolbars.svg"); + width = 6.3ex; + height = 0.7ex; +} + +QPushButton +{ + color: #eff0f1; + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #3b4045, stop: 0.5 #31363b); + border-width: 1px; + border-color: #76797c; + border-style: solid; + padding: 0.5ex; + border-radius: 0.2ex; + outline: none; +} + +QPushButton:disabled +{ + background-color: #31363b; + border-width: 1px; + border-color: #454545; + border-style: solid; + padding-top: 0.5ex; + padding-bottom: 0.5ex; + padding-left: 1ex; + padding-right: 1ex; + border-radius: 0.2ex; + color: #454545; +} + +QPushButton:focus +{ + color: white; +} + +QPushButton:pressed +{ + background-color: #31363b; + padding-top: -1.5ex; + padding-bottom: -1.7ex; +} + +QComboBox +{ + selection-background-color: #3daee9; + border-style: solid; + border: 1px solid #76797c; + border-radius: 0.2ex; + padding: 0.5ex; + min-width: 7.5ex; +} + +QPushButton:checked +{ + background-color: #76797c; + border-color: #6A6969; +} + +QPushButton:hover +{ + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #454a4f, stop: 0.5 #3b4045); + border: 1px solid #3daee9; + color: #eff0f1; +} + +QPushButton:checked:hover +{ + background-color: qlineargradient(x1: 0.5, y1: 0.5 x2: 0.5, y2: 1, stop: 0 #808386, stop: 0.5 #76797c); + border: 1px solid #3daee9; + color: #eff0f1; +} + +QComboBox:hover, +QAbstractSpinBox:hover, +QLineEdit:hover, +QTextEdit:hover, +QPlainTextEdit:hover, +QAbstractView:hover, +QTreeView:hover +{ + border: 1px solid #3daee9; + color: #eff0f1; +} + +QComboBox:hover:pressed, +QPushButton:hover:pressed, +QAbstractSpinBox:hover:pressed, +QLineEdit:hover:pressed, +QTextEdit:hover:pressed, +QPlainTextEdit:hover:pressed, +QAbstractView:hover:pressed, +QTreeView:hover:pressed +{ + background-color: #31363b; +} + +QComboBox:on +{ + padding-top: 0.3ex; + padding-left: 0.4ex; + selection-background-color: #4a4a4a; +} + +QComboBox QAbstractItemView +{ + background-color: #232629; + border-radius: 0.2ex; + border: 1px solid #76797c; + selection-background-color: #3daee9; +} + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 1.5ex; + + border-left-width: 0ex; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 0.3ex; + border-bottom-right-radius: 0.3ex; +} + +QComboBox::down-arrow +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QComboBox::down-arrow:on, +QComboBox::down-arrow:hover, +QComboBox::down-arrow:focus +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox +{ + padding: 0.5ex; + border: 1px solid #76797c; + background-color: #232629; + color: #eff0f1; + border-radius: 0.2ex; + min-width: 7.5ex; +} + +QAbstractSpinBox:up-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: center right; +} + +QAbstractSpinBox:down-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: center left; +} + +QAbstractSpinBox::up-arrow, +QAbstractSpinBox::up-arrow:disabled, +QAbstractSpinBox::up-arrow:off +{ + border-image: url("@path_to_pics@/BreezeDark/up_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::up-arrow:hover +{ + border-image: url("@path_to_pics@/BreezeDark/up_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::down-arrow, +QAbstractSpinBox::down-arrow:disabled, +QAbstractSpinBox::down-arrow:off +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow_disabled.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QAbstractSpinBox::down-arrow:hover +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QLabel +{ + border: 0ex solid black; +} + +/* BORDERS */ +QTabWidget::pane +{ + padding: 0.5ex; + margin: 0.1ex; +} + +QTabWidget::pane:top +{ + border: 1px solid #76797c; + top: -0.1ex; +} + +QTabWidget::pane:bottom +{ + border: 1px solid #76797c; + bottom: -0.1ex; +} + +QTabWidget::pane:left +{ + border: 1px solid #76797c; + right: -0.1ex; +} + +QTabWidget::pane:right +{ + border: 1px solid #76797c; + left: -0.1ex; +} + + +QTabBar +{ + qproperty-drawBase: 0; + left: 0.5ex; /* move to the right by 0.5ex */ + border-radius: 0.3ex; +} + +QTabBar:focus +{ + border: 0ex transparent black; +} + +QTabBar::close-button +{ + border-image: url("@path_to_pics@/BreezeDark/close.svg"); + background: transparent; +} + +QTabBar::close-button:hover +{ + border-image: url("@path_to_pics@/BreezeDark/close-hover.svg"); + width: 1.2ex; + height: 1.2ex; + background: transparent; +} + +QTabBar::close-button:pressed +{ + border-image: url("@path_to_pics@/BreezeDark/close-pressed.svg"); + width: 1.2ex; + height: 1.2ex; + background: transparent; +} + +/* TOP TABS */ +QTabBar::tab:top +{ + color: #eff0f1; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-top: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + min-width: 50px; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:last, +QTabBar::tab:top:only-one +{ + color: #eff0f1; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-right: 1px solid #76797c; + border-top: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + min-width: 50px; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:first:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:top:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); + border-left: 1px solid #76797c; +} + +QTabBar::tab:top:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); +} + +/* BOTTOM TABS */ + +QTabBar::tab:bottom +{ + color: #eff0f1; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-bottom: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-width: 50px; +} + +QTabBar::tab:bottom:last, +QTabBar::tab:bottom:only-one +{ + color: #eff0f1; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-right: 1px solid #76797c; + border-bottom: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-width: 50px; +} + +QTabBar::tab:bottom:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-left: 1px solid #76797c; + border-bottom-left-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; +} + +QTabBar::tab:bottom:first:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-top-left-radius: 0.2ex; + border-top-right-radius: 0.2ex; +} + +QTabBar::tab:bottom:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); + border-left: 1px solid #76797c; +} + +QTabBar::tab:bottom:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); +} + +/* LEFT TABS */ +QTabBar::tab:left +{ + color: #eff0f1; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-right: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-height: 50px; +} + +QTabBar::tab:left:last, +QTabBar::tab:left:only-one +{ + color: #eff0f1; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-bottom: 1px solid #76797c; + border-right: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; + min-height: 50px; +} + +QTabBar::tab:left:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-top-right-radius: 0.2ex; + border-bottom-right-radius: 0.2ex; +} + +QTabBar::tab:left:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); + border-top: 1px solid #76797c; +} + +QTabBar::tab:left:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); +} + +/* RIGHT TABS */ +QTabBar::tab:right +{ + color: #eff0f1; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-left: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; + min-height: 50px; +} + +QTabBar::tab:right:last, +QTabBar::tab:right:only-one +{ + color: #eff0f1; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-bottom: 1px solid #76797c; + border-left: 1px solid #76797c; + background-color: #31363b; + padding: 0.5ex; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; + min-height: 50px; +} + +QTabBar::tab:right:!selected +{ + color: #eff0f1; + background-color: #54575B; + border: 1px transparent black; + border-top: 1px solid #76797c; + border-top-left-radius: 0.2ex; + border-bottom-left-radius: 0.2ex; +} + +QTabBar::tab:right:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); + border-top: 1px solid #76797c; +} + +QTabBar::tab:right:!selected:first:hover +{ + background-color: rgba(61, 173, 232, 0.2); + border: 1px rgba(61, 173, 232, 0.2); +} + +QTabBar QToolButton::right-arrow:enabled +{ + border-image: url("@path_to_pics@/BreezeDark/right_arrow.svg"); +} + +QTabBar QToolButton::left-arrow:enabled +{ + border-image: url("@path_to_pics@/BreezeDark/left_arrow.svg"); +} + +QTabBar QToolButton::right-arrow:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/right_arrow_disabled.svg"); +} + +QTabBar QToolButton::left-arrow:disabled +{ + border-image: url("@path_to_pics@/BreezeDark/left_arrow_disabled.svg"); +} + +QDockWidget +{ + background: #31363b; + border: 1px solid #403F3F; + titlebar-close-icon: url("@path_to_pics@/BreezeDark/transparent.svg"); + titlebar-normal-icon: url("@path_to_pics@/BreezeDark/transparent.svg"); +} + +QDockWidget::close-button, +QDockWidget::float-button +{ + border: 1px solid transparent; + border-radius: 0.2ex; + background: transparent; +} + +QDockWidget::float-button +{ + border-image: url("@path_to_pics@/BreezeDark/undock.svg"); +} + +QDockWidget::float-button:hover +{ + border-image: url("@path_to_pics@/BreezeDark/undock-hover.svg") ; +} + +QDockWidget::close-button +{ + border-image: url("@path_to_pics@/BreezeDark/close.svg") ; +} + +QDockWidget::close-button:hover +{ + border-image: url("@path_to_pics@/BreezeDark/close-hover.svg") ; +} + +QDockWidget::close-button:pressed +{ + border-image: url("@path_to_pics@/BreezeDark/close-pressed.svg") ; +} + +QTreeView, +QListView +{ + border: 1px solid #76797c; + background-color: #232629; +} + +QTreeView::branch:has-siblings:!adjoins-item +{ + border-image: url("@path_to_pics@/BreezeDark/stylesheet-vline.svg") 0; +} + +QTreeView::branch:has-siblings:adjoins-item +{ + border-image: url("@path_to_pics@/BreezeDark/stylesheet-branch-more.svg") 0; +} + +QTreeView::branch:!has-children:!has-siblings:adjoins-item +{ + border-image: url("@path_to_pics@/BreezeDark/stylesheet-branch-end.svg") 0; +} + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings +{ + border-image: url("@path_to_pics@/BreezeDark/stylesheet-branch-end-closed.svg") 0; + image: url("@path_to_pics@/BreezeDark/branch_closed.svg"); +} + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings +{ + border-image: url("@path_to_pics@/BreezeDark/stylesheet-branch-end-open.svg") 0; + image: url("@path_to_pics@/BreezeDark/branch_open.svg"); +} + +/* +QTreeView::branch:has-siblings:!adjoins-item { + background: cyan; +} + +QTreeView::branch:has-siblings:adjoins-item { + background: red; +} + +QTreeView::branch:!has-children:!has-siblings:adjoins-item { + background: blue; +} + +QTreeView::branch:closed:has-children:has-siblings { + background: pink; +} + +QTreeView::branch:has-children:!has-siblings:closed { + background: gray; +} + +QTreeView::branch:open:has-children:has-siblings { + background: magenta; +} + +QTreeView::branch:open:has-children:!has-siblings { + background: green; +} +*/ + +QTableView::item, +QListView::item, +QTreeView::item +{ + padding: 0.3ex; +} + +QTableView::item:!selected:hover, +QListView::item:!selected:hover, +QTreeView::item:!selected:hover +{ + background-color: rgba(61, 173, 232, 0.2); + outline: 0; + color: #eff0f1; + padding: 0.3ex; +} + + +QSlider::groove:horizontal +{ + border: 1px solid #31363b; + height: 0.4ex; + background: #565a5e; + margin: 0ex; + border-radius: 0.2ex; +} + +QSlider::handle:horizontal +{ + background: #232629; + border: 1px solid #626568; + width: 1.6ex; + height: 1.6ex; + margin: -0.8ex 0; + border-radius: 0.9ex; +} + +QSlider::groove:vertical +{ + border: 1px solid #31363b; + width: 0.4ex; + background: #565a5e; + margin: 0ex; + border-radius: 0.3ex; +} + +QSlider::handle:vertical +{ + background: #232629; + border: 1px solid #626568; + width: 1.6ex; + height: 1.6ex; + margin: 0 -0.8ex; + border-radius: 0.9ex; +} + +QSlider::handle:horizontal:hover, +QSlider::handle:horizontal:focus, +QSlider::handle:vertical:hover, +QSlider::handle:vertical:focus +{ + border: 1px solid #3daee9; +} + +QSlider::sub-page:horizontal, +QSlider::add-page:vertical +{ + background: #3daee9; + border-radius: 0.3ex; +} + +QSlider::add-page:horizontal, +QSlider::sub-page:vertical +{ + background: #626568; + border-radius: 0.3ex; +} + +QToolButton +{ + background-color: transparent; + border: 1px solid #76797c; + border-radius: 0.2ex; + margin: 0.3ex; + padding: 0.5ex; +} + +QToolButton[popupMode="1"] /* only for MenuButtonPopup */ +{ + padding-right: 2ex; /* make way for the popup button */ +} + +QToolButton[popupMode="2"] /* only for InstantPopup */ +{ + padding-right: 1ex; /* make way for the popup button */ +} + +QToolButton::menu-indicator +{ + border-image: none; + image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); + top: -0.7ex; + left: -0.2ex; +} + +QToolButton::menu-arrow +{ + border-image: none; + image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); +} + +QToolButton:hover, +QToolButton::menu-button:hover +{ + background-color: transparent; + border: 1px solid #3daee9; +} + +QToolButton:checked, +QToolButton:pressed, +QToolButton::menu-button:pressed +{ + background-color: #3daee9; + border: 1px solid #3daee9; + padding: 0.5ex; +} + +QToolButton::menu-button +{ + border: 1px solid #76797c; + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + /* 1ex width + 0.4ex for border + no text = 2ex allocated above */ + width: 1ex; + padding: 0.5ex; + outline: none; +} + +QToolButton::menu-arrow:open +{ + border: 1px solid #76797c; +} + +QPushButton::menu-indicator +{ + subcontrol-origin: padding; + subcontrol-position: bottom right; + left: 0.8ex; +} + +QTableView +{ + border: 1px solid #76797c; + gridline-color: #31363b; + background-color: #232629; +} + + +QTableView, +QHeaderView +{ + border-radius: 0px; +} + +QTableView::item:pressed, +QListView::item:pressed, +QTreeView::item:pressed +{ + background: #3daee9; + color: #eff0f1; +} + +QTableView::item:selected:active, +QTreeView::item:selected:active, +QListView::item:selected:active +{ + background: #3daee9; + color: #eff0f1; +} + +QListView::item:selected:hover, +QTreeView::item:selected:hover +{ + background-color: #47b8f3; + color: #eff0f1; +} + +QHeaderView +{ + background-color: #31363b; + border: 1px transparent; + border-radius: 0px; + margin: 0px; + padding: 0px; + +} + +QHeaderView::section +{ + background-color: #31363b; + color: #eff0f1; + padding: 0.5ex; + border: 1px solid #76797c; + border-radius: 0px; + text-align: center; +} + +QHeaderView::section::vertical::first, +QHeaderView::section::vertical::only-one +{ + border-top: 1px solid #76797c; +} + +QHeaderView::section::vertical +{ + border-top: transparent; +} + +QHeaderView::section::horizontal::first, +QHeaderView::section::horizontal::only-one +{ + border-left: 1px solid #76797c; +} + +QHeaderView::section::horizontal +{ + border-left: transparent; +} + + +QHeaderView::section:checked +{ + color: white; + background-color: #334e5e; +} + + /* style the sort indicator */ +QHeaderView::down-arrow +{ + image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); +} + +QHeaderView::up-arrow +{ + image: url("@path_to_pics@/BreezeDark/up_arrow.svg"); +} + +QTableCornerButton::section +{ + background-color: #31363b; + border: 1px transparent #76797c; + border-radius: 0px; +} + +QToolBox +{ + padding: 0.5ex; + border: 1px transparent black; +} + +QToolBox:selected +{ + background-color: #31363b; + border-color: #3daee9; +} + +QToolBox:hover +{ + border-color: #3daee9; +} + +QStatusBar::item +{ + border: 0px transparent dark; +} + +QFrame[height="3"], +QFrame[width="3"] +{ + background-color: #76797c; +} + +QSplitter::handle +{ + border: 1px dashed #76797c; +} + +QSplitter::handle:hover +{ + background-color: #787876; + border: 1px solid #76797c; +} + +QSplitter::handle:horizontal +{ + width: 0.1ex; +} + +QSplitter::handle:vertical +{ + height: 0.1ex; +} + +QProgressBar:horizontal +{ + background-color: #626568; + border: 1px solid #31363b; + border-radius: 0.3ex; + height: 0.5ex; + text-align: right; + margin-top: 0.5ex; + margin-bottom: 0.5ex; + margin-right: 5ex; + padding: 0px; +} + +QProgressBar::chunk:horizontal +{ + background-color: #3daee9; + border: 1px transparent; + border-radius: 0.3ex; +} + +QSpinBox, +QDoubleSpinBox +{ + padding-right: 1.5ex; +} + +QSpinBox::up-button, +QDoubleSpinBox::up-button +{ + subcontrol-origin: content; + subcontrol-position: right top; + + width: 1.6ex; + border-width: 1px; +} + +QSpinBox::up-arrow, +QDoubleSpinBox::up-arrow +{ + border-image: url("@path_to_pics@/BreezeDark/up_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::up-arrow:hover, +QSpinBox::up-arrow:pressed, +QDoubleSpinBox::up-arrow:hover, +QDoubleSpinBox::up-arrow:pressed +{ + border-image: url("@path_to_pics@/BreezeDark/up_arrow-hover.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::up-arrow:disabled, +QSpinBox::up-arrow:off, +QDoubleSpinBox::up-arrow:disabled, +QDoubleSpinBox::up-arrow:off +{ + border-image: url("@path_to_pics@/BreezeDark/up_arrow_disabled.svg"); +} + +QSpinBox::down-button, +QDoubleSpinBox::down-button +{ + subcontrol-origin: content; + subcontrol-position: right bottom; + + width: 1.6ex; + border-width: 1px; +} + +QSpinBox::down-arrow, +QDoubleSpinBox::down-arrow +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::down-arrow:hover, +QSpinBox::down-arrow:pressed, +QDoubleSpinBox::down-arrow:hover, +QDoubleSpinBox::down-arrow:pressed +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow-hover.svg"); + width: 0.9ex; + height: 0.6ex; +} + +QSpinBox::down-arrow:disabled, +QSpinBox::down-arrow:off, +QDoubleSpinBox::down-arrow:disabled, +QDoubleSpinBox::down-arrow:off +{ + border-image: url("@path_to_pics@/BreezeDark/down_arrow_disabled.svg"); +} + +RelinkingDialog QListView::item +{ + margin-right: 1.8em; +} diff --git a/src/stylesheets/BreezeDark/LICENSE.md b/src/stylesheets/BreezeDark/LICENSE.md new file mode 100644 index 0000000..ef01015 --- /dev/null +++ b/src/stylesheets/BreezeDark/LICENSE.md @@ -0,0 +1,26 @@ +The MIT License (MIT) +===================== + +Copyright © `<2013-2014>` `` +Copyright © `<2015-2016>` `` + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/stylesheets/BreezeDark/README.md b/src/stylesheets/BreezeDark/README.md new file mode 100644 index 0000000..33b930a --- /dev/null +++ b/src/stylesheets/BreezeDark/README.md @@ -0,0 +1,23 @@ +BreezeStyleSheets for STU +================= + +Breeze and BreezeDark-like stylesheets adapted for [Scan Tailor Universal](https://github.com/trufanov-nok/scantailor-universal) + +License +======= + +MIT, see [license](/LICENSE.md). + +Acknowledgements +================ + +*BreezeStyleSheets for STU* is a fork of [BreezeStyleSheets](https://github.com/trufanov-nok/BreezeStyleSheets). +[BreezeStyleSheets](https://github.com/trufanov-nok/BreezeStyleSheets) is a fork of [QDarkStyleSheet](https://github.com/ColinDuquesnoy/QDarkStyleSheet). + +Contacts of BreezeStyleSheets author +======= + +Alexander Huszagh +Email: ahuszagh@gmail.com +Twitter: KardOnIce + diff --git a/src/stylesheets/BreezeDark/branch_closed-on.svg b/src/stylesheets/BreezeDark/branch_closed-on.svg new file mode 100644 index 0000000..8bd398f --- /dev/null +++ b/src/stylesheets/BreezeDark/branch_closed-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/branch_closed.svg b/src/stylesheets/BreezeDark/branch_closed.svg new file mode 100644 index 0000000..f5a072f --- /dev/null +++ b/src/stylesheets/BreezeDark/branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/branch_open-on.svg b/src/stylesheets/BreezeDark/branch_open-on.svg new file mode 100644 index 0000000..4dd0c06 --- /dev/null +++ b/src/stylesheets/BreezeDark/branch_open-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/branch_open.svg b/src/stylesheets/BreezeDark/branch_open.svg new file mode 100644 index 0000000..0745890 --- /dev/null +++ b/src/stylesheets/BreezeDark/branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/checkbox_checked.svg b/src/stylesheets/BreezeDark/checkbox_checked.svg new file mode 100644 index 0000000..6753d8b --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_checked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/BreezeDark/checkbox_checked_disabled.svg b/src/stylesheets/BreezeDark/checkbox_checked_disabled.svg new file mode 100644 index 0000000..ff7e63a --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_checked_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/BreezeDark/checkbox_indeterminate.svg b/src/stylesheets/BreezeDark/checkbox_indeterminate.svg new file mode 100644 index 0000000..0f17124 --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_indeterminate.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/BreezeDark/checkbox_indeterminate_disabled.svg b/src/stylesheets/BreezeDark/checkbox_indeterminate_disabled.svg new file mode 100644 index 0000000..bc0f285 --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_indeterminate_disabled.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/BreezeDark/checkbox_unchecked.svg b/src/stylesheets/BreezeDark/checkbox_unchecked.svg new file mode 100644 index 0000000..6f3e569 --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_unchecked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/checkbox_unchecked_disabled.svg b/src/stylesheets/BreezeDark/checkbox_unchecked_disabled.svg new file mode 100644 index 0000000..dd73f75 --- /dev/null +++ b/src/stylesheets/BreezeDark/checkbox_unchecked_disabled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/close-hover.svg b/src/stylesheets/BreezeDark/close-hover.svg new file mode 100644 index 0000000..e2b0dd8 --- /dev/null +++ b/src/stylesheets/BreezeDark/close-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/close-pressed.svg b/src/stylesheets/BreezeDark/close-pressed.svg new file mode 100644 index 0000000..a0dc249 --- /dev/null +++ b/src/stylesheets/BreezeDark/close-pressed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/close.svg b/src/stylesheets/BreezeDark/close.svg new file mode 100644 index 0000000..07b50c9 --- /dev/null +++ b/src/stylesheets/BreezeDark/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/down_arrow-hover.svg b/src/stylesheets/BreezeDark/down_arrow-hover.svg new file mode 100644 index 0000000..408397f --- /dev/null +++ b/src/stylesheets/BreezeDark/down_arrow-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/down_arrow.svg b/src/stylesheets/BreezeDark/down_arrow.svg new file mode 100644 index 0000000..a50df00 --- /dev/null +++ b/src/stylesheets/BreezeDark/down_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/down_arrow_disabled.svg b/src/stylesheets/BreezeDark/down_arrow_disabled.svg new file mode 100644 index 0000000..af74a30 --- /dev/null +++ b/src/stylesheets/BreezeDark/down_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/hmovetoolbar.svg b/src/stylesheets/BreezeDark/hmovetoolbar.svg new file mode 100644 index 0000000..e4904db --- /dev/null +++ b/src/stylesheets/BreezeDark/hmovetoolbar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/hsepartoolbar.svg b/src/stylesheets/BreezeDark/hsepartoolbar.svg new file mode 100644 index 0000000..89beb22 --- /dev/null +++ b/src/stylesheets/BreezeDark/hsepartoolbar.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/left_arrow.svg b/src/stylesheets/BreezeDark/left_arrow.svg new file mode 100644 index 0000000..9c787ce --- /dev/null +++ b/src/stylesheets/BreezeDark/left_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/left_arrow_disabled.svg b/src/stylesheets/BreezeDark/left_arrow_disabled.svg new file mode 100644 index 0000000..2d749e7 --- /dev/null +++ b/src/stylesheets/BreezeDark/left_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/radio_checked.svg b/src/stylesheets/BreezeDark/radio_checked.svg new file mode 100644 index 0000000..b8f7064 --- /dev/null +++ b/src/stylesheets/BreezeDark/radio_checked.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/BreezeDark/radio_checked_disabled.svg b/src/stylesheets/BreezeDark/radio_checked_disabled.svg new file mode 100644 index 0000000..523ee00 --- /dev/null +++ b/src/stylesheets/BreezeDark/radio_checked_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/BreezeDark/radio_unchecked.svg b/src/stylesheets/BreezeDark/radio_unchecked.svg new file mode 100644 index 0000000..1a556e3 --- /dev/null +++ b/src/stylesheets/BreezeDark/radio_unchecked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/radio_unchecked_disabled.svg b/src/stylesheets/BreezeDark/radio_unchecked_disabled.svg new file mode 100644 index 0000000..b3da8a2 --- /dev/null +++ b/src/stylesheets/BreezeDark/radio_unchecked_disabled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/right_arrow.svg b/src/stylesheets/BreezeDark/right_arrow.svg new file mode 100644 index 0000000..b793513 --- /dev/null +++ b/src/stylesheets/BreezeDark/right_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/right_arrow_disabled.svg b/src/stylesheets/BreezeDark/right_arrow_disabled.svg new file mode 100644 index 0000000..4940025 --- /dev/null +++ b/src/stylesheets/BreezeDark/right_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/sizegrip.svg b/src/stylesheets/BreezeDark/sizegrip.svg new file mode 100644 index 0000000..3388f07 --- /dev/null +++ b/src/stylesheets/BreezeDark/sizegrip.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/spinup_disabled.svg b/src/stylesheets/BreezeDark/spinup_disabled.svg new file mode 100644 index 0000000..838436d --- /dev/null +++ b/src/stylesheets/BreezeDark/spinup_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/stylesheet-branch-end-closed.svg b/src/stylesheets/BreezeDark/stylesheet-branch-end-closed.svg new file mode 100644 index 0000000..eb73b13 --- /dev/null +++ b/src/stylesheets/BreezeDark/stylesheet-branch-end-closed.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/stylesheet-branch-end-open.svg b/src/stylesheets/BreezeDark/stylesheet-branch-end-open.svg new file mode 100644 index 0000000..eb73b13 --- /dev/null +++ b/src/stylesheets/BreezeDark/stylesheet-branch-end-open.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/stylesheet-branch-end.svg b/src/stylesheets/BreezeDark/stylesheet-branch-end.svg new file mode 100644 index 0000000..334ca0c --- /dev/null +++ b/src/stylesheets/BreezeDark/stylesheet-branch-end.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/stylesheet-branch-more.svg b/src/stylesheets/BreezeDark/stylesheet-branch-more.svg new file mode 100644 index 0000000..f5250ba --- /dev/null +++ b/src/stylesheets/BreezeDark/stylesheet-branch-more.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/stylesheets/BreezeDark/stylesheet-vline.svg b/src/stylesheets/BreezeDark/stylesheet-vline.svg new file mode 100644 index 0000000..4e7ff6a --- /dev/null +++ b/src/stylesheets/BreezeDark/stylesheet-vline.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/transparent.svg b/src/stylesheets/BreezeDark/transparent.svg new file mode 100644 index 0000000..3a8ca5c --- /dev/null +++ b/src/stylesheets/BreezeDark/transparent.svg @@ -0,0 +1 @@ + diff --git a/src/stylesheets/BreezeDark/undock-hover.svg b/src/stylesheets/BreezeDark/undock-hover.svg new file mode 100644 index 0000000..6bddbd7 --- /dev/null +++ b/src/stylesheets/BreezeDark/undock-hover.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/stylesheets/BreezeDark/undock.svg b/src/stylesheets/BreezeDark/undock.svg new file mode 100644 index 0000000..9ab2197 --- /dev/null +++ b/src/stylesheets/BreezeDark/undock.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/up_arrow-hover.svg b/src/stylesheets/BreezeDark/up_arrow-hover.svg new file mode 100644 index 0000000..dd1271a --- /dev/null +++ b/src/stylesheets/BreezeDark/up_arrow-hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/up_arrow.svg b/src/stylesheets/BreezeDark/up_arrow.svg new file mode 100644 index 0000000..9f42239 --- /dev/null +++ b/src/stylesheets/BreezeDark/up_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/up_arrow_disabled.svg b/src/stylesheets/BreezeDark/up_arrow_disabled.svg new file mode 100644 index 0000000..742e1c5 --- /dev/null +++ b/src/stylesheets/BreezeDark/up_arrow_disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/stylesheets/BreezeDark/vmovetoolbar.svg b/src/stylesheets/BreezeDark/vmovetoolbar.svg new file mode 100644 index 0000000..0a30d45 --- /dev/null +++ b/src/stylesheets/BreezeDark/vmovetoolbar.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/stylesheets/BreezeDark/vsepartoolbars.svg b/src/stylesheets/BreezeDark/vsepartoolbars.svg new file mode 100644 index 0000000..00e91ab --- /dev/null +++ b/src/stylesheets/BreezeDark/vsepartoolbars.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/stylesheets/CMakeLists.txt b/src/stylesheets/CMakeLists.txt deleted file mode 100644 index 65cfa60..0000000 --- a/src/stylesheets/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -FILE(GLOB_RECURSE QSS_FILES *.qss) -SET(STYLESHEET_PIXMAP_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/BreezeStyleSheets/Breeze" - "${CMAKE_CURRENT_SOURCE_DIR}/BreezeStyleSheets/BreezeDark") -IF(WIN32 OR APPLE) - # Let QSS_FILES and STYLESHEET_PIXMAP_DIRS be accessible in packaging/windows/ - SET (QSS_FILES ${QSS_FILES} PARENT_SCOPE) - SET (STYLESHEET_PIXMAP_DIRS ${STYLESHEET_PIXMAP_DIRS} PARENT_SCOPE) -ELSE(WIN32 OR APPLE) - SET(QSS_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/share/scantailor-universal/stylesheets") - SET(PIX_INSTALL_PATH ${PIXMAPS_DIR_ABS}) - INSTALL(FILES ${QSS_FILES} DESTINATION ${QSS_INSTALL_PATH}) - INSTALL(DIRECTORY ${STYLESHEET_PIXMAP_DIRS} DESTINATION ${PIX_INSTALL_PATH}) -ENDIF(WIN32 OR APPLE) diff --git a/src/stylesheets/dark_blue.qss b/src/stylesheets/dark_blue.qss new file mode 100644 index 0000000..ed7ee02 --- /dev/null +++ b/src/stylesheets/dark_blue.qss @@ -0,0 +1,785 @@ +/*** Borders ***/ + +/** Borders - Base **/ + +NewOpenProjectPanel > QWidget, +QComboBox, +QDoubleSpinBox, +QGroupBox, +QLineEdit, +QListView, +QPushButton, +QSlider:handle, +QSpinBox, +QTableView, +QToolButton, +QTreeView +{ + border-style: solid; + border-width: 1px; + border-radius: 2px; +} + +QTabBar:tab +{ + border-style: solid; + border-width: 1px; +} + +QComboBox:drop-down +{ + border: none; +} + +QSplitter:handle +{ + border-style: dashed; + border-left-width: 1px; + border-right-width: 1px; +} + +QMainWindow:separator +{ + border-style: dashed; + border-width: 1px; +} + +QScrollBar:handle +{ + border-radius: 0.2em; +} + +QSlider::groove +{ + border-radius: 0.12em; +} + +/** Borders - Focus **/ + +QComboBox QListView, +QComboBox:focus, +QComboBox:open, +QDoubleSpinBox:focus, +QLineEdit:focus, +QPushButton:focus, +QSlider::handle:focus, +QSpinBox:focus, +QToolButton:focus +{ + border-style: solid; + border-width: 2px; + border-radius: 4px; +} + +QTabBar:tab:selected, +QToolButton:focus +{ + border-style: solid; + border-width: 2px; +} + +/** Borders - Hover**/ + +QListView:item:hover, +QTableView:item:hover, +QTreeView:item:first:hover +{ + border-width: 1px; + border-style: solid; +} + +QTreeView:item:!first:hover, +QTreeView:item:!first:selected +{ + border: none; +} + +/*** Colors ***/ + +/** Colors - Borders **/ + +/* Colors - Borders - Base */ + +NewOpenProjectPanel > QWidget, +QComboBox, +QDoubleSpinBox, +QLineEdit, +QPushButton, +QSlider:handle, +QSpinBox, +QTabBar:tab, +QToolButton +{ + border-color: #F0F0F0; +} + +QGroupBox, +QListView, +QMainWindow:separator, +QSplitter:handle, +QTableView, +QTreeView +{ + border-color: #646464; +} + +/* Colors - Borders - Disabled */ + +QComboBox:disabled, +QDoubleSpinBox:disabled, +QLineEdit:disabled, +QSpinBox:disabled +{ + border-color: #646464; +} + +QPushButton:disabled, +QSlider:handle:disabled, +QToolButton:disabled +{ + border-color: #7F7F7F; +} + +/* Colors - Borders - Focus */ + +QComboBox QListView, +QComboBox:focus, +QComboBox:open, +QDoubleSpinBox:focus, +QLineEdit:focus, +QPushButton:focus, +QSlider::handle:focus, +QSpinBox:focus, +QToolButton:focus +{ + border-color: #40A0F0; +} + +/* Colors - Borders - Hover */ + +QComboBox:hover, +QDoubleSpinBox:hover, +QLineEdit:hover, +QListView:item:hover, +QPushButton:hover, +QSlider::handle:hover, +QSpinBox:hover, +QTabBar:tab:!selected:hover, +QTableView:item:hover, +QToolButton:hover, +QTreeView:item:first:hover +{ + border-color: #40A0F0; +} + +/* Colors - Widgets */ + +/* Colors - Widgets - All */ + +QHeaderView:section, +QWidget +{ + color: #F0F0F0; + background-color: #333333; + selection-color: #FFFFFF; + selection-background-color: #40A0F0; +} + +/* Colors - Widgets - Base */ + +QComboBox, +QDoubleSpinBox, +QLineEdit, +QSpinBox +{ + background-color: #242424; +} + +QDoubleSpinBox:down-button, +QDoubleSpinBox:up-button, +QMenuBar:item, +QScrollBar:add-line, +QScrollBar:add-page, +QScrollBar:sub-line, +QScrollBar:sub-page, +QSizeGrip, +QSpinBox:down-button, +QSpinBox:up-button, +QStatusBar:item +{ + background-color: transparent; +} + +QPushButton, +QScrollBar, +QSlider:handle, +QTabBar:tab, +QToolButton +{ + background-color: #505050; +} + +QScrollBar:handle, +QSlider::groove +{ + background-color: #C9C9C9; +} + +QTableView, +QTreeView +{ + alternate-background-color: #242424; +} + +/* Colors - Widgets - Disabled */ + +QCheckBox:disabled, +QComboBox:disabled, +QDoubleSpinBox:disabled, +QGroupBox:disabled, +QLabel:disabled, +QLineEdit:disabled, +QRadioButton:disabled, +QSpinBox:disabled +{ + color: #646464; +} + +QScrollBar:handle:disabled +{ + background-color: #646464; +} + +QPushButton:disabled, +QSlider:handle:disabled, +QToolButton:disabled +{ + color: #7F7F7F; +} + +QSlider:groove:disabled +{ + background-color: #7F7F7F; +} + +/* Colors - Widgets - Focus */ + +QComboBox:focus, +QDoubleSpinBox:focus, +QLineEdit:focus, +QPushButton:focus, +QSpinBox:focus, +QToolButton:focus +{ + color: #FFFFFF; +} + +QSlider:groove:focus, +QToolButton:checked +{ + background-color: #40A0F0; +} + +/* Colors - Widgets - Hover */ + +QCheckBox:hover, +QGroupBox:title:hover, +QRadioButton:hover +{ + color: #40A0F0; +} + +QScrollBar:handle:hover, +QSlider:groove:hover, +QTreeView:branch:closed:has-children:hover, +QTreeView:branch:open:has-children:hover +{ + background-color: #40A0F0; +} + +/* Colors - Widgets - Selected */ + +QListView:item:selected, +QMenuBar:item:selected, +QTabBar:tab:selected, +QTableView:item:selected, +QTreeView:branch:selected, +QTreeView:item:selected +{ + color: #FFFFFF; + background-color: #40A0F0; +} + +/*** Images ***/ + +/** Images - CheckBox **/ + +QCheckBox:indicator:checked, +QListView:indicator:checked, +QTreeView:indicator:checked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_checked.svg); +} + +QCheckBox:indicator:unchecked, +QListView:indicator:unchecked, +QTreeView:indicator:unchecked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked.svg); +} + +QCheckBox:indicator:unchecked:hover, +QListView:indicator:unchecked:hover, +QTreeView:indicator:unchecked:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked_hover.svg); +} + +QCheckBox:indicator:indeterminate, +QListView:indicator:indeterminate, +QTreeView:indicator:indeterminate +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_indeterminate.svg); +} + +QCheckBox:indicator:indeterminate:hover, +QListView:indicator:indeterminate:hover, +QTreeView:indicator:indeterminate:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_indeterminate_hover.svg); +} + +QCheckBox:indicator:checked:disabled, +QListView:indicator:checked:disabled, +QTreeView:indicator:checked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_checked_disabled.svg); +} + +QCheckBox:indicator:unchecked:disabled, +QListView:indicator:unchecked:disabled, +QTreeView:indicator:unchecked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked_disabled.svg); +} + +QCheckBox:indicator:indeterminate:disabled, +QListView:indicator:indeterminate:disabled, +QTreeView:indicator:indeterminate:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_indeterminate_disabled.svg); +} + +/** Images - ComboBox **/ + +QComboBox:down-arrow +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/combobox_arrow_down.svg); +} + +QComboBox:down-arrow:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/combobox_arrow_down_disabled.svg); +} + +/** Images - GroupBox **/ + +QGroupBox:indicator:checked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_checked.svg); +} + +QGroupBox:indicator:unchecked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked.svg); +} + +QGroupBox:indicator:unchecked:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked_hover.svg); +} + +QGroupBox:indicator:indeterminate +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_indeterminate.svg); +} + +QGroupBox:indicator:checked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_checked_disabled.svg); +} + +QGroupBox:indicator:unchecked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_unchecked_disabled.svg); +} + +QGroupBox:indicator:indeterminate:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/checkbox_indeterminate_disabled.svg); +} + +/** Images - SpinBox **/ + +QDoubleSpinBox:up-arrow, +QSpinBox:up-arrow +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/spinbox_arrow_up.svg); +} + +QDoubleSpinBox:down-arrow, +QSpinBox:down-arrow +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/spinbox_arrow_down.svg); +} + +QDoubleSpinBox:up-arrow:disabled, +QSpinBox:up-arrow:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/spinbox_arrow_up_disabled.svg); +} + +QDoubleSpinBox:down-arrow:disabled, +QSpinBox:down-arrow:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/spinbox_arrow_down_disabled.svg); +} + +/* Images - RadioButton */ + +QRadioButton:indicator:checked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/radiobutton_checked.svg); +} + +QRadioButton:indicator:unchecked +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/radiobutton_unchecked.svg); +} + +QRadioButton:indicator:unchecked:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/radiobutton_unchecked_hover.svg); +} + +QRadioButton:indicator:checked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/radiobutton_checked_disabled.svg); +} + +QRadioButton:indicator:unchecked:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/radiobutton_unchecked_disabled.svg); +} + +QTableView:item, +QTreeView:item +{ + height: 1.7em; +} + +/* Images - ScrollBar */ + +QScrollBar:up-arrow:vertical +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_up.svg); +} + +QScrollBar:down-arrow:vertical +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_down.svg); +} + +QScrollBar:right-arrow:horizontal +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_right.svg); +} + +QScrollBar:left-arrow:horizontal +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_left.svg); +} + +QScrollBar:up-arrow:vertical:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_up_hover.svg); +} + +QScrollBar:down-arrow:vertical:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_down_hover.svg); +} + +QScrollBar:right-arrow:horizontal:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_right_hover.svg); +} + +QScrollBar:left-arrow:horizontal:hover +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_left_hover.svg); +} + +QScrollBar:up-arrow:vertical:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_up_disabled.svg); +} + +QScrollBar:down-arrow:vertical:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_down_disabled.svg); +} + +QScrollBar:up-arrow:horizontal:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_right_disabled.svg); +} + +QScrollBar:down-arrow:horizontal:disabled +{ + width: 1em; + height: 1em; + image: url(@path_to_pics@/dark_blue/scrollbar_arrow_left_disabled.svg); +} + +/* Images - SizeGrip */ + +QSizeGrip +{ + width: 1.5em; + height: 1.5em; + image: url(@path_to_pics@/dark_blue/sizegrip.svg); +} + +QSizeGrip:hover +{ + width: 1.5em; + height: 1.5em; + image: url(@path_to_pics@/dark_blue/sizegrip_hover.svg); +} + +/** Images - TreeView **/ + +QTreeView:branch +{ + background: transparent; +} + +QTreeView:branch:closed:has-children +{ + image: url(@path_to_pics@/dark_blue/treeview_arrow_right.svg); +} + +QTreeView:branch:open:has-children +{ + image: url(@path_to_pics@/dark_blue/treeview_arrow_down.svg); +} + +QTreeView:branch:has-siblings:adjoins-item +{ + border-image: url(@path_to_pics@/dark_blue/treeview_line_sibling_item.svg); +} + +QTreeView:branch:has-siblings:!adjoins-item +{ + border-image: url(@path_to_pics@/dark_blue/treeview_line_sibling.svg); +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item, +QTreeView:branch:has-children:!has-siblings +{ + border-image: url(@path_to_pics@/dark_blue/treeview_line_item.svg); +} + +QTreeView:indicator:checked:selected +{ + image: url(@path_to_pics@/dark_blue/treeview_indicator_checked_selected.svg); +} + +/*** Margins ***/ + +QGroupBox +{ + margin: 0.5em 0 0 0; +} + +QScrollBar:handle:horizontal +{ + margin: 0.2em 1em 0.2em 1em; +} + +QScrollBar:handle:vertical +{ + margin: 1em 0.2em 1em 0.2em; +} + +QSlider::handle:horizontal +{ + margin: -0.4em 0 -0.4em 0; +} + +QSlider::handle:vertical +{ + margin: 0 -0.4em 0 -0.4em; +} + +RelinkingDialog QListView::item +{ + margin-right: 1.5em; +} + +/*** Paddings ***/ + +QComboBox, +QDoubleSpinBox, +QLineEdit, +QSpinBox +{ + padding: 0.1em 0.3em 0.1em 0.3em; +} + +QGroupBox +{ + padding: 0.5em 0.1em 0.5em 0.1em; +} + +QGroupBox:title +{ + padding: 0 0.25em 0 0.25em; +} + +QPushButton +{ + padding: 0.3em 0.5em 0.3em 0.5em; +} + +QTabBar:tab:bottom, +QTabBar:tab:top +{ + padding: 0.3em 0.6em 0.3em 0.6em; +} + +QTabBar:tab:left, +QTabBar:tab:right +{ + padding: 0.6em 0.3em 0.6em 0.3em; +} + +/*** Positions ***/ + +QGroupBox:title +{ + subcontrol-origin: margin; + left: 1em; +} + +/*** Sizes ***/ + +QSlider::handle +{ + width: 1em; + height: 1em; +} + +QScrollBar:horizontal +{ + height: 1em; +} + +QScrollBar:vertical +{ + width: 1em; +} + +QSlider::groove:horizontal +{ + height: 0.3em; +} +QSlider::groove:vertical +{ + width: 0.3em; +} + +QScrollBar:handle:vertical +{ + min-height: 1em; +} + +QScrollBar:handle:horizontal +{ + min-width: 1em; +} diff --git a/src/stylesheets/dark_blue/checkbox_checked.svg b/src/stylesheets/dark_blue/checkbox_checked.svg new file mode 100644 index 0000000..09739d9 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_checked.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_checked_disabled.svg b/src/stylesheets/dark_blue/checkbox_checked_disabled.svg new file mode 100644 index 0000000..a7a5769 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_checked_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_indeterminate.svg b/src/stylesheets/dark_blue/checkbox_indeterminate.svg new file mode 100644 index 0000000..6f354a6 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_indeterminate.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_indeterminate_disabled.svg b/src/stylesheets/dark_blue/checkbox_indeterminate_disabled.svg new file mode 100644 index 0000000..f8f5914 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_indeterminate_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_indeterminate_hover.svg b/src/stylesheets/dark_blue/checkbox_indeterminate_hover.svg new file mode 100644 index 0000000..a532d6b --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_indeterminate_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_unchecked.svg b/src/stylesheets/dark_blue/checkbox_unchecked.svg new file mode 100644 index 0000000..1070c96 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_unchecked.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_unchecked_disabled.svg b/src/stylesheets/dark_blue/checkbox_unchecked_disabled.svg new file mode 100644 index 0000000..83ae5c9 --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_unchecked_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/checkbox_unchecked_hover.svg b/src/stylesheets/dark_blue/checkbox_unchecked_hover.svg new file mode 100644 index 0000000..f6a3f4c --- /dev/null +++ b/src/stylesheets/dark_blue/checkbox_unchecked_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/combobox_arrow_down.svg b/src/stylesheets/dark_blue/combobox_arrow_down.svg new file mode 100644 index 0000000..021f651 --- /dev/null +++ b/src/stylesheets/dark_blue/combobox_arrow_down.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/combobox_arrow_down_disabled.svg b/src/stylesheets/dark_blue/combobox_arrow_down_disabled.svg new file mode 100644 index 0000000..f769e8f --- /dev/null +++ b/src/stylesheets/dark_blue/combobox_arrow_down_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/radiobutton_checked.svg b/src/stylesheets/dark_blue/radiobutton_checked.svg new file mode 100644 index 0000000..ce371ee --- /dev/null +++ b/src/stylesheets/dark_blue/radiobutton_checked.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/radiobutton_checked_disabled.svg b/src/stylesheets/dark_blue/radiobutton_checked_disabled.svg new file mode 100644 index 0000000..2019d27 --- /dev/null +++ b/src/stylesheets/dark_blue/radiobutton_checked_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/radiobutton_unchecked.svg b/src/stylesheets/dark_blue/radiobutton_unchecked.svg new file mode 100644 index 0000000..6a67e45 --- /dev/null +++ b/src/stylesheets/dark_blue/radiobutton_unchecked.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/radiobutton_unchecked_disabled.svg b/src/stylesheets/dark_blue/radiobutton_unchecked_disabled.svg new file mode 100644 index 0000000..880c70d --- /dev/null +++ b/src/stylesheets/dark_blue/radiobutton_unchecked_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/radiobutton_unchecked_hover.svg b/src/stylesheets/dark_blue/radiobutton_unchecked_hover.svg new file mode 100644 index 0000000..c2d6ce3 --- /dev/null +++ b/src/stylesheets/dark_blue/radiobutton_unchecked_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_down.svg b/src/stylesheets/dark_blue/scrollbar_arrow_down.svg new file mode 100644 index 0000000..583884a --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_down.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_down_disabled.svg b/src/stylesheets/dark_blue/scrollbar_arrow_down_disabled.svg new file mode 100644 index 0000000..8cbf3de --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_down_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_down_hover.svg b/src/stylesheets/dark_blue/scrollbar_arrow_down_hover.svg new file mode 100644 index 0000000..1b80807 --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_down_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_left.svg b/src/stylesheets/dark_blue/scrollbar_arrow_left.svg new file mode 100644 index 0000000..7a01f02 --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_left.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_left_disabled.svg b/src/stylesheets/dark_blue/scrollbar_arrow_left_disabled.svg new file mode 100644 index 0000000..5cd5d3b --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_left_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_left_hover.svg b/src/stylesheets/dark_blue/scrollbar_arrow_left_hover.svg new file mode 100644 index 0000000..9ecc0fd --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_left_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_right.svg b/src/stylesheets/dark_blue/scrollbar_arrow_right.svg new file mode 100644 index 0000000..5a812f3 --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_right.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_right_disabled.svg b/src/stylesheets/dark_blue/scrollbar_arrow_right_disabled.svg new file mode 100644 index 0000000..f40c978 --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_right_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_right_hover.svg b/src/stylesheets/dark_blue/scrollbar_arrow_right_hover.svg new file mode 100644 index 0000000..833926b --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_right_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_up.svg b/src/stylesheets/dark_blue/scrollbar_arrow_up.svg new file mode 100644 index 0000000..eed676c --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_up.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_up_disabled.svg b/src/stylesheets/dark_blue/scrollbar_arrow_up_disabled.svg new file mode 100644 index 0000000..645553f --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_up_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/scrollbar_arrow_up_hover.svg b/src/stylesheets/dark_blue/scrollbar_arrow_up_hover.svg new file mode 100644 index 0000000..97b3547 --- /dev/null +++ b/src/stylesheets/dark_blue/scrollbar_arrow_up_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/sizegrip.svg b/src/stylesheets/dark_blue/sizegrip.svg new file mode 100644 index 0000000..103c483 --- /dev/null +++ b/src/stylesheets/dark_blue/sizegrip.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/sizegrip_hover.svg b/src/stylesheets/dark_blue/sizegrip_hover.svg new file mode 100644 index 0000000..e76b647 --- /dev/null +++ b/src/stylesheets/dark_blue/sizegrip_hover.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/spinbox_arrow_down.svg b/src/stylesheets/dark_blue/spinbox_arrow_down.svg new file mode 100644 index 0000000..ba78ae5 --- /dev/null +++ b/src/stylesheets/dark_blue/spinbox_arrow_down.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/spinbox_arrow_down_disabled.svg b/src/stylesheets/dark_blue/spinbox_arrow_down_disabled.svg new file mode 100644 index 0000000..ffc4ca8 --- /dev/null +++ b/src/stylesheets/dark_blue/spinbox_arrow_down_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/spinbox_arrow_up.svg b/src/stylesheets/dark_blue/spinbox_arrow_up.svg new file mode 100644 index 0000000..26bb652 --- /dev/null +++ b/src/stylesheets/dark_blue/spinbox_arrow_up.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/spinbox_arrow_up_disabled.svg b/src/stylesheets/dark_blue/spinbox_arrow_up_disabled.svg new file mode 100644 index 0000000..6e509b7 --- /dev/null +++ b/src/stylesheets/dark_blue/spinbox_arrow_up_disabled.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_arrow_down.svg b/src/stylesheets/dark_blue/treeview_arrow_down.svg new file mode 100644 index 0000000..415b2ee --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_arrow_down.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_arrow_right.svg b/src/stylesheets/dark_blue/treeview_arrow_right.svg new file mode 100644 index 0000000..caed8d9 --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_arrow_right.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_indicator_checked_selected.svg b/src/stylesheets/dark_blue/treeview_indicator_checked_selected.svg new file mode 100644 index 0000000..a86c8cc --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_indicator_checked_selected.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_line_item.svg b/src/stylesheets/dark_blue/treeview_line_item.svg new file mode 100644 index 0000000..09d4552 --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_line_item.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_line_sibling.svg b/src/stylesheets/dark_blue/treeview_line_sibling.svg new file mode 100644 index 0000000..c8dfbee --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_line_sibling.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/dark_blue/treeview_line_sibling_item.svg b/src/stylesheets/dark_blue/treeview_line_sibling_item.svg new file mode 100644 index 0000000..4f1ad4e --- /dev/null +++ b/src/stylesheets/dark_blue/treeview_line_sibling_item.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/stylesheets/ubuntu.qss b/src/stylesheets/ubuntu.qss index 172deb1..078b206 100644 --- a/src/stylesheets/ubuntu.qss +++ b/src/stylesheets/ubuntu.qss @@ -358,7 +358,7 @@ QSlider::sub-page:vertical { QScrollBar:horizontal { max-height: 20px; border: 1px transparent grey; - margin: 0px 20px 0px 20px; + margin: 0px 22px 0px 22px; } QScrollBar::handle:horizontal { background: rgb(253,253,253); @@ -462,7 +462,7 @@ QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { QScrollBar:vertical { max-width: 20px; border: 1px transparent grey; - margin: 20px 0px 20px 0px; + margin: 22px 0px 22px 0px; } QScrollBar::add-line:vertical { border: 1px solid; diff --git a/src/translations/scantailor-universal_ru.ts b/src/translations/scantailor-universal_ru.ts index 4634682..a553757 100644 --- a/src/translations/scantailor-universal_ru.ts +++ b/src/translations/scantailor-universal_ru.ts @@ -61,12 +61,12 @@ Notable ST contributors: - Участники разработки оригинальной версии + Участники разработки оригинальной версии: <html><head/><body>Robert B. - First generation dewarping algorithm<br>Andrey Bergman - System load adjustment<br>U235 - Picture auto-detection algorithm<br>Petr Kovář - Command line interface</body></html> - <html><head/><body>Robert B. - Алгоритм устранения геометрических искажений<br>Andrey Bergman - Регулировка загрузки системы<br>U235 - Алгоритм поиска иллюстраций<br>Petr Kovář - Версия для командной строки</body></html> + <html><head/><body>Robert B. - Алгоритм устранения геометрических искажений<br>Andrey Bergman - Регулировка загрузки системы<br>U235 - Алгоритм поиска иллюстраций<br>Petr Kovář - Версия для командной строки</body></html> @@ -350,47 +350,47 @@ Do you want to replace it? Foreground (b/w text and graphics) - Передний план (текст и ч/б графика) + Передний план (текст и ч/б графика) Data to export: - Экспортировать данные: + Экспортировать данные: Image as it is in ./out subfolder - Изображение из подпапки ./out без изменений + Изображение из подпапки ./out без изменений Whole image - Изображение целиком + Изображение целиком Only black (#000000) and white (#ffffff) pixels of the image - Только чёрные (#000000) и белые (#ffffff) пиксели изображения + Только чёрные (#000000) и белые (#ffffff) пиксели изображения Only non black (> #000000) pixels of the image - Только не чёрные (> #000000) пиксели изображения + Только не чёрные (> #000000) пиксели изображения Automask (b/w mask for auto layer) - Маска автоматически найденных изображений (ч/б) + Маска автоматически найденных изображений (ч/б) Mask (b/w mask for background) - Маска (ч/б маска для фона) + Маска (ч/б маска для фона) Coordinates of zones - Координаты зон + Координаты зон @@ -405,22 +405,22 @@ Do you want to replace it? ... - + ... Export selected pages only - Экспортировать только выделенные страницы + Экспортировать только выделенные страницы Rare options - Настройки + Редко используемые параметры Save images as multipage tiff file - Сохранять как многостраничный tiff файл + Сохранять как многостраничный tiff файл @@ -440,39 +440,39 @@ Do you want to replace it? <html><head/><body><p>This will have effect if only Export Foreground is checked.</p><p>Foreground is a b/w image with a black content of resulting</p><p>image drown on white. With this mode on every black pixel will</p><p>be replaced with pixel on the same position taken from original</p><p>image. This may let you get colored or grayscale text instead of</p><p>binarized black one. Require image reprocessing so may be</p><p>time consuming.</p></body></html> - <html><head/><body><p>Работает только при включенном Экспорте Переднего плана.</p><p>Передний план - это ч/б изображение, содержащее все чёрные пиксели изображения результата</p><p>на белом фоне. Если эта опция включена, то каждый такой чёрный пиксель будет заменен соответствующим</p><p>пикселем изображения-оригинала. Это позволит вам получать цветной текст или</p><p>текст в градациях серого, вместо бинаризованного чёрного.</p><p>Функция потребует генерации изображения заново и займёт значительное время.</p></body></html> + <html><head/><body><p>Работает только при включенном Экспорте Переднего плана.</p><p>Передний план - это ч/б изображение, содержащее все чёрные пиксели изображения результата</p><p>на белом фоне. Если эта опция включена, то каждый такой чёрный пиксель будет заменен соответствующим</p><p>пикселем изображения-оригинала. Это позволит вам получать цветной текст или</p><p>текст в градациях серого, вместо бинаризованного чёрного.</p><p>Функция потребует генерации изображения заново и займёт значительное время.</p></body></html> Background (color and grayscale images) - Фон (изображения цветные и в оттенках серого) + Фон (изображения цветные и в оттенках серого) Automask could be found in ./out/cache/automask and contains autodetected mask before any zones are applied - Маска найденных изображений обычно хранится в ./out/cache/automask/ и содержит + Маска найденных изображений обычно хранится в ./out/cache/automask/ и содержит автоматически обнаруженные зоны изображений до применения каких-либо пользовательских зон Binarized and inverted background - Бинаризованный и инвертированный фон + Бинаризованный и инвертированный фон Some pages might have user defined zones to fill with color or indicate some content. Their coordinates may be exported to tsv text file. - На некоторых страницах пользователем могут быть заданы зоны заливки или изображений. Их координаты могут быть экспортированы в tsv файл. + На некоторых страницах пользователем могут быть заданы зоны заливки или изображений. Их координаты могут быть экспортированы в tsv файл. <html><head/><body><p>This will have effect if only Export Whole image is checked.</p><p>The exported image will be drawn with colors of original image.</p><p>Only fill zones will be applied. In other words the exported</p><p>image will be a part of original image after split, rotation,</p><p>deskew, applying margins and fill zones. This require image</p><p>reprocessing so it may be time consuming.</p></body></html> - <html><head/><body><p>Работает только при включенном Экспорте Изображения целиком.</p><p>Экспортированное изображение отрисовывается в цветах исходного изображения (применяются только зоны заливки).</p><p> Другими словами, экспортируемое изображение будет представлять собой часть</p><p>исходного изображения, после разделения на страницы, поворота,</p><p>компенсации наклона, применения полей и зон заливки.</p><p>Это потребует генерации изображения заново и займёт значительное время.</p></body></html> + <html><head/><body><p>Работает только при включенном Экспорте Изображения целиком.</p><p>Экспортированное изображение отрисовывается в цветах исходного изображения (применяются только зоны заливки).</p><p> Другими словами, экспортируемое изображение будет представлять собой часть</p><p>исходного изображения, после разделения на страницы, поворота,</p><p>компенсации наклона, применения полей и зон заливки.</p><p>Это потребует генерации изображения заново и займёт значительное время.</p></body></html> Skip processing at Output stage (except for Fill Zones) for exported image (lengthy) - Пропустить обработку этапа Вывод (за искл. зон заливки) + Пропустить обработку этапа Вывод (за искл. зон заливки) при экспорте Изображения целиком (сильно замедляет выполнение экспорта) @@ -480,19 +480,19 @@ for exported image (lengthy) Skip processing at Output stage (except for Fill Zones) for content in foreground subscans (lengthy) - Пропустить обработку этапа Вывод (за искл. зон заливки) + Пропустить обработку этапа Вывод (за искл. зон заливки) при экспорте Переднего плана (сильно замедляет выполнение экспорта) Reset export settings to default values - Сбросить параметры экспорта на значения по умолчанию + Сбросить параметры экспорта на значения по умолчанию Restore Defaults - Сброс настроек + Сброс настроек @@ -634,107 +634,107 @@ for content in foreground subscans (lengthy) MainWindow - - - - - - + + + + + + Error Ошибка - - + + Batch processing is in the progress. Выполняется пакетная обработка. - - + + No project is loaded. Ни один проект не открыт. - + build on от - + %2 - Scan Tailor "Universal" %3 [%1bit] %2 - Scan Tailor "Universal" %3 [%1бит] - - + + Error saving the project file! Ошибка при сохранении файла проекта! - + Saving project... Сохранение проекта... - + Files to insert Выбор файлов для вставки - + Skip failed files Игнорировать файлы с ошибками - + Overwrite default file name for resulting image - Переопределение имени файла результата + Переопределение имени файла результата - + Here you may overwrite default resulting image file name that will be generated for this page. It may be helpful to keep the right alphabetical order of files in out subfolder. - Здесь вы можете переопределить имя файла в который + Здесь вы можете переопределить имя файла в который будет сохранено изображение страницы после обработки. Эта возможность полезна в случае, если необходимо добиться совпадения алфавитного порядка файлов в папке с результатами и порядка следования страниц в проекте. - + File %1 already exists in out subfolder. Would you like to replace it? - Файл %1 уже существует в папке результатов. + Файл %1 уже существует в папке результатов. Желаете перезаписать его? - + Can't remove file %1! Cancelling... - Невозможно удалить файл %1! + Невозможно удалить файл %1! Отмена операции... - + Can't rename file %1! Cancelling... - Невозможно переименовать файл %1! + Невозможно переименовать файл %1! Отмена операции... - + p. %1 стр. %1 - + %1, %2 %1, %2 - + Use %1, %2, %3 (or %4), %5 (or %6) to navigate between pages. Используйте %1, %2, %3 (или %4), %5 (или %6) для перемещения между страницами. @@ -751,7 +751,7 @@ Cancelling... Open source with... - Открыть оригинал с помощью... + Открыть оригинал с помощью... @@ -776,12 +776,12 @@ Cancelling... Insert empty page - Вставка пустой страницы + Вставка пустой страницы Rename result filename... - Переименовать файл с результатом... + Переименовать файл с результатом... @@ -789,22 +789,22 @@ Cancelling... Удалить из проекта... - + Go to page Переход к странице - + Page number: Номер страницы: - + Select pages by number Выбор страниц по их номерам - + Numbers should start from 1 Line ends are ignored Any non digit symbols are interpreted as number separators @@ -816,12 +816,12 @@ Number followed by '-' or ':' treated as a start of page seq Число с последующим '-' или ':' интерпретируется как начало интервала номеров страниц - + Input page numbers: Введите номера страниц: - + Pages to be selected: %1 Будет выбрано страниц: %1 @@ -833,47 +833,47 @@ Number followed by '-' or ':' treated as a start of page seq Copy - Копировать + Копировать Insert - Вставить + Вставить - + Scan Tailor Projects Проекты Scan Tailor - + Output is not yet possible, as the final size of pages is not yet known. To determine it, run batch processing at "Select Content" or "Page Layout". - Вывод невозможен, поскольку еще не известны итоговые размеры страниц. + Вывод невозможен, поскольку еще не известны итоговые размеры страниц. Для их определения, выполните пакетную обработку на этапах "Область контента" или "Поля". - + Unnamed Без имени - + %1% - %2 - + - + Insert before - Вставить перед + Вставить перед - + Insert after - Вставить после + Вставить после @@ -923,7 +923,7 @@ To determine it, run batch processing at "Select Content" or "Pag Edit - Правка + Правка @@ -933,22 +933,22 @@ To determine it, run batch processing at "Select Content" or "Pag Keep selection key pressed - Удерживать клавишу выделения нажатой + Удерживать клавишу выделения нажатой Simulate press of the modifier key for fast page selection (Ctrl+CapsLock) - Симулировать удерживание нажатой клавиши выделения для быстрого выбора нескольких страниц (Ctrl+CapsLock) + Симулировать удерживание нажатой клавиши выделения для быстрого выбора нескольких страниц (Ctrl+CapsLock) Ctrl+CapsLock - + Reset sorting to default - Сброс сортировки на значение по умолчанию + Сброс сортировки на значение по умолчанию @@ -983,22 +983,22 @@ To determine it, run batch processing at "Select Content" or "Pag Save Project &As... - Сохранить &проект как... + Сохранить &проект как... Ctrl+Shift+S - + &New Project... - &Новый проект... + &Новый проект... &Open Project... - &Открыть проект... + &Открыть проект... @@ -1043,35 +1043,35 @@ To determine it, run batch processing at "Select Content" or "Pag Ctrl+Shift+B - + Ctrl+Shift+A - + Copy source file name(s) - Копировать имена исходных файлов + Копировать имена исходных файлов Ctrl+C - + Copy output file name(s) - Копировать имена обработанных файлов + Копировать имена обработанных файлов Copy page number(s) - Копировать номера страниц + Копировать номера страниц - + Open Project Открытие проекта @@ -1081,22 +1081,22 @@ To determine it, run batch processing at "Select Content" or "Pag Пересоздать результат - + Unable to open the project file. Не удалось открыть файл проекта. - + The project file is broken. Файл проекта поврежден. - + Images not in project (%1) Изображений не в проекте: %1 - + Remove Удалить @@ -1134,7 +1134,7 @@ To determine it, run batch processing at "Select Content" or "Pag - + Recent Projects Недавние проекты @@ -1144,7 +1144,7 @@ To determine it, run batch processing at "Select Content" or "Pag Новый проект... - + Open Project... Открыть проект... @@ -1223,7 +1223,7 @@ To determine it, run batch processing at "Select Content" or "Pag When working with grayscale images, make sure they are really grayscale. If they are actually color images that just happen to look grayscale, convert them to grayscale using some kind of batch image converter. This will both save memory and increase performance. - Если вы работаете с изображениями в оттенках серого, убедитесь что они в таком виде и сохранены. Если же они сохранены как цветные изображения, пересохраните их в режиме оттенков серого используя какой-нибудь пакетный конвертер изображений. Это сократит расход памяти а также ускорит обработку. + Если вы работаете с изображениями в оттенках серого, убедитесь что они в таком виде и сохранены. Если же они сохранены как цветные изображения, пересохраните их в режиме оттенков серого используя какой-нибудь пакетный конвертер изображений. Это сократит расход памяти а также ускорит обработку. @@ -1286,35 +1286,35 @@ To determine it, run batch processing at "Select Content" or "Pag Mode - Режим + Режим Off - Отключено + Отключено Auto - Автоматически + Автоматически Manual - Вручную + Вручную Marginal (experimental) - Краевое (экспериментально) + Краевое (экспериментально) OutputOptionsWidget - + No despeckling - Не удалять мусор + Не удалять мусор @@ -1322,102 +1322,133 @@ To determine it, run batch processing at "Select Content" or "Pag Разрешение результата: - + + + + value + + + + Mode: Режим: - + Auto layer - Слой поиска иллюстраций + Слой поиска иллюстраций - + Picture Zones layer - Слой зон иллюстраций + Слой зон иллюстраций - + Foreground layer - Слой всего контента + Слой всего контента - - - - - <a href="#">Apply To...</a> - <a href="#">Применить к...</a> + <a href="#">Применить к...</a> + + + + + + + + Apply To... + Применить к... - + Binarisation threshold: Порог бинаризации ч/б: - + + Window size: + Размер окна: + + + + The dimensions of a pixel neighborhood to consider. + Размеры окрестности пикселя, которые следует учитывать. + + + + Default value is 0.34. + Значение по умолчанию 0.34. + + + + Coef: + Коэффициент: + + + Foreground layer threshold: - Порог слоя всего контента: + Порог слоя всего контента: - + Depth perception: Коэф. глубины искривления: - + Dewarping: Распрямление строк: - + Despeckling: - Удаление мусора: + Удаление мусора: - + Cautious despeckling - Осторожное удаление мусора + Осторожное удаление мусора - + Normal despeckling - Обычное удаление мусора + Обычное удаление мусора - + Aggressive despeckling - Агрессивное удаление мусора + Агрессивное удаление мусора - + &Black and White &Чёрно/Белый - + &Color / Grayscale &Цветной / Оттенки серого - + &Mixed &Смешанный - - + + &Reset to default value &Установить по умолчанию - + White margins Белые поля - + Equalize illumination Выровнять освещение @@ -1427,17 +1458,17 @@ To determine it, run batch processing at "Select Content" or "Pag Apply what - Перенести настройки + Перенести настройки Margin values - Значений полей + Значений полей Auto Margin setting state - Состояние режима Авто-полей + Состояние режима Авто-полей @@ -1450,7 +1481,7 @@ To determine it, run batch processing at "Select Content" or "Pag Millimeters (mm) - Миллиметры (мм) + Миллиметры (мм) @@ -1466,7 +1497,7 @@ To determine it, run batch processing at "Select Content" or "Pag ... - + @@ -1497,7 +1528,7 @@ To determine it, run batch processing at "Select Content" or "Pag Currently selected content alignment - Выбранное в данный момент выравнивание положения области контента + Выбранное в данный момент выравнивание положения области контента @@ -1525,7 +1556,7 @@ To determine it, run batch processing at "Select Content" or "Pag All pages before current one - Все страницы перед текущей + Все страницы перед текущей @@ -1575,12 +1606,12 @@ To determine it, run batch processing at "Select Content" or "Pag (current page is odd) - (текущая страница - нечётная) + (текущая страница - нечётная) (current page is even) - (текущая страница - чётная) + (текущая страница - чётная) @@ -1593,27 +1624,27 @@ To determine it, run batch processing at "Select Content" or "Pag Options - Настройки + Настройки Apply cut - Скопировать координаты разреза + Скопировать координаты разреза Mode - Режим + Режим Auto - Автоматически + Автоматически Manual - Вручную + Вручную @@ -1621,17 +1652,17 @@ To determine it, run batch processing at "Select Content" or "Pag Form - + Page Layout on image - Тип разреза страницы + Тип разреза страницы ? - + @@ -1669,12 +1700,12 @@ To determine it, run batch processing at "Select Content" or "Pag Add to auto layer - Добавить к слою поиска иллюстраций + Добавить к слою поиска иллюстраций Subtract from auto layer - Вычесть из слоя поиска иллюстраций + Вычесть из слоя поиска иллюстраций @@ -1724,7 +1755,7 @@ To determine it, run batch processing at "Select Content" or "Pag Output directory doesn't exist. Create it? - Папка для сохранения результатов не существует. Создать её? + Папка для сохранения результатов не существует. Создать её? @@ -1903,7 +1934,7 @@ and press [Enter] to edit the shortcut: Page Layout - Макетирование страницы + Макетирование страницы @@ -1978,7 +2009,7 @@ and press [Enter] to edit the shortcut: Change size of thumbnails - Изменение размера страниц в ленте + Изменение размера страниц в ленте @@ -1988,12 +2019,12 @@ and press [Enter] to edit the shortcut: Insert empty page before - Вставка пустой страницы до + Вставка пустой страницы до Insert empty page after - Вставка пустой страницы после + Вставка пустой страницы после @@ -2018,22 +2049,22 @@ and press [Enter] to edit the shortcut: Stretch or squeeze - Сжатие и растягивание + Сжатие и растягивание Create ellipse zone - Создать зону-эллипс + Создать зону-эллипс Move zone horizontally - Переместить горизонтально + Переместить горизонтально The hotkeys scheme in your settings file is incompatible with current application version. Hotkeys settings will be reseted. - Схема горячих клавиш в вашем файле настроек несовместима с текущей версией приложения. Настройки горячих клавиш будут сброшены на настройки по умолчанию. + Схема горячих клавиш в вашем файле настроек несовместима с текущей версией приложения. Настройки горячих клавиш будут сброшены на настройки по умолчанию. @@ -2043,7 +2074,7 @@ and press [Enter] to edit the shortcut: Pages manipulation - Операции со страницами + Операции со страницами @@ -2124,7 +2155,7 @@ and press [Enter] to edit the shortcut: Clone last modified zone - Вставить копию последней зоны + Вставить копию последней зоны @@ -2159,32 +2190,32 @@ and press [Enter] to edit the shortcut: Switch off despeckling - Отклчить удаление мусора + Отклчить удаление мусора Switch to cautious mode - Осторожное удаление мусора + Осторожное удаление мусора Switch to normal mode - Обычное удаление мусора + Обычное удаление мусора Switch to aggressive mode - Аггресивное удаление мусора + Аггресивное удаление мусора Despeckling - Удаление мусора + Удаление мусора Scan Tailor Universal - + @@ -2224,7 +2255,7 @@ and press [Enter] to edit the shortcut: %1 page - %1 страница + %1 страница @@ -2235,87 +2266,87 @@ and press [Enter] to edit the shortcut: centered - по центру + по центру centered horizontally - по центру горизонтально + по центру горизонтально centered vertically - по центру вертикально + по центру вертикально top-left corner - к левому-верхнему углу + к левому-верхнему углу top-right corner - к правому-верхнему углу + к правому-верхнему углу top side - к верхней стороне + к верхней стороне bottom-left corner - к левому-нижнему углу + к левому-нижнему углу bottom-right corner - к правому-нижнему углу + к правому-нижнему углу bottom side - к нижней стороне + к нижней стороне left side - к левой стороне + к левой стороне right side - к правой стороне + к правой стороне automatically - автоматически + автоматически automatically by width - автоматически по шрине + автоматически по шрине automatically by height - автоматически по высоте + автоматически по высоте proportional to original position - пропорционально положению на исходном изображении + пропорционально положению на исходном изображении proportional to original horizontal position - пропорционально горизонтальному положению на исходном изображении + пропорционально горизонтальному положению на исходном изображении proportional to original vertical position - пропорционально вертикальному положению на исходном изображении + пропорционально вертикальному положению на исходном изображении @@ -2326,271 +2357,287 @@ and press [Enter] to edit the shortcut: x: center - x: центр + x: центр y: center - y: центр + y: центр top-left - вверх и влево + вверх и влево top-right - вверх и вправо + вверх и вправо y: top - y: вверх + y: вверх bottom-left - вниз и влево + вниз и влево bottom-right - вниз и вправо + вниз и вправо y: bottom - y: вниз + y: вниз x: left - x: влево + x: влево x: right - x: вправо + x: вправо + + + + off + Отключено + + + + manual + Вручную + + + + marginal + Краевое + auto - авто + Автоматически x: auto - x: авто + x: авто y: auto - y: авто + y: авто proportional - пропорц. + пропорц. x: prop. - x: проп. + x: проп. y: prop. - y: проп. + y: проп. Natural order - Естественный порядок + Естественный порядок - + Processed then unprocessed - Сначала уже обработанные + Сначала уже обработанные Order by angle - По величине угла + По величине угла Order by absolute angle - По абсолютной величине угла + По абсолютной величине угла b/w - ч/б + ч/б color/grayscale - цветной/серый + цветной/серый mixed - смешанный + смешанный grayscale source - исходник не цветной + исходник не цветной color source - исходник цветной + исходник цветной not defined - не определено + не определено height: %1 - высота: %1 + высота: %1 ? - + width: %1 - ширина: %1 + ширина: %1 uncut - нет + нет offcut - один + один two pages - на 2 страницы + на 2 страницы unknown - неизвестно + неизвестно split: %1 - разрез: %1 + разрез: %1 - + Remove %n page(s) from project? - + Удалить %n страницу из проекта? Удалить %n страницы из проекта? Удалить %n страниц из проекта? - + %1 x %2 %3 - %1 x %2 %3 + %1 x %2 %3 px - px + px in - in + in mm - мм + мм cm - см + см Warning - Предупреждение + Предупреждение The file "%1" is not ready for output. - Файл "%1" еще не обработан. + Файл "%1" еще не обработан. Meta - + Ctrl - + angle: %1° - угол: %1° + угол: %1° Order by rotation - По повороту + По повороту rotation: %1° - поворот: %1° + поворот: %1° max width: %1 px - макс. ширина: %1 px + макс. ширина: %1 px max width: %1 %2 (%3 dpi) - макс. ширина: %1 %2 (%3 dpi) + макс. ширина: %1 %2 (%3 dpi) Pages processing is complete. - Обработка страниц завершена. + Обработка страниц завершена. %1 %2 (%3 dpi) - + @@ -2644,13 +2691,13 @@ and press [Enter] to edit the shortcut: Content Box - Область контента + Область контента Auto - Искать + Искать @@ -2722,169 +2769,169 @@ and press [Enter] to edit the shortcut: Настройки - + Features - Функции + Функции - + Enabled - Включено + Включено - + Filter - Фильтр - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Фильтр + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Description Описание - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Options - Настройки + Настройки - + Application language: Язык интерфейса: - + Batch processing Пакетная обработка - + All pages Все страницы - + Start from selected С текущей до конца - + Ask every time Спрашивать каждый раз - + Application style: - Стиль приложения: + Стиль приложения: - + Application stylesheet: - Таблица стилей приложения: + Таблица стилей приложения: - + &Reset to defaults - &Сбросить на значения по умолчанию + &Сбросить на значения по умолчанию - + TIFF compression (b/w): - Метод сжатия TIFF (ч/б): + Метод сжатия TIFF (ч/б): - + TIFF compression (non b/w): - Метод сжатия TIFF (не ч/б): + Метод сжатия TIFF (не ч/б): - + Grid and lines color: - Цвет линий и координатной сетки: + Цвет линий и координатной сетки: - + Content zone highlight color: - Цвет подсветки зоны контента: + Цвет подсветки зоны контента: - + <html><head/><body><p>Alignment setting has no sense if &quot;Match with other pages&quot; is switched off. In this case final size for all pages is calculated separately and equal to content one plus its hard margins.</p><p><span style=" font-weight:600;">Alignment</span> defines how to align content zone with its hard margins by changing soft margins. It could be combination of values of following alignment types: manual, auto-magnet and original proportions (last two are optional features).</p><p><span style=" font-weight:600;">Manual alignment</span> is always available to user and allows him to choose the page side (top, left etc.), page corner (top-left, bottom-right etc.) where soft margins will be set to 0. In case of hard margins are zero for such side this means content zone will touch page border. It also allows to center content zone on page horizontally, vertically or both.</p><p><span style=" font-weight:600;">Auto-Magnet alignment</span> (just Auto in other version of ST) is very similar to Manual mode. In fact - it automatically chooses one of Manual mode options based on how close original content zone to page borders. I would say content zone is magnetized to the closest side or corner of page or to its center. This type of alignment is optional.</p><p><span style=" font-style:italic;">Note</span>: in case Original Proportions alignment is enabled then Auto-Magnet considers it as one of options and may choose it automatically for vertical/horizontal alignment or both.</p><p><span style=" font-weight:600;">Original Proportions alignment</span> (based on Original alignment in other versions of ST) distributes soft margins proportionally to space around content zone on original page. For example, if your content on left pages of document is closer to right border of page and content on right pages is closer to left border of page and you want to keep this alignment for left/right pages in a result you'll face some problems. Because due to different dpi, scan size, splits or deskew angle your page most probably will have a slightly different sizes. And thus even if you set auto-margins or manually set unequal hard margins for left/right pages you'll end up with non-zero soft margins (unless you switch off &quot;Match with other pages&quot; and all your pages final sizes will be different). Or this could happen if you have cover page in your project and want all page sizes be equal - cover pages may be bigger than other pages. Anyway you'll end up with necessity to distribute non-zero soft margins. Original proportions alignment may do it for you automatically proportionally to your content zone original position on page. This type of alignment is optional.</p><p><span style=" font-style:italic;">Note</span>: Original proportions alignment is done for content zone with its hard margins around, while position proportions are calculated without considering hard margin values.</p><p><span style=" font-style:italic;">Note</span>: Original proportions mode considers page size after its refinement by Page Detection feature (if enabled) on previous processing step.</p><p><span style=" font-style:italic;">Note</span>: Final alignment is a sum of horizontal and vertical alignments (or one may say alignment by height and by width). There is a way to define them separately even for different types of alignment. For example: auto-magnet horizontally and original proportions vertically. Or original proportions horizontally and align to top border vertically.</p></body></html> - <html><head/><body><p>Настройка Выравнивание не имеет смысла если для всех страниц отключена опция &quot;Выровнять размеры с другими страницами&quot;. В этом случае конечный размер каждой страницы страницы рассчитывается отдельно и равен размеру области контента с жёстко заданными полями вокруг него.</p><p><span style=" font-weight:600;">Выравнивание</span> определяет то, как область контента с её жёстко заданными полями располагаются внутри этой страницы, после её приведения к общему для всех страниц размеру. Этот общий размер равен максимальной среди всех страниц ширине области контента (с жёстко заданными полями слева и справа) и высоте области контента (с жёстко заданными полями сверху и снизу). Для этого к каждой странице меньше этого размера добавляются компенсирующие &quot;косвенно определённые поля&quot;. Выравнивание также можно назвать принципом, по которому распределяются компенсирующие ширина и высота между этими полями. Выравнивание бывает: ручным, автоматическим (Авто-магнит) и пропорциональным положению на оригинале (последние два - опциональны).</p><p><span style=" font-weight:600;">Ручное выравнивание</span> всегда доступно пользователю и технически, является комбинацией выравниваний по вертикали (вверх, по центру, вниз) и горизонтали (влево, по центру, вправо). Что позволяет прижать область контента с её жёстко заданными полями к центру одной из сторон (левой, верхней и т.п.) или одному из четырёх углов результирующей страницы. Технически это достигается путем установки значения одного или двух косвенно определённых полей в 0. Также оно позволяет разместить область контента с её жёсткими полями по центру результирующей страницы, равно распределив величины компенсирующих ширины и высоты между соответствующими косвенно определёнными полями по вертикали и горизонтали.</p><p><span style=" font-weight:600;">Автоматическое выравнивание (Авто-Магнит)</span> основано на ручном выравнивании и, по факту, всего лишь выбирает один из вариантов ручного выравнивания на основании того, как близка область контента к той или иной стороне на оригинальной странице. Можно сказать, что зону контента с её жёстко заданными полями примагничивает к одной из 9 точек: центру результирующей страницы, центрам её сторон или её углам. Этот тип выравнивания опционален.</p><p><span style=" font-style:italic;">Замечание</span>: если включена функция выравнивания пропорционально положению на оригинале, то Авто-Магнит также рассматривает его как вариант и может выбрать такой тип для выравнивания по горизонтали, вертикали или обоим направлениям.</p><p><span style=" font-weight:600;">Выравнивание пропорционально положению на оригинале</span> - распределяет величину компенсирующих значений по ширине и высоте между косвенно определёнными полями пропорционально расстоянию области контента до краёв оригинальной страницы (после разрезания и компенсации наклона, естественно). К примеру, если ваша область контента на левых страницах ближе к правой её границе, а на правых - к левой (что часто бывает в книгах) и вы хотите сохранить такое положение в результатах, то вы столкнетесь с некоторыми трудностями. Из-за различий в dpi исходных сканов, их размере, положению разрезов, углов наклона и пр. ваши страницы будут иметь немного разный размер. И поэтому, даже при помощи Авто-полей или заданных вручную неравных левых/правых полей на левых/правых страницах у вас все равно останутся ненулевые косвенно определённые поля (если только вы не отключите им &quot;Выровнять размеры с другими страницами&quot; и получите разные размеры страниц в результате). В итоге, вам придется как-то распределять разницу между общим размером и размером каждой страницы по её косвенным поля. И автоматическое распределение этой разницы пропорционально положению области контента на оригинале здесь будет лучшим решением. Данный тип выравнивания опционален.</p><p><span style=" font-style:italic;">Замечание</span>: Выравнивание пропорционально положению на оригинале выполняется для области контента и её жёстко заданных полей, хотя сами эти пропорции вычисляются без учёта жестко заданных полей. Возможно, если вы применяете данный тип выравнивания и по вертикали и по горизонтали, то вам будет проще просто не задавать поля вообще.</p><p><span style=" font-style:italic;">Замечание</span>: Выравнивание пропорционально положению на оригинале рассчитывается с учётом результатов поиска Области страницы (если выполнялось) на предыдущем этапе обработки.</p><p><span style=" font-style:italic;">Замечание</span>: Т.к. выравнивание фактически является комбинацией горизонтального и вертикального выравниваний (или, можно сказать, выравниваний по ширине и высоте) то предусмотрена возможность задать их отдельно для разных типов выравнивания. Например, Авто-магнит по ширине и оригинальные пропорции по высоте. Или оригинальные пропорции по ширине и прижимание к верхнему краю по высоте.</p></body></html> + <html><head/><body><p>Настройка Выравнивание не имеет смысла если для всех страниц отключена опция &quot;Выровнять размеры с другими страницами&quot;. В этом случае конечный размер каждой страницы страницы рассчитывается отдельно и равен размеру области контента с жёстко заданными полями вокруг него.</p><p><span style=" font-weight:600;">Выравнивание</span> определяет то, как область контента с её жёстко заданными полями располагаются внутри этой страницы, после её приведения к общему для всех страниц размеру. Этот общий размер равен максимальной среди всех страниц ширине области контента (с жёстко заданными полями слева и справа) и высоте области контента (с жёстко заданными полями сверху и снизу). Для этого к каждой странице меньше этого размера добавляются компенсирующие &quot;косвенно определённые поля&quot;. Выравнивание также можно назвать принципом, по которому распределяются компенсирующие ширина и высота между этими полями. Выравнивание бывает: ручным, автоматическим (Авто-магнит) и пропорциональным положению на оригинале (последние два - опциональны).</p><p><span style=" font-weight:600;">Ручное выравнивание</span> всегда доступно пользователю и технически, является комбинацией выравниваний по вертикали (вверх, по центру, вниз) и горизонтали (влево, по центру, вправо). Что позволяет прижать область контента с её жёстко заданными полями к центру одной из сторон (левой, верхней и т.п.) или одному из четырёх углов результирующей страницы. Технически это достигается путем установки значения одного или двух косвенно определённых полей в 0. Также оно позволяет разместить область контента с её жёсткими полями по центру результирующей страницы, равно распределив величины компенсирующих ширины и высоты между соответствующими косвенно определёнными полями по вертикали и горизонтали.</p><p><span style=" font-weight:600;">Автоматическое выравнивание (Авто-Магнит)</span> основано на ручном выравнивании и, по факту, всего лишь выбирает один из вариантов ручного выравнивания на основании того, как близка область контента к той или иной стороне на оригинальной странице. Можно сказать, что зону контента с её жёстко заданными полями примагничивает к одной из 9 точек: центру результирующей страницы, центрам её сторон или её углам. Этот тип выравнивания опционален.</p><p><span style=" font-style:italic;">Замечание</span>: если включена функция выравнивания пропорционально положению на оригинале, то Авто-Магнит также рассматривает его как вариант и может выбрать такой тип для выравнивания по горизонтали, вертикали или обоим направлениям.</p><p><span style=" font-weight:600;">Выравнивание пропорционально положению на оригинале</span> - распределяет величину компенсирующих значений по ширине и высоте между косвенно определёнными полями пропорционально расстоянию области контента до краёв оригинальной страницы (после разрезания и компенсации наклона, естественно). К примеру, если ваша область контента на левых страницах ближе к правой её границе, а на правых - к левой (что часто бывает в книгах) и вы хотите сохранить такое положение в результатах, то вы столкнетесь с некоторыми трудностями. Из-за различий в dpi исходных сканов, их размере, положению разрезов, углов наклона и пр. ваши страницы будут иметь немного разный размер. И поэтому, даже при помощи Авто-полей или заданных вручную неравных левых/правых полей на левых/правых страницах у вас все равно останутся ненулевые косвенно определённые поля (если только вы не отключите им &quot;Выровнять размеры с другими страницами&quot; и получите разные размеры страниц в результате). В итоге, вам придется как-то распределять разницу между общим размером и размером каждой страницы по её косвенным поля. И автоматическое распределение этой разницы пропорционально положению области контента на оригинале здесь будет лучшим решением. Данный тип выравнивания опционален.</p><p><span style=" font-style:italic;">Замечание</span>: Выравнивание пропорционально положению на оригинале выполняется для области контента и её жёстко заданных полей, хотя сами эти пропорции вычисляются без учёта жестко заданных полей. Возможно, если вы применяете данный тип выравнивания и по вертикали и по горизонтали, то вам будет проще просто не задавать поля вообще.</p><p><span style=" font-style:italic;">Замечание</span>: Выравнивание пропорционально положению на оригинале рассчитывается с учётом результатов поиска Области страницы (если выполнялось) на предыдущем этапе обработки.</p><p><span style=" font-style:italic;">Замечание</span>: Т.к. выравнивание фактически является комбинацией горизонтального и вертикального выравниваний (или, можно сказать, выравниваний по ширине и высоте) то предусмотрена возможность задать их отдельно для разных типов выравнивания. Например, Авто-магнит по ширине и оригинальные пропорции по высоте. Или оригинальные пропорции по ширине и прижимание к верхнему краю по высоте.</p></body></html> - + Description of currently selected alignment - Подробное описание выбранного в данный момент выравнивания + Подробное описание выбранного в данный момент выравнивания - + In this mode page content is not changed. Margins can be filled with white or left as is. If the margins are filled in white, then the option to equalize illumination also becomes available. Equalize illumination option normalizes the background color, bringing it to white, and normalizes contrast, increasing it in the shaded areas. - В этом режиме содержимое области контента не изменяется. + В этом режиме содержимое области контента не изменяется. Области жёстко заданных полей могут быть заполнены белым цветом или оставлены как есть. Если поля затираются, то становится доступной дополнительная опция выравнивания освещенности в области контента. Опция выравнивания освещенности нормализует цвет фона, сводя его к белому и нормализует контраст, увеличивая его в затененных областях. - + Mixed mode is used for projects in which there are scans from half-tone images (grayscale or color). Pictures will be automatically detected and displayed as it is, just as in the "Color / Grayscale" with the included equalized illumination. The rest of the page is displayed in black and white. Automatic picture zones detection works well enough, but if the picture merges smoothly into the background the result may be unsatisfactory. In this case, you must create and configure the picture zone images. It is important to note that the creation of zones of images is possible only in mixed mode. - Смешанный режим используется для страниц, на которых есть цветные изображения или изображения в оттенках серого. Он также пригодится при наличии цветного текста. Он позволяет автоматически обнаружить зоны картинок и отобразить их без изменений (как в режиме «Цветной / Оттенки серого») с опциональным выравниванием освещения. Остальная же часть страницы отображается в чёрно-белом режиме. + Смешанный режим используется для страниц, на которых есть цветные изображения или изображения в оттенках серого. Он также пригодится при наличии цветного текста. Он позволяет автоматически обнаружить зоны картинок и отобразить их без изменений (как в режиме «Цветной / Оттенки серого») с опциональным выравниванием освещения. Остальная же часть страницы отображается в чёрно-белом режиме. Автоматическое определение зон изображений работает достаточно хорошо, но если иллюстрация плавно переходит в цвет фона страницы, то результат может быть неудовлетворительным. В этом случае вы должны создать и настраивать зоны изображения вручную. Создание зон изображений возможно только в смешанном режиме. - + Picture zones layer works on top of Auto layer results and could be useful if your pictures are known to be rectangles. Auto layer is build automatically and doesn't make any assumptions on areas geometry. Picture zones layer tries to improve its mask assuming all picture areas found should be rectangles. This layer doesn't modify auto layer mask but automatically creates rectangle zones on top of it. So usually it covers all auto layer with polygons. User can change these polygons as regular picture zones. In case sensitivity parameter is 100% the picture detection algorithm looks for the separate picture areas and adds a minimal bounding rect for each of them as a zone. In this case zone contains pixels from auto layer mask and may contain pixels that are not included in auto layer mask but still inside the rect. If sensitivity is less than 100% the algorithm additionally investigates each side of bounding rect and tries to move it towards the center of rect while the line of pixels behind it contains more than N% of pixels that are not from auto layer mask. Decreasing sensitivity may help to better fit picture zone over picture area by ignoring pixels-outliers incorrectly included in auto layer mask. Usually, the sensitivity is 75-100%. - Слой зон иллюстраций работает поверх результатов слоя поиска иллюстраций, и может быть полезен, если иллюстрации на ваших сканах имеют прямоугольную форму (наиболее частый вариант). Слой поиска иллюстраций формируется автоматически и не делает никаких предположений о геометрии областей изображений. Слой зон иллюстраций пытается улучшить его маску, предполагая, что все области изображения должны быть прямоугольниками. + Слой зон иллюстраций работает поверх результатов слоя поиска иллюстраций, и может быть полезен, если иллюстрации на ваших сканах имеют прямоугольную форму (наиболее частый вариант). Слой поиска иллюстраций формируется автоматически и не делает никаких предположений о геометрии областей изображений. Слой зон иллюстраций пытается улучшить его маску, предполагая, что все области изображения должны быть прямоугольниками. Этот слой не изменяет маску слоя поиска, но автоматически создает над ним прямоугольные зоны (зоны - это геометрические примитивы, доступные для редактирования пользователем). Таким образом, обычно он покрывает весь слой поиска иллюстраций своими полигонами. Пользователь может изменять эти полигоны как обычные зоны изображения. При этом зоны данного слоя добавляются к маске слоя поиска иллюстраций. Если же слой поиска иллюстраций отключен, а слой зон иллюстраций включен, то маска игнорируется и зоны работают сами по себе. (Технически маска все равно будет создаваться, но будет использоваться только для создания по ней зон иллюстраций - не более). Автоматически созданные зоны можно не только менять, но даже удалять. Они не будут создаваться заново, пока их не удалят все, а затем выключат и снова включатслой зон иллюстраций @@ -2892,34 +2939,37 @@ In case sensitivity parameter is 100% the picture detection algorithm looks for Параметр чувствительности влияет на то, как именно на основе маски создаются зоны изображений. Если он равен 100%, то алгоритм обнаружения изображений просто обводит прямоугольной зоной все области изображений, какой бы формы они ни были. В этом случае в такую зону могут попасть как пиксели маски, так и пиксели, маски не принадлежавшие. Представьте иллюстрацию с круглым мячом без фона. Обведенный вокруг нее прямоугольник захватит фон. Если чувствительность составляет менее 100%, то алгоритм дополнительно исследует каждую сторону описанного прямоугольника и пытается сдвинуть её в центр прямоугольника, если линия пикселей с этой стороны него содержит более N% пикселей, которые не принадлежат маске. В нашем примере с мячом это означает, что со снижением чувствительности зона изображения перестанет быть описанным вокруг мяча прямоугольником, а начнет стремиться к его центру, пока не превратиться во вписанный в мяч прямоугольник. Подобно тому, как слой зон иллюстраций позволяет бороться с выпадением пикселей по краям иллюстраций сливающихся с фоном страницы из маски из предположений об их геометрии, данный параметр позволяет бороться с небольшими участками незаслуженно включенных в маску пикселей по краям подобных иллюстраций. Обычно значение чувствительности составляет от 75 до 100%. - + <html><head/><body><p>Dewarping tries to detect and fix distortion of page surface by analyzing lines of text on it. It assumes that the lines should be horizontal.</p><p>Automatic, marginal and manual modes are supported.</p><p>Try to correct auto distortion model if too skewed - if enabled then some vertical edges of automatically generated distortion model that deviate to more than 2.75 degrees to Y-axis may be treated as invalid and slope is set to sero. That may help in some cases when auto generation of distortion model gives incorrect results.</p><p>Try to apply additional deskew after dewarp - we already deskewed our image on one of previous processing stage but sometimes image may get skewed after dewarping. Thus additional attempt to deskew resulting image may be applied. The skew of the image after dewarping is measured and if the angle is more than 2.0 degrees - it's deskewed. There is no controls to tune this automatic deskew, it takes some CPU time and it's not working with automatic dewarping. So use it with <a name="result_box"/>with caution.</p></body></html> - <html><head/><body><p>Функция "Распрямление строк" пытается обнаружить и исправить искажение поверхности страницы, проанализировав на нем строки текста. Она исходит из того, что линии должны быть строго горизонтальными.</p><p>Поддерживаются автоматический, краевой и ручной режимы работы.</p><p>Попытаться исправить слишком перекошенную автоматическую модель искажений - после автоматического построения модели искажений её вертикальные границы (левая и правая) могут быть наклоненными к осям координат. Если угол такого наклона превышает 2,75 градусов к оси Y, то он признается неверным и сбрасывается в ноль. Т.о. граница модели станет совпадать с направлением оси. Если обе вертикальных границы модели слишком наклонены, то корректируется самая скошенная. Этот режим может помочь в случае, если автоматическое построение модели искажений стабильно делает ошибки подобного рода.</p><p>Дополнительное исправление наклона после распрямления строк, при необходимости - мы уже исправляли угол наклона всего скана на одном из предыдущих этапов обработки, но иногда уже после распрямления строк изображение может снова оказаться перекошенным. Если данная опция включена, то после распрямления строк снова производится оценка наклона всего изображения и, если оно превышает 2,0 градуса, - оно компенсируется. Данный инструмент не имеет дополнительных настроек и выполняется полностью автоматически. Он также тратит некоторое кол-во процессорного времени и не работает с автоматическим режимом распрямления строк. Поэтому, используйте его с осторожностью.</p></body></html> + <html><head/><body><p>Функция "Распрямление строк" пытается обнаружить и исправить искажение поверхности страницы, проанализировав на нем строки текста. Она исходит из того, что линии должны быть строго горизонтальными.</p><p>Поддерживаются автоматический, краевой и ручной режимы работы.</p><p>Попытаться исправить слишком перекошенную автоматическую модель искажений - после автоматического построения модели искажений её вертикальные границы (левая и правая) могут быть наклоненными к осям координат. Если угол такого наклона превышает 2,75 градусов к оси Y, то он признается неверным и сбрасывается в ноль. Т.о. граница модели станет совпадать с направлением оси. Если обе вертикальных границы модели слишком наклонены, то корректируется самая скошенная. Этот режим может помочь в случае, если автоматическое построение модели искажений стабильно делает ошибки подобного рода.</p><p>Дополнительное исправление наклона после распрямления строк, при необходимости - мы уже исправляли угол наклона всего скана на одном из предыдущих этапов обработки, но иногда уже после распрямления строк изображение может снова оказаться перекошенным. Если данная опция включена, то после распрямления строк снова производится оценка наклона всего изображения и, если оно превышает 2,0 градуса, - оно компенсируется. Данный инструмент не имеет дополнительных настроек и выполняется полностью автоматически. Он также тратит некоторое кол-во процессорного времени и не работает с автоматическим режимом распрямления строк. Поэтому, используйте его с осторожностью.</p></body></html> - + Try to correct auto distortion model if too skewed - Попытаться исправить слишком перекошенную автоматическую модель искажений + Попытаться исправить слишком перекошенную +автоматическую модель искажений - + Try to apply additional deskew after dewarp - Дополнительное исправление наклона после распрямления строк, при необходимости + Дополнительное исправление наклона после +распрямления строк, при необходимости - + Copy ICC profile from source image - Копировать цветовой профиль ICC из исходного изображения + Копировать цветовой профиль ICC +из исходного изображения - + Most of the processing stages require multiple steps of image transformation, cropping, scaling, changing colors, applying filters etc. to calculate resulting image with specified parameters. These transformations could be displayed to user for debugging purposes. If debugging enabled you may find a new tabs on top of page view panel. Each tab contain one debugging image representing processing one step described in its title. In case the page was already processed when you switch Debug Mode on these tabs won't appear as cached resulting image is displayed and no real processing is done in this case. You have to force page reprocessing to get debug images. Use "Regenerate result" command from context menu in Thumbnail view for this. Debug images are saved as png in temporary folder with unique filenames. These files are automatically removed when application doesn't need them anymore. You can find them there or use Save as command from debug tab's image view context menu to make a persistent copy of image. - Большинство этапов обработки содержат в себе несколько шагов трансформации изображения, его обрезки, масштабирования, изменения цветов, освещенности, применения фильтров и пр. для создания изображения-результата с заданными параметрами. В целях отладки, состояние изображения на различных промежуточных шагах могут быть показаны пользователю. + Большинство этапов обработки содержат в себе несколько шагов трансформации изображения, его обрезки, масштабирования, изменения цветов, освещенности, применения фильтров и пр. для создания изображения-результата с заданными параметрами. В целях отладки, состояние изображения на различных промежуточных шагах могут быть показаны пользователю. При включенной функции отладки вы можете обнаружить новые вкладки вверху панели просмотра изображений. Каждая вкладка содержит состояние изображения соответствующего её названию шага. В случае если страница была обработана до того, как вы включили функцию отладки, эти вкладки не появятся, т.к. вам будут отображаться результаты из кэша, и никакие реальные вычисления не производятся. Чтобы увидеть результаты отладки вам необходимо заставить программу обработать страницу заново. Для этого можно либо немного изменить один из параметров, либо воспользоваться командой "Пересоздать результат" из контекстного меню ленты предпросмотра страниц. При отключенном режиме отладки эта команда не отображается. @@ -2927,115 +2977,117 @@ Debug images are saved as png in temporary folder with unique filenames. These f Отладочные изображения автоматически сохраняются в формате PNG во временной папке система с уникальными именами файлов. Эти файлы автоматически удаляются, как только они больше не нужны приложению. Вы можете воспользоваться командой "Сохранить как..." контекстного меню вкладки с таким изображением для создания постоянной копии. - + <html><head/><body><p>These settings should let you fine tune thumbnails display. By default thumbnails are added one after each other in rows, so if you change width of the thumbnails view you can get &quot;multicolumn&quot;-like style. Still you should remember that this is a list and not a grid alignment. Thus in case of different sizes of thumbnails equal spaces between &quot;columns&quot; are not guaranteed as well as equal number of thumbnails in each row. Disable first check-box to stay with single-column mode even if width of the view allows to display more.</p><p>By default you can use Alt+mouse wheel to change max size of thumbnails in the list. The key could be changed in hotkey manager. Mouse cursor should be other the thumbnails view. Thumbnails are automatically scaled to max size keeping their proportions. Switch off this mode and define fixed size (160x250 is recommended) if needed.</p><p>Even if you increase max size of thumbnails to some big values you want be able to find small details on them due to pure quality of the image. That's because they are cached after scaling to size 200x200 pixels. You can change this to 600x600 or 1200x1200 to increase thumbnail quality. Note: this affects only newly created thumbnails. If you already have them cached you'll need to delete cache subfolder in project folder manually to regenerate them.</p><p>All thumbnails have minimal margin between them and left/top borders of the view. It could be changed.</p><p>Thumbnail size is defined as a size of thumbnail image with boundary adjustments around it. These adjustments could be tuned here too.</p><p>Note: currently final boundary of the thumbnails could be affected by too long filenames displayed below them.</p><p><br/></p><p>In case of any problems use reset button which reset thumbnail settings only to their defaults.</p></body></html> - <html><head/><body><p> Собранные здесь настройки позволяют адаптировать ленту предпросмотра страниц на ваш вкус. По умолчанию страницы добавляются друг за другом в строки, поэтому, если вы увеличите ширину ленты, то вы получите представление страниц в несколько колонок. Тем не менее, следует помнить, что это именно список страниц, а не таблица или сетка. Поэтому, при наличии разницы в пропорциях размеров страниц одного проекта (а это бывает часто) одинаковое расстояние между страницами одной строки не гарантируется. Вы можете отключить первую настройку ниже чтобы запретить добавление нескольких страниц в одну строку и получите представление страниц в одну колонку, независимо от ширины ленты.</p><p>По умолчанию вы можете воспользоваться Alt+колесо мыши для изменения максимального размера страницы в ленте (страница будет смасштабирована в этот размер с учетом пропорций её миниатюры). Клавиша может быть изменена в менеджере горячих клавиш. Для того, чтобы лента отозвалась на ваше действие, курсор мыши должен находиться над ней. Вы можете отключить эту функцию и задать фиксированный максимальный размер страницы (рекомендуется 160x250 пикселей).</p><p>Даже если вы увеличите максимальный размер страницы в ленте до максимально возможных значений, это не позволит вам рассмотреть на её миниатюре какие-то мелкие детали. Все потому, что само изображение миниатюры страницы кэшируется смасштабированным в квадрат 200 на 200 пикселей, и при изменении размера страниц в ленте этот кэш автоматически не меняется и не перестраивается. Вы можете изменить этот размер в настройках на 600x600 или 1200x1200 для увеличения качества изображений в ленте. Но эта настройка повлияет только на впервые кэшируемые страницы - существующий кэш автоматически не пересоздастся. Чтобы пересоздать кэш уже существующего проекта, вам придется вручную удалить подпапку ./out/cache/thumbs в папке результатов вашего проекта. Кроме этого, при увеличении качества миниатюр многократно возрастает объем, занимаемый ими на диске.</p><p>Все страницы имеют минимальный отступ между ними, а также от верхней и левой границ ленты. Его можно менять, при желании.</p><p>Размер страницы в ленте определяется как размер миниатюры изображения плюс некоторые поля вокруг него. Эти поля также можно настроить.</p><p>Замечание: на данный момент на конечный размер страницы в ленте также может повлиять слишком длинное имя файла, отображаемое под ним.</p><p><br/></p><p>В случае каких-либо проблем используйте кнопку сброса настроек ленты страниц на значения по умолчанию.</p></body></html> + <html><head/><body><p> Собранные здесь настройки позволяют адаптировать ленту предпросмотра страниц на ваш вкус. По умолчанию страницы добавляются друг за другом в строки, поэтому, если вы увеличите ширину ленты, то вы получите представление страниц в несколько колонок. Тем не менее, следует помнить, что это именно список страниц, а не таблица или сетка. Поэтому, при наличии разницы в пропорциях размеров страниц одного проекта (а это бывает часто) одинаковое расстояние между страницами одной строки не гарантируется. Вы можете отключить первую настройку ниже чтобы запретить добавление нескольких страниц в одну строку и получите представление страниц в одну колонку, независимо от ширины ленты.</p><p>По умолчанию вы можете воспользоваться Alt+колесо мыши для изменения максимального размера страницы в ленте (страница будет смасштабирована в этот размер с учетом пропорций её миниатюры). Клавиша может быть изменена в менеджере горячих клавиш. Для того, чтобы лента отозвалась на ваше действие, курсор мыши должен находиться над ней. Вы можете отключить эту функцию и задать фиксированный максимальный размер страницы (рекомендуется 160x250 пикселей).</p><p>Даже если вы увеличите максимальный размер страницы в ленте до максимально возможных значений, это не позволит вам рассмотреть на её миниатюре какие-то мелкие детали. Все потому, что само изображение миниатюры страницы кэшируется смасштабированным в квадрат 200 на 200 пикселей, и при изменении размера страниц в ленте этот кэш автоматически не меняется и не перестраивается. Вы можете изменить этот размер в настройках на 600x600 или 1200x1200 для увеличения качества изображений в ленте. Но эта настройка повлияет только на впервые кэшируемые страницы - существующий кэш автоматически не пересоздастся. Чтобы пересоздать кэш уже существующего проекта, вам придется вручную удалить подпапку ./out/cache/thumbs в папке результатов вашего проекта. Кроме этого, при увеличении качества миниатюр многократно возрастает объем, занимаемый ими на диске.</p><p>Все страницы имеют минимальный отступ между ними, а также от верхней и левой границ ленты. Его можно менять, при желании.</p><p>Размер страницы в ленте определяется как размер миниатюры изображения плюс некоторые поля вокруг него. Эти поля также можно настроить.</p><p>Замечание: на данный момент на конечный размер страницы в ленте также может повлиять слишком длинное имя файла, отображаемое под ним.</p><p><br/></p><p>В случае каких-либо проблем используйте кнопку сброса настроек ленты страниц на значения по умолчанию.</p></body></html> - + Application language - allows to switch the language of the interface. If there is no language you need and you can help us with translation please contact the project maintainer. Batch processing - a simple dialog that appears if you press the launch button and allows you to start page processing from the beginning instead of a current page. You can add new images (for ex. missing pages) after project is created with Insert new image command in thumbnails context menu. Images that already in the project may be filtered out in file selection dialog automatically. But this require non-native dialog implementation which may look unusual and lack some platform features. You can turn option "Filter existing files in insert new image dialog" off and stick to usage of native dialog. But filtering existing images is not guaranteed in this case. - Язык интерфейса - позволяет переключать язык приложения. Изменения вступают в силу без перезапуска приложения. + Язык интерфейса - позволяет переключать язык приложения. Изменения вступают в силу без перезапуска приложения. Пакетная обработка - простой диалог, который появляется, если вы нажимаете кнопку пакетной обработки рядом с названием этапа обработки. Он позволяет вам выбрать, какие именно страницы будут обработаны: с первой по последнюю или с текущей по последнюю. Вы можете вставлять новые страницы (напр., пропущенные при первом сканировании) и после создания проекта, при помощи команды контекстного меню "Вставить новую страницу" в ленте страниц. При этом файлы изображений, уже использующихся в вашем проекте, могут автоматически скрываться в диалоге выбора файла. Но работа данной функции гарантируется только при использовании собственной реализации диалогового окна Qt, которое может выглядить иначе и не иметь некоторых функций, присущих обычным диалогам выбора файлов в вашей системе. Вы можете отключить опцию "Фильтрация использующихся файлов в диалоге вставки новой страницы" и использовать только системные диалоги, но фильтрация файлов в этом случае не гарантирована. - + Filter existing files in insert new image dialog - Фильтрация использующихся файлов в диалоге вставки новой страницы + Фильтрация использующихся файлов +в диалоге вставки новой страницы - + Place as many thumbnails in a row as possible - Помещать страницы в ряд, если ширина позволяет + Помещать страницы в ряд, если ширина позволяет - + Use fixed max thumbnail size - Фиксировать максимальный размер миниатюры + Фиксировать максимальный размер миниатюры - - - - - - - - + + + + + + + + px px - + Scale cached images to this size: - Размер кэшированных изображений (макс.): + Размер кэшированных изображений (макс.): - + Minimal space between images: - Минимальный отступ между страницами: + Минимальный отступ между страницами: - + Thumbnail boundary adjustments: - Дополнительные поля вокруг миниатюры страницы: + Дополнительные поля вокруг миниатюры страницы: - + &Reset - &Сбросить на значения по умолчанию + &Сбросить на значения по умолчанию - + Display hints under pages if order isn't natural - Показывать подсказки под страницами, если их порядок изменён + Показывать подсказки под страницами, +если их порядок изменён - + Allows to automatically save project file (*.scantailor) with a specified time interval. If project was never saved before this will create UnnamedAutoSave.Scantailor file in project's input directory. Otherwise project file will be backed up to *.bak file in the its folder and then overwritten with current project state. - Позволяет автоматически сохранять файл проекта (* .scantailor) через заданный интервал времени. + Позволяет автоматически сохранять файл проекта (* .scantailor) через заданный интервал времени. Если проект недавно создан и ещё никогда прежде не сохранялся, то он будет помещен в файл UnnamedAutoSave.Scantailor в каталоге ввода результатов проекта. В противном случае старый файл проекта будет скопирован в файл * .bak в его папке, а затем перезаписан текущим состоянием проекта. - + Save project every: - Сохранять проект каждые: + Сохранять проект каждые: - + min. - мин. + мин. - + Hide rare or unsupported methods - Скрыть редкоиспользуемые методы + Скрыть редкоиспользуемые методы - + Use horizontal differencing predictor - Использовать horizontal differencing predictor + Использовать horizontal differencing predictor - + At this stage it is possible to turn scans by multiples of 90 degrees. i.e., to correct sideways or upside-down scans. This is a manual stage because the program does not know how to determine the correct orientation of scans - the user must do this. This also means that using batch processing at this stage is useless. Obviously it behooves the user to make sure all initial scans are of the same orientation, if possible; mixing orientation will make this stage less automatic and more time-consuming. Use "Apply To..." dialog to apply changes to a specified range of pages. - На этом этапе обработки можно поворачивать сканы на угол, кратный 90 градусам. То есть, корректировать страницы, отсканированные вверх ногами или на боку. + На этом этапе обработки можно поворачивать сканы на угол, кратный 90 градусам. То есть, корректировать страницы, отсканированные вверх ногами или на боку. Сделать это для всех страниц придется вручную, т.к. алгоритма автоматического распознавания ориентации в программе не реализовано. Но вам может очень пригодиться использование инструмента «Применить к...», чтобы распространить настройки поворота текущей страницы на указанный диапазон страниц. Естественно, желательно, чтобы на этапе сканирования ориентация сканов была как можно менее случайной и как можно более однородной. В любом случае - этот этап обработки обычно самый простой и наименее трудозатратный. - + This stage determines whether you want to divide the page(s). Type of division: @@ -3046,7 +3098,7 @@ Type of division: The type of division is determined automatically, but can be set manually. If image width twice bigger than image height it's treated as a scan of two-pages. Use the "Change ...", to manually set. The type of division can be applied to all pages at once or individual pages. The dividing line can also be determined/moved automatically or specified manually, but it can not be applied to other pages unless Apply cut mode is on. It is useful to quickly check out the preview pane of each page to ensure the page splits have been correctly applied - sometimes images in pages can affect the split operation. - На этом этапе вы определяете, нужно ли вам разделение оригинального изображения на отдельные страницы, и как именно это будет происходить. + На этом этапе вы определяете, нужно ли вам разделение оригинального изображения на отдельные страницы, и как именно это будет происходить. Имеются следующие варианты: • Изображение содержит скан одной страницы, без каких-либо частей последующей страницы на нем. Эти сканы обычно получают из специализированных сканеров или фотографий. Никакого разрезания они не требуют. @@ -3060,162 +3112,162 @@ The dividing line can also be determined/moved automatically or specified manual Обычно, после автоматической разрезки страниц в режиме пакетной обработки достаточно бегло просмотреть ленту предпросмотра страниц, чтобы убедится в том, что все типы разрезов были определены правильно, а линия разреза не проходит по области контента. - + If this feature is enabled the application shows "Apply cut" check box in "Apply to..." dialog at Split pages stage. In case it's checked the application tries to copy dividing lines position to the specified page range. In case target page size mismatch the original page the dividing line position will be scaled. - Если эта функция включена, приложение показывает флажок «Копировать координаты разреза» в диалоговом окне «Применить к...» на этапе «Разрезка страниц». Если он включен, приложение пытается скопировать позицию и угол линий разреза в указанный диапазон страниц. Если размер целевой страницы не соответствует исходной странице, позиция разделительной линии будет сдвигать пропорционально разнице в размерах. + Если эта функция включена, приложение показывает флажок «Копировать координаты разреза» в диалоговом окне «Применить к...» на этапе «Разрезка страниц». Если он включен, приложение пытается скопировать позицию и угол линий разреза в указанный диапазон страниц. Если размер целевой страницы не соответствует исходной странице, позиция разделительной линии будет сдвигать пропорционально разнице в размерах. - + Switched on by default: - По умолчанию включено: + По умолчанию включено: - + At this stage one may determine the angle which the page needs to be turned for the text to be properly horizontal. Since compensation is a simple rotation such distortions as keystone or curling can not be corrected at this stage. The rotation angle is determined automatically, but you can also set it manually. Images can be rotated by dragging the round handles at the edges. You can also explicitly specify the rotation angle in degrees. Positive angles will rotate the image clockwise, negative counter-clockwise. For fine adjustment of the angle it may be convenient to click the mouse on the text portion of the input field corner, then move the mouse wheel to fix it. - На этом этапе обработки можно задать угол, на который страница должна быть повернута для ровного отображения текста по горизонтали. Поскольку компенсация представляет собой простой поворот, такие искажения геометрии текста, как трапецеидальность или керлинг, не могут быть исправлены на данном этапе. Угол поворота определяется автоматически, но вы также можете установить его вручную. + На этом этапе обработки можно задать угол, на который страница должна быть повернута для ровного отображения текста по горизонтали. Поскольку компенсация представляет собой простой поворот, такие искажения геометрии текста, как трапецеидальность или керлинг, не могут быть исправлены на данном этапе. Угол поворота определяется автоматически, но вы также можете установить его вручную. Изображения можно поворачивать, перетаскивая круглые ручки по краям отображаемой страницы. Вы также можете указать угол поворота в градусах. Положительные углы повернут изображение по часовой стрелке, отрицательное против часовой стрелки. Для точной регулировки угла может быть удобно при вводе значения угла вручную использовать колесико мыши мышью. Поле ввода угла должно быть активным и иметь фокус. - + If enabled - marks deviant pages with red asterisks in Thumbnails panel. The Deviant page on this stage is defined as a page which absolute deskew angle value is bigger than specified in command line (5 degrees by default) or differs from average angle more than 1.5 standard deviations. Average angle and standard deviation are statistical measurements calculated based on all pages. - Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. + Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. Аномальной на этом этапе обработки считается страница, абсолютное значение угла поворота которой больше, чем указано в параметре командной строки (по умолчанию 5 градусов) или отличается от среднего угла более чем на 1,5 стандартных отклонения. Средний угол и стандартное отклонение - это статистические характеристики, рассчитанные на основе всех страниц. - + Fine tune page corners: - Избегать чёрных уголков: + Избегать чёрных уголков: - + Default value for page: enabled - Включать по умолчанию + Включать по умолчанию - + Target page size in MM: - Задать искомый размер страницы в мм: + Задать искомый размер страницы в мм: - - + + Click to change color - Нажмите для изменения цвета + Нажмите для изменения цвета - - + + Reset color to default - Сбросить цвет на значение по-умолчанию + Сбросить цвет на значение по-умолчанию - + <html><head/><body><p>At this stage you may adjust the margins added to the content box. There are <span style=" font-weight:600;">two types of margins</span> - hard and soft.</p><p><span style=" font-weight:600;">Hard margin</span> - is that between the solid lines. They are set by the user. You can either move over any solid line, be it an inner or outer edge, or set the margins through numerical values.</p><p><span style=" font-weight:600;">Soft margin</span> - is that between the solid and the dotted line. These margins are <span style=" text-decoration: underline;">automatically</span> added to bring the page size to the same size of other pages. If you see a dotted line - this means that somewhere in the project there is a page with that width (usable area of Hard + margin), and (possibly others) with that height. This is one big page causing the soft margins in all the other pages, if only for not leveling them off.</p><p><span style=" font-weight:600;">Alignment</span> defines how to align content zone with its hard margins by changing soft margins. It could be: manual, auto-magnet and original proportions (last two are optional features).</p></body></html> - <html><head/><body><p>На этом этапе вы можете настроить поля, добавляемые вокруг области контента. Существует <span style=" font-weight:600;">два вида полей</span> - жёстко заданные и косвенно определённые.</p><p><span style=" font-weight:600;">Жёстко заданные поля</span> рисуются на макете страницы сплошными линиями. Они задаются пользователем. Вы можете изменять их, двигая мышью эти линии, или задать их введя числовые значения.</p><p><span style=" font-weight:600;">Косвенно определённые</span> - это поля между сплошными и пунктирными линями макета. Эти поля добавляются <span style=" text-decoration: underline;">автоматически</span> чтобы компенсировать разнице размера вашей страницы до размера остальных страниц. Если вы видите пунктирный контур - это значит, что где-то в вашем проекте есть страницы с такой шириной (вычисленной как область контента плюс поля слева и справа) и такой высотой (высота области контента плюс поля сверху и снизу). Возможно, это одна страница - тогда на ней пунктирных линий не будет вообще. Часто самой большой страницей проекта оказывается обложка. Размер, до которого происходит компенсация косвенно определёнными полями, вычисляется как максимальные ширина и высота среди всех областей контента проекта с их жёстко заданными полями. Исключением являются страницы, для которых отключена опция "Выровнять размеры с другими страницами" - у них косвенно определённых полей не бывает вообще, их размер полностью определяется размером области контента и жёстко заданных полей. Если вы отключите эту опцию на странице, влиявшей на величины косвенно определённых полей - они будут пересчитаны заново, исходя из размеров оставшихся страниц.</p><p><span style=" font-weight:600;">Выравнивание</span> определяет то, как распределяются значения косвенно определённых полей вокруг области контента с её жёстко заданными полями. Распределяться они могут по разному. Например, если вам нужно прибавить такое поле для того, чтобы компенсировать высоту вашей страницы до общего размера, то вы можете добавить эту разницу сверху, а можете снизу, или и сверху и снизу так, чтобы область контента оказалась отцентрированной по вертикали (если размер жёстко заданных полей не слишком большой). В результате на макете это выражается в типе выравнивания области страницы внутри площади общего размера страниц. Выравнивание бывает: ручным, автоматическим (Авто-магнит) и пропорциональным положению на оригинале (последние два - опциональны).</p></body></html> + <html><head/><body><p>На этом этапе вы можете настроить поля, добавляемые вокруг области контента. Существует <span style=" font-weight:600;">два вида полей</span> - жёстко заданные и косвенно определённые.</p><p><span style=" font-weight:600;">Жёстко заданные поля</span> рисуются на макете страницы сплошными линиями. Они задаются пользователем. Вы можете изменять их, двигая мышью эти линии, или задать их введя числовые значения.</p><p><span style=" font-weight:600;">Косвенно определённые</span> - это поля между сплошными и пунктирными линями макета. Эти поля добавляются <span style=" text-decoration: underline;">автоматически</span> чтобы компенсировать разнице размера вашей страницы до размера остальных страниц. Если вы видите пунктирный контур - это значит, что где-то в вашем проекте есть страницы с такой шириной (вычисленной как область контента плюс поля слева и справа) и такой высотой (высота области контента плюс поля сверху и снизу). Возможно, это одна страница - тогда на ней пунктирных линий не будет вообще. Часто самой большой страницей проекта оказывается обложка. Размер, до которого происходит компенсация косвенно определёнными полями, вычисляется как максимальные ширина и высота среди всех областей контента проекта с их жёстко заданными полями. Исключением являются страницы, для которых отключена опция "Выровнять размеры с другими страницами" - у них косвенно определённых полей не бывает вообще, их размер полностью определяется размером области контента и жёстко заданных полей. Если вы отключите эту опцию на странице, влиявшей на величины косвенно определённых полей - они будут пересчитаны заново, исходя из размеров оставшихся страниц.</p><p><span style=" font-weight:600;">Выравнивание</span> определяет то, как распределяются значения косвенно определённых полей вокруг области контента с её жёстко заданными полями. Распределяться они могут по разному. Например, если вам нужно прибавить такое поле для того, чтобы компенсировать высоту вашей страницы до общего размера, то вы можете добавить эту разницу сверху, а можете снизу, или и сверху и снизу так, чтобы область контента оказалась отцентрированной по вертикали (если размер жёстко заданных полей не слишком большой). В результате на макете это выражается в типе выравнивания области страницы внутри площади общего размера страниц. Выравнивание бывает: ручным, автоматическим (Авто-магнит) и пропорциональным положению на оригинале (последние два - опциональны).</p></body></html> - + <html><head/><body><p>Here you can set default <span style=" font-weight:600;">&quot;hard margins&quot;</span> values for <span style=" font-weight:600;">top, left, right</span> and <span style=" font-weight:600;">bottom</span> sides.</p><p><span style=" font-weight:600;">Auto margins</span> let you automatically calculate margin values for content area so their combined size will match page size. Page area is usually equal to image area (after page splitting and deskew) but could be affected with optional page detection feature on content selection stage.</p><p>Note: Even if you apply auto margins to all pages in project that doesn't guarantee that all content rects plus corresponding hard margins will result to the same size. Thus in case of &quot;Match with other pages&quot; enabled you'll get some <span style=" font-weight:600;">soft margins</span> that should be addressed with help of Alignment. There could be many reasons of page size mismatch: different size of original scans, different page splitting, page geometry change after deskew or distinction in page detection results.</p></body></html> - <html><head/><body><p>Здесь вы можете задать значения по умолчанию для<span style=" font-weight:600;">&quot;жёстко заданных полей&quot;</span> с <span style=" font-weight:600;">верхней, левой, правой</span> и <span style=" font-weight:600;">нижней</span> сторон области контента.</p><p><span style=" font-weight:600;">Авто-поля</span> автоматически устанавливают значения жёстких полей такими, чтобы их сумма с размером области контента была равна размеру области страницы, и область контента сохраняла исходное местоположение в этих рамках. Область страницы обычно принимается равной размеру изображения (после разрезания и компенсации наклона), но может быть меньше, если включена соответствующая функция на этапе определения Области контента.</p><p>Замечание: Даже если вы примените Авто-поля ко всем страницам в проекте, это не гарантирует того, что косвенно вычисляемые поля для них окажутся нулевыми (если только вы не отключите им всем опцию "Выровнять размеры с другими страницами"). Поэтому, вам всё ещё нужно позаботиться о типе <span style=" font-weight:600;">выравнивания</span> ваших страниц. Это происходит из за разницы в размерах областей страниц (или изображений целиком, если область страниц не искалась), чему может быть множество причин: разный размер исходных сканов, разные координаты автоматической разрезки на страницы, изменение геометрии страницы после компенсации наклона или погрешности в работе алгоритма определения области страницы. Покуда у вас есть страницы с опцией "Выровнять размеры с другими страницами" - у вас будут ненулевые косвенно определённые поля и вам будет требоваться выравнивание</p></body></html> + <html><head/><body><p>Здесь вы можете задать значения по умолчанию для<span style=" font-weight:600;">&quot;жёстко заданных полей&quot;</span> с <span style=" font-weight:600;">верхней, левой, правой</span> и <span style=" font-weight:600;">нижней</span> сторон области контента.</p><p><span style=" font-weight:600;">Авто-поля</span> автоматически устанавливают значения жёстких полей такими, чтобы их сумма с размером области контента была равна размеру области страницы, и область контента сохраняла исходное местоположение в этих рамках. Область страницы обычно принимается равной размеру изображения (после разрезания и компенсации наклона), но может быть меньше, если включена соответствующая функция на этапе определения Области контента.</p><p>Замечание: Даже если вы примените Авто-поля ко всем страницам в проекте, это не гарантирует того, что косвенно вычисляемые поля для них окажутся нулевыми (если только вы не отключите им всем опцию "Выровнять размеры с другими страницами"). Поэтому, вам всё ещё нужно позаботиться о типе <span style=" font-weight:600;">выравнивания</span> ваших страниц. Это происходит из за разницы в размерах областей страниц (или изображений целиком, если область страниц не искалась), чему может быть множество причин: разный размер исходных сканов, разные координаты автоматической разрезки на страницы, изменение геометрии страницы после компенсации наклона или погрешности в работе алгоритма определения области страницы. Покуда у вас есть страницы с опцией "Выровнять размеры с другими страницами" - у вас будут ненулевые косвенно определённые поля и вам будет требоваться выравнивание</p></body></html> - - + + Default values: - Значения по умолчанию: + Значения по умолчанию: - + Auto layer is switched on by default and contains automatically detected areas which are most likely pictures and should be left grayscaled/colored while other converted to b/w. The result is binary mask and could be viewed in Layers tab. It's highlighted by blue and glowing. This mask can't be changed directly but only switched on/off. User could also create zones (polygons) with "subtract from Auto layer" or "Add to Auto layer" flags to modify it. - Слой поиска иллюстраций включен по умолчанию и отображает области, которые наиболее вероятно являются иллюстрациями так, как они выглядят в оригинале (не приводя к ч/б виду). + Слой поиска иллюстраций включен по умолчанию и отображает области, которые наиболее вероятно являются иллюстрациями так, как они выглядят в оригинале (не приводя к ч/б виду). В результате его работы создаётся бинарная маска, отличающая области ч/б контента от остальных. При просмотре страницы на соотв. закладке она подсвечивается синим и мерцает. Изменять эту маску напрямую нельзя, только включить/выключить весь слой. Но пользователь может создать зоны со свойствами "Добавить к слою иллюстраций" или "Вычесть из слоя иллюстраций", чтобы её модифицировать. Также доступна настройка порогового значения, используемого для отделения пикселей контента от фона. В дальнейшем этот контент анализируется на предмет его "плотности" для выделения из него пикселей, наиболее вероятно составляющим иллюстрации. - - + + Width: Ширина: - - + + Height: Высота: - + Default borders in MM: Отступы по умолчанию в мм: - - + + Left: Слева: - - + + Right: Справа: - - + + Top: Сверху: - + If docking is enabled the Filters and Thumbnails panels could be pop out from their positions (left and right sides of the ain application window) and float over page view one. Once pop out they could be placed back by double clicking panel's title or pressing an icon on it (icon might be not displayable of your system). This option allows to increase page view panel size to almost a whole application window size which may be useful in some cases. - Если режим плавающих панелей включен, то над панелями "Этапы обработки" и "Страницы" главного окна появятся кнопки, позволяющие открепить их от него и свободно перетаскивать по экрану мышью. Место, доступное для просмотра страницы, в этом случае несколько увеличивается. Вернуть плавующую панель на место можно двойным щелчком по её заголовку или нажатием соответствующей кнопки в нем (отображается не на всех системах). Вероятно, наиболее полезным этот режим будет для владельцев систем с двумя мониторами, т.к. в этом случае ленту предпросмотра страниц можно вывести на отдельный монитор. + Если режим плавающих панелей включен, то над панелями "Этапы обработки" и "Страницы" главного окна появятся кнопки, позволяющие открепить их от него и свободно перетаскивать по экрану мышью. Место, доступное для просмотра страницы, в этом случае несколько увеличивается. Вернуть плавующую панель на место можно двойным щелчком по её заголовку или нажатием соответствующей кнопки в нем (отображается не на всех системах). Вероятно, наиболее полезным этот режим будет для владельцев систем с двумя мониторами, т.к. в этом случае ленту предпросмотра страниц можно вывести на отдельный монитор. - - + + Bottom: Снизу: - + Once all processing stages are complete the resulting images are saved in "./out" sub-folder of your project input folder in TIFF format. TIFF format supports dozens of image compression methods from None to JPEG. Default is LZW. Stick to it till you are sure you need something different. Availability of compression methods depends on their support in libtiff and options used to build it. So not all methods are available. Also some could be used with black/white images only. Horizontal differencing predictor - a preprocessing step applied to image data that might improve compression rate. Only few compression methods are benefit from this. In particular - LZW. - После завершения всех этапов обработки результаты сохраняются в подпапке "./out" папки ввода проекта (если не указана отдельная папка вывода) в формате TIFF. Формат TIFF поддерживает десятки различных методов сжатия изображений от None до JPEG. По умолчанию используется LZW. Не меняйте этого, пока не будете уверены, что вам нужно что-то другое. + После завершения всех этапов обработки результаты сохраняются в подпапке "./out" папки ввода проекта (если не указана отдельная папка вывода) в формате TIFF. Формат TIFF поддерживает десятки различных методов сжатия изображений от None до JPEG. По умолчанию используется LZW. Не меняйте этого, пока не будете уверены, что вам нужно что-то другое. Доступность методов сжатия зависит от их поддержки в библиотке libtiff, встраиваемой в приложение, и опций, используемых при её компиляции. Поэтому, программе обычно доступны не все методы. Также некоторые методы сжатия могут использоваться только с черно-белыми изображениями. Horizontal differencing predictor - это шаг предобработки данных изображения, который может повысить эффективность их последующего сжатия (в основном, методом LZW. Подавляющее большинство остальных методов от этого шага не выигрывают). Естественно, сама предобработка требует некоторого процессорного времени. Если вы используете сжатие LZW, хотите сэкономить место на диске и у вас мощный ПК - то можете попробовать эту опцию. - + This stage determines the rectangular region with "useful" or usable content (shaded in color). Why do we need to define this area? Firstly in order to determine the page size to the output. The content will be added to the total margin area, and the outer limit of these margins affects the size of the output file. Secondly so that the final images don't show the line of fold or other debris from the edges. Strictly speaking whether the debris falls in the margin in the output stage depends on the mode. In most modes the margin is filled in white. If areas are identified incorrectly, you can tweak individual pages manually by setting the mouse pointer over the edge, clicking & dragging as needed. Check Hotkeys manager for a list of all possible operations. Occasionally Scan Tailor may find non-existent content or conversely not select content where it should. In this case, you can manually create / delete a region by right-clicking on the image, and select the appropriate menu item. - Этот этап позволяет задать прямоугольную область, содержащую полезный контент (текст, изображения и пр.). Все, что в эту область изображения не попадёт -- будет в дальнейшем отброшено. Зачем необходимо задание этой области? Во-первых, чтобы определить размер страницы результата на этапе вывода. К области контента будут добавлены поля, что определит её собственный размер. Далее, если включена опция "Выровнять размеры с другими страницами" их общий размер будет определён как максимальная ширина максимальная высота собственных размеров таких страниц. Во-вторых, это необходимо, чтобы в результате не отображалась линия сгиба разворотов страниц или другие заломы с краев. Строго говоря, попадет ли мусор по краям в результат зависит от выбранного режима на этапе вывода результата. В большинстве режимов поля заполняется белым цветом (в режиме Цветной это можно отключить). + Этот этап позволяет задать прямоугольную область, содержащую полезный контент (текст, изображения и пр.). Все, что в эту область изображения не попадёт -- будет в дальнейшем отброшено. Зачем необходимо задание этой области? Во-первых, чтобы определить размер страницы результата на этапе вывода. К области контента будут добавлены поля, что определит её собственный размер. Далее, если включена опция "Выровнять размеры с другими страницами" их общий размер будет определён как максимальная ширина максимальная высота собственных размеров таких страниц. Во-вторых, это необходимо, чтобы в результате не отображалась линия сгиба разворотов страниц или другие заломы с краев. Строго говоря, попадет ли мусор по краям в результат зависит от выбранного режима на этапе вывода результата. В большинстве режимов поля заполняется белым цветом (в режиме Цветной это можно отключить). Если результат автоматического определение области контента вас не устроил, вы можете настроить её вручную, перетащив области мышью за края. В настройках «Менеджера горячих клавиш» вы найдете список всех возможных операций, доступных при помощи клавиатуры. Иногда Scan Tailor может найти несуществующий контент или, наоборот, вообще не найти контент там, где он должен быть. В этом случае вы можете вручную создать / удалить область контента, щелкнув правой кнопкой мыши на изображении и выбрать соответствующий пункт меню. - + If enabled - marks deviant pages with red asterisks in Thumbnails panel. The Deviant page on this stage is defined as a page which content zone square differs from average square more than 1.0 standard deviation. Factor 1.0 may be changed via command line. Average square and standard deviation are statistical measurements calculated based on all pages. - Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. + Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. Аномальной на этом этапе обработки считается страница, площадь области контента которой отличается от средней более чем на 1,0 стандартного отклонения. Коэффициент 1,0 может быть изменен через параметр командной строки. Среднее значение и стандартное отклонение - это статистические характеристики, рассчитанные на основе площадей всех страниц. - + By default application tries to find a content area on whole page. But sometimes user have an scan bigger than page. This could happen if you scan whole possible scanner area even if your pages are smaller than it. In this case you might end up with a big image with huge black borders. If page detection is enabled the application tries to find a real page area in image before content area detection. In case of success the content area is searched inside area found only. Technically it preprocess image to excludes black borders from page area. The following enhancements could be applied (in order they're listed): Fine tune page corners - move corners of detected page area towards the center of page while the corner pixel won't be non black. @@ -3225,7 +3277,7 @@ Page detection target size - you may specify real physical size of a single page Page borders - after page area is found this will decrease it by given borders. Everything outside page area is highlighted with yellow in page view panel. - По умолчанию приложение пытается найти область контента, рассматривая площадь всего изображения. Но, зачастую, сканы пользователей существенно больше, чем размер страницы на них. Например, так может получиться, если вы не задали область сканирования, и на сканере площадью A4 сканируете разворот книги гораздо меньшей площади. В этом случае, на изображении вокруг разворота могут быть большие чёрные поля. И они останутся после разрезания. Иными словами - скан страницы окажется на чёрном фоне. + По умолчанию приложение пытается найти область контента, рассматривая площадь всего изображения. Но, зачастую, сканы пользователей существенно больше, чем размер страницы на них. Например, так может получиться, если вы не задали область сканирования, и на сканере площадью A4 сканируете разворот книги гораздо меньшей площади. В этом случае, на изображении вокруг разворота могут быть большие чёрные поля. И они останутся после разрезания. Иными словами - скан страницы окажется на чёрном фоне. Если включена функция обнаружения Области страницы, то приложение, перед тем как искать на изображении область контента, попытается сузить зону поиска путём предварительного определения размера и местоположения страницы на нём. Если это удастся сделать, то область контента будет искаться исключительно внутри области страницы изображения, а не на всей его площади. Технически, алгоритм пытается обнаружить и исключить из рассмотрения чёрные поля вокруг страницы на скане. Его работа может быть скорректирована следующими настройками: @@ -3238,32 +3290,32 @@ Everything outside page area is highlighted with yellow in page view panel. - + Millimeters (mm) Миллиметры (мм) - + Inches (in) Дюймы (in) - + Top Сверху - + Left Слева - + Right Справа - + Bottom Снизу @@ -3273,101 +3325,102 @@ Everything outside page area is highlighted with yellow in page view panel.Не удалять пятна - + If enabled - marks deviant pages with red asterisks in Thumbnails panel. The Deviant page on this stage is defined as a page which has no alignment. - Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. + Если включено - помечает аномальные страницы в ленте предварительного просмотра страниц при помощи красных звездочек. Аномальной на этом этапе обработки считается страница, у не задано выравнивание (отключено выравнивание размера с другими страницами). - + Switched on for page by default Включать по умолчанию - + Auto-Magnet alignment - Автоматическое определение выравнивания + Автоматическое определение выравнивания - + Original proportions alignment - Выравнивание пропорционально положению на оригинале + Выравнивание пропорционально +положению на оригинале - + Selected alignment Выбранный тип выравнивания - + At this stage the output files are created from the images and written to the disk. The resultant images also appear in the central window of the program. Unlike the other stages, the "Output" stage becomes available only after all page pass the stages of "Select Content" and "Page Layout". This is because the size of pages in the output depend on each other. Say if it found a big page, then all the other fields are increasing (more is described in the documentation on the Page Layout stage). Therefore it is important to know the final size of pages, and it can only be done through the stages of "Select Content" and "Page Layout". - На этом этапе создаются и сохраняются на диск файлы с результатами обработки. Результирующие изображения также отображаются в центральном окне программы. + На этом этапе создаются и сохраняются на диск файлы с результатами обработки. Результирующие изображения также отображаются в центральном окне программы. В отличие от других этапов, этап «Вывод результатов» становится доступным только после того, как все страницы будут обработаны на этапах «Область контента» и «Макетирование». Это связано с тем, что размер страниц-результатов может зависеть друг от друга. Скажем, если на этапе «Макетирование» появляется страница с большим размером, то увеличивается общий размер страниц и пересчитываются значения косвенно определённых полей (подробнее описано в документации для этапа макетирования страницы). Поэтому важно знать конечный размер всех страниц, и это можно сделать только на этапах «Область контента» и «Макетирование». - + Default DPI: DPI по умолчанию для результата: - + Threshold control diapason: - Диапазон допустимого при выборе пороговых значений: + Диапазон допустимого при выборе пороговых значений: - + Min.: Мин.: - + Max.: Макс.: - + Default threshold value: Пороговые значения по умолчанию равны: - + Hold spacebar to display original page Показывать оригинал страницы при нажатом пробеле - + Black and White is not suitable for any images and some drawings. There is an option to "despeckle", and to increase or decrease the line thickness (i.e. of the text). In general it is best to not despeckle if the image is reasonably clean as despeckling can result in the loss of some portions of text. This may be compensated for to a degree by increasing the line thickness but it's probably important to experiment on a few pages before applying to the entire project. Making black and white image from grayscale or color source requires binarization. Binarization contains several steps which could be seen in debug mode. One of these is image smoothing. In few cases better results could be achieved if smoothing is disabled, but it's enabled by default. - Чёрно/белый режим не подходит для изображений и некоторых рисунков. Он имеет опцию «Удаление мусора» и настройку порога бинаризации (одним из результатов работы которого является увеличение или уменьшение толщины линий (т. е. текста). В общем, «Удаление мусора» лучше не использовать, если изображение достаточно чистое, так как «Удаление мусора» может привести к потере некоторых частей текста. Это может быть компенсировано в некоторой степени за счет увеличения порога бинаризации, но, вероятно, вам лучше поэкспериментировать на нескольких страницах перед тем, как применить эти настройки ко всему проекту. + Чёрно/белый режим не подходит для изображений и некоторых рисунков. Он имеет опцию «Удаление мусора» и настройку порога бинаризации (одним из результатов работы которого является увеличение или уменьшение толщины линий (т. е. текста). В общем, «Удаление мусора» лучше не использовать, если изображение достаточно чистое, так как «Удаление мусора» может привести к потере некоторых частей текста. Это может быть компенсировано в некоторой степени за счет увеличения порога бинаризации, но, вероятно, вам лучше поэкспериментировать на нескольких страницах перед тем, как применить эти настройки ко всему проекту. Создание черно-белого изображений из исходного цветного изображения или изображения в оттенках серого называют его бинаризацией. Бинаризация содержит несколько шагов, результаты работы которых можно увидеть в режиме отладки. Одним из этих шагов является сглаживание изображения. В некоторых (редких) случаях результат без сглаживания может оказаться лучше, но по умолчанию оно включено. - + Disable smoothing Отключить сглаживание - + Sensitivity: - Чувствительность: + Чувствительность: - + % % - + Foreground layer allows user to fill page with white while keeping its content grayscaled or colored. Technically, it binarizes image to a b/w mask and uses such mask to separate background from foreground. Then background is filled with white while foreground is kept as is. It could be useful if you have some colored text, arrows or other glyphs which could be hardly represented as a rectangle picture. Foreground layer could be adjusted with zones. Use zones with "subtract from all layers" property to left a part of image below it in b/w mode. Or "subtract to auto layer" to remove auto layer mask below it. By default auto layer masks (if enabled) and foreground layer masks are combined. As Foreground layer is using binarization to separate content from background it's uses binarization threshold value. By default it's the same value that used for b/w layer. But sometimes you may need bigger threshold to be used for mask detection while keeping b/w threshold for regular binarization. In this case you can switch on "Separate threshold control" check box and make additional threshold control visible for foreground layer. - Слой всего контента позволяет пользователю получить страницу на которой фон залит белым, а все остальное остается как в оригинале: в тонах серого или цветным. Технически, в нем используется тот же подход, что и в слое поиска иллюстраций, но в качестве маски применяется бинаризованное изображение целиком, что позволяет отображать как есть не только иллюстрации, но и весь текст. + Слой всего контента позволяет пользователю получить страницу на которой фон залит белым, а все остальное остается как в оригинале: в тонах серого или цветным. Технически, в нем используется тот же подход, что и в слое поиска иллюстраций, но в качестве маски применяется бинаризованное изображение целиком, что позволяет отображать как есть не только иллюстрации, но и весь текст. Он может быть полезен, если у вас есть цветной текст, стрелки или другие символы, которые игнорирует слой поиска иллюстраций и которые сложно выделить вручную. Слой всего контента можно корректировать накладывая на него зоны. Используйте зоны со свойством "вычесть из всех слоев", чтобы контент в ней бинаризовывался в чёрно-белом режиме. По умолчанию маска слоя поиска иллюстраций (если он включен) и маска слоя всего контента объединяются в одну. Используйте зоны со свойством "Вычесть из слоя поиска иллюстраций", чтобы убрать часть маски слоя поиска иллюстраций при этом не трогая маску слоя всего контента. @@ -3376,39 +3429,39 @@ As Foreground layer is using binarization to separate content from background it Маска данного слоя отображается вместе с маской слоя поиска иллюстраций - обе подсвечены синим и мерцают. - + Separate threshold control - Отдельно настраивать пороговое значение + Отдельно настраивать пороговое значение для слоя всего контента - + Fill zones tab allows user to specify zones that will be filled with background cover. This is usually used to remove the library stamps, and spots that are too big to be automatically removed with Despeckle function. - Вкладка "Зоны заливки" позволяет пользователю задать зоны, которые будут закрашены цветом фона. Обычно это используется для удаления библиотечных штампов, и пятен, слишком больших, чтобы быть убранными функцией удаления мусора. + Вкладка "Зоны заливки" позволяет пользователю задать зоны, которые будут закрашены цветом фона. Обычно это используется для удаления библиотечных штампов, и пятен, слишком больших, чтобы быть убранными функцией удаления мусора. - + Despeckling mode tries to automatically clean page content from spots. It analyses only areas of page rendered in b/w. In a nutshell it looks for connected set of black pixels that could be bounded with a rect smaller then Despeckling mode sensitivity rect - in this case these pixels are filled with background color. Currently 3 levels of sensitivity are supported. - Функция "Удаление мусора" пытается автоматически очистить содержимое страницы от мелких точек, появляющихся в результате загрязнения страницы книги. Она анализирует только области страницы, отображаемые чёрно-белыми. Технически, функция ищет связные группы чёрных пикселей, которые могут быть вписаны в прямоугольник достаточно малого размера. Чувствительность функции "Удаление мусора" задает этот размер. В настоящее время поддерживаются 3 уровня чувствительности. Будьте осторожны с агрессивным уровнем - он может принять за мусор знаки препинания (точки, особенно в оглавлении книг). Весь достаточно мелкий мусор удаляется путем заливки площади описанного вокруг него прямоугольника цветом фона. + Функция "Удаление мусора" пытается автоматически очистить содержимое страницы от мелких точек, появляющихся в результате загрязнения страницы книги. Она анализирует только области страницы, отображаемые чёрно-белыми. Технически, функция ищет связные группы чёрных пикселей, которые могут быть вписаны в прямоугольник достаточно малого размера. Чувствительность функции "Удаление мусора" задает этот размер. В настоящее время поддерживаются 3 уровня чувствительности. Будьте осторожны с агрессивным уровнем - он может принять за мусор знаки препинания (точки, особенно в оглавлении книг). Весь достаточно мелкий мусор удаляется путем заливки площади описанного вокруг него прямоугольника цветом фона. Всегда контролируйте работу функции на соответствующей вкладке - удаленные точки подсвечиваются там красным. - + Default: Режим по умолчанию: - + <html><head/><body><p>Various image formats allow to specify additional data in files. </p><p>In some cases you may want to copy such information from the source image files to the resulting image files after image processing.</p><p>These settings let you control metadata propagation.</p><p><span style=" font-weight:600;">Copy ICC profile from source image </span>- if enabled the embedded Color Profile data will be copied from source to resulting image. Some color profiles are not compatible with all possible color spaces thus this setting turns off some color space optimizations (e.g. RGB image won't be converted to grayscale color space even if all pixels in it are the shades of gray). The resulting image will keep the color space of the original unless it's converted to b/w.</p></body></html> - <html><head/><body><p>Различные форматы изображений позволяют хранить дополнительные данные в файлах. </p><p>В некоторых случаях может иметь смысл копировать эту информацию из файла исходного изображения в файл результата обработки.</p><p>Эти настройки позволяют контролировать копирование таких метаданных.</p><p><span style=" font-weight:600;">Копировать цветовой профиль ICC из исходного изображения </span>- если включено, встроенные данные цветового профиля будут продублированы в изображении-результате. Некоторые цветовые профили не совместимы с частью цветовых пространств, поэтому данная опция отключает часть оптимизаций файла изображения (в частности RGB изображение не будет переводиться в формат grayscale, даже если все пиксели в нем являются оттенками серого). Изображение результат сохранит то же цветовое пространство, что и оригинал, за исключением режима, в котором оно конвертируется в ч/б формат.</p></body></html> + <html><head/><body><p>Различные форматы изображений позволяют хранить дополнительные данные в файлах. </p><p>В некоторых случаях может иметь смысл копировать эту информацию из файла исходного изображения в файл результата обработки.</p><p>Эти настройки позволяют контролировать копирование таких метаданных.</p><p><span style=" font-weight:600;">Копировать цветовой профиль ICC из исходного изображения </span>- если включено, встроенные данные цветового профиля будут продублированы в изображении-результате. Некоторые цветовые профили не совместимы с частью цветовых пространств, поэтому данная опция отключает часть оптимизаций файла изображения (в частности RGB изображение не будет переводиться в формат grayscale, даже если все пиксели в нем являются оттенками серого). Изображение результат сохранит то же цветовое пространство, что и оригинал, за исключением режима, в котором оно конвертируется в ч/б формат.</p></body></html> - + Expand all Развернуть все - + Collapse all Свернуть все @@ -3420,7 +3473,7 @@ As Foreground layer is using binarization to separate content from background it Not applicable. Page size is equal to content zone with margins. So content position is defined by margins. - Неприменимо. Размер страницы будет равен размеру области контента с полями. Поэтому, положение контента полностью определяется размером полей. + Неприменимо. Размер страницы будет равен размеру области контента с полями. Поэтому, положение контента полностью определяется размером полей. @@ -3436,7 +3489,7 @@ As Foreground layer is using binarization to separate content from background it General - Общее + Общее @@ -3451,7 +3504,7 @@ As Foreground layer is using binarization to separate content from background it Thumbnails panel - Лента предпросмотра страниц + Лента предпросмотра страниц @@ -3508,7 +3561,7 @@ As Foreground layer is using binarization to separate content from background it Page layout - Макетирование страницы + Макетирование страницы @@ -3523,43 +3576,43 @@ As Foreground layer is using binarization to separate content from background it Image metadata - Метаданные изображения + Метаданные изображения Cautious - Осторожное + Осторожное Aggressive - Агрессивный + Агрессивный Standard stylesheet - Стандартная + Стандартная None stylesheet - Нет + Нет Thumbnails view settings will be reseted to their defaults. Continue? - Настройки ленты предпросмотра страниц будут сброшены на значения по умолчанию. Продолжить? + Настройки ленты предпросмотра страниц будут сброшены на значения по умолчанию. Продолжить? Color selection - Выбор цвета + Выбор цвета - + Auto margins Авто-поля @@ -3586,22 +3639,22 @@ As Foreground layer is using binarization to separate content from background it Auto layer - Слой поиска иллюстраций + Слой поиска иллюстраций Picture zones layer - Слой зон иллюстраций + Слой зон иллюстраций Foreground layer - Слой всего контента + Слой всего контента Fill zones - Зоны заливки + Зоны заливки @@ -3611,7 +3664,7 @@ As Foreground layer is using binarization to separate content from background it Despeckling - Удаление мусора + Удаление мусора @@ -3681,7 +3734,7 @@ As Foreground layer is using binarization to separate content from background it Sometimes this could happen accidentally due to misclicks. Please note that there is a button on top of pages list panel that toggles simulation of the %2 key pressing.You can use it to safely select several pages across the project. Continue? - Вы собираетесь снять выделение с %1 страниц. + Вы собираетесь снять выделение с %1 страниц. Иногда это может происходить случайно в результате ошибочного нажатия. Пожалуйста, обратите внимание на кнопку симуляции удерживания клавиши выделения (%2) на верхней части панели ленты страниц. С её помощью вы можете быстро и удобно добавлять страницы к уже выделенным, не боясь потерять выделение в результате неверного нажатия. @@ -3690,7 +3743,7 @@ Continue? Don't show this again. - Больше не показывать. + Больше не показывать. @@ -3723,7 +3776,7 @@ Continue? Delete &from... - Удалить &из... + Удалить &из... @@ -3733,7 +3786,7 @@ Continue? Copy &to... - Копировать &в... + Копировать &в... @@ -3756,7 +3809,7 @@ Continue? Zones need to have at least 3 points. Hold %2 for rectangle, %3 for ellipse. %1 to cancel. - Зоны должны состоять мин. из 3 точек. Удерживайте %2 для прямоугольника, %3 для эллипса. %1 - отмена. + Зоны должны состоять мин. из 3 точек. Удерживайте %2 для прямоугольника, %3 для эллипса. %1 - отмена. @@ -3774,12 +3827,12 @@ Continue? Hold to move the ellipse. - Удерживайте для перемещения эллипса. + Удерживайте для перемещения эллипса. Hold to change ellipse size or angle. - Удерживайте для изменения размера или наклона эллипса. + Удерживайте для изменения размера или наклона эллипса. @@ -3794,7 +3847,7 @@ Continue? %1 + double click to repeat the last zone. - %1 + двойной щелчёк для повторной вставки последней зоны. + %1 + двойной щелчёк для повторной вставки последней зоны. @@ -3815,7 +3868,7 @@ Continue? Hold %1 to make a circle. - Удерживайте %1 для задания круга. + Удерживайте %1 для задания круга. @@ -3857,7 +3910,7 @@ Continue? Apply Deskew - Применение наклона + Применение наклона @@ -3867,12 +3920,12 @@ Continue? Export - Экспорт результатов + Экспорт результатов Close - &Отмена + &Отмена @@ -3881,74 +3934,74 @@ Continue? Error - Ошибка + Ошибка The export output directory is empty. - Не задана папка для сохранения результатов экспорта. + Не задана папка для сохранения результатов экспорта. Create Directory? - Создать папку? + Создать папку? The export output directory doesn't exist. Create it? - Папка для сохранения результатов не существует. Создать её? + Папка для сохранения результатов не существует. Создать её? Unable to create the export output directory. - Не удаётся создать папку для сохранения результатов экспорта. + Не удаётся создать папку для сохранения результатов экспорта. The export output directory is not set or doesn't exist. - Папка для сохранения результатов не задана или не существует. + Папка для сохранения результатов не задана или не существует. Stop - &Стоп + &Стоп Export output directory - Выбор папки для сохранения результатов + Выбор папки для сохранения результатов Processed pages %1 of %2 - Обработка страницы %1 из %2 + Обработка страницы %1 из %2 Information - Информация + Информация The files export is stopped by the user. - Экспорт изображений прерван пользователем. + Экспорт изображений прерван пользователем. The files export is finished. - Экспорт изображений завершен. + Экспорт изображений завершен. Nothing to export. Please select some data to export. - Нечего экспортировать. Пожалуйста, выберите данные для экспорта. + Нечего экспортировать. Пожалуйста, выберите данные для экспорта. Starting the export... - Экспорт начинается... + Экспорт начинается... @@ -3956,12 +4009,12 @@ Continue? The file - Файл + Файл is not found - не найден + не найден @@ -3977,7 +4030,7 @@ Continue? Fix Orientation - Исправление ориентации + Исправление ориентации @@ -3985,29 +4038,29 @@ Continue? Custom - Особый + Особый Error - Ошибка + Ошибка DPI is not set. - DPI не указан. + DPI не указан. DPI is too low! - DPI слишком низкий! + DPI слишком низкий! DPI is too high! - DPI слишком высокий! + DPI слишком высокий! @@ -4029,29 +4082,34 @@ Continue? output::Filter - + Natural order - Естественный порядок + Естественный порядок - + Order by mode - Сортировка по режиму + Сортировка по режиму - + + Order by dewarping mode + Сортировка по режиму исправления геометрии + + + Grayscale sources on top - Чёрно-белые исходники сверху + Чёрно-белые исходники сверху - + Groups the pages by presence of a non grey color in the source files - Группирует страницы по наличию + Группирует страницы по наличию цветных (не серых) пикселей в исходных файлах - + Output Вывод @@ -4059,103 +4117,138 @@ of a non grey color in the source files output::OptionsWidget - + Apply Despeckling Level - Применить уровень удаления мусора + Применить уровень удаления мусора - + Apply Depth Perception Применить восприятие глубины - + + Otsu + + + + + Sauvola + + + + + Wolf + + + + + Bradley + + + + + EdgePlus + + + + + BlurDiv + + + + + EdgeDiv + + + + %1 x %2 dpi %1 x %2 dpi - + %1 dpi %1 dpi - + Enforced if dewarping is on - Принудительно включается при использовании исправления геометрии + Принудительно включается при использовании исправления геометрии - + Disabled if dewarping is on - Принудительно отключается при использовании исправления геометрии + Принудительно отключается при использовании исправления геометрии - - + + Off Отключено - + Auto Автоматически - + Manual Вручную - + Marginal - Краевое + Краевое - + Cautious Осторожное - + Normal - Обычное + Обычное - + Aggressive - Агрессивный + Агрессивный - + Apply Dewarping Mode - Режим распрямления строк + Режим распрямления строк - + Apply Mode - Применить режим вывода + Применить режим вывода - + Apply Output Resolution - Применить разрешение вывода + Применить разрешение вывода - + Apply Foreground layer threshold - Применить значение порога фона + Применить значение порога фона - + Copy zone and its settings to: - Копировать зону и ее параметры в: + Копировать зону и ее параметры в: - + Find and remove this zone from: - Поиск и удаление зоны из: + Поиск и удаление зоны из: - + Apply Threshold Применить значение Ч/Б порога @@ -4170,7 +4263,7 @@ of a non grey color in the source files Despeckling can't be done in Color / Grayscale mode. - Удаление мусора не роизводится в режиме "Цветной / Оттенки серого". + Удаление мусора не роизводится в режиме "Цветной / Оттенки серого". @@ -4195,7 +4288,7 @@ of a non grey color in the source files Despeckling - Удаление мусора + Удаление мусора @@ -4208,7 +4301,7 @@ of a non grey color in the source files Order by alignment type - Сортировка по типу выравнивания + Сортировка по типу выравнивания @@ -4219,7 +4312,7 @@ of a non grey color in the source files Groups the pages by the width of detected content zone and it's left and right hard margins - Группирует страницы по возрастанию суммарной ширины + Группирует страницы по возрастанию суммарной ширины обнаруженной зоны контента, а также левого и правого поля отступа @@ -4231,13 +4324,13 @@ and it's left and right hard margins Groups the pages by the height of detected content zone and it's top and bottom hard margins - Группирует страницы по возрастанию суммарной высоты + Группирует страницы по возрастанию суммарной высоты обнаруженной зоны контента, а также верхнего и нижнего поля отступа Page Layout - Макетирование страницы + Макетирование страницы @@ -4286,7 +4379,7 @@ and it's top and bottom hard margins Order by page size - По размеру страницы + По размеру страницы @@ -4320,7 +4413,7 @@ and it's top and bottom hard margins Split Pages - Разрезание страниц + Разрезание страниц @@ -4346,7 +4439,7 @@ and it's top and bottom hard margins Orders the pages by the width of detected content zone - Сортирует страницы по возрастанию ширины обнаруженной зоны контента + Сортирует страницы по возрастанию ширины обнаруженной зоны контента @@ -4356,32 +4449,32 @@ and it's top and bottom hard margins Orders the pages by the height of detected content zone - Сортирует страницы по возрастанию высоты обнаруженной зоны контента + Сортирует страницы по возрастанию высоты обнаруженной зоны контента Order by increasing logical width - Сортирует страницы по возрастанию ширины логического размера (не зависит от dpi) + Сортирует страницы по возрастанию ширины логического размера (не зависит от dpi) Orders the pages by the logical width of detected content zone - Сортирует страницы по возрастанию ширины логического размера (не зависит от dpi) зоны контента + Сортирует страницы по возрастанию ширины логического размера (не зависит от dpi) зоны контента Order by increasing logical height - Сортирует страницы по возрастанию высоты логического размера (не зависит от dpi) + Сортирует страницы по возрастанию высоты логического размера (не зависит от dpi) Orders the pages by the logical height of detected content zone - Сортирует страницы по возрастанию высоты логического размера (не зависит от dpi) зоны контента + Сортирует страницы по возрастанию высоты логического размера (не зависит от dpi) зоны контента Select Content - Область контента + Область контента @@ -4389,22 +4482,32 @@ and it's top and bottom hard margins Drag lines or corners to resize the content box. Hold %1 to move it, %2 to move along axes, %3 to shrink/stretch. - Меняйте область контента за её углы и стороны. Удерживайте %1 для перемещения (%2 вдоль осей), %3 для растягивания. + Меняйте область контента за её углы и стороны. Удерживайте %1 для перемещения (%2 вдоль осей), %3 для растягивания. + + + + Hold left mouse button to drag the content box. + Удерживайте левую кнопку мыши, чтобы перетащить поле содержимого. - + + Release left mouse button to finish dragging. + Отпустите левую кнопку мыши, чтобы завершить перетаскивание. + + + Create Content Box - Создать область контента + Создать область контента - + Remove Content Box - Убрать область контента + Убрать область контента Use the context menu to enable / disable the content box. - Используйте контекстное меню для включения / отключения области контента. + Используйте контекстное меню для включения / отключения области контента. @@ -4412,17 +4515,17 @@ and it's top and bottom hard margins Select Content - Область контента + Область контента Options - Настройки + Настройки Apply content box - Копировать геометрию зоны контента + Копировать геометрию зоны контента @@ -4430,7 +4533,7 @@ and it's top and bottom hard margins DPI - DPI + DPI