10 Commits

Author SHA1 Message Date
f0ed9d0ca1 chore: update release info to 1.1.1 2025-08-02 13:30:14 +08:00
13227cfac9 i18n: Translations update from Hosted Weblate (#157)
* Translated using Weblate (Korean)

Currently translated at 100.0% (166 of 166 strings)

Translation: pineapple-pictures/Application
Translate-URL: https://hosted.weblate.org/projects/pineapple-pictures/application/ko/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (166 of 166 strings)

Translation: pineapple-pictures/Application
Translate-URL: https://hosted.weblate.org/projects/pineapple-pictures/application/nl/

---------

Co-authored-by: VenusGirl <VenusGirl@outlook.com>
Co-authored-by: Heimen Stoffels <vistausss@fastmail.com>
2025-08-01 23:44:43 +08:00
b73df5ea1a refactor: make fitByOrientation() more sane 2025-07-27 15:53:23 +08:00
4375fe1c2d chore: avoid use screenAt(QCursor::pos()) 2025-07-26 16:03:13 +08:00
4654cb21a0 fix: REUSE compliance 2025-07-23 21:29:18 +08:00
ba23208a7a chore: add config file for CRLF to LF change 2025-07-23 21:22:41 +08:00
ed5a602332 chore: let's use LF all the time 2025-07-23 21:20:34 +08:00
347681e604 feat(macOS): click dock icon to show window when it's hidden 2025-07-22 00:08:06 +08:00
505ab9e2a6 chore: update README 2025-07-11 19:41:09 +08:00
c787e14a69 chore(CI): bump exiv2 version for msvc build 2025-07-11 00:31:10 +08:00
46 changed files with 3643 additions and 3519 deletions

3
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,3 @@
# .git-blame-ignore-revs
# CR LF to LF
ed5a6023326fd2ab420ded76976501be33e0b389

5
.gitattributes vendored Normal file
View File

@ -0,0 +1,5 @@
*.txt text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.ui text eol=lf
*.qml text eol=lf

View File

@ -72,9 +72,9 @@ jobs:
set CMAKE_PREFIX_PATH=%PWD%/dependencies_bin set CMAKE_PREFIX_PATH=%PWD%/dependencies_bin
mkdir dependencies_src mkdir dependencies_src
echo ::group::===== exiv2 ===== echo ::group::===== exiv2 =====
curl -fsSL -o exiv2_bin.zip https://github.com/Exiv2/exiv2/releases/download/v0.28.3/exiv2-0.28.3-2019msvc64.zip curl -fsSL -o exiv2_bin.zip https://github.com/Exiv2/exiv2/releases/download/v0.28.5/exiv2-0.28.5-2022msvc-AMD64.zip
7z x exiv2_bin.zip -y 7z x exiv2_bin.zip -y
ren .\exiv2-0.28.3-2019msvc64 dependencies_bin ren .\exiv2-0.28.5-2022msvc-AMD64 dependencies_bin
echo ::endgroup:: echo ::endgroup::
echo ::group::===== zlib ===== echo ::group::===== zlib =====
curl -fsSL -o zlib_src.zip https://zlib.net/zlib131.zip curl -fsSL -o zlib_src.zip https://zlib.net/zlib131.zip
@ -109,7 +109,7 @@ jobs:
echo ::endgroup:: echo ::endgroup::
echo ::group::===== KArchive ===== echo ::group::===== KArchive =====
git clone -q https://invent.kde.org/frameworks/karchive.git dependencies_src/karchive git clone -q https://invent.kde.org/frameworks/karchive.git dependencies_src/karchive
cmake .\dependencies_src\karchive -Bbuild_dependencies/karchive -DWITH_LIBZSTD=OFF -DWITH_BZIP2=OFF -DWITH_LIBLZMA=OFF -DCMAKE_INSTALL_PREFIX="dependencies_bin" || goto :error cmake .\dependencies_src\karchive -Bbuild_dependencies/karchive -DBUILD_TESTING=OFF -DWITH_LIBZSTD=OFF -DWITH_BZIP2=OFF -DWITH_LIBLZMA=OFF -DCMAKE_INSTALL_PREFIX="dependencies_bin" || goto :error
cmake --build build_dependencies/karchive --config Release --target=install || goto :error cmake --build build_dependencies/karchive --config Release --target=install || goto :error
echo ::endgroup:: echo ::endgroup::
echo ::group::===== KImageFormats ===== echo ::group::===== KImageFormats =====

View File

@ -4,7 +4,7 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(pineapple-pictures VERSION 1.1.0) # don't forget to update NEWS file and AppStream metadata. project(pineapple-pictures VERSION 1.1.1) # don't forget to update NEWS file and AppStream metadata.
include(GNUInstallDirs) include(GNUInstallDirs)
include(FeatureSummary) include(FeatureSummary)

17
NEWS
View File

@ -1,3 +1,20 @@
Version 1.1.1
~~~~~~~~~~~~~
Released: 2025-08-02
Features:
* Click dock icon should show window when it's hidden on macOS
Bugfixes:
* Ensure "Fit by Width" position the view to the beginning of the image
Miscellaneous:
* Update translations
* Update Exiv2 version for Windows binary build
Contributors:
Heimen Stoffels, VenusGirl, தமிழ்நேரம்
Version 1.1.0 Version 1.1.0
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
Released: 2025-07-06 Released: 2025-07-06

View File

@ -23,8 +23,7 @@ Pineapple Pictures is a lightweight image viewer that allows you view JPEG, PNG,
### Maintained by contributors / certain distro's package maintainers ### Maintained by contributors / certain distro's package maintainers
- Debian (since bullseye) or Ubuntu (since 21.04): `sudo apt install pineapple-pictures` [![Packaging status](https://repology.org/badge/vertical-allrepos/pineapple-pictures.svg?columns=4)](https://repology.org/project/pineapple-pictures/versions)
- Nix / NixOS: [pineapple-pictures](https://search.nixos.org/packages?channel=unstable&show=pineapple-pictures&from=0&size=50&sort=relevance&type=packages&query=pineapple-pictures) (maintained by @wineee)
## Help Translation! ## Help Translation!

View File

@ -24,8 +24,7 @@
### 由贡献者/对应发行版的打包人员维护 ### 由贡献者/对应发行版的打包人员维护
- Debian (自 bullseye 起) 或 Ubuntu (自 21.04 起): `sudo apt install pineapple-pictures` [![打包状态](https://repology.org/badge/vertical-allrepos/pineapple-pictures.svg?columns=4)](https://repology.org/project/pineapple-pictures/versions)
- Nix / NixOS: [pineapple-pictures](https://search.nixos.org/packages?channel=unstable&show=pineapple-pictures&from=0&size=50&sort=relevance&type=packages&query=pineapple-pictures) (由 [@wineee](https://github.com/wineee) 维护)
## 帮助翻译! ## 帮助翻译!

View File

@ -3,7 +3,7 @@ SPDX-PackageName = "Pineapple Pictures"
SPDX-PackageDownloadLocation = "https://github.com/BLumia/pineapple-pictures" SPDX-PackageDownloadLocation = "https://github.com/BLumia/pineapple-pictures"
[[annotations]] [[annotations]]
path = [".gitignore", "appveyor.yml", ".github/**"] path = [".gitattributes", ".git-blame-ignore-revs", ".gitignore", "appveyor.yml", ".github/**"]
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "None" SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0" SPDX-License-Identifier = "CC0-1.0"

View File

@ -171,21 +171,90 @@ void GraphicsView::fitByOrientation(Qt::Orientation ori, bool scaleDownOnly)
{ {
resetScale(); resetScale();
QRectF viewRect = this->viewport()->rect().adjusted(2, 2, -2, -2); QRectF viewRect = this->viewport()->rect();
QRectF imageRect = transform().mapRect(sceneRect()); QRectF imageRect = transform().mapRect(sceneRect());
QSize viewSize = viewRect.size().toSize();
qreal ratio; qreal ratio;
if (ori == Qt::Horizontal) { if (ori == Qt::Horizontal) {
// Horizontal fit means fit by width
if (scaleDownOnly && imageRect.width() <= viewSize.width()) {
// Image width already fits, no scaling needed
ratio = 1;
} else {
ratio = viewRect.width() / imageRect.width(); ratio = viewRect.width() / imageRect.width();
}
} else {
// Vertical fit means fit by height
if (scaleDownOnly && imageRect.height() <= viewSize.height()) {
// Image height already fits, no scaling needed
ratio = 1;
} else { } else {
ratio = viewRect.height() / imageRect.height(); ratio = viewRect.height() / imageRect.height();
} }
}
if (scaleDownOnly && ratio > 1) ratio = 1; if (ratio != 1) {
scale(ratio, ratio); scale(ratio, ratio);
centerOn(imageRect.top(), 0); }
// Position the image correctly based on orientation with rotation consideration
QRectF originalScene = sceneRect();
QTransform currentTransform = transform();
if (ori == Qt::Horizontal) {
// For horizontal fit (fit by width), position at top (for tall images)
// Find the scene point that corresponds to the top-center of the transformed image
QPointF sceneTopCenter;
if (qFuzzyIsNull(currentTransform.m12()) && qFuzzyIsNull(currentTransform.m21())) {
// 0° or 180° rotation
if (currentTransform.m11() > 0 && currentTransform.m22() > 0) {
// 0° rotation: use original top-center
sceneTopCenter = QPointF(originalScene.center().x(), originalScene.top());
} else {
// 180° rotation: the visual "top" is now at the scene bottom
sceneTopCenter = QPointF(originalScene.center().x(), originalScene.bottom());
}
} else {
// 90/270 degree rotation: the "top" in view corresponds to left/right in scene
if (currentTransform.m12() > 0) {
// 90 degree: top in view = left in scene
sceneTopCenter = QPointF(originalScene.left(), originalScene.center().y());
} else {
// 270 degree: top in view = right in scene
sceneTopCenter = QPointF(originalScene.right(), originalScene.center().y());
}
}
centerOn(sceneTopCenter);
} else {
// For vertical fit (fit by height), position at left (for wide images)
// Find the scene point that corresponds to the left-center of the transformed image
QPointF sceneLeftCenter;
if (qFuzzyIsNull(currentTransform.m12()) && qFuzzyIsNull(currentTransform.m21())) {
// 0° or 180° rotation
if (currentTransform.m11() > 0 && currentTransform.m22() > 0) {
// 0° rotation: use original left-center
sceneLeftCenter = QPointF(originalScene.left(), originalScene.center().y());
} else {
// 180° rotation: the visual "left" is now at the scene right
sceneLeftCenter = QPointF(originalScene.right(), originalScene.center().y());
}
} else {
// 90/270 degree rotation: the "left" in view corresponds to top/bottom in scene
if (currentTransform.m21() > 0) {
// 90 degree: left in view = top in scene
sceneLeftCenter = QPointF(originalScene.center().x(), originalScene.top());
} else {
// 270 degree: left in view = bottom in scene
sceneLeftCenter = QPointF(originalScene.center().x(), originalScene.bottom());
}
}
centerOn(sceneLeftCenter);
}
m_enableFitInView = false; m_enableFitInView = false;
applyTransformationModeByScaleFactor(); applyTransformationModeByScaleFactor();

View File

@ -76,6 +76,18 @@ int main(int argc, char *argv[])
w.showUrls({url}); w.showUrls({url});
w.initWindowSize(); w.initWindowSize();
}); });
// Handle dock icon clicks to show hidden window
a.connect(&a, &QApplication::applicationStateChanged, [&w](Qt::ApplicationState state) {
if (state == Qt::ApplicationActive && w.isHidden()) {
w.showUrls({});
w.galleryCurrent(true, true);
w.setWindowOpacity(1);
w.showNormal();
w.raise();
w.activateWindow();
}
});
#endif // Q_OS_MACOS #endif // Q_OS_MACOS
QStringList urlStrList = parser.positionalArguments(); QStringList urlStrList = parser.positionalArguments();

View File

@ -188,6 +188,7 @@ void MainWindow::showUrls(const QList<QUrl> &urls)
m_pm->loadPlaylist(urls); m_pm->loadPlaylist(urls);
} else { } else {
m_graphicsView->showText(tr("File url list is empty")); m_graphicsView->showText(tr("File url list is empty"));
m_pm->setPlaylist(urls);
return; return;
} }
@ -221,7 +222,7 @@ void MainWindow::adjustWindowSizeBySceneRect()
if (m_graphicsView->scaleFactor() < 1 || size().expandedTo(sceneSizeWithMargins) != size()) { if (m_graphicsView->scaleFactor() < 1 || size().expandedTo(sceneSizeWithMargins) != size()) {
// if it scaled down by the resize policy: // if it scaled down by the resize policy:
QSize screenSize = qApp->screenAt(QCursor::pos())->availableSize(); QSize screenSize = window()->screen()->availableSize();
if (screenSize.expandedTo(sceneSize) == screenSize) { if (screenSize.expandedTo(sceneSize) == screenSize) {
// we can show the picture by increase the window size. // we can show the picture by increase the window size.
QSize finalSize = (screenSize.expandedTo(sceneSizeWithMargins) == screenSize) ? QSize finalSize = (screenSize.expandedTo(sceneSizeWithMargins) == screenSize) ?
@ -583,7 +584,7 @@ void MainWindow::centerWindow()
Qt::LeftToRight, Qt::LeftToRight,
Qt::AlignCenter, Qt::AlignCenter,
this->size(), this->size(),
qApp->screenAt(QCursor::pos())->availableGeometry() window()->screen()->availableGeometry()
) )
); );
} }

View File

@ -242,7 +242,7 @@
<message> <message>
<location filename="../mainwindow.cpp" line="781"/> <location filename="../mainwindow.cpp" line="781"/>
<source>Failed to move file to trash</source> <source>Failed to move file to trash</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../mainwindow.cpp" line="782"/> <location filename="../mainwindow.cpp" line="782"/>
@ -296,12 +296,12 @@
<message> <message>
<location filename="../actionmanager.cpp" line="108"/> <location filename="../actionmanager.cpp" line="108"/>
<source>Pause/Resume Animation</source> <source>Pause/Resume Animation</source>
<translation type="unfinished"></translation> <translation> /</translation>
</message> </message>
<message> <message>
<location filename="../actionmanager.cpp" line="109"/> <location filename="../actionmanager.cpp" line="109"/>
<source>Animation Go to Next Frame</source> <source>Animation Go to Next Frame</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../actionmanager.cpp" line="111"/> <location filename="../actionmanager.cpp" line="111"/>
@ -729,27 +729,27 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="39"/> <location filename="../settingsdialog.cpp" line="39"/>
<source>Options</source> <source>Options</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="51"/> <location filename="../settingsdialog.cpp" line="51"/>
<source>Shortcuts</source> <source>Shortcuts</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="61"/> <location filename="../settingsdialog.cpp" line="61"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source> <source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation> <translation> &quot;%1&quot; :</translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="70"/> <location filename="../settingsdialog.cpp" line="70"/>
<source>Failed to set shortcuts</source> <source>Failed to set shortcuts</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="71"/> <location filename="../settingsdialog.cpp" line="71"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source> <source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation> <translation> .</translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="78"/> <location filename="../settingsdialog.cpp" line="78"/>
@ -769,7 +769,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="81"/> <location filename="../settingsdialog.cpp" line="81"/>
<source>Toggle fullscreen</source> <source>Toggle fullscreen</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="85"/> <location filename="../settingsdialog.cpp" line="85"/>
@ -794,7 +794,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="92"/> <location filename="../settingsdialog.cpp" line="92"/>
<source>Windowed</source> <source>Windowed</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="96"/> <location filename="../settingsdialog.cpp" line="96"/>
@ -828,7 +828,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="123"/> <location filename="../settingsdialog.cpp" line="123"/>
<source>Use built-in close window animation</source> <source>Use built-in close window animation</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="124"/> <location filename="../settingsdialog.cpp" line="124"/>
@ -838,7 +838,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="125"/> <location filename="../settingsdialog.cpp" line="125"/>
<source>Loop the loaded gallery</source> <source>Loop the loaded gallery</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="126"/> <location filename="../settingsdialog.cpp" line="126"/>
@ -866,7 +866,7 @@
<message> <message>
<location filename="../shortcutedit.cpp" line="109"/> <location filename="../shortcutedit.cpp" line="109"/>
<source>No shortcuts</source> <source>No shortcuts</source>
<translation type="unfinished"></translation> <translation> </translation>
</message> </message>
</context> </context>
<context> <context>
@ -874,7 +874,7 @@
<message> <message>
<location filename="../shortcutedit.cpp" line="75"/> <location filename="../shortcutedit.cpp" line="75"/>
<source>Shortcut #%1</source> <source>Shortcut #%1</source>
<translation type="unfinished"></translation> <translation> #%1</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -832,7 +832,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="123"/> <location filename="../settingsdialog.cpp" line="123"/>
<source>Use built-in close window animation</source> <source>Use built-in close window animation</source>
<translation type="unfinished"></translation> <translation>Meegeleverde animatie voor venster sluiten gebruiken</translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="124"/> <location filename="../settingsdialog.cpp" line="124"/>
@ -842,7 +842,7 @@
<message> <message>
<location filename="../settingsdialog.cpp" line="125"/> <location filename="../settingsdialog.cpp" line="125"/>
<source>Loop the loaded gallery</source> <source>Loop the loaded gallery</source>
<translation type="unfinished"></translation> <translation>Gekozen galerij herhalen</translation>
</message> </message>
<message> <message>
<location filename="../settingsdialog.cpp" line="126"/> <location filename="../settingsdialog.cpp" line="126"/>

View File

@ -90,7 +90,7 @@ build_script:
- cd karchive - cd karchive
- mkdir build - mkdir build
- cd build - cd build
- cmake .. -G "Ninja" -DWITH_LIBZSTD=OFF -DWITH_BZIP2=OFF -DWITH_LIBLZMA=OFF -DWITH_OPENSSL=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%CMAKE_INSTALL_PREFIX% - cmake .. -G "Ninja" -DBUILD_TESTING=OFF -DWITH_LIBZSTD=OFF -DWITH_BZIP2=OFF -DWITH_LIBLZMA=OFF -DWITH_OPENSSL=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%CMAKE_INSTALL_PREFIX%
- cmake --build . --config Release - cmake --build . --config Release
- cmake --build . --config Release --target install/strip - cmake --build . --config Release --target install/strip
- cd %APPVEYOR_BUILD_FOLDER% - cd %APPVEYOR_BUILD_FOLDER%

View File

@ -80,6 +80,25 @@
</screenshot> </screenshot>
</screenshots> </screenshots>
<releases> <releases>
<release type="stable" version="1.1.1" date="2025-08-02T00:00:00Z">
<description>
<p>This release adds the following feature:</p>
<ul>
<li>Click dock icon should show window when it's hidden on macOS</li>
</ul>
<p>This release fixes the following bug:</p>
<ul>
<li>Ensure "Fit by Width" position the view to the beginning of the image</li>
</ul>
<p>This release includes the following changes:</p>
<ul>
<li>Update translations</li>
<li>Update Exiv2 version for Windows binary build</li>
</ul>
<p>With contributions from:</p>
<p>Heimen Stoffels, VenusGirl, தமிழ்நேரம்</p>
</description>
</release>
<release type="stable" version="1.1.0" date="2025-07-06T00:00:00Z"> <release type="stable" version="1.1.0" date="2025-07-06T00:00:00Z">
<description> <description>
<p>This release adds the following features:</p> <p>This release adds the following features:</p>