Skip to content

Commit a8f876d

Browse files
committed
merge upstream master into feature/flatpak-manifest-ci-docs
2 parents 441126f + a1b7bb8 commit a8f876d

10 files changed

Lines changed: 165 additions & 52 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
name: Build (Ubuntu)
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@v5
1616

1717
- name: Install dependencies
1818
run: |

.github/workflows/clang-format.yml

Lines changed: 0 additions & 14 deletions
This file was deleted.

.github/workflows/cmake.yml

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,60 +18,76 @@ jobs:
1818
runs-on: ubuntu-latest
1919

2020
steps:
21-
- uses: actions/checkout@v4
22-
21+
- uses: actions/checkout@v5
22+
2323
- name: Install dependencies
24-
run: sudo apt install gcc g++ cmake libjpeg-dev libpng-dev libtiff5 libtiff5-dev libboost-test-dev qtbase5-dev libqt5svg5-dev qttools5-dev qttools5-dev-tools libqt5opengl5-dev libpthread-stubs0-dev rpm libfuse2
24+
run: |
25+
sudo apt-get update
26+
sudo apt-get install -y --fix-missing \
27+
gcc g++ cmake \
28+
libjpeg-dev libpng-dev \
29+
libtiff6 libtiff5-dev \
30+
libboost-test-dev \
31+
qtbase5-dev libqt5svg5-dev \
32+
qttools5-dev qttools5-dev-tools \
33+
libqt5opengl5-dev \
34+
libpthread-stubs0-dev \
35+
rpm libfuse2t64
2536
2637
- name: Configure CMake
2738
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
2839
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
29-
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
40+
run: cmake -B "${{ github.workspace }}/build" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
3041

3142
- name: Build
3243
# Build your program with the given configuration
33-
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
44+
run: cmake --build "${{ github.workspace }}/build" --config ${{env.BUILD_TYPE}}
3445

3546
- name: Create DEB package
36-
working-directory: ${{github.workspace}}/build
47+
working-directory: "${{ github.workspace }}/build"
3748
run: |
3849
cpack -G "DEB"
3950
mv scantailor*.deb scantailor.deb
4051
4152
- name: Create RPM package
42-
working-directory: ${{github.workspace}}/build
53+
working-directory: "${{ github.workspace }}/build"
4354
run: |
4455
cpack -G "RPM"
4556
mv scantailor*.rpm scantailor.rpm
4657
4758
- name: Create AppImage package
48-
working-directory: ${{github.workspace}}/build
59+
working-directory: "${{ github.workspace }}/build"
4960
run: |
5061
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
5162
chmod +x linuxdeploy-x86_64.AppImage
52-
./linuxdeploy-x86_64.AppImage --appdir AppDir --desktop-file ../src/resources/unix/scantailor.desktop --icon-file ../src/resources/ScanTailor.png --executable scantailor --output appimage
63+
./linuxdeploy-x86_64.AppImage \
64+
--appdir AppDir \
65+
--desktop-file "${{ github.workspace }}/build/scantailor.desktop" \
66+
--icon-file "${{ github.workspace }}/src/resources/ScanTailor.png" \
67+
--executable scantailor \
68+
--output appimage
5369
mv ScanTailor*.AppImage scantailor.AppImage
5470
5571
- name: Upload Linux bin
56-
uses: actions/upload-artifact@v4
72+
uses: actions/upload-artifact@v6
5773
with:
5874
name: scantailor-linux-ubuntu-latest-qt5
5975
path: build/scantailor
6076

6177
- name: Upload Linux DEB
62-
uses: actions/upload-artifact@v4
78+
uses: actions/upload-artifact@v6
6379
with:
6480
name: scantailor-linux-ubuntu-latest-qt5-deb
6581
path: build/scantailor.deb
6682

6783
- name: Upload Linux RPM
68-
uses: actions/upload-artifact@v4
84+
uses: actions/upload-artifact@v6
6985
with:
7086
name: scantailor-linux-ubuntu-latest-qt5-rpm
7187
path: build/scantailor.rpm
7288

7389
- name: Upload Linux AppImage
74-
uses: actions/upload-artifact@v4
90+
uses: actions/upload-artifact@v6
7591
with:
7692
name: scantailor-linux-appimage
7793
path: build/scantailor.AppImage

.github/workflows/lint.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
name: clang-format
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@v4
15+
- uses: actions/checkout@v5
1616
with:
1717
fetch-depth: 0
1818

@@ -34,8 +34,12 @@ jobs:
3434
| grep -E '\.(cpp|h)$' \
3535
| grep -v '/translations/' \
3636
|| true)
37-
COUNT=$(echo "$SRC_FILES" | grep -c . || echo 0)
38-
echo "count=$COUNT" >> $GITHUB_OUTPUT
37+
if [ -z "$SRC_FILES" ]; then
38+
COUNT=0
39+
else
40+
COUNT=$(echo "$SRC_FILES" | grep -c .)
41+
fi
42+
echo "count=${COUNT}" >> "$GITHUB_OUTPUT"
3943
if [ "$COUNT" = "0" ]; then
4044
echo "No changed source files to check."
4145
exit 0

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
name: Build .deb
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v5
1818

1919
- name: Set version from tag
2020
run: |
@@ -34,7 +34,7 @@ jobs:
3434
run: ./build-deb.sh build
3535

3636
- name: Upload .deb artifact
37-
uses: actions/upload-artifact@v4
37+
uses: actions/upload-artifact@v5
3838
with:
3939
name: deb-package
4040
path: scantailor-advanced_*_amd64.deb
@@ -43,7 +43,7 @@ jobs:
4343
name: Build AppImage
4444
runs-on: ubuntu-latest
4545
steps:
46-
- uses: actions/checkout@v4
46+
- uses: actions/checkout@v5
4747

4848
- name: Set version from tag
4949
run: |

.gitignore

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,22 @@ bin/
77
lib/
88
*.dir/
99

10-
# CMake
10+
# CMake (generated). Tracked helper modules live under cmake/.
1111
CMakeCache.txt
1212
CMakeFiles/
1313
cmake_install.cmake
1414
Makefile
1515
*.cmake
1616
!CMakeLists.txt
17+
!cmake/**/*.cmake
1718
*.cbp
1819
CTestTestfile.cmake
1920
_deps/
2021
install_manifest.txt
2122
compile_commands.json
23+
CMakeUserPresets.json
2224

23-
# C/C++ compilado
25+
# C/C++ build artifacts
2426
*.o
2527
*.obj
2628
*.a
@@ -60,7 +62,8 @@ ui_*.h
6062
*.includes
6163
*.config
6264

63-
# IDEs y editores
65+
# Editors / IDEs
66+
.cursor/
6467
.vscode/
6568
.idea/
6669
*.sublime-project
@@ -69,16 +72,25 @@ ui_*.h
6972
*.swp
7073
*.swo
7174
.*.sw?
75+
.clangd
76+
.cache/clangd/
77+
*.code-workspace
7278

73-
# Sistema operativo
79+
# Visual Studio (CMake "Open Folder")
80+
.vs/
81+
CMakeSettings.json
82+
CppProperties.json
83+
84+
# Operating system junk
7485
.DS_Store
7586
.DS_Store?
7687
._*
7788
Thumbs.db
7889
ehthumbs.db
7990
Desktop.ini
91+
.directory
8092

81-
# Depuradores y profiling
93+
# Debuggers / profiling
8294
*.core
8395
/core
8496
*.stackdump
@@ -91,36 +103,55 @@ Desktop.ini
91103
perf.data
92104
perf.data.old
93105

94-
# Documentación generada
106+
# Ctags / cscope
107+
tags
108+
TAGS
109+
GTAGS
110+
GRTAGS
111+
GPATH
112+
cscope.out
113+
114+
# Generated docs
95115
doc/html/
96116
doc/latex/
97117
docs/_build/
98118
*.dox
99119

100-
# Tests y cobertura
120+
# Tests / coverage output
101121
Testing/
102122
test_results/
103123
coverage/
104-
*.gcov
105124
lcov.info
106125

107-
# Empaquetado y distribución
126+
# Packaging / distribution artifacts
108127
*.tar
109128
*.tar.gz
110129
*.zip
111130
*.rar
112131
*.deb
113132
*.rpm
114133
*.msi
134+
*.AppImage
135+
*.flatpak
115136
packaging/build/
116137

117-
# Variables de entorno / local
138+
# flatpak-builder output (local smoke builds / CI)
139+
.flatpak-builder/
140+
flatpak/.flatpak-builder/
141+
repo/
142+
build-dir/
143+
144+
# Patch / merge leftovers
145+
*.orig
146+
*.rej
147+
148+
# Local env / CMake overrides
118149
.env
119150
.env.local
120151
*.local
121152
local.cmake
122153

123-
# Otros
154+
# Misc
124155
*.log
125156
*.tmp
126157
*.temp

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ Go to [this repository](https://github.com/ScanTailor-Advanced/scantailor-libs-b
7070

7171
**Windows – large JPEG/PNG (issue #20):** If large-format JPEG or PNG files fail to load on Windows, ensure the build uses **libjpeg-turbo** (or libjpeg 9+) and a recent libpng. The [scantailor-libs-build](https://github.com/ScanTailor-Advanced/scantailor-libs-build) repository provides compatible libraries.
7272

73+
**Windows – Visual C++ runtime (issue #101):** Pre-built binaries are linked with **Microsoft Visual C++** (MSVC) runtimes. If the application does not start and Windows reports missing **`VCRUNTIME*.dll`**, **`MSVCP*.dll`**, or similar, install the **latest supported x64 “Visual C++ Redistributable”** from Microsoft’s page: [Latest supported VC++ Redistributable downloads](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170). Match **x64** vs **x86** to the build you run.
74+
75+
**Windows – supported OS versions (issue #101):** Release builds follow upstream **Qt** and **toolchain** support policies; **legacy Windows** (for example Windows 7) is **not** exercised in this project’s CI and is **best-effort only**. You may need an **older tagged release** or a **self-built** binary against an older Qt/MSVC stack. Community reports (including compatibility tips) are welcome in the issue tracker.
76+
7377
**Linux – Wayland (issue #97):** If you see rendering issues (blank or corrupted windows) when running under Wayland, try starting the application with `QT_QPA_PLATFORM=xcb` to use the X11 compatibility layer.
7478

7579
**Linux – Flatpak / Flathub ([issue #105](https://github.com/ScanTailor-Advanced/scantailor-advanced/issues/105)):**

src/app/MainWindow.cpp

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ MainWindow::MainWindow()
106106
m_interactiveQueue(std::make_unique<ProcessingTaskQueue>()),
107107
m_outOfMemoryDialog(std::make_unique<OutOfMemoryDialog>()),
108108
m_curFilter(0),
109-
m_savedZoomLevel(1.0),
109+
m_savedMainAreaViewState(),
110110
m_ignoreSelectionChanges(0),
111111
m_ignorePageOrderingChanges(0),
112112
m_debug(false),
@@ -710,6 +710,54 @@ void MainWindow::setOptionsWidget(FilterOptionsWidget* widget, const Ownership o
710710
connect(widget, SIGNAL(fixDpiRequested()), this, SLOT(fixDpiDialogRequested()));
711711
} // MainWindow::setOptionsWidget
712712

713+
ImageViewBase* MainWindow::findPrimaryImageView(QWidget* root) {
714+
if (!root) {
715+
return nullptr;
716+
}
717+
if (auto* tabs = qobject_cast<output::TabbedImageView*>(root)) {
718+
QWidget* const page = tabs->currentWidget();
719+
if (page) {
720+
return Utils::castOrFindChild<ImageViewBase*>(page);
721+
}
722+
return nullptr;
723+
}
724+
return Utils::castOrFindChild<ImageViewBase*>(root);
725+
}
726+
727+
void MainWindow::applySavedMainAreaViewState(ImageViewBase* view, const SavedMainAreaViewState& state) {
728+
if (!view) {
729+
return;
730+
}
731+
view->setZoomLevel(state.zoom);
732+
if (!state.hasScrollNorm) {
733+
return;
734+
}
735+
QScrollBar* const h = view->horizontalScrollBar();
736+
QScrollBar* const v = view->verticalScrollBar();
737+
const int hr = h->maximum() - h->minimum();
738+
const int vr = v->maximum() - v->minimum();
739+
if (hr <= 0 || vr <= 0) {
740+
return;
741+
}
742+
const double nx = qBound(0.0, state.scrollNormX, 1.0);
743+
const double ny = qBound(0.0, state.scrollNormY, 1.0);
744+
h->setValue(h->minimum() + qRound(nx * hr));
745+
v->setValue(v->minimum() + qRound(ny * vr));
746+
}
747+
748+
void MainWindow::scheduleSavedMainAreaViewStateRestore(const QPointer<ImageViewBase>& view) {
749+
if (view.isNull()) {
750+
return;
751+
}
752+
const SavedMainAreaViewState state = m_savedMainAreaViewState;
753+
QTimer::singleShot(0, this, [view, state]() {
754+
if (view.isNull()) {
755+
return;
756+
}
757+
MainWindow::applySavedMainAreaViewState(view.data(), state);
758+
});
759+
}
760+
713761
void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, DebugImages* debugImages, bool overlay) {
714762
if (isBatchProcessingInProgress() && (widget != m_batchProcessingWidget.get())) {
715763
if (ownership == TRANSFER_OWNERSHIP) {
@@ -720,8 +768,19 @@ void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, Debu
720768

721769
if (!overlay && m_imageFrameLayout->count() > 0) {
722770
QWidget* oldW = m_imageFrameLayout->widget(0);
723-
if (ImageViewBase* oldView = Utils::castOrFindChild<ImageViewBase*>(oldW)) {
724-
m_savedZoomLevel = oldView->zoomLevel();
771+
if (ImageViewBase* oldView = findPrimaryImageView(oldW)) {
772+
m_savedMainAreaViewState.zoom = oldView->zoomLevel();
773+
QScrollBar* const h = oldView->horizontalScrollBar();
774+
QScrollBar* const v = oldView->verticalScrollBar();
775+
const int hr = h->maximum() - h->minimum();
776+
const int vr = v->maximum() - v->minimum();
777+
if (hr > 0 && vr > 0) {
778+
m_savedMainAreaViewState.hasScrollNorm = true;
779+
m_savedMainAreaViewState.scrollNormX = double(h->value() - h->minimum()) / hr;
780+
m_savedMainAreaViewState.scrollNormY = double(v->value() - v->minimum()) / vr;
781+
} else {
782+
m_savedMainAreaViewState.hasScrollNorm = false;
783+
}
725784
}
726785
}
727786

@@ -739,8 +798,8 @@ void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, Debu
739798
if (overlay) {
740799
m_imageFrameLayout->setCurrentWidget(widget);
741800
}
742-
if (ImageViewBase* newView = Utils::castOrFindChild<ImageViewBase*>(widget)) {
743-
newView->setZoomLevel(m_savedZoomLevel);
801+
if (ImageViewBase* newView = findPrimaryImageView(widget)) {
802+
scheduleSavedMainAreaViewStateRestore(QPointer<ImageViewBase>(newView));
744803
}
745804
}
746805
} else {

0 commit comments

Comments
 (0)