Cherry-picking upstream release 0.5.0.

* Added build-dependency libqt5svg5-dev
* Bumped compat to 10
* Bumped minimum version debhelper (>= 10)
* Bumped minimum version libfm-qt-dev (>= 0.11.1)
* Bumped minimum version liblxqt0-dev (>= 0.11.0)
* Bumped minimum version libqt5xdg-dev (>= 2.0.0)
* Removed --parallel from rules, standard compat 10
debian/0.5.0-1
Alf Gaida 8 years ago
parent bd6523229f
commit d1838aa1bc

3
.gitignore vendored

@ -0,0 +1,3 @@
build
*.kdev4
src/translations/lximage-qt

@ -0,0 +1,169 @@
lximage-qt-0.5.0 / 2016-09-24
=============================
* Bump version to 0.5.0 (#67)
* Remove Core and Qt from Categories in desktop file (#64)
* Extend README.md
* Fix broken compatibility introduced by libfm-qt API changes. This closes lxde/lximage-qt#63.
* Add Catalan translations
* Quieten compiler warning
* Code cleanup
* Use LXQtCompilerSettings cmake module
* Treat SVG files separately as SVG images
* build: Update translations based on *.ui
* Fix typo in Portuguese translation for desktop file
* Fix typo in German translation for desktop file (#55)
* build: Use external translations (#54)
* ts-files removal (#53)
* Hide cursor smartly in fullscreen mode
* build: Use liblxqt's TranslateDesktop module
* Adds support for GIF animation.
* Implement an EOG-like behavior on starting By clicking on an image for the first time, the user wants to see it clearly with lximage-qt. So, the following behavior is implemented here:
* Add --version command line option
* Fix missing Russian translation in desktop file
* Fix memory leak if taking screenshot with cursor
* Polish translation updated
* Another update
* Improved Russian translation - thanks to uazure
* Fix typo
* Add Russian translation
* Italian translation update
* CMake: Adapt to libfm-qt Targets
* Turn on C++11 support. This closes bug lxde/lximage-qt #36.
* Exec should have an argument
* all GPL files are (or any later)
* Add release script
* Update translations
* Set the color table properly for scaled images
* Add Greek (el) translation Remove needless country variant from language code
* Corrected language code (de_DE -> de) of german translation, marked translations as done.
* replace tabs with spaces
* remove trailing spaces
* replace glib with Qt for command-line parsing
* Don't save file in private mode
* Prevents the slideshow timeout to be set to 0 in the UI
* Correctly include CMake modules in intree/superbuild mode
* Remove lximage-qt from the Utilities category
* Update README
* Update .gitignore
* Hungarian translations added
* save and restore window size and maximized state
0.4.0 / 2015-02-18
==================
* Release v0.4.0
* src/CMakeLists.txt: do not completely overwrite CMAKE_CXX_FLAGS
* Create lximage-qt_it.desktop
* Create lximage-qt_it.ts
* CMakeLists cleanups
* Portuguese update
* Added german translation, re-generated all other .ts files.
* Added keyboard shortcut to print.
* Adds .desktop translation support
* Portuguese language update
* Remove debian directory (Close #9)
* Fix typo Zoomo -> Zoom
* Use proper naming conventions for translations
* Clean up CMakeLists, dropping support for Qt 5
0.3.0 / 2014-10-15
==================
* Release v0.3.0
* Rename preferencedialog.ui to preferencesdialog.ui
* Ignore build dir.
* debian: enable qt5 by default
* Fix lxde/lxde-qt #269 - Screenshots are not saved aedequately unless file extension is chosen manually.
* Support Qt5 and libfm-qt5.
* Make sure all enums are handled in switch
0.2.0 / 2014-05-09
==================
* Release 0.2.0
* Update desktop files
* Update README/COPYING/AUTHORS
* Add some missing link_directories()
* Commit from LXDE Pootle server by user yinghua_wang.: 70 of 70 strings translated (0 fuzzy).
* Add CPack rules for creating tarball
* Avoid creating a scaled image cache if current scale factor is 1.0 (original size).
* Rewrite the scaled image caching code in LxImage::ImageView to improve its readability and correctness.
* Add LxImage::Job class as a base class for multi-threading jobs.
* Avoid copying subimages to speed up scaling images.
* Limit the size of pixmap cache.
* Limit the size of pixmap cache.
* Create a cache for the high-quality scaled image of the currently viewport and use it to override the default paintEvent() of QGraphicsView as needed. This improves the image quality a lot when we scale down large photos.
* Cancel autoZoomFit when calling zoomOriginal(), zoomIn(), and zoomOut().
* Add copy and paste buttons to the toolbar.
* Automatically zoom to fit current window size by default.
* Make the preferences dialog non-modal and apply the settings to all existing windows.
* Add "Delete file" and "File properties" actions to the file menu.
* Add a very basic thumbnails pane based on Fm::FolderView of libfm-qt.
* Implement the preferences dialog. * Enable keyboard shortcuts in fullscreen mode.
* Implement very basic slide show functionality.
* Jump to the previous or the next image by using mouse wheel.
* Avoid scaling up an image while zoomFit() if it's smaller than the current view.
* Support grabbing mouse cursor when taking a screenshot.
* Add very basic printing support.
* Commit from LXDE Pootle server by user adrianoh2.: 70 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user Fitoschido.: 70 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user hirkmt.: 70 of 70 strings translated (0 fuzzy).
* Remove xsettings support and add an option in the preference dialog to set a fallback icon theme instead.
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Improve cmake integration for translations. The *.ts files are only updated when UPDATE_TRANSLATIONS cmake option is turned on.
* Commit from LXDE Pootle server by user zvacet.: 65 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user zvacet.: 50 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user wwycheuk.: 65 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user mbouzada.: 70 of 70 strings translated (0 fuzzy).
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Commit from LXDE Pootle server by user Fitoschido.: 68 of 70 strings translated (0 fuzzy).
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Corrected caml cased string toolBar.
* Commit from LXDE Pootle server by user smarquespt.: 70 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user brother.: 24 of 24 strings translated (0 fuzzy).
* Correct misspelled 'Zoom'.
* Commit from LXDE Pootle server by user andika.: 70 of 70 strings translated (0 fuzzy).
* New files added from LXDE Pootle server based on templates
* Commit from LXDE Pootle server by user strebski.: 70 of 70 strings translated (0 fuzzy).
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Commit from LXDE Pootle server by user LStranger.: 70 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user brother.: 70 of 70 strings translated (0 fuzzy).
* Commit from LXDE Pootle server by user LStranger.: 2 of 70 strings translated (0 fuzzy).
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* New files added from LXDE Pootle server based on templates
* Add zh_TW translation and a template ts file.
* Add a desktop entry file for the built-in screenshot tool.
* Add --screenshot command line argument to launch the built-in screenshot utility.
* Improve the screenshot tool. Implement pasting from clipboard.
* Add ability to taking screenshots to lximage-qt.
* debian : Add missing libx11 build-depend
* Add missing files.
* Add Xdg::DesktopSettings for detecting desktop-specific settings. Get icon theme name via XSettings or config files when available.
* Supporting saving files. (needs some more polishing, though).
* Add a basic debian directory to enable daily builds.
* Add a context menu.
* Use libexif to read EXIF orientation tags then apply them to images loaded.
* Refactor - move image loading code to LxImage::LoadImageJob class.
* Remove unused data member.
* Add a preferences dialog (not working yet). Little adjustment for menu positions and add placeholders for features not implemented.
* Fix filename encoding handling so non-English filenames can be passed correctly from command line arguments.
* Canonicalize filenames passed through command line arguments. Add an icon borrowed from GPicView. Rearrange menus and implement "fullscreen" and "copy to clipboard".
* Implement basic single instance support and command line argument parsing.
* Properly cancel pending tasks and make going back/forward more smooth. Enhance window title display.
* Little fix to avoid loading a cancelled image.
* Supports rotation of images.
* Use the latest libfm-qt APIs to filter out non-image files. Implement jumping to first and last file in the folder.
* Fix incorrect reference couting of GCancellable objects to avoid crashes. Add some shortcut keys to improve usability.
* Use glib/gio GInputStream + GIOSchedulerJob to load the images with multi-threading. Refactor, simplify class methods of LxImage::MainWindow.
* Use libfm to load folders containing the specified image. Add dependency on libexif for future implementation of EXIF related stuff. Add LxImage::Applcation class to handle application initiation.
* Initial import into git

@ -5,7 +5,7 @@ project(lximage-qt)
include(GNUInstallDirs)
set(MAJOR_VERSION 0)
set(MINOR_VERSION 4)
set(MINOR_VERSION 5)
set(PATCH_VERSION 0)
set(LXIMAGE_VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION})
@ -13,35 +13,18 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_AUTOMOC ON)
# C++ 11 support
if (CMAKE_VERSION VERSION_LESS "3.1")
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
# -std=c++0x is deprecated but some tools e.g. qmake or older gcc are still using it
if(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER} does not support c++11/c++0x")
endif()
endif()
else()
set(CMAKE_CXX_STANDARD 11)
endif()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5DBus REQUIRED)
find_package(Qt5PrintSupport REQUIRED QUIET)
find_package(Qt5X11Extras REQUIRED QUIET)
find_package(Qt5LinguistTools REQUIRED QUIET)
find_package(Qt5Svg REQUIRED QUIET)
find_package(fm-qt REQUIRED QUIET)
find_package(lxqt REQUIRED) #just a build dependency for .desktop files translation
message(STATUS "Building with Qt ${Qt5Core_VERSION_STRING}")
include(LXQtCompilerSettings NO_POLICY_SCOPE)
find_package(PkgConfig REQUIRED)
# FIXME: we'll need this to provide detail info for photos in the future

@ -1,3 +1,25 @@
# lximage-qt
# LXImage-Qt
The Qt port of LXImage, a simple and fast image viewer.
## Overview
LXImage-Qt is the Qt port of LXImage, a simple and fast image viewer.
In addition it features a tool to take screenshots.
It is maintained by the LXQt project but can be used independently from this desktop environment.
## Installation
### Compiling source code
Runtime dependencies are qtx11extras and [libfm-qt](https://github.com/lxde/libfm-qt) (LXImage-Qt used to depend on [PCManFM-Qt](https://github.com/lxde/pcmanfm-qt) but the relevant code belongs to what was outsourced in libfm-qt).
Additional build dependencies are CMake and optionally Git to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
### Binary packages
Official binary packages are available in Arch Linux, Debian (as of Debian stretch), Fedora and openSUSE (Leap 42.1 and Tumbleweed).
Just use the distributions' package manager to search for string 'lximage'.

@ -7,5 +7,5 @@ Icon=lximage-qt
Exec=lximage-qt %F
StartupNotify=true
Terminal=false
Categories=Graphics;Core;Qt;Viewer;RasterGraphics;2DGraphics;Photography;
Categories=Graphics;Viewer;RasterGraphics;2DGraphics;Photography;
MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/png;image/tiff;image/x-bmp;image/x-pcx;image/x-tga;image/x-portable-pixmap;image/x-portable-bitmap;image/x-targa;image/x-portable-greymap;application/pcx;image/svg+xml;image/svg-xml;

1
debian/.gitignore vendored

@ -1,6 +1,7 @@
/*.debhelper
/*.log
/*.substvars
/debhelper-build-stamp
/files
/lximage-qt/

13
debian/changelog vendored

@ -1,3 +1,16 @@
lximage-qt (0.5.0-1) experimental; urgency=medium
* Cherry-picking upstream release 0.5.0.
* Added build-dependency libqt5svg5-dev
* Bumped compat to 10
* Bumped minimum version debhelper (>= 10)
* Bumped minimum version libfm-qt-dev (>= 0.11.1)
* Bumped minimum version liblxqt0-dev (>= 0.11.0)
* Bumped minimum version libqt5xdg-dev (>= 2.0.0)
* Removed --parallel from rules, standard compat 10
-- Alf Gaida <agaida@siduction.org> Sun, 25 Sep 2016 22:49:20 +0200
lximage-qt (0.4.1~38-gf8fc532-1) experimental; urgency=medium
* Cherry-picking upstream version 0.4.1~38-gf8fc532.

9
debian/control vendored

@ -10,19 +10,20 @@ Build-Depends: debhelper (>= 10),
libexif-dev,
libglib2.0-dev,
libfm-dev,
libfm-qt-dev (>= 0.11.1~),
libfm-qt-dev (>= 0.11.1),
libkf5windowsystem-dev,
liblxqt0-dev (>= 0.10.96~),
liblxqt0-dev (>= 0.11.0),
libmenu-cache-dev,
libqt5svg5-dev,
libqt5x11extras5-dev,
libqt5xdg-dev (>= 1.3.1~),
libqt5xdg-dev (>= 2.0.0),
libx11-dev,
libxfixes-dev,
pkg-config,
qttools5-dev,
qttools5-dev-tools
Standards-Version: 3.9.8
Vcs-Browser: https://anonscm.debian.org/git/pkg-lxqt/lximage-qt.git/?h=debian/experimental
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-lxqt/lximage-qt.git/?h=debian/experimental
Vcs-Git: https://anonscm.debian.org/git/pkg-lxqt/lximage-qt.git -b debian/experimental
Homepage: https://github.com/lxde/lximage-qt

3
debian/rules vendored

@ -6,8 +6,7 @@ export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh ${@} --buildsystem cmake\
--parallel
dh ${@} --buildsystem cmake
override_dh_auto_configure:
dh_auto_configure -- \

@ -1,6 +1,3 @@
# set visibility to hidden to hide symbols, unlesss they're exporeted manually in the code
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
include_directories(
${X11_INCLUDE_DIR}
${XFIXES_INCLUDE_DIRS}
@ -81,7 +78,7 @@ add_definitions(
-DLXIMAGE_VERSION="${LXIMAGE_VERSION}"
)
set(QT_LIBRARIES Qt5::Widgets Qt5::Core Qt5::DBus Qt5::PrintSupport Qt5::X11Extras)
set(QT_LIBRARIES Qt5::Widgets Qt5::Core Qt5::DBus Qt5::PrintSupport Qt5::X11Extras Qt5::Svg)
target_link_libraries(lximage-qt
fm-qt

@ -35,8 +35,8 @@ static const char* ifaceName = "org.lxde.LxImage.Application";
Application::Application(int& argc, char** argv):
QApplication(argc, argv),
windowCount_(0),
libFm() {
libFm(),
windowCount_(0) {
setApplicationVersion(LXIMAGE_VERSION);
}
@ -63,7 +63,7 @@ bool Application::init(int argc, char** argv) {
new ApplicationAdaptor(this);
dbus.registerObject("/Application", this);
connect(this, SIGNAL(aboutToQuit()), SLOT(onAboutToQuit()));
connect(this, &Application::aboutToQuit, this, &Application::onAboutToQuit);
if(settings_.useFallbackIconTheme())
QIcon::setThemeName(settings_.fallbackIconTheme());
@ -179,6 +179,5 @@ void Application::editPreferences() {
}
void Application::onAboutToQuit() {
qDebug("aboutToQuit");
settings_.save();
}

@ -41,11 +41,9 @@ public:
void addWindow() { // call this when you create a new toplevel window
++windowCount_;
qDebug("add window");
}
void removeWindow() { // call this when you destroy a toplevel window
qDebug("remove window");
--windowCount_;
if(0 == windowCount_)
quit();

@ -24,21 +24,25 @@
#include <QPainter>
#include <QTimer>
#include <QPolygon>
#include <QDebug>
#include <QStyle>
#include <QLabel>
#include <QGraphicsProxyWidget>
#include <QGraphicsSvgItem>
#define CURSOR_HIDE_DELY 3000
namespace LxImage {
ImageView::ImageView(QWidget* parent):
QGraphicsView(parent),
imageItem_(new QGraphicsRectItem()),
scene_(new QGraphicsScene(this)),
gifMovie_(NULL),
imageItem_(new QGraphicsRectItem()),
gifMovie_(nullptr),
cacheTimer_(nullptr),
cursorTimer_(nullptr),
scaleFactor_(1.0),
autoZoomFit_(false),
cacheTimer_(NULL),
scaleFactor_(1.0) {
isSVG(false) {
setViewportMargins(0, 0, 0, 0);
setContentsMargins(0, 0, 0, 0);
@ -58,6 +62,10 @@ ImageView::~ImageView() {
cacheTimer_->stop();
delete cacheTimer_;
}
if(cursorTimer_) {
cursorTimer_->stop();
delete cursorTimer_;
}
}
@ -88,6 +96,34 @@ void ImageView::mouseDoubleClickEvent(QMouseEvent* event) {
QAbstractScrollArea::mouseDoubleClickEvent(event);
}
void ImageView::mousePressEvent(QMouseEvent * event) {
QGraphicsView::mousePressEvent(event);
if(cursorTimer_) cursorTimer_->stop();
}
void ImageView::mouseReleaseEvent(QMouseEvent* event) {
QGraphicsView::mouseReleaseEvent(event);
if(cursorTimer_) cursorTimer_->start(CURSOR_HIDE_DELY);
}
void ImageView::mouseMoveEvent(QMouseEvent* event) {
QGraphicsView::mouseMoveEvent(event);
if(cursorTimer_ && (viewport()->cursor().shape() == Qt::BlankCursor
|| viewport()->cursor().shape() == Qt::OpenHandCursor)) {
cursorTimer_->start(CURSOR_HIDE_DELY); // restart timer
viewport()->setCursor(Qt::OpenHandCursor);
}
}
void ImageView::focusInEvent(QFocusEvent* event) {
QGraphicsView::focusInEvent(event);
if(cursorTimer_ && (viewport()->cursor().shape() == Qt::BlankCursor
|| viewport()->cursor().shape() == Qt::OpenHandCursor)) {
cursorTimer_->start(CURSOR_HIDE_DELY); // restart timer
viewport()->setCursor(Qt::OpenHandCursor);
}
}
void ImageView::resizeEvent(QResizeEvent* event) {
QGraphicsView::resizeEvent(event);
if(autoZoomFit_)
@ -136,10 +172,13 @@ void ImageView::zoomOriginal() {
}
void ImageView::setImage(QImage image, bool show) {
if(gifMovie_ && show) { // a gif animation was shown
if(show && (gifMovie_ || isSVG)) { // a gif animation or SVG file was shown before
scene_->clear();
delete gifMovie_;
gifMovie_ = NULL;
isSVG = false;
if(gifMovie_) { // should be deleted explicitly
delete gifMovie_;
gifMovie_ = nullptr;
}
// recreate the rect item
imageItem_ = new QGraphicsRectItem();
imageItem_->hide();
@ -168,21 +207,24 @@ void ImageView::setImage(QImage image, bool show) {
}
void ImageView::setGifAnimation(QString fileName) {
QImage image(fileName);
if(image.isNull()) {
image_ = QImage();
imageItem_->hide();
imageItem_->setBrush(QBrush());
/* the built-in gif reader gives the first frame, which won't
be shown but is used for tracking position and dimensions */
image_ = QImage(fileName);
if(image_.isNull()) {
if(imageItem_) {
imageItem_->hide();
imageItem_->setBrush(QBrush());
}
scene_->setSceneRect(0, 0, 0, 0);
}
else {
scene_->clear();
imageItem_ = NULL; // it's deleted by clear();
imageItem_ = nullptr; // it's deleted by clear();
if(gifMovie_) {
delete gifMovie_;
gifMovie_ = NULL;
gifMovie_ = nullptr;
}
QPixmap pix(image.size());
QPixmap pix(image_.size());
pix.fill(Qt::transparent);
QGraphicsItem *gifItem = new QGraphicsPixmapItem(pix);
QLabel *gifLabel = new QLabel();
@ -192,9 +234,6 @@ void ImageView::setGifAnimation(QString fileName) {
gifLabel->setMovie(gifMovie_);
gifWidget->setWidget(gifLabel);
gifMovie_->start();
/* the first frame won't be shown but will be
used for tracking position and dimensions */
image_ = gifMovie_->currentImage();
scene_->addItem(gifItem);
scene_->setSceneRect(gifItem->boundingRect());
}
@ -204,6 +243,29 @@ void ImageView::setGifAnimation(QString fileName) {
queueGenerateCache(); // deletes the cache timer in this case
}
void ImageView::setSVG(QString fileName) {
image_ = QImage(fileName); // for tracking position and dimensions
if(image_.isNull()) {
if(imageItem_) {
imageItem_->hide();
imageItem_->setBrush(QBrush());
}
scene_->setSceneRect(0, 0, 0, 0);
}
else {
scene_->clear();
imageItem_ = nullptr;
isSVG = true;
QGraphicsSvgItem *svgItem = new QGraphicsSvgItem(fileName);
scene_->addItem(svgItem);
scene_->setSceneRect(svgItem->boundingRect());
}
if(autoZoomFit_)
zoomFit();
queueGenerateCache(); // deletes the cache timer in this case
}
void ImageView::setScaleFactor(double factor) {
if(factor != scaleFactor_) {
scaleFactor_ = factor;
@ -215,7 +277,7 @@ void ImageView::setScaleFactor(double factor) {
void ImageView::paintEvent(QPaintEvent* event) {
// if the image is scaled and we have a high quality cached image
if(scaleFactor_ != 1.0 && !cachedPixmap_.isNull()) {
if(imageItem_ && scaleFactor_ != 1.0 && !cachedPixmap_.isNull()) {
// rectangle of the whole image in viewport coordinate
QRect viewportImageRect = sceneToViewport(imageItem_->rect());
// the visible part of the image.
@ -244,20 +306,20 @@ void ImageView::queueGenerateCache() {
cachedPixmap_ = QPixmap();
// we don't need to cache the scaled image if its the same as the original image (scale:1.0)
// no cache for gif animations either
if(scaleFactor_ == 1.0 || gifMovie_) {
// no cache for gif animations or SVG images either
if(scaleFactor_ == 1.0 || gifMovie_ || isSVG) {
if(cacheTimer_) {
cacheTimer_->stop();
delete cacheTimer_;
cacheTimer_ = NULL;
cacheTimer_ = nullptr;
}
return;
}
if(!cacheTimer_ && !gifMovie_) {
if(!cacheTimer_) {
cacheTimer_ = new QTimer();
cacheTimer_->setSingleShot(true);
connect(cacheTimer_, SIGNAL(timeout()), SLOT(generateCache()));
connect(cacheTimer_, &QTimer::timeout, this, &ImageView::generateCache);
}
if(cacheTimer_)
cacheTimer_->start(200); // restart the timer
@ -267,7 +329,9 @@ void ImageView::queueGenerateCache() {
void ImageView::generateCache() {
// disable the one-shot timer
cacheTimer_->deleteLater();
cacheTimer_ = NULL;
cacheTimer_ = nullptr;
if(!imageItem_ || image_.isNull()) return;
// generate a cache for "the visible part" of the scaled image
// rectangle of the whole image in viewport coordinate
@ -295,12 +359,6 @@ void ImageView::generateCache() {
// convert the cached scaled image to pixmap
cachedPixmap_ = QPixmap::fromImage(scaled);
viewport()->update();
/*
qDebug() << "viewportImageRect" << viewportImageRect
<< "cachedRect_" << cachedRect_
<< "cachedSceneRect_" << cachedSceneRect_
<< "subRect" << subRect;
*/
}
// convert viewport coordinate to the original image (not scaled).
@ -317,5 +375,26 @@ QRect ImageView::sceneToViewport(const QRectF& rect) {
return QRect(topLeft, bottomRight);
}
void ImageView::blankCursor() {
viewport()->setCursor(Qt::BlankCursor);
}
void ImageView::hideCursor(bool enable) {
if(enable) {
if(cursorTimer_) delete cursorTimer_;
cursorTimer_ = new QTimer(this);
cursorTimer_->setSingleShot(true);
connect(cursorTimer_, &QTimer::timeout, this, &ImageView::blankCursor);
if(viewport()->cursor().shape() == Qt::OpenHandCursor)
cursorTimer_->start(CURSOR_HIDE_DELY);
}
else if (cursorTimer_) {
cursorTimer_->stop();
delete cursorTimer_;
cursorTimer_ = nullptr;
if(viewport()->cursor().shape() == Qt::BlankCursor)
viewport()->setCursor(Qt::OpenHandCursor);
}
}
} // namespace LxImage

@ -42,6 +42,7 @@ public:
void setImage(QImage image, bool show = true);
void setGifAnimation(QString fileName);
void setSVG(QString fileName);
QImage image() {
return image_;
@ -67,9 +68,16 @@ public:
autoZoomFit_ = value;
}
// if set to true, hides the cursor after 3s of inactivity
void hideCursor(bool enable);
protected:
virtual void wheelEvent(QWheelEvent* event);
virtual void mouseDoubleClickEvent(QMouseEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void focusInEvent(QFocusEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void paintEvent(QPaintEvent* event);
@ -80,6 +88,7 @@ private:
private Q_SLOTS:
void generateCache();
void blankCursor();
private:
QGraphicsScene* scene_; // the topmost container of all graphic items
@ -90,8 +99,10 @@ private:
QRect cachedRect_; // rectangle containing the cached region (in viewport coordinate)
QRect cachedSceneRect_; // rectangle containing the cached region (in scene/original image coordinate)
QTimer* cacheTimer_;
QTimer *cursorTimer_; // for hiding cursor in fullscreen mode
double scaleFactor_;
bool autoZoomFit_;
bool isSVG; // is the image an SVG file?
};
}

@ -35,7 +35,7 @@ Job::~Job() {
// This is called from the worker thread, not main thread
gboolean Job::_jobThread(GIOSchedulerJob* job, GCancellable* cancellable, Job* pThis) {
bool ret = pThis->run();
pThis->run();
// do final step in the main thread
if(!g_cancellable_is_cancelled(pThis->cancellable_))
g_io_scheduler_job_send_to_mainloop(job, GSourceFunc(_finish), pThis, NULL);

@ -29,8 +29,8 @@ using namespace LxImage;
LoadImageJob::LoadImageJob(MainWindow* window, FmPath* filePath):
Job(),
path_(fm_path_ref(filePath)),
mainWindow_(window) {
mainWindow_(window),
path_(fm_path_ref(filePath)) {
}
LoadImageJob::~LoadImageJob() {
@ -71,7 +71,7 @@ bool LoadImageJob::run() {
// use libexif to extract additional info embedded in jpeg files
ExifLoader *exif_loader = exif_loader_new();
// write image data to exif loader
int ret = exif_loader_write(exif_loader, (unsigned char*)imageBuffer.data().constData(), (unsigned int)imageBuffer.size());
exif_loader_write(exif_loader, (unsigned char*)imageBuffer.data().constData(), (unsigned int)imageBuffer.size());
ExifData *exif_data = exif_loader_get_data(exif_loader);
exif_loader_unref(exif_loader);
if(exif_data) {

@ -28,7 +28,6 @@
#include <QPainter>
#include <QPrintDialog>
#include <QPrinter>
#include <QDebug>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QTimer>
@ -36,6 +35,7 @@
#include <QDockWidget>
#include <QScrollBar>
#include <QDesktopWidget>
#include <QGraphicsSvgItem>
#include "application.h"
#include <libfm-qt/path.h>
#include <libfm-qt/folderview.h>
@ -46,21 +46,21 @@ using namespace LxImage;
MainWindow::MainWindow():
QMainWindow(),
currentFile_(NULL),
slideShowTimer_(NULL),
// currentFileInfo_(NULL),
loadJob_(NULL),
saveJob_(NULL),
folder_(NULL),
folderPath_(NULL),
contextMenu_(new QMenu(this)),
slideShowTimer_(nullptr),
image_(),
currentFile_(nullptr),
// currentFileInfo_(nullptr),
imageModified_(false),
folder_(nullptr),
folderPath_(nullptr),
folderModel_(new Fm::FolderModel()),
proxyModel_(new Fm::ProxyFolderModel()),
modelFilter_(new ModelFilter()),
imageModified_(false),
contextMenu_(new QMenu(this)),
thumbnailsDock_(NULL),
thumbnailsView_(NULL),
image_() {
thumbnailsDock_(nullptr),
thumbnailsView_(nullptr),
loadJob_(nullptr),
saveJob_(nullptr) {
setAttribute(Qt::WA_DeleteOnClose); // FIXME: check if current image is saved before close
@ -70,8 +70,8 @@ MainWindow::MainWindow():
Settings& settings = app->settings();
ui.setupUi(this);
connect(ui.actionScreenshot, SIGNAL(triggered(bool)), app, SLOT(screenshot()));
connect(ui.actionPreferences, SIGNAL(triggered(bool)), app ,SLOT(editPreferences()));
connect(ui.actionScreenshot, &QAction::triggered, app, &Application::screenshot);
connect(ui.actionPreferences, &QAction::triggered, app , &Application::editPreferences);
proxyModel_->addFilter(modelFilter_);
proxyModel_->sort(Fm::FolderModel::ColumnFileName, Qt::AscendingOrder);
@ -79,7 +79,7 @@ MainWindow::MainWindow():
// build context menu
ui.view->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.view, SIGNAL(customContextMenuRequested(QPoint)), SLOT(onContextMenu(QPoint)));
connect(ui.view, &QWidget::customContextMenuRequested, this, &MainWindow::onContextMenu);
// install an event filter on the image view
ui.view->installEventFilter(this);
@ -107,11 +107,11 @@ MainWindow::MainWindow():
// create shortcuts
QShortcut* shortcut = new QShortcut(Qt::Key_Left, this);
connect(shortcut, SIGNAL(activated()), SLOT(on_actionPrevious_triggered()));
connect(shortcut, &QShortcut::activated, this, &MainWindow::on_actionPrevious_triggered);
shortcut = new QShortcut(Qt::Key_Right, this);
connect(shortcut, SIGNAL(activated()), SLOT(on_actionNext_triggered()));
connect(shortcut, &QShortcut::activated, this, &MainWindow::on_actionNext_triggered);
shortcut = new QShortcut(Qt::Key_Escape, this);
connect(shortcut, SIGNAL(activated()), SLOT(onExitFullscreen()));
connect(shortcut, &QShortcut::activated, this, &MainWindow::onExitFullscreen);
}
MainWindow::~MainWindow() {
@ -174,7 +174,6 @@ void MainWindow::on_actionZoomOut_triggered() {
}
void MainWindow::onFolderLoaded(FmFolder* folder) {
qDebug("Finish loading: %d files", proxyModel_->rowCount());
// if currently we're showing a file, get its index in the folder now
// since the folder is fully loaded.
if(currentFile_ && !currentIndex_.isValid()) {
@ -207,14 +206,14 @@ void MainWindow::pasteImage(QImage newImage) {
// cancel loading of current image
if(loadJob_) {
loadJob_->cancel(); // the job object will be freed automatically later
loadJob_ = NULL;
loadJob_ = nullptr;
}
setModified(true);
currentIndex_ = QModelIndex(); // invaludate current index since we don't have a folder model now
if(currentFile_)
fm_path_unref(currentFile_);
currentFile_ = NULL;
currentFile_ = nullptr;
image_ = newImage;
ui.view->setImage(image_);
@ -302,7 +301,13 @@ void MainWindow::on_actionSave_triggered() {
void MainWindow::on_actionSaveAs_triggered() {
if(saveJob_) // if we're currently saving another file
return;
QString fileName = saveFileName(currentFile_ ? Fm::Path(currentFile_).displayName() : QString());
QString baseName;
if(currentFile_) {
char* dispName = fm_path_display_name(currentFile_, false);
baseName = QString::fromUtf8(dispName);
g_free(dispName);
}
QString fileName = saveFileName(baseName);
if(!fileName.isEmpty()) {
FmPath* path = fm_path_new_for_str(qPrintable(fileName));
// save the image file asynchronously
@ -354,7 +359,6 @@ void MainWindow::on_actionNext_triggered() {
FmFileInfo* info = proxyModel_->fileInfoFromIndex(index);
if(info) {
FmPath* path = fm_file_info_get_path(info);
qDebug("try load: %s", fm_path_get_basename(path));
loadImage(path, index);
}
}
@ -365,7 +369,6 @@ void MainWindow::on_actionPrevious_triggered() {
return;
if(currentIndex_.isValid()) {
QModelIndex index;
qDebug("current row: %d", currentIndex_.row());
if(currentIndex_.row() > 0)
index = proxyModel_->index(currentIndex_.row() - 1, 0);
else
@ -373,7 +376,6 @@ void MainWindow::on_actionPrevious_triggered() {
FmFileInfo* info = proxyModel_->fileInfoFromIndex(index);
if(info) {
FmPath* path = fm_file_info_get_path(info);
qDebug("try load: %s", fm_path_get_basename(path));
loadImage(path, index);
}
}
@ -385,7 +387,6 @@ void MainWindow::on_actionFirst_triggered() {
FmFileInfo* info = proxyModel_->fileInfoFromIndex(index);
if(info) {
FmPath* path = fm_file_info_get_path(info);
qDebug("try load: %s", fm_path_get_basename(path));
loadImage(path, index);
}
}
@ -396,8 +397,7 @@ void MainWindow::on_actionLast_triggered() {
if(index.isValid()) {
FmFileInfo* info = proxyModel_->fileInfoFromIndex(index);
if(info) {
FmPath* path = fm_file_info_get_path(info);
qDebug("try load: %s", fm_path_get_basename(path));
FmPath* path = fm_file_info_get_path(info);;
loadImage(path, index);
}
}
@ -423,7 +423,7 @@ void MainWindow::loadFolder(FmPath* newFolderPath) {
// the image is loaded (the method is only called if the loading is not cancelled)
void MainWindow::onImageLoaded(LoadImageJob* job) {
loadJob_ = NULL; // the job object will be freed later automatically
loadJob_ = nullptr; // the job object will be freed later automatically
image_ = job->image();
ui.view->setAutoZoomFit(true);
@ -448,12 +448,11 @@ void MainWindow::onImageSaved(SaveImageJob* job) {
if(!job->error()) {
setModified(false);
}
saveJob_ = NULL;
saveJob_ = nullptr;
}
// filter events of other objects, mainly the image view.
bool MainWindow::eventFilter(QObject* watched, QEvent* event) {
// qDebug() << event;
if(watched == ui.view) { // we got an event for the image view
switch(event->type()) {
case QEvent::Wheel: { // mouse wheel event
@ -585,7 +584,7 @@ void MainWindow::loadImage(FmPath* filePath, QModelIndex index) {
// cancel loading of current image
if(loadJob_) {
loadJob_->cancel(); // the job object will be freed automatically later
loadJob_ = NULL;
loadJob_ = nullptr;
}
if(imageModified_) {
// TODO: ask the user to save the modified image?
@ -601,21 +600,27 @@ void MainWindow::loadImage(FmPath* filePath, QModelIndex index) {
image_ = QImage();
const char* basename = fm_path_get_basename(currentFile_);
char* mimeType = g_content_type_guess(basename, NULL, 0, NULL);
if(mimeType && strcmp(mimeType, "image/gif") == 0) {
g_free(mimeType);
char *file_Name = fm_path_to_str(currentFile_);
QString fileName(file_Name);
g_free(file_Name);
char* mime_type = g_content_type_guess(basename, NULL, 0, NULL);
QString mimeType;
if (mime_type) {
mimeType = QString(mime_type);
g_free(mime_type);
}
if(mimeType == "image/gif"
|| mimeType == "image/svg+xml" || mimeType == "image/svg+xml-compressed") {
char *file_name = fm_path_to_str(currentFile_);
QString fileName(file_name);
g_free(file_name);
ui.view->setAutoZoomFit(true); // like in onImageLoaded()
ui.view->setGifAnimation(fileName);
if(mimeType == "image/gif")
ui.view->setGifAnimation(fileName);
else
ui.view->setSVG(fileName);
image_ = ui.view->image();
updateUI();
show();
}
else {
if(mimeType)
g_free(mimeType);
// start a new gio job to load the specified image
loadJob_ = new LoadImageJob(this, filePath);
loadJob_->start();
@ -633,55 +638,55 @@ void MainWindow::saveImage(FmPath* filePath) {
// FIXME: add a cancel button to the UI? update status bar?
}
QGraphicsItem* MainWindow::getGifItem() {
if(!ui.view->items().isEmpty()) {
QGraphicsItem *gifItem = ui.view->items().at(0);
if(gifItem->isWidget()) // we have gif animation
return gifItem;
}
return NULL;
QGraphicsItem* MainWindow::getGraphicsItem() {
if(!ui.view->items().isEmpty())
return ui.view->items().at(0);
return nullptr;
}
void MainWindow::on_actionRotateClockwise_triggered() {
QGraphicsItem *gifItem = getGifItem();
QGraphicsItem *graphItem = getGraphicsItem();
if(!image_.isNull()) {
QTransform transform;
transform.rotate(90.0);
image_ = image_.transformed(transform, Qt::SmoothTransformation);
/* when this is a gif animation, we need to rotate the first frame
/* when this is GIF or SVG, we need to rotate its corresponding QImage
without showing it to have the right measure for auto-zooming */
ui.view->setImage(image_, gifItem ? false : true);
ui.view->setImage(image_, graphItem->isWidget() // we have gif animation
|| static_cast<QGraphicsSvgItem*>(graphItem) // an SVG image
? false : true);
setModified(true);
}
if(gifItem) {
if(graphItem) {
QTransform transform;
transform.translate(gifItem->sceneBoundingRect().height(), 0);
transform.translate(graphItem->sceneBoundingRect().height(), 0);
transform.rotate(90);
// we need to apply transformations in the reverse order
QTransform prevTrans = gifItem->transform();
gifItem->setTransform(transform, false);
gifItem->setTransform(prevTrans, true);
QTransform prevTrans = graphItem->transform();
graphItem->setTransform(transform, false);
graphItem->setTransform(prevTrans, true);
}
}
void MainWindow::on_actionRotateCounterclockwise_triggered() {
QGraphicsItem *gifItem = getGifItem();
QGraphicsItem *graphItem = getGraphicsItem();
if(!image_.isNull()) {
QTransform transform;
transform.rotate(-90.0);
image_ = image_.transformed(transform, Qt::SmoothTransformation);
ui.view->setImage(image_, gifItem ? false : true);
ui.view->setImage(image_, graphItem->isWidget() || static_cast<QGraphicsSvgItem*>(graphItem)
? false : true);
setModified(true);
}
if(gifItem) {
if(graphItem) {
QTransform transform;
transform.translate(0, gifItem->sceneBoundingRect().width());
transform.translate(0, graphItem->sceneBoundingRect().width());
transform.rotate(-90);
QTransform prevTrans = gifItem->transform();
gifItem->setTransform(transform, false);
gifItem->setTransform(prevTrans, true);
QTransform prevTrans = graphItem->transform();
graphItem->setTransform(transform, false);
graphItem->setTransform(prevTrans, true);
}
}
@ -708,37 +713,37 @@ void MainWindow::on_actionPaste_triggered() {
}
void MainWindow::on_actionFlipVertical_triggered() {
if(QGraphicsItem *gifItem = getGifItem()) {
bool hasQGraphicsItem(false);
if(QGraphicsItem *graphItem = getGraphicsItem()) {
hasQGraphicsItem = true;
QTransform transform;
transform.scale(1, -1);
transform.translate(0, -gifItem->sceneBoundingRect().height());
QTransform prevTrans = gifItem->transform();
gifItem->setTransform(transform, false);
gifItem->setTransform(prevTrans, true);
setModified(true);
/* we don't need to flip the first frame because its position
and dimensions are the same as before while it isn't shown */
transform.translate(0, -graphItem->sceneBoundingRect().height());
QTransform prevTrans = graphItem->transform();
graphItem->setTransform(transform, false);
graphItem->setTransform(prevTrans, true);
}
else if(!image_.isNull()) {
if(!image_.isNull()) {
image_ = image_.mirrored(false, true);
ui.view->setImage(image_);
ui.view->setImage(image_, !hasQGraphicsItem);
setModified(true);
}
}
void MainWindow::on_actionFlipHorizontal_triggered() {
if(QGraphicsItem *gifItem = getGifItem()) {
bool hasQGraphicsItem(false);
if(QGraphicsItem *graphItem = getGraphicsItem()) {
hasQGraphicsItem = true;
QTransform transform;
transform.scale(-1, 1);
transform.translate(-gifItem->sceneBoundingRect().width(), 0);
QTransform prevTrans = gifItem->transform();
gifItem->setTransform(transform, false);
gifItem->setTransform(prevTrans, true);
setModified(true);
transform.translate(-graphItem->sceneBoundingRect().width(), 0);
QTransform prevTrans = graphItem->transform();
graphItem->setTransform(transform, false);
graphItem->setTransform(prevTrans, true);
}
else if(!image_.isNull()) {
image_ = image_.mirrored(true, false);
ui.view->setImage(image_);
if(!image_.isNull()) {
image_ = image_.mirrored(true, true);
ui.view->setImage(image_, !hasQGraphicsItem);
setModified(true);
}
}
@ -767,11 +772,9 @@ void MainWindow::on_actionPrint_triggered() {
QRect pageRect = printer.pageRect();
int cols = (image_.width() / pageRect.width()) + (image_.width() % pageRect.width() ? 1 : 0);
int rows = (image_.height() / pageRect.height()) + (image_.height() % pageRect.height() ? 1 : 0);
// qDebug() << "page:" << printer.pageRect() << "image:" << image_.size() << "cols, rows:" << cols << rows;
for(int row = 0; row < rows; ++row) {
for(int col = 0; col < cols; ++col) {
QRect srcRect(pageRect.width() * col, pageRect.height() * row, pageRect.width(), pageRect.height());
// qDebug() << "row:" << row << "col:" << col << "src:" << srcRect << "page:" << printer.pageRect();
painter.drawImage(QPoint(0, 0), image_, srcRect);
if(col + 1 == cols && row + 1 == rows) // this is the last page
break;
@ -795,7 +798,7 @@ void MainWindow::on_actionSlideShow_triggered(bool checked) {
if(!slideShowTimer_) {
slideShowTimer_ = new QTimer();
// switch to the next image when timeout
connect(slideShowTimer_, SIGNAL(timeout()), SLOT(on_actionNext_triggered()));
connect(slideShowTimer_, &QTimer::timeout, this, &MainWindow::on_actionNext_triggered);
}
Application* app = static_cast<Application*>(qApp);
slideShowTimer_->start(app->settings().slideShowInterval() * 1000);
@ -805,7 +808,7 @@ void MainWindow::on_actionSlideShow_triggered(bool checked) {
else {
if(slideShowTimer_) {
delete slideShowTimer_;
slideShowTimer_ = NULL;
slideShowTimer_ = nullptr;
ui.actionSlideShow->setIcon(QIcon::fromTheme("media-playback-start"));
}
}
@ -838,15 +841,16 @@ void MainWindow::setShowThumbnails(bool show) {
QCoreApplication::processEvents();
listView->scrollTo(currentIndex_, QAbstractItemView::PositionAtCenter);
}
connect(thumbnailsView_->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(onThumbnailSelChanged(QItemSelection,QItemSelection)));
connect(thumbnailsView_->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MainWindow::onThumbnailSelChanged);
}
}
else {
if(thumbnailsDock_) {
delete thumbnailsView_;
thumbnailsView_ = NULL;
thumbnailsView_ = nullptr;
delete thumbnailsDock_;
thumbnailsDock_ = NULL;
thumbnailsDock_ = nullptr;
}
proxyModel_->setShowThumbnails(false);
}
@ -876,6 +880,7 @@ void MainWindow::changeEvent(QEvent* event) {
addAction(action);
}
addActions(ui.menubar->actions());
ui.view->hideCursor(true);
}
else { // restore to normal window mode
ui.view->setFrameStyle(QFrame::StyledPanel|QFrame::Sunken);
@ -890,6 +895,7 @@ void MainWindow::changeEvent(QEvent* event) {
ui.statusBar->show();
if(thumbnailsDock_)
thumbnailsDock_->show();
ui.view->hideCursor(false);
}
}
QWidget::changeEvent(event);

@ -126,7 +126,7 @@ private:
void updateUI();
void setModified(bool modified);
QModelIndex indexFromPath(FmPath* filePath);
QGraphicsItem* getGifItem();
QGraphicsItem* getGraphicsItem();
// GObject related signal handers and callbacks
static void _onFolderLoaded(FmFolder* folder, MainWindow* _this) {

@ -221,7 +221,7 @@
<string>Zoom &amp;In</string>
</property>
<property name="shortcut">
<string>Ctrl++</string>
<string>Ctrl+=</string>
</property>
</action>
<action name="actionZoomOut">
@ -288,6 +288,9 @@
<property name="text">
<string>Original Size</string>
</property>
<property name="shortcut">
<string>Ctrl+0</string>
</property>
</action>
<action name="actionZoomFit">
<property name="icon">

@ -96,8 +96,6 @@ static void findIconThemesInDir(QHash<QString, QString>& iconThemes, QString dir
}
void PreferencesDialog::initIconThemes(Settings& settings) {
Application* app = static_cast<Application*>(qApp);
// check if auto-detection is done (for example, from xsettings)
if(settings.useFallbackIconTheme()) { // auto-detection failed
// load xdg icon themes and select the current one

@ -28,8 +28,8 @@ using namespace LxImage;
SaveImageJob::SaveImageJob(MainWindow* window, FmPath* filePath):
Job(),
path_(fm_path_ref(filePath)),
mainWindow_(window),
path_(fm_path_ref(filePath)),
image_(window->image()) {
}

@ -25,6 +25,7 @@
#include <QPainter>
#include "application.h"
#include <QDesktopWidget>
#include <QScreen>
#include <QX11Info>
#include <X11/Xlib.h>
@ -83,7 +84,7 @@ QRect ScreenshotDialog::windowFrame(WId wid) {
int x, y;
// translate to root coordinate
XTranslateCoordinates(QX11Info::display(), wid, wa.root, 0, 0, &x, &y, &child);
qDebug("%d, %d, %d, %d", x, y, wa.width, wa.height);
//qDebug("%d, %d, %d, %d", x, y, wa.width, wa.height);
result.setRect(x, y, wa.width, wa.height);
// get the frame widths added by the window manager
@ -140,38 +141,42 @@ void ScreenshotDialog::doScreenshot() {
}
}
QPixmap pixmap;
pixmap = QPixmap::grabWindow(wid, x, y, width, height);
QImage image = pixmap.toImage();
if(hasXfixes_ && ui.includeCursor->isChecked()) {
// capture the cursor if needed
XFixesCursorImage* cursor = XFixesGetCursorImage(QX11Info::display());
if(cursor) {
if(cursor->pixels) { // pixles should be an ARGB array
QImage cursorImage;
if(sizeof(long) == 4) {
// FIXME: will we encounter byte-order problems here?
cursorImage = QImage((uchar*)cursor->pixels, cursor->width, cursor->height, QImage::Format_ARGB32);
QImage image;
QScreen *screen = QGuiApplication::primaryScreen();
if(screen) {
QPixmap pixmap = screen->grabWindow(wid, x, y, width, height);
image = pixmap.toImage();
if(hasXfixes_ && ui.includeCursor->isChecked()) {
// capture the cursor if needed
XFixesCursorImage* cursor = XFixesGetCursorImage(QX11Info::display());
if(cursor) {
if(cursor->pixels) { // pixles should be an ARGB array
QImage cursorImage;
if(sizeof(long) == 4) {
// FIXME: will we encounter byte-order problems here?
cursorImage = QImage((uchar*)cursor->pixels, cursor->width, cursor->height, QImage::Format_ARGB32);
}
else { // XFixes returns long integers which is not 32 bit on 64 bit systems.
long len = cursor->width * cursor->height;
quint32* buf = new quint32[len];
for(long i = 0; i < len; ++i)
buf[i] = (quint32)cursor->pixels[i];
cursorImage = QImage((uchar*)buf, cursor->width, cursor->height, QImage::Format_ARGB32, [](void* b) { delete[] (quint32*)b; }, buf);
}
// paint the cursor on the current image
QPainter painter(&image);
painter.drawImage(cursor->x - cursor->xhot, cursor->y - cursor->yhot, cursorImage);
}
else { // XFixes returns long integers which is not 32 bit on 64 bit systems.
long len = cursor->width * cursor->height;
quint32* buf = new quint32[len];
for(long i = 0; i < len; ++i)
buf[i] = (quint32)cursor->pixels[i];
cursorImage = QImage((uchar*)buf, cursor->width, cursor->height, QImage::Format_ARGB32, [](void* b) { delete[] (quint32*)b; }, buf);
}
// paint the cursor on the current image
QPainter painter(&image);
painter.drawImage(cursor->x - cursor->xhot, cursor->y - cursor->yhot, cursorImage);
XFree(cursor);
}
XFree(cursor);
}
}
Application* app = static_cast<Application*>(qApp);
MainWindow* window = app->createWindow();
window->pasteImage(image);
if(!image.isNull())
window->pasteImage(image);
window->show();
deleteLater(); // destroy ourself

@ -27,11 +27,11 @@ using namespace LxImage;
Settings::Settings():
useFallbackIconTheme_(QIcon::themeName().isEmpty() || QIcon::themeName() == "hicolor"),
bgColor_(255, 255, 255),
fullScreenBgColor_(0, 0, 0),
showThumbnails_(false),
showSidePane_(false),
fullScreenBgColor_(0, 0, 0),
fallbackIconTheme_("oxygen"),
slideShowInterval_(5),
fallbackIconTheme_("oxygen"),
fixedWindowWidth_(640),
fixedWindowHeight_(480),
lastWindowWidth_(640),
@ -49,7 +49,7 @@ bool Settings::load() {
fullScreenBgColor_ = settings.value("fullScreenBgColor", fullScreenBgColor_).value<QColor>();
// showThumbnails_;
// showSidePane_;
int slideShowInterval_ = settings.value("slideShowInterval", slideShowInterval_).toInt();
slideShowInterval_ = settings.value("slideShowInterval", slideShowInterval_).toInt();
settings.beginGroup("Window");
fixedWindowWidth_ = settings.value("FixedWidth", 640).toInt();

@ -0,0 +1,4 @@
#Translations
Name[ca]=Captura de pantalla
GenericName[ca]=Captura de pantalla
Comment[ca]=Preneu una captura de pantalla

@ -0,0 +1,4 @@
#Translations
Name[ca]=LXImage
GenericName[ca]=Visualitzador d'imatges
Comment[ca]=El visualitzador d'imatges de LXQt
Loading…
Cancel
Save