Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qimgv for openSUSE:Factory checked in at 2021-09-27 20:08:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qimgv (Old) and /work/SRC/openSUSE:Factory/.qimgv.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qimgv" Mon Sep 27 20:08:45 2021 rev:20 rq:921532 version:1.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/qimgv/qimgv.changes 2021-09-22 22:13:46.816364075 +0200 +++ /work/SRC/openSUSE:Factory/.qimgv.new.1899/qimgv.changes 2021-09-27 20:08:53.402460910 +0200 @@ -1,0 +2,17 @@ +Sun Sep 26 19:40:25 UTC 2021 - Luigi Baldoni <aloi...@gmx.com> + +- Update to version 1.0.1 + Bug fixes: + * fix mouse wheel not working with libinput 1.19 + * fix thumbnails not rendering properly when fractional + scaling is enabled + * fix "Save As" working incorrectly when changing file + extension (KDE) + * add confirmation when editing from folderview + * fix crop selection not working when another aspect ratio is + selected first + * fix possible crash when opening the context menu + * fix WheelUp / WheelDown being swapped around (no user action + needed) + +------------------------------------------------------------------- Old: ---- qimgv-1.0.0.tar.gz New: ---- qimgv-1.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qimgv.spec ++++++ --- /var/tmp/diff_new_pack.Z73Zlk/_old 2021-09-27 20:08:55.334463038 +0200 +++ /var/tmp/diff_new_pack.Z73Zlk/_new 2021-09-27 20:08:55.338463042 +0200 @@ -17,7 +17,7 @@ Name: qimgv -Version: 1.0.0 +Version: 1.0.1 Release: 0 Summary: Qt5 image viewer License: GPL-3.0-only ++++++ qimgv-1.0.0.tar.gz -> qimgv-1.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/CMakeLists.txt new/qimgv-1.0.1/CMakeLists.txt --- old/qimgv-1.0.0/CMakeLists.txt 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/CMakeLists.txt 2021-09-26 18:19:06.000000000 +0200 @@ -1,7 +1,7 @@ # qimgv root cmake_minimum_required(VERSION 3.13) project(qimgv - VERSION 1.0.0 + VERSION 1.0.1 HOMEPAGE_URL "https://github.com/easymodo/qimgv" LANGUAGES CXX) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/README.md new/qimgv-1.0.1/README.md --- old/qimgv-1.0.0/README.md 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/README.md 2021-09-26 18:19:06.000000000 +0200 @@ -1,6 +1,6 @@ qimgv | Current version: 1.0.0 ===== -Qt5 image viewer. Fast, configurable, easy to use. Optional video support. +Image viewer. Fast, easy to use. Optional video support. ## Screenshots @@ -63,6 +63,7 @@ | Delete file | Shift+Delete | | Save | Ctrl+S | | Save As | Ctrl+Shift+S | +| Folder view | Enter / Backspace | | Open | Ctrl+O | | Print / Export PDF | Ctrl+P | | Settings | P | @@ -72,15 +73,13 @@ Note: you can configure every shortcut by going to __Settings > Controls__ -## User interface +# User interface The idea is to have a uncluttered, simple and easy to use UI. You can see UI elements only when you need them. -There is a pull-down panel with thumbnails, as well as folder view (accessible by pressing Return). +There is a pull-down panel with thumbnails, as well as folder view. You can also bring up a context menu via right click. -You can also bring up a context menu by right-clicking an image. - -### Using quick copy / quick move panels +## Using quick copy / quick move panels Bring up the panel with C or M shortcut. You will see 9 destination directories, click them to set them up. @@ -88,7 +87,7 @@ When you are done press C or M again to hide the panel. -### Running scripts +## Running scripts You can run custom scripts on a current image. @@ -107,54 +106,43 @@ When you've created your script go to __Settings > Controls > Add__, then select it and assign a shortcut like for any regular action. -### HiDPI +## HiDPI (Linux / MacOS only) If qimgv appears too small / too big on your display, you can override the scale factor. Example: ``` QT_SCALE_FACTOR="1.5" qimgv /path/to/image.png ``` -You can put it in `qimgv.desktop` file to make it permanent. Using values less than `1.0` may break some things. +You can put it in `qimgv.desktop` file to make it permanent. Using values less than `1.0` is not supported. qimgv should also obey the global scale factor set in KDE's systemsettings. -### High quality scaling - -qimgv supports nicer scaling filters when compiled with `opencv` support (ON by default, might vary depending on your distribution). Filter options are available in __Settings > Scaling__. `Bicubic` or `bilinear+sharpen` is recommended. - -### APNG support - -APNG is supported via third-party qt plugin. (Included in windows qimgv package) - -If you are linux user, install the latest [QtApng by Skycoder42](https://github.com/Skycoder42/QtApng). - -### HEIF / HEIC support - -Apple's `heif` format is supported via third-party qt plugin. Included in windows qimgv package. - -See [github.com/jakar/qt-heif-image-plugin](https://github.com/jakar/qt-heif-image-plugin) - -### JPEG-XL (JXL) support: +## High quality scaling -qimgv can open `jxl` files via third-party qt plugin. +qimgv supports nicer scaling filters when compiled with `opencv` support (ON by default, but might vary depending on your linux distribution). Filter options are available in __Settings > Scaling__. `Bicubic` or `bilinear+sharpen` is recommended. -See [github.com/novomesk/qt-jpegxl-image-plugin](https://github.com/novomesk/qt-jpegxl-image-plugin) +# Additional image formats -### AVIF support +qimgv can open some extra formats via third-party image plugins. All of them are included with windows package. -qimgv can open `avif` files via third-party qt plugin. +| Format | Plugin | +| ------- | ------------- | +| JPEG-XL | [github.com/novomesk/qt-jpegxl-image-plugin](https://github.com/novomesk/qt-jpegxl-image-plugin) | +| AVIF | [github.com/novomesk/qt-avif-image-plugin](https://github.com/novomesk/qt-avif-image-plugin) | +| APNG | [github.com/Skycoder42/QtApng](https://github.com/Skycoder42/QtApng) | +| HEIF / HEIC | [github.com/jakar/qt-heif-image-plugin](https://github.com/jakar/qt-heif-image-plugin) | +| RAW | [https://gitlab.com/mardy/qtraw](https://gitlab.com/mardy/qtraw) | -See [github.com/novomesk/qt-avif-image-plugin](https://github.com/novomesk/qt-avif-image-plugin) +# Installation -### RAW support +## Windows builds -Viewing raw is supported via [qtraw plugin](https://gitlab.com/mardy/qtraw). (Included in windows qimgv package) - - -## Installation instructions + [Grab the latest release here](https://github.com/easymodo/qimgv/releases) + + Windows builds are portable (everything is contained within install folder). Installer additionally sets up file associations. -### GNU+Linux +## GNU+Linux -__Arch Linux / Manjaro / etc.:__ +### Arch Linux / Manjaro / etc. AUR package: @@ -162,7 +150,7 @@ qimgv-git ``` -__Ubuntu / Linux Mint / Pop!\_OS / etc.__ +### Ubuntu / Linux Mint / Pop!\_OS / etc. ``` sudo add-apt-repository ppa:easymodo/qimgv @@ -176,127 +164,43 @@ sudo apt install qimgv-kde ``` -__Gentoo:__ - -``` -emerge qimgv -``` - -__OpenSUSE__: - -``` -zypper install qimgv -``` - -__Void linux__: - -``` -xbps-install -S qimgv -``` - -__Alpine Linux__: - -``` -apk add qimgv -``` - -__Fedora__: +### Fedora ``` sudo dnf install qimgv ``` -If your favorite distro is not included refer to [Manual install] section at the end of this document. - -### Windows builds - - [Grab the latest release here.](https://github.com/easymodo/qimgv/releases) - - Windows builds are portable (everything is contained within install folder). - - Installer additionally sets up file associations. - - -### Manual install - -Note: in order to compile you will need gcc 8 or later! - -__Install dependencies ( `gcc` >= 9.0, `git`, `cmake` >= 3.13, `qt` >= 5.9, `exiv2`, `mpv`, `opencv (core and imgproc)`__ - -_Ubuntu & derivatives:_ - -``` -sudo apt install build-essential git cmake qt5-default libmpv-dev gcc-8 g++-8 -``` -Optional: `libkf5windowsystem-dev` - -_Fedora:_ - -Enable RPMFusion [https://rpmfusion.org/Configuration](https://rpmfusion.org/Configuration). - -It is needed for video playback (mpv), but you also can build without it. See __CMake build options__ at the end. - -``` -sudo dnf install git cmake make qt5 qt5-devel gcc-c++ mpv mpv-libs-devel exiv2-devel opencv opencv-devel -``` -Optional: `kf5-kwindowsystem` - -__Configure & install__ - -Get sources +### OpenSUSE ``` -git clone https://github.com/easymodo/qimgv.git -cd qimgv && mkdir -p build && cd build +zypper install qimgv ``` -Configure +### Gentoo ``` -cmake ../ -DCMAKE_INSTALL_PREFIX=/usr/ -DCMAKE_INSTALL_LIBDIR=lib +emerge qimgv ``` -Build +### Void linux ``` -make -j`nproc --ignore=1` +xbps-install -S qimgv ``` -Install +### Alpine Linux ``` -sudo make install +apk add qimgv ``` -### Possible build issues - -- If you get errors like "/usr/lib64 exists in filesystem" during install: - -add `-DCMAKE_INSTALL_LIBDIR:PATH=/usr/lib` to cmake command. +This list may be incomplete. -- If you get some errors like "std::filesystem not found": +## Compiling from source -qimgv needs a compiler with c++17 support - for example gcc 8.0+ (every recent distro has it) - -If you have multiple version of gcc installed you _might_ need to specify a which version for `cmake` to use, for example - -`CC=gcc-8 CXX=g++-8 cmake [........]` - -### CMake build options - -| Option | Default value | Description | -| ------- | ------------- | ----------- | -| VIDEO_SUPPORT | ON | Enables video playback via `mpv` | -| EXIV2 | ON | Support reading exif tags via `exiv2` | -| OPENCV_SUPPORT | ON | Enables high quality scaling options | -| KDE_SUPPORT | OFF | Use some features from KDE, like background blur | - -Usage example: -``` -cmake ../ -DKDE_SUPPORT=ON -DCMAKE_INSTALL_PREFIX=/usr/ -``` +See [Compiling qimgv from source](https://github.com/easymodo/qimgv/wiki/Compiling-qimgv-from-source) on the wiki -### Donate +# Donate If you wish to throw me a few bucks, you can do it here: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/CMakeLists.txt new/qimgv-1.0.1/qimgv/CMakeLists.txt --- old/qimgv-1.0.0/qimgv/CMakeLists.txt 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/CMakeLists.txt 2021-09-26 18:19:06.000000000 +0200 @@ -80,8 +80,8 @@ set_target_properties(qimgv PROPERTIES MACOSX_BUNDLE YES MACOSX_BUNDLE_BUNDLE_NAME "qimgv" - MACOSX_BUNDLE_BUNDLE_VERSION "1.0.0" - MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0.0" + MACOSX_BUNDLE_BUNDLE_VERSION "1.0.1" + MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0.1" MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/distrib/MyBundleInfo.plist.in MACOSX_BUNDLE_ICON_FILE ${APPLE_ICON_NAME} ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/appversion.cpp new/qimgv-1.0.1/qimgv/appversion.cpp --- old/qimgv-1.0.0/qimgv/appversion.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/appversion.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -1,3 +1,3 @@ #include "appversion.h" -QVersionNumber appVersion(1,0,0); +QVersionNumber appVersion(1,0,1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/components/actionmanager/actionmanager.cpp new/qimgv-1.0.1/qimgv/components/actionmanager/actionmanager.cpp --- old/qimgv-1.0.0/qimgv/components/actionmanager/actionmanager.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/components/actionmanager/actionmanager.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -23,8 +23,8 @@ actionManager->defaults.insert("Left", "prevImage"); actionManager->defaults.insert("XButton2", "nextImage"); actionManager->defaults.insert("XButton1", "prevImage"); - actionManager->defaults.insert("WheelUp", "nextImage"); - actionManager->defaults.insert("WheelDown", "prevImage"); + actionManager->defaults.insert("WheelDown", "nextImage"); + actionManager->defaults.insert("WheelUp", "prevImage"); actionManager->defaults.insert("F", "toggleFullscreen"); actionManager->defaults.insert("F11", "toggleFullscreen"); actionManager->defaults.insert("LMB_DoubleClick", "toggleFullscreen"); @@ -38,8 +38,8 @@ actionManager->defaults.insert("V", "flipV"); actionManager->defaults.insert(InputMap::keyNameCtrl() + "+R", "rotateRight"); actionManager->defaults.insert(InputMap::keyNameCtrl() + "+L", "rotateLeft"); - actionManager->defaults.insert(InputMap::keyNameCtrl() + "+WheelDown", "zoomInCursor"); - actionManager->defaults.insert(InputMap::keyNameCtrl() + "+WheelUp", "zoomOutCursor"); + actionManager->defaults.insert(InputMap::keyNameCtrl() + "+WheelUp", "zoomInCursor"); + actionManager->defaults.insert(InputMap::keyNameCtrl() + "+WheelDown", "zoomOutCursor"); actionManager->defaults.insert("+", "zoomIn"); actionManager->defaults.insert("-", "zoomOut"); actionManager->defaults.insert(InputMap::keyNameCtrl() + "+Down", "zoomOut"); @@ -160,12 +160,29 @@ } } //------------------------------------------------------------------------------ -// argument: target version -// every action added from next version onwards will be reset -// TODO: maybe move this to core or something? -// TODO: save this to settings immediately -// settings <=> actionManager <=> settingsDialog -void ActionManager::resetDefaultsFromVersion(QVersionNumber lastVer) { +void ActionManager::adjustFromVersion(QVersionNumber lastVer) { + // swap Ctrl-P & P + if(lastVer < QVersionNumber(0,9,2)) { + actionManager->resetDefaults("print"); + actionManager->resetDefaults("openSettings"); + } + // swap WheelUp/WheelDown. derp + if(lastVer < QVersionNumber(1,0,1)) { + qDebug() << "[actionManager]: swapping WheelUp/WheelDown"; + QMapIterator<QString, QString> i(shortcuts); + QMap<QString, QString> swapped; + while(i.hasNext()) { + i.next(); + QString key = i.key(); + if(key.contains("WheelUp")) + key.replace("WheelUp", "WheelDown"); + else if(key.contains("WheelDown")) + key.replace("WheelDown", "WheelUp"); + swapped.insert(key, i.value()); + } + shortcuts = swapped; + } + // add new default actions QMapIterator<QString, QString> i(defaults); while(i.hasNext()) { i.next(); @@ -178,6 +195,8 @@ } } } + // apply + saveShortcuts(); } //------------------------------------------------------------------------------ void ActionManager::saveShortcuts() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/components/actionmanager/actionmanager.h new/qimgv-1.0.1/qimgv/components/actionmanager/actionmanager.h --- old/qimgv-1.0.0/qimgv/components/actionmanager/actionmanager.h 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/components/actionmanager/actionmanager.h 2021-09-26 18:19:06.000000000 +0200 @@ -36,7 +36,7 @@ void removeAllShortcuts(); void removeAllShortcuts(QString actionName); QString keyForNativeScancode(quint32 scanCode); - void resetDefaultsFromVersion(QVersionNumber lastVer); + void adjustFromVersion(QVersionNumber lastVer); void saveShortcuts(); public slots: bool invokeAction(const QString &actionName); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/core.cpp new/qimgv-1.0.1/qimgv/core.cpp --- old/qimgv-1.0.0/qimgv/core.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/core.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -201,6 +201,7 @@ void Core::onUpdate() { QVersionNumber lastVer = settings->lastVersion(); + if(lastVer < QVersionNumber(0,9,2)) { actionManager->resetDefaults("print"); actionManager->resetDefaults("openSettings"); @@ -211,8 +212,8 @@ settings->setScalingFilter(QI_FILTER_CV_CUBIC); #endif - actionManager->resetDefaultsFromVersion(lastVer); - actionManager->saveShortcuts(); + actionManager->adjustFromVersion(lastVer); + qDebug() << "Updated: " << settings->lastVersion().toString() << ">" << appVersion.toString(); // TODO: finish changelogs //if(settings->showChangelogs()) @@ -623,7 +624,7 @@ args << "-e"; args << "activate"; args << "-e"; - args << "select POSIX file \""+selectedFilePath()+"\""; + args << "select POSIX file \""+selectedPath()+"\""; args << "-e"; args << "end tell"; QProcess::startDetached("osascript", args); @@ -854,9 +855,11 @@ } template<typename... Args> -void Core::edit_template(bool save, const std::function<QImage*(std::shared_ptr<const QImage>, Args...)>& editFunc, Args&&... as) { +void Core::edit_template(bool save, QString action, const std::function<QImage*(std::shared_ptr<const QImage>, Args...)>& editFunc, Args&&... as) { if(model->isEmpty()) return; + if(save && !mw->showConfirmation(action, "Perform action \""+ action +"\"? \n\nChanges will be saved immediately.")) + return; for(auto path : currentSelection()) { auto img = getEditableImage(path); if(!img) @@ -873,31 +876,33 @@ } void Core::flipH() { - edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), { ImageLib::flippedH }); + edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), "Flip horizontal", { ImageLib::flippedH }); } void Core::flipV() { - edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), { ImageLib::flippedV }); + edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), "Flip vertical", { ImageLib::flippedV }); } void Core::rotateByDegrees(int degrees) { - edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), { ImageLib::rotated }, degrees); + edit_template((mw->currentViewMode() == MODE_FOLDERVIEW), "Rotate", { ImageLib::rotated }, degrees); } void Core::resize(QSize size) { - edit_template(false, { ImageLib::scaled }, size, QI_FILTER_BILINEAR); + edit_template(false, "Resize", { ImageLib::scaled }, size, QI_FILTER_BILINEAR); } void Core::crop(QRect rect) { if(mw->currentViewMode() == MODE_FOLDERVIEW) return; - edit_template(false, { ImageLib::cropped }, rect); + edit_template(false, "Crop", { ImageLib::cropped }, rect); } void Core::cropAndSave(QRect rect) { if(mw->currentViewMode() == MODE_FOLDERVIEW) return; - edit_template(true, { ImageLib::cropped }, rect); + edit_template(false, "Crop", { ImageLib::cropped }, rect); + saveFile(selectedPath()); + updateInfoString(); } // ---------------------------------------------------------------- image operations ^ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/core.h new/qimgv-1.0.1/qimgv/core.h --- old/qimgv-1.0.0/qimgv/core.h 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/core.h 2021-09-26 18:19:06.000000000 +0200 @@ -86,7 +86,7 @@ QList<QString> currentSelection(); template<typename... Args> - void edit_template(bool save, const std::function<QImage*(std::shared_ptr<const QImage>, Args...)>& func, Args&&... as); + void edit_template(bool save, QString actionName, const std::function<QImage*(std::shared_ptr<const QImage>, Args...)>& func, Args&&... as); void doInteractiveCopy(QString path, QString destDirectory, DialogResult &overwriteAllFiles); void doInteractiveMove(QString path, QString destDirectory, DialogResult &overwriteAllFiles); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/contextmenu.cpp new/qimgv-1.0.1/qimgv/gui/contextmenu.cpp --- old/qimgv-1.0.0/qimgv/gui/contextmenu.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/contextmenu.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -114,11 +114,15 @@ void ContextMenu::setGeometry(QRect geom) { auto screen = QGuiApplication::screenAt(cursor().pos()); - // fit inside the current screen - if(geom.bottom() > screen->geometry().bottom()) - geom.moveBottom(cursor().pos().y()); - if(geom.right() > screen->geometry().right()) - geom.moveRight(screen->geometry().right()); + if(!screen) // fallback + screen = QGuiApplication::primaryScreen(); + if(screen) { + // fit inside the current screen + if(geom.bottom() > screen->geometry().bottom()) + geom.moveBottom(cursor().pos().y()); + if(geom.right() > screen->geometry().right()) + geom.moveRight(screen->geometry().right()); + } QWidget::setGeometry(geom); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/customwidgets/thumbnailwidget.cpp new/qimgv-1.0.1/qimgv/gui/customwidgets/thumbnailwidget.cpp --- old/qimgv-1.0.0/qimgv/gui/customwidgets/thumbnailwidget.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/customwidgets/thumbnailwidget.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -16,7 +16,7 @@ thumbStyle(THUMB_SIMPLE) { setAttribute(Qt::WA_OpaquePaintEvent, true); - setCacheMode(QGraphicsItem::DeviceCoordinateCache); + //setCacheMode(QGraphicsItem::DeviceCoordinateCache); breaks hidpi fractional scaling setAcceptHoverEvents(true); font.setBold(false); QFontMetrics fm(font); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/mainwindow.cpp new/qimgv-1.0.1/qimgv/gui/mainwindow.cpp --- old/qimgv-1.0.0/qimgv/gui/mainwindow.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/mainwindow.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -441,13 +441,46 @@ void MW::showSaveDialog(QString filePath) { viewerWidget->hidePanel(); + QStringList filters; + // generate filter for writable images + // todo: some may need to be blacklisted + auto writerFormats = QImageWriter::supportedImageFormats(); + if(writerFormats.contains("jpg")) filters.append("JPEG (*.jpg *.jpeg *jpe *jfif)"); + if(writerFormats.contains("png")) filters.append("PNG (*.png)"); + if(writerFormats.contains("webp")) filters.append("WebP (*.webp)"); + // may not work.. + if(writerFormats.contains("jp2")) filters.append("JPEG 2000 (*.jp2 *.j2k *.jpf *.jpx *.jpm *.jpgx)"); + if(writerFormats.contains("jxl")) filters.append("JPEG-XL (*.jxl)"); + if(writerFormats.contains("avif")) filters.append("AVIF (*.avif *.avifs)"); + if(writerFormats.contains("tif")) filters.append("TIFF (*.tif *.tiff)"); + if(writerFormats.contains("bmp")) filters.append("BMP (*.bmp)"); +#ifdef _WIN32 + if(writerFormats.contains("ico")) filters.append("Icon Files (*.ico)"); +#endif + if(writerFormats.contains("ppm")) filters.append("PPM (*.ppm)"); + if(writerFormats.contains("xbm")) filters.append("XBM (*.xbm)"); + if(writerFormats.contains("xpm")) filters.append("XPM (*.xpm)"); + if(writerFormats.contains("dds")) filters.append("DDS (*.dds)"); + if(writerFormats.contains("wbmp")) filters.append("WBMP (*.wbmp)"); + // add everything else from imagewriter + for(auto fmt : writerFormats) { + if(filters.filter(fmt).isEmpty()) + filters.append(fmt.toUpper() + " (*." + fmt + ")"); + } + QString filterString = filters.join(";; "); - const QString imagesFilter = settings->supportedFormatsString(); - filePath = QFileDialog::getSaveFileName(this, tr("Save File"), - filePath, - imagesFilter); - if(!filePath.isEmpty()) - emit saveAsRequested(filePath); + // find matching filter for the current image + QString selectedFilter = "JPEG (*.jpg *.jpeg *jpe *jfif)"; + QFileInfo fi(filePath); + for(auto filter : filters) { + if(filter.contains(fi.suffix().toLower())) { + selectedFilter = filter; + break; + } + } + QString newFilePath = QFileDialog::getSaveFileName(this, tr("Save File as..."), filePath, filterString, &selectedFilter); + if(!newFilePath.isEmpty()) + emit saveAsRequested(newFilePath); } void MW::showOpenDialog(QString path) { @@ -455,7 +488,7 @@ QFileDialog dialog(this); QStringList imageFilter; - imageFilter.append(settings->supportedFormatsString()); + imageFilter.append(settings->supportedFormatsFilter()); imageFilter.append("All Files (*)"); dialog.setDirectory(path); dialog.setNameFilters(imageFilter); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/mainwindow.h new/qimgv-1.0.1/qimgv/gui/mainwindow.h --- old/qimgv-1.0.0/qimgv/gui/mainwindow.h 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/mainwindow.h 2021-09-26 18:19:06.000000000 +0200 @@ -6,6 +6,7 @@ #include <QMessageBox> #include <QFileDialog> #include <QMimeData> +#include <QImageWriter> #include "gui/customwidgets/floatingwidgetcontainer.h" #include "gui/viewers/viewerwidget.h" #include "gui/overlays/controlsoverlay.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/overlays/cropoverlay.cpp new/qimgv-1.0.1/qimgv/gui/overlays/cropoverlay.cpp --- old/qimgv-1.0.0/qimgv/gui/overlays/cropoverlay.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/overlays/cropoverlay.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -447,6 +447,7 @@ QPoint point = mapPointToImage(event->pos() * dpr); selectionRect.setTopLeft(point); selectionRect.setBottomRight(point); + resizeAnchor = point; } } else if(event->buttons() & Qt::RightButton) { clearSelection(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/gui/viewers/imageviewerv2.cpp new/qimgv-1.0.1/qimgv/gui/viewers/imageviewerv2.cpp --- old/qimgv-1.0.0/qimgv/gui/viewers/imageviewerv2.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/gui/viewers/imageviewerv2.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -575,11 +575,14 @@ // warning for future me: // for some reason in qgraphicsview wheelEvent is followed by moveEvent (wtf?) void ImageViewerV2::wheelEvent(QWheelEvent *event) { - // we don't need these + #ifdef __APPLE__ + // this event goes off during force touch with Qt::ScrollPhase being set to begin/end + // lets filter these if(event->phase() == Qt::ScrollBegin || event->phase() == Qt::ScrollEnd) { event->accept(); return; } + #endif if(event->buttons() & Qt::RightButton) { event->accept(); @@ -590,36 +593,52 @@ else if(angleDelta < 0) zoomOutCursor(); } else if(event->modifiers() == Qt::NoModifier) { - event->accept(); QPoint pixelDelta = event->pixelDelta(); QPoint angleDelta = event->angleDelta(); - // high-precision touchpad - if(pixelDelta != QPoint(0,0) && settings->imageScrolling() != ImageScrolling::SCROLL_NONE) { - stopPosAnimation(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pixelDelta.x() * TRACKPAD_SCROLL_MULTIPLIER); - verticalScrollBar()->setValue(verticalScrollBar()->value() - pixelDelta.y() * TRACKPAD_SCROLL_MULTIPLIER); - centerIfNecessary(); - snapToEdges(); - } else if(angleDelta != QPoint(0,0)) { // mouse wheel & (windows) touchpad - // wheel usually sends angleDelta = 120 / 240 / ... - // there doesnt seem to be a way to detect event source except this - // this issue is windows only as both linux touchpad drivers send pixelDelta instead - // as a workaround we use QElapsedTimer to guess where the event came from - bool isWheel = angleDelta.y() && !(angleDelta.y() % 120); - if(isWheel && lastTouchpadScroll.elapsed() > 100) { - if(settings->imageScrolling() == SCROLL_BY_TRACKPAD_AND_WHEEL) - scroll(0, -angleDelta.y(), true); - else - QWidget::wheelEvent(event); - return; // return immediately so we wont restart the scroll timer - } else if(settings->imageScrolling() != ImageScrolling::SCROLL_NONE) { + /* for reference + * linux + * trackpad: + * pixelDelta = (x,y) + * angleDelta = (x*scale,y*scale) + * wheel: + * pixelDelta = (0,0) - libinput <= 1.18 + * pixelDelta = (0,120*m) - libinput 1.19 + * angleDelta = (0,120*m) + * ----------------------------------------- + * macOS + * trackpad: + * pixelDelta = (x,y) + * angleDelta = (x*scale,y*scale) + * wheel: + * pixelDelta = (0,y*scrollAccel) + * angleDelta = (0,120*m) + * ----------------------------------------- + * windows + * trackpad: + * ?? (dont have the hardware with precision drivers) + * wheel: + * pixelDelta = (0,0) + * AngleDelta = (0,120*m) + */ + bool isWheel = angleDelta.y() && !(angleDelta.y() % 120) && lastTouchpadScroll.elapsed() > 100; + if(!isWheel) { + lastTouchpadScroll.restart(); + event->accept(); + if(settings->imageScrolling() != ImageScrolling::SCROLL_NONE) { + // scroll (high precision) stopPosAnimation(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - angleDelta.x() * TRACKPAD_SCROLL_MULTIPLIER); - verticalScrollBar()->setValue(verticalScrollBar()->value() - angleDelta.y() * TRACKPAD_SCROLL_MULTIPLIER); + horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pixelDelta.x() * TRACKPAD_SCROLL_MULTIPLIER); + verticalScrollBar()->setValue(verticalScrollBar()->value() - pixelDelta.y() * TRACKPAD_SCROLL_MULTIPLIER); centerIfNecessary(); snapToEdges(); } - lastTouchpadScroll.restart(); + } else if(isWheel && settings->imageScrolling() == SCROLL_BY_TRACKPAD_AND_WHEEL) { + // scroll by interval + event->accept(); + scroll(0, -angleDelta.y(), true); + } else { + event->ignore(); + QWidget::wheelEvent(event); } saveViewportPos(); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/settings.cpp new/qimgv-1.0.1/qimgv/settings.cpp --- old/qimgv-1.0.0/qimgv/settings.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/settings.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -250,9 +250,9 @@ return formats; } //------------------------------------------------------------------------------ -// (for open/save dialogs) +// (for open/save dialogs, as a single string) // example: "Images (*.jpg, *.png)" -QString Settings::supportedFormatsString() { +QString Settings::supportedFormatsFilter() { QString filters; auto formats = supportedFormats(); filters.append("Supported files ("); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/settings.h new/qimgv-1.0.1/qimgv/settings.h --- old/qimgv-1.0.0/qimgv/settings.h 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/settings.h 2021-09-26 18:19:06.000000000 +0200 @@ -104,7 +104,7 @@ ~Settings(); QStringList supportedMimeTypes(); QList<QByteArray> supportedFormats(); - QString supportedFormatsString(); + QString supportedFormatsFilter(); QString supportedFormatsRegex(); int panelPreviewsSize(); void setPanelPreviewsSize(int size); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qimgv-1.0.0/qimgv/shortcutbuilder.cpp new/qimgv-1.0.1/qimgv/shortcutbuilder.cpp --- old/qimgv-1.0.0/qimgv/shortcutbuilder.cpp 2021-09-22 18:21:10.000000000 +0200 +++ new/qimgv-1.0.1/qimgv/shortcutbuilder.cpp 2021-09-26 18:19:06.000000000 +0200 @@ -16,11 +16,10 @@ //------------------------------------------------------------------------------ QString ShortcutBuilder::processWheelEvent(QWheelEvent *event) { QString sequence; - if(event->angleDelta().ry() < 0) { - sequence = "WheelUp"; - } else if(event->angleDelta().ry() > 0) { + if(event->angleDelta().ry() < 0) sequence = "WheelDown"; - } + else if(event->angleDelta().ry() > 0) + sequence = "WheelUp"; sequence.prepend(modifierKeys(event)); return sequence; }