diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 48a8685f..6ca16442 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,199 +1,197 @@ project(gwenviewlib) # Extract version of libjpeg so that we can use the appropriate dir # See bug #227313 file(READ "${JPEG_INCLUDE_DIR}/jpeglib.h" jpeglib_h_content) string(REGEX MATCH "#define +JPEG_LIB_VERSION +([0-9]+)" "\\1" jpeglib_version "${jpeglib_h_content}") set(jpeglib_version ${CMAKE_MATCH_1}) if ("${jpeglib_version}" STREQUAL "") # libjpeg-turbo keeps JPEG_LIB_VERSION in jconfig.h, not jpeglib.h :/ file(READ "${JPEG_INCLUDE_DIR}/jconfig.h" jconfig_h_content) string(REGEX MATCH "#define +JPEG_LIB_VERSION +([0-9]+)" "\\1" jpeglib_version "${jconfig_h_content}") set(jpeglib_version ${CMAKE_MATCH_1}) endif ("${jpeglib_version}" STREQUAL "") if ("${jpeglib_version}" LESS 80) set(GV_JPEG_DIR libjpeg-62) endif ("${jpeglib_version}" LESS 80) if ("${jpeglib_version}" EQUAL 80) set(GV_JPEG_DIR libjpeg-80) endif ("${jpeglib_version}" EQUAL 80) if ("${GV_JPEG_DIR}" STREQUAL "") message(FATAL_ERROR "Unknown libjpeg version: ${jpeglib_version}") endif ("${GV_JPEG_DIR}" STREQUAL "") message(STATUS "libjpeg version: ${jpeglib_version}") add_definitions(-Dlibjpeg_EXPORTS) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/${GV_JPEG_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR} ${SOPRANO_INCLUDE_DIR} ${EXIV2_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ) # For config-gwenview.h include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ) set(gwenviewlib_SRCS crop/cropwidget.cpp crop/cropimageoperation.cpp crop/croptool.cpp document/abstractdocumentimpl.cpp document/documentjob.cpp document/animateddocumentloadedimpl.cpp document/document.cpp document/documentfactory.cpp document/documentloadedimpl.cpp document/emptydocumentimpl.cpp document/jpegdocumentloadedimpl.cpp document/loadingdocumentimpl.cpp document/loadingjob.cpp document/savejob.cpp document/svgdocumentloadedimpl.cpp document/videodocumentloadedimpl.cpp documentview/abstractdocumentviewadapter.cpp documentview/abstractimageview.cpp documentview/abstractrasterimageviewtool.cpp documentview/documentview.cpp documentview/documentviewcontroller.cpp documentview/documentviewsynchronizer.cpp documentview/messageviewadapter.cpp documentview/imageviewadapter.cpp documentview/rasterimageview.cpp documentview/svgviewadapter.cpp documentview/videoviewadapter.cpp abstractimageoperation.cpp - abstractimageviewtool.cpp documentview/documentviewcontainer.cpp binder.cpp eventwatcher.cpp splittercollapser.cpp historymodel.cpp archiveutils.cpp datewidget.cpp exiv2imageloader.cpp flowlayout.cpp fullscreenbar.cpp fullscreentheme.cpp graphicshudwidget.cpp graphicswidgetfloater.cpp hudwidget.cpp imageformats/imageformats.cpp imageformats/jpegplugin.cpp imageformats/jpeghandler.cpp imagemetainfomodel.cpp imagescaler.cpp imageutils.cpp - imageview.cpp invisiblebuttongroup.cpp iodevicejpegsourcemanager.cpp jpegcontent.cpp semanticinfo/sorteddirmodel.cpp memoryutils.cpp messagebubble.cpp mimetypeutils.cpp paintutils.cpp placetreemodel.cpp preferredimagemetainfomodel.cpp print/printhelper.cpp print/printoptionspage.cpp slidecontainer.cpp slideshow.cpp statusbartoolbutton.cpp redeyereduction/redeyereductionimageoperation.cpp redeyereduction/redeyereductiontool.cpp resize/resizeimageoperation.cpp resize/resizeimagedialog.cpp thumbnailloadjob.cpp thumbnailview/abstractthumbnailviewhelper.cpp thumbnailview/abstractdocumentinfoprovider.cpp thumbnailview/contextbarbutton.cpp thumbnailview/itemeditor.cpp thumbnailview/previewitemdelegate.cpp thumbnailview/thumbnailbarview.cpp thumbnailview/thumbnailslider.cpp thumbnailview/thumbnailview.cpp thumbnailview/tooltipwidget.cpp timeutils.cpp transformimageoperation.cpp urlutils.cpp widgetfloater.cpp zoomslider.cpp zoomwidget.cpp ${GV_JPEG_DIR}/transupp.c ) if (NOT GWENVIEW_SEMANTICINFO_BACKEND_NONE) set(gwenviewlib_SRCS ${gwenviewlib_SRCS} semanticinfo/abstractsemanticinfobackend.cpp semanticinfo/semanticinfodirmodel.cpp semanticinfo/tagitemdelegate.cpp semanticinfo/tagmodel.cpp semanticinfo/tagwidget.cpp ) endif (NOT GWENVIEW_SEMANTICINFO_BACKEND_NONE) if (GWENVIEW_SEMANTICINFO_BACKEND_FAKE) set(gwenviewlib_SRCS ${gwenviewlib_SRCS} semanticinfo/fakesemanticinfobackend.cpp ) endif (GWENVIEW_SEMANTICINFO_BACKEND_FAKE) if (GWENVIEW_SEMANTICINFO_BACKEND_NEPOMUK) set(gwenviewlib_SRCS ${gwenviewlib_SRCS} semanticinfo/nepomuksemanticinfobackend.cpp ) endif (GWENVIEW_SEMANTICINFO_BACKEND_NEPOMUK) set_source_files_properties( exiv2imageloader.cpp PROPERTIES COMPILE_FLAGS "${KDE4_ENABLE_EXCEPTIONS}" ) kde4_add_ui_files(gwenviewlib_SRCS crop/cropwidget.ui documentview/messageview.ui print/printoptionspage.ui redeyereduction/redeyereductionhud.ui resize/resizeimagewidget.ui ) kde4_add_kcfg_files(gwenviewlib_SRCS gwenviewconfig.kcfgc ) kde4_add_library(gwenviewlib SHARED ${gwenviewlib_SRCS}) set_target_properties(gwenviewlib PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) if(WIN32) set_target_properties( gwenviewlib PROPERTIES COMPILE_FLAGS -DJPEG_STATIC ) endif(WIN32) target_link_libraries(gwenviewlib ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBS} ${JPEG_LIBRARY} ${EXIV2_LIBRARIES} ${QT_QTOPENGL_LIBRARY} ) if( WIN32 ) target_link_libraries( gwenviewlib ${EXPAT_LIBRARIES} ) endif( WIN32 ) if (NOT GWENVIEW_SEMANTICINFO_BACKEND_NONE) target_link_libraries(gwenviewlib ${NEPOMUK_LIBRARIES} ${SOPRANO_LIBRARIES} ) endif (NOT GWENVIEW_SEMANTICINFO_BACKEND_NONE) install(TARGETS gwenviewlib ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/lib/abstractimageviewtool.cpp b/lib/abstractimageviewtool.cpp deleted file mode 100644 index 7c3e9de7..00000000 --- a/lib/abstractimageviewtool.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// vim: set tabstop=4 shiftwidth=4 noexpandtab: -/* -Gwenview: an image viewer -Copyright 2007 Aurélien Gâteau - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -// Self -#include "abstractimageviewtool.h" - -// Qt - -// KDE - -// Local -#include "imageview.h" - -namespace Gwenview { - - -struct AbstractImageViewToolPrivate { - ImageView* mImageView; -}; - - -AbstractImageViewTool::AbstractImageViewTool(ImageView* view) -: QObject(view) -, d(new AbstractImageViewToolPrivate) { - d->mImageView = view; -} - - -AbstractImageViewTool::~AbstractImageViewTool() { - delete d; -} - - -ImageView* AbstractImageViewTool::imageView() const { - return d->mImageView; -} - - -} // namespace diff --git a/lib/abstractimageviewtool.h b/lib/abstractimageviewtool.h deleted file mode 100644 index 01c0c8c3..00000000 --- a/lib/abstractimageviewtool.h +++ /dev/null @@ -1,69 +0,0 @@ -// vim: set tabstop=4 shiftwidth=4 noexpandtab: -/* -Gwenview: an image viewer -Copyright 2007 Aurélien Gâteau - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -#ifndef ABSTRACTIMAGEVIEWTOOL_H -#define ABSTRACTIMAGEVIEWTOOL_H - -#include - -// Qt -#include - -// KDE - -// Local - -class QKeyEvent; -class QMouseEvent; -class QWheelEvent; -class QPainter; - -namespace Gwenview { - -class ImageView; - -struct AbstractImageViewToolPrivate; -class GWENVIEWLIB_EXPORT AbstractImageViewTool : public QObject { -public: - AbstractImageViewTool(ImageView* view); - virtual ~AbstractImageViewTool(); - - ImageView* imageView() const; - - virtual void paint(QPainter*) {} - - virtual void mousePressEvent(QMouseEvent*) {} - virtual void mouseMoveEvent(QMouseEvent*) {} - virtual void mouseReleaseEvent(QMouseEvent*) {} - virtual void wheelEvent(QWheelEvent*) {} - virtual void keyPressEvent(QKeyEvent*) {} - virtual void keyReleaseEvent(QKeyEvent*) {} - - virtual void toolActivated() {} - virtual void toolDeactivated() {} - -private: - AbstractImageViewToolPrivate * const d; -}; - - -} // namespace - -#endif /* ABSTRACTIMAGEVIEWTOOL_H */ diff --git a/lib/crop/croptool.cpp b/lib/crop/croptool.cpp index 21a13c59..dbc09d19 100644 --- a/lib/crop/croptool.cpp +++ b/lib/crop/croptool.cpp @@ -1,419 +1,418 @@ // vim: set tabstop=4 shiftwidth=4 noexpandtab: /* Gwenview: an image viewer Copyright 2007 Aurélien Gâteau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Self #include "croptool.moc" // Qt #include #include #include #include #include #include #include #include #include #include // KDE #include #include // Local #include #include "cropimageoperation.h" #include "cropwidget.h" -#include "imageview.h" static const int HANDLE_SIZE = 15; namespace Gwenview { enum CropHandleFlag { CH_None, CH_Top = 1, CH_Left = 2, CH_Right = 4, CH_Bottom = 8, CH_TopLeft = CH_Top | CH_Left, CH_BottomLeft = CH_Bottom | CH_Left, CH_TopRight = CH_Top | CH_Right, CH_BottomRight = CH_Bottom | CH_Right, CH_Content = 16 }; Q_DECLARE_FLAGS(CropHandle, CropHandleFlag) } // namespace inline QPoint boundPointX(const QPoint& point, const QRect& rect) { return QPoint( qBound(rect.left(), point.x(), rect.right()), point.y() ); } inline QPoint boundPointXY(const QPoint& point, const QRect& rect) { return QPoint( qBound(rect.left(), point.x(), rect.right()), qBound(rect.top(), point.y(), rect.bottom()) ); } Q_DECLARE_OPERATORS_FOR_FLAGS(Gwenview::CropHandle) namespace Gwenview { struct CropToolPrivate { CropTool* mCropTool; QRect mRect; QList mCropHandleList; CropHandle mMovingHandle; QPoint mLastMouseMovePos; double mCropRatio; CropWidget* mCropWidget; QRect viewportCropRect() const { return mCropTool->imageView()->mapToView(mRect.adjusted(0, 0, 1, 1)); } QRect handleViewportRect(CropHandle handle) { QSize viewportSize = mCropTool->imageView()->size().toSize(); QRect rect = viewportCropRect(); int left, top; if (handle & CH_Top) { top = rect.top(); } else if (handle & CH_Bottom) { top = rect.bottom() - HANDLE_SIZE; } else { top = rect.top() + (rect.height() - HANDLE_SIZE) / 2; top = qBound(0, top, viewportSize.height() - HANDLE_SIZE); } if (handle & CH_Left) { left = rect.left(); } else if (handle & CH_Right) { left = rect.right() - HANDLE_SIZE; } else { left = rect.left() + (rect.width() - HANDLE_SIZE) / 2; left = qBound(0, left, viewportSize.width() - HANDLE_SIZE); } return QRect(left, top, HANDLE_SIZE, HANDLE_SIZE); } CropHandle handleAt(const QPointF& pos) { Q_FOREACH(const CropHandle& handle, mCropHandleList) { QRectF rect = handleViewportRect(handle); if (rect.contains(pos)) { return handle; } } QRectF rect = viewportCropRect(); if (rect.contains(pos)) { return CH_Content; } return CH_None; } void updateCursor(CropHandle handle, bool buttonDown) { Qt::CursorShape shape; switch (handle) { case CH_TopLeft: case CH_BottomRight: shape = Qt::SizeFDiagCursor; break; case CH_TopRight: case CH_BottomLeft: shape = Qt::SizeBDiagCursor; break; case CH_Left: case CH_Right: shape = Qt::SizeHorCursor; break; case CH_Top: case CH_Bottom: shape = Qt::SizeVerCursor; break; case CH_Content: shape = buttonDown ? Qt::ClosedHandCursor : Qt::OpenHandCursor; break; default: shape = Qt::ArrowCursor; break; } mCropTool->imageView()->setCursor(shape); } void keepRectInsideImage() { const QSize imageSize = mCropTool->imageView()->documentSize().toSize(); if (mRect.width() > imageSize.width() || mRect.height() > imageSize.height()) { // This can happen when the crop ratio changes QSize rectSize = mRect.size(); rectSize.scale(imageSize, Qt::KeepAspectRatio); mRect.setSize(rectSize); } if (mRect.right() >= imageSize.width()) { mRect.moveRight(imageSize.width() - 1); } else if (mRect.left() < 0) { mRect.moveLeft(0); } if (mRect.bottom() >= imageSize.height()) { mRect.moveBottom(imageSize.height() - 1); } else if (mRect.top() < 0) { mRect.moveTop(0); } } void setupWidget() { RasterImageView* view = mCropTool->imageView(); mCropWidget = new CropWidget(0, view, mCropTool); QObject::connect(mCropWidget, SIGNAL(cropRequested()), mCropTool, SLOT(slotCropRequested())); QObject::connect(mCropWidget, SIGNAL(done()), mCropTool, SIGNAL(done())); } void connectToView() { RasterImageView* view = mCropTool->imageView(); QObject::connect(view, SIGNAL(zoomChanged(qreal)), mCropTool, SLOT(updateHudWidgetPosition())); QObject::connect(view, SIGNAL(scrollPosChanged()), mCropTool, SLOT(updateHudWidgetPosition())); // FIXME: QGV /* // rangeChanged() is emitted when the view is resized QObject::connect(view->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)), mCropTool, SLOT(updateHudWidgetPosition())); QObject::connect(view->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), mCropTool, SLOT(updateHudWidgetPosition())); */ } }; CropTool::CropTool(RasterImageView* view) : AbstractRasterImageViewTool(view) , d(new CropToolPrivate) { d->mCropTool = this; d->mCropHandleList << CH_Left << CH_Right << CH_Top << CH_Bottom << CH_TopLeft << CH_TopRight << CH_BottomLeft << CH_BottomRight; d->mMovingHandle = CH_None; const QRect imageRect = QRect(QPoint(0, 0), view->documentSize().toSize()); const QRect viewportRect = view->mapToImage(view->rect().toRect()); d->mRect = imageRect & viewportRect; d->mCropRatio = 0.; d->setupWidget(); } CropTool::~CropTool() { delete d; } void CropTool::setCropRatio(double ratio) { d->mCropRatio = ratio; } void CropTool::setRect(const QRect& rect) { d->mRect = rect; d->keepRectInsideImage(); if (d->mRect != rect) { rectUpdated(d->mRect); } imageView()->update(); } QRect CropTool::rect() const { return d->mRect; } void CropTool::paint(QPainter* painter) { QRect rect = d->viewportCropRect(); QRect imageRect = imageView()->rect().toRect(); static const QColor outerColor = QColor::fromHsvF(0, 0, 0, 0.5); // For some reason nothing gets drawn if borderColor is not fully opaque! //static const QColor borderColor = QColor::fromHsvF(0, 0, 1.0, 0.66); static const QColor borderColor = QColor::fromHsvF(0, 0, 1.0); static const QColor fillColor = QColor::fromHsvF(0, 0, 0.75, 0.66); QRegion outerRegion = QRegion(imageRect) - QRegion(rect); Q_FOREACH(const QRect& outerRect, outerRegion.rects()) { painter->fillRect(outerRect, outerColor); } painter->setPen(borderColor); rect.adjust(0, 0, -1, -1); painter->drawRect(rect); if (d->mMovingHandle == CH_None) { // Only draw handles when user is not resizing painter->setBrush(fillColor); Q_FOREACH(const CropHandle& handle, d->mCropHandleList) { rect = d->handleViewportRect(handle); painter->drawRect(rect); } } } void CropTool::mousePressEvent(QGraphicsSceneMouseEvent* event) { event->accept(); if (event->buttons() != Qt::LeftButton) { return; } d->mMovingHandle = d->handleAt(event->pos()); d->updateCursor(d->mMovingHandle, true /* down */); if (d->mMovingHandle == CH_Content) { d->mLastMouseMovePos = imageView()->mapToImage(event->pos().toPoint()); } // Update to hide handles imageView()->update(); } void CropTool::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { event->accept(); if (event->buttons() != Qt::LeftButton) { return; } const QSize imageSize = imageView()->document()->size(); QPoint point = imageView()->mapToImage(event->pos().toPoint()); int posX = qBound(0, point.x(), imageSize.width() - 1); int posY = qBound(0, point.y(), imageSize.height() - 1); if (d->mMovingHandle == CH_None) { return; } // Adjust edge if (d->mMovingHandle & CH_Top) { d->mRect.setTop(posY); } else if (d->mMovingHandle & CH_Bottom) { d->mRect.setBottom(posY); } if (d->mMovingHandle & CH_Left) { d->mRect.setLeft(posX); } else if (d->mMovingHandle & CH_Right) { d->mRect.setRight(posX); } // Normalize rect and handles (this is useful when user drag the right side // of the crop rect to the left of the left side) if (d->mRect.height() < 0) { d->mMovingHandle = d->mMovingHandle ^ (CH_Top | CH_Bottom); } if (d->mRect.width() < 0) { d->mMovingHandle = d->mMovingHandle ^ (CH_Left | CH_Right); } d->mRect = d->mRect.normalized(); // Enforce ratio if (d->mCropRatio > 0.) { if (d->mMovingHandle == CH_Top || d->mMovingHandle == CH_Bottom) { // Top or bottom int width = int(d->mRect.height() / d->mCropRatio); d->mRect.setWidth(width); } else if (d->mMovingHandle == CH_Left || d->mMovingHandle == CH_Right) { // Left or right int height = int(d->mRect.width() * d->mCropRatio); d->mRect.setHeight(height); } else if (d->mMovingHandle & CH_Top) { // Top left or top right int height = int(d->mRect.width() * d->mCropRatio); d->mRect.setTop(d->mRect.bottom() - height); } else if (d->mMovingHandle & CH_Bottom) { // Bottom left or bottom right int height = int(d->mRect.width() * d->mCropRatio); d->mRect.setHeight(height); } } if (d->mMovingHandle == CH_Content) { d->mRect.translate(point - d->mLastMouseMovePos); d->mLastMouseMovePos = point; } d->keepRectInsideImage(); imageView()->update(); rectUpdated(d->mRect); } void CropTool::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { event->accept(); d->mMovingHandle = CH_None; d->updateCursor(d->handleAt(event->lastPos()), false); // Update to show handles imageView()->update(); } void CropTool::hoverMoveEvent(QGraphicsSceneHoverEvent* event) { event->accept(); // Make sure cursor is updated when moving over handles CropHandle handle = d->handleAt(event->lastPos()); d->updateCursor(handle, false /* buttonDown */); } void CropTool::toolActivated() { imageView()->setCursor(Qt::CrossCursor); } void CropTool::toolDeactivated() { //delete d->mHudWidget; } void CropTool::slotCropRequested() { CropImageOperation* op = new CropImageOperation(d->mRect); emit imageOperationRequested(op); emit done(); } QWidget* CropTool::widget() { return d->mCropWidget; } } // namespace diff --git a/lib/documentview/imageviewadapter.cpp b/lib/documentview/imageviewadapter.cpp index 85699003..a3d45a45 100644 --- a/lib/documentview/imageviewadapter.cpp +++ b/lib/documentview/imageviewadapter.cpp @@ -1,121 +1,120 @@ // vim: set tabstop=4 shiftwidth=4 noexpandtab: /* Gwenview: an image viewer Copyright 2008 Aurélien Gâteau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. */ // Self #include "imageviewadapter.moc" // Local -#include -#include #include #include +#include // KDE #include // Qt namespace Gwenview { //// ImageViewAdapter //// struct ImageViewAdapterPrivate { ImageViewAdapter* that; RasterImageView* mView; }; ImageViewAdapter::ImageViewAdapter() : d(new ImageViewAdapterPrivate) { d->that = this; d->mView = new RasterImageView; connect(d->mView, SIGNAL(zoomChanged(qreal)), SIGNAL(zoomChanged(qreal)) ); connect(d->mView, SIGNAL(zoomToFitChanged(bool)), SIGNAL(zoomToFitChanged(bool)) ); setWidget(d->mView); } ImageViewAdapter::~ImageViewAdapter() { delete d; } QCursor ImageViewAdapter::cursor() const { return d->mView->cursor(); } void ImageViewAdapter::setCursor(const QCursor& cursor) { d->mView->setCursor(cursor); } void ImageViewAdapter::setDocument(Document::Ptr doc) { d->mView->setDocument(doc); connect(doc.data(), SIGNAL(loadingFailed(KUrl)), SLOT(slotLoadingFailed()) ); if (doc->loadingState() == Document::LoadingFailed) { slotLoadingFailed(); } } qreal ImageViewAdapter::zoom() const { return d->mView->zoom(); } void ImageViewAdapter::setZoomToFit(bool on) { d->mView->setZoomToFit(on); } bool ImageViewAdapter::zoomToFit() const { return d->mView->zoomToFit(); } void ImageViewAdapter::setZoom(qreal zoom, const QPointF& center) { d->mView->setZoom(zoom, center); } qreal ImageViewAdapter::computeZoomToFit() const { return d->mView->computeZoomToFit(); } Document::Ptr ImageViewAdapter::document() const { return d->mView->document(); } void ImageViewAdapter::slotLoadingFailed() { d->mView->setDocument(Document::Ptr()); } void ImageViewAdapter::loadConfig() { d->mView->setAlphaBackgroundMode(GwenviewConfig::alphaBackgroundMode()); d->mView->setAlphaBackgroundColor(GwenviewConfig::alphaBackgroundColor()); d->mView->setEnlargeSmallerImages(GwenviewConfig::enlargeSmallerImages()); } RasterImageView* ImageViewAdapter::rasterImageView() const { return d->mView; } } // namespace diff --git a/lib/imageview.cpp b/lib/imageview.cpp deleted file mode 100644 index c352f2ec..00000000 --- a/lib/imageview.cpp +++ /dev/null @@ -1,793 +0,0 @@ -/* -Gwenview: an image viewer -Copyright 2007 Aurélien Gâteau - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -#include "imageview.moc" - -// Qt -#include -#include -#include -#include -#include -#include - -// KDE -#include - -// Local -#include "abstractimageviewtool.h" -#include "imagescaler.h" - - -namespace Gwenview { - -#undef ENABLE_LOG -#undef LOG -//#define ENABLE_LOG -#ifdef ENABLE_LOG -#define LOG(x) kDebug() << x -#else -#define LOG(x) ; -#endif - -struct ImageViewPrivate { - ImageView* mView; - QPixmap mBackgroundTexture; - QWidget* mViewport; - QTimer* mZoomToFitUpdateTimer; - ImageView::AlphaBackgroundMode mAlphaBackgroundMode; - QColor mAlphaBackgroundColor; - bool mEnlargeSmallerImages; - Document::Ptr mDocument; - qreal mZoom; - bool mZoomToFit; - QPixmap mCurrentBuffer; - QPixmap mAlternateBuffer; - ImageScaler* mScaler; - QPointer mTool; - QPointer mDefaultTool; - bool mInsideSetZoom; - - void setupZoomToFitUpdateTimer() { - mZoomToFitUpdateTimer = new QTimer(mView); - mZoomToFitUpdateTimer->setInterval(500); - mZoomToFitUpdateTimer->setSingleShot(true); - QObject::connect(mZoomToFitUpdateTimer, SIGNAL(timeout()), - mView, SLOT(updateZoomToFit())); - } - - void createBackgroundTexture() { - mBackgroundTexture = QPixmap(32, 32); - QPainter painter(&mBackgroundTexture); - painter.fillRect(mBackgroundTexture.rect(), QColor(128, 128, 128)); - QColor light = QColor(192, 192, 192); - painter.fillRect(0, 0, 16, 16, light); - painter.fillRect(16, 16, 16, 16, light); - } - - - QSize visibleImageSize() const { - if (!mDocument) { - return QSize(); - } - QSize size; - qreal zoom; - if (mZoomToFit) { - zoom = mView->computeZoomToFit(); - } else { - zoom = mZoom; - } - - size = mDocument->size() * zoom; - size = size.boundedTo(mViewport->size()); - - return size; - } - - - void drawAlphaBackground(QPainter* painter, const QRect& viewportRect, const QPoint& zoomedImageTopLeft) { - if (mAlphaBackgroundMode == ImageView::AlphaBackgroundCheckBoard) { - QPoint textureOffset( - zoomedImageTopLeft.x() % mBackgroundTexture.width(), - zoomedImageTopLeft.y() % mBackgroundTexture.height() - ); - painter->drawTiledPixmap( - viewportRect, - mBackgroundTexture, - textureOffset); - } else { - painter->fillRect(viewportRect, mAlphaBackgroundColor); - } - } - - void createBuffer() { - QSize size = visibleImageSize(); - if (size == mCurrentBuffer.size()) { - return; - } - if (!size.isValid()) { - mAlternateBuffer = QPixmap(); - mCurrentBuffer = QPixmap(); - return; - } - - mAlternateBuffer = QPixmap(size); - mAlternateBuffer.fill(Qt::transparent); - { - QPainter painter(&mAlternateBuffer); - painter.drawPixmap(0, 0, mCurrentBuffer); - } - qSwap(mAlternateBuffer, mCurrentBuffer); - - mAlternateBuffer = QPixmap(); - } - - - int hScroll() const { - if (mZoomToFit) { - return 0; - } else { - return mView->horizontalScrollBar()->value(); - } - } - - int vScroll() const { - if (mZoomToFit) { - return 0; - } else { - return mView->verticalScrollBar()->value(); - } - } - - QRect mapViewportToZoomedImage(const QRect& viewportRect) { - QPoint offset = mView->imageOffset(); - QRect rect = QRect( - viewportRect.x() + hScroll() - offset.x(), - viewportRect.y() + vScroll() - offset.y(), - viewportRect.width(), - viewportRect.height() - ); - - return rect; - } - - - void setScalerRegionToVisibleRect() { - QRect rect = mapViewportToZoomedImage(mViewport->rect()); - mScaler->setDestinationRegion(QRegion(rect)); - } - - - void forceBufferRecreation() { - mCurrentBuffer = QPixmap(); - createBuffer(); - setScalerRegionToVisibleRect(); - } - - - void startAnimationIfNecessary() { - if (mDocument && mView->isVisible()) { - mDocument->startAnimation(); - } - } - - - // At least gcc 3.4.6 on FreeBSD requires a default constructor. - ImageViewPrivate() { } -}; - - -ImageView::ImageView(QWidget* parent) -: QAbstractScrollArea(parent) -, d(new ImageViewPrivate) -{ - setAttribute(Qt::WA_NoSystemBackground); - - d->mAlphaBackgroundMode = AlphaBackgroundCheckBoard; - d->mAlphaBackgroundColor = Qt::black; - - d->mView = this; - d->mZoom = 1.; - d->mZoomToFit = true; - d->createBackgroundTexture(); - setFrameShape(QFrame::NoFrame); - //setBackgroundRole(QPalette::Base); - d->mViewport = new QWidget(); - d->mViewport->setAttribute(Qt::WA_NoSystemBackground); - setViewport(d->mViewport); - d->mViewport->setMouseTracking(true); - horizontalScrollBar()->setSingleStep(16); - verticalScrollBar()->setSingleStep(16); - d->mScaler = new ImageScaler(this); - d->mInsideSetZoom = false; - - d->setupZoomToFitUpdateTimer(); - - if (QApplication::isRightToLeft()) { - // Ensure we don't get weird behavior in RightToleft mode - // See bug #210058 - horizontalScrollBar()->setLayoutDirection(Qt::LeftToRight); - } - connect(d->mScaler, SIGNAL(scaledRect(int,int,QImage)), - SLOT(updateFromScaler(int,int,QImage)) ); -} - -ImageView::~ImageView() { - delete d; -} - - -void ImageView::setAlphaBackgroundMode(AlphaBackgroundMode mode) { - d->mAlphaBackgroundMode = mode; - if (d->mDocument && d->mDocument->hasAlphaChannel()) { - d->forceBufferRecreation(); - } -} - - -void ImageView::setAlphaBackgroundColor(const QColor& color) { - d->mAlphaBackgroundColor = color; - if (d->mDocument && d->mDocument->hasAlphaChannel()) { - d->forceBufferRecreation(); - } -} - - -void ImageView::setEnlargeSmallerImages(bool value) { - d->mEnlargeSmallerImages = value; - if (d->mZoomToFit) { - setZoom(computeZoomToFit()); - } -} - - -void ImageView::setDocument(Document::Ptr document) { - if (d->mDocument) { - d->mDocument->stopAnimation(); - disconnect(d->mDocument.data(), 0, this, 0); - } - d->mDocument = document; - if (!document) { - d->mViewport->update(); - return; - } - - connect(d->mDocument.data(), SIGNAL(metaInfoLoaded(KUrl)), - SLOT(slotDocumentMetaInfoLoaded()) ); - connect(d->mDocument.data(), SIGNAL(isAnimatedUpdated()), - SLOT(slotDocumentIsAnimatedUpdated()) ); - - const Document::LoadingState state = d->mDocument->loadingState(); - if (state == Document::MetaInfoLoaded || state == Document::Loaded) { - slotDocumentMetaInfoLoaded(); - } -} - - -void ImageView::slotDocumentMetaInfoLoaded() { - if (d->mDocument->size().isValid()) { - finishSetDocument(); - } else { - // Could not retrieve image size from meta info, we need to load the - // full image now. - connect(d->mDocument.data(), SIGNAL(loaded(KUrl)), - SLOT(finishSetDocument()) ); - d->mDocument->startLoadingFullImage(); - } -} - - -void ImageView::finishSetDocument() { - if (!d->mDocument->size().isValid()) { - kError() << "No valid image size available, this should not happen!"; - return; - } - - d->createBuffer(); - d->mScaler->setDocument(d->mDocument); - - connect(d->mDocument.data(), SIGNAL(imageRectUpdated(QRect)), - SLOT(updateImageRect(QRect)) ); - - if (d->mZoomToFit) { - // Set the zoom to an invalid value to make sure setZoom() does not - // return early because the new zoom is the same as the old zoom. - d->mZoom = -1; - setZoom(computeZoomToFit()); - } else { - QRect rect(QPoint(0, 0), d->mDocument->size()); - updateImageRect(rect); - updateScrollBars(); - } - - d->startAnimationIfNecessary(); - d->mViewport->update(); -} - - -Document::Ptr ImageView::document() const { - return d->mDocument; -} - - -void ImageView::slotDocumentIsAnimatedUpdated() { - d->startAnimationIfNecessary(); -} - - -void ImageView::updateImageRect(const QRect& imageRect) { - LOG("imageRect" << imageRect); - QRect viewportRect = mapToViewport(imageRect); - viewportRect = viewportRect.intersected(d->mViewport->rect()); - if (viewportRect.isEmpty()) { - return; - } - - if (d->mZoomToFit) { - setZoom(computeZoomToFit()); - } - d->setScalerRegionToVisibleRect(); - d->mViewport->update(); -} - - -void ImageView::paintEvent(QPaintEvent* event) { - QPainter painter(d->mViewport); - painter.setClipRect(event->rect()); - - QSize viewportSize = d->mViewport->size(); - - QSize bufferSize = d->mCurrentBuffer.size(); - - QSize paintSize; - if (d->mZoomToFit) { - paintSize = d->mDocument->size() * computeZoomToFit(); - } else { - paintSize = bufferSize; - } - painter.drawPixmap( - (viewportSize.width() - paintSize.width()) / 2, - (viewportSize.height() - paintSize.height()) / 2, - paintSize.width(), - paintSize.height(), - d->mCurrentBuffer); - - if (d->mTool) { - d->mTool->paint(&painter); - } -} - -void ImageView::resizeEvent(QResizeEvent*) { - if (d->mZoomToFit) { - d->mZoomToFitUpdateTimer->start(); - // Make sure one can't use mousewheel in zoom-to-fit mode - horizontalScrollBar()->setRange(0, 0); - verticalScrollBar()->setRange(0, 0); - } else { - d->createBuffer(); - updateScrollBars(); - d->setScalerRegionToVisibleRect(); - } -} - -void ImageView::updateZoomToFit() { - if (!d->mZoomToFit) { - return; - } - // Bypass "same zoom" test: even if the zoom is the same we want a new - // buffer of the correct size (and if switching from/to fullscreen, using - // the correct background) to be created - d->mZoom = -1; - setZoom(computeZoomToFit()); -} - -QPoint ImageView::imageOffset() const { - QSize size = d->visibleImageSize(); - int left = qMax( (d->mViewport->width() - size.width()) / 2, 0); - int top = qMax( (d->mViewport->height() - size.height()) / 2, 0); - - return QPoint(left, top); -} - - -void ImageView::setZoom(qreal zoom, const QPoint& _center) { - if (!d->mDocument) { - return; - } - - qreal oldZoom = d->mZoom; - if (qAbs(zoom - oldZoom) < 0.001) { - return; - } - // Get offset *before* setting mZoom, otherwise we get the new offset - QPoint oldOffset = imageOffset(); - d->mZoom = zoom; - - QPoint center; - if (_center == QPoint(-1, -1)) { - center = QPoint(d->mViewport->width() / 2, d->mViewport->height() / 2); - } else { - center = _center; - } - - // If we zoom more than twice, then assume the user wants to see the real - // pixels, for example to fine tune a crop operation - if (d->mZoom < 2.) { - d->mScaler->setTransformationMode(Qt::SmoothTransformation); - } else { - d->mScaler->setTransformationMode(Qt::FastTransformation); - } - - d->createBuffer(); - d->mInsideSetZoom = true; - - /* - We want to keep the point at viewport coordinates "center" at the same - position after zooming. The coordinates of this point in image coordinates - can be expressed like this: - - oldScroll + center - imagePointAtOldZoom = ------------------ - oldZoom - - scroll + center - imagePointAtZoom = --------------- - zoom - - So we want: - - imagePointAtOldZoom = imagePointAtZoom - - oldScroll + center scroll + center - <=> ------------------ = --------------- - oldZoom zoom - - zoom - <=> scroll = ------- (oldScroll + center) - center - oldZoom - */ - - /* - Compute oldScroll - It's useless to take the new offset in consideration because if a direction - of the new offset is not 0, we won't be able to center on a specific point - in that direction. - */ - QPointF oldScroll = QPointF(d->hScroll(), d->vScroll()) - oldOffset; - - QPointF scroll = (zoom / oldZoom) * (oldScroll + center) - center; - - updateScrollBars(); - horizontalScrollBar()->setValue(int(scroll.x())); - verticalScrollBar()->setValue(int(scroll.y())); - d->mInsideSetZoom = false; - - d->mScaler->setZoom(d->mZoom); - d->setScalerRegionToVisibleRect(); - emit zoomChanged(d->mZoom); -} - -qreal ImageView::zoom() const { - return d->mZoom; -} - -bool ImageView::zoomToFit() const { - return d->mZoomToFit; -} - -void ImageView::setZoomToFit(bool on) { - d->mZoomToFit = on; - if (d->mZoomToFit) { - setZoom(computeZoomToFit()); - } -} - -void ImageView::updateScrollBars() { - if (!d->mDocument || d->mZoomToFit) { - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - return; - } - setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); - setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - - int max; - int width = d->mViewport->width(); - int height = d->mViewport->height(); - - max = qMax(0, int(d->mDocument->width() * d->mZoom) - width); - horizontalScrollBar()->setRange(0, max); - horizontalScrollBar()->setPageStep(width); - - max = qMax(0, int(d->mDocument->height() * d->mZoom) - height); - verticalScrollBar()->setRange(0, max); - verticalScrollBar()->setPageStep(height); -} - - -void ImageView::scrollContentsBy(int dx, int dy) { - if (d->mInsideSetZoom) { - // Do not scroll anything: since we are zooming the whole viewport will - // eventually be repainted - return; - } - // Scroll existing - { - if (d->mAlternateBuffer.size() != d->mCurrentBuffer.size()) { - d->mAlternateBuffer = QPixmap(d->mCurrentBuffer.size()); - } - QPainter painter(&d->mAlternateBuffer); - painter.drawPixmap(dx, dy, d->mCurrentBuffer); - } - qSwap(d->mCurrentBuffer, d->mAlternateBuffer); - - // Scale missing parts - QRegion region; - int posX = d->hScroll(); - int posY = d->vScroll(); - int width = d->mViewport->width(); - int height = d->mViewport->height(); - - QRect rect; - if (dx > 0) { - rect = QRect(posX, posY, dx, height); - } else { - rect = QRect(posX + width + dx, posY, -dx, height); - } - region |= rect; - - if (dy > 0) { - rect = QRect(posX, posY, width, dy); - } else { - rect = QRect(posX, posY + height + dy, width, -dy); - } - region |= rect; - - d->mScaler->setDestinationRegion(region); - d->mViewport->update(); -} - - -void ImageView::updateFromScaler(int zoomedImageLeft, int zoomedImageTop, const QImage& image) { - LOG(""); - int viewportLeft = zoomedImageLeft - d->hScroll(); - int viewportTop = zoomedImageTop - d->vScroll(); - - { - QPainter painter(&d->mCurrentBuffer); - if (d->mDocument->hasAlphaChannel()) { - d->drawAlphaBackground( - &painter, QRect(viewportLeft, viewportTop, image.width(), image.height()), - QPoint(zoomedImageLeft, zoomedImageTop) - ); - } else { - painter.setCompositionMode(QPainter::CompositionMode_Source); - } - painter.drawImage(viewportLeft, viewportTop, image); - /* - // Debug rects - QPen pen(Qt::red); - pen.setStyle(Qt::DotLine); - painter.setPen(pen); - painter.drawRect(viewportLeft, viewportTop, image.width() - 1, image.height() - 1); - */ - } - d->mViewport->update(); -} - - -void ImageView::setCurrentTool(AbstractImageViewTool* tool) { - if (d->mTool) { - d->mTool->toolDeactivated(); - } - d->mTool = tool ? QPointer(tool) : d->mDefaultTool; - if (d->mTool) { - d->mTool->toolActivated(); - } - d->mViewport->update(); -} - - -AbstractImageViewTool* ImageView::currentTool() const { - return d->mTool; -} - - -void ImageView::setDefaultTool(AbstractImageViewTool* tool) { - d->mDefaultTool = tool; - if (!d->mTool && tool) { - setCurrentTool(tool); - } -} - - -AbstractImageViewTool* ImageView::defaultTool() const { - return d->mDefaultTool; -} - - -QPoint ImageView::mapToViewport(const QPoint& src) const { - QPoint dst(int(src.x() * d->mZoom), int(src.y() * d->mZoom)); - - dst += imageOffset(); - - dst.rx() -= d->hScroll(); - dst.ry() -= d->vScroll(); - - return dst; -} - - -QPointF ImageView::mapToViewportF(const QPointF& src) const { - QPointF dst(src.x() * d->mZoom, src.y() * d->mZoom); - - dst += imageOffset(); - - dst.rx() -= d->hScroll(); - dst.ry() -= d->vScroll(); - - return dst; -} - - -QRect ImageView::mapToViewport(const QRect& src) const { - QRect dst( - mapToViewport(src.topLeft()), - mapToViewport(src.bottomRight()) - ); - return dst; -} - - -QRectF ImageView::mapToViewportF(const QRectF& src) const { - QRectF dst( - mapToViewportF(src.topLeft()), - mapToViewportF(src.bottomRight()) - ); - return dst; -} - - -QPoint ImageView::mapToImage(const QPoint& src) const { - QPoint dst = src; - - dst.rx() += d->hScroll(); - dst.ry() += d->vScroll(); - - dst -= imageOffset(); - - return QPoint(int(dst.x() / d->mZoom), int(dst.y() / d->mZoom)); -} - - -QPointF ImageView::mapToImageF(const QPointF& src) const { - QPointF dst = src; - - dst.rx() += d->hScroll(); - dst.ry() += d->vScroll(); - - dst -= imageOffset(); - - return dst / d->mZoom; -} - - -QRect ImageView::mapToImage(const QRect& src) const { - QRect dst( - mapToImage(src.topLeft()), - mapToImage(src.bottomRight()) - ); - return dst; -} - - -QRectF ImageView::mapToImageF(const QRectF& src) const { - QRectF dst( - mapToImageF(src.topLeft()), - mapToImageF(src.bottomRight()) - ); - return dst; -} - - -qreal ImageView::computeZoomToFit() const { - qreal zoom = qMin(computeZoomToFitWidth(), computeZoomToFitHeight()); - - if (!d->mEnlargeSmallerImages) { - zoom = qMin(zoom, qreal(1.0)); - } - - return zoom; -} - - -qreal ImageView::computeZoomToFitWidth() const { - if (!d->mDocument || !d->mDocument->size().isValid()) { - return 1.; - } - return qreal(d->mViewport->width()) / d->mDocument->width(); -} - - -qreal ImageView::computeZoomToFitHeight() const { - if (!d->mDocument || !d->mDocument->size().isValid()) { - return 1.; - } - return qreal(d->mViewport->height()) / d->mDocument->height(); -} - - -void ImageView::showEvent(QShowEvent* event) { - QAbstractScrollArea::showEvent(event); - d->startAnimationIfNecessary(); -} - - -void ImageView::hideEvent(QHideEvent* event) { - QAbstractScrollArea::hideEvent(event); - if (d->mDocument) { - d->mDocument->stopAnimation(); - } -} - - -void ImageView::mousePressEvent(QMouseEvent* event) { - if (d->mTool) { - d->mTool->mousePressEvent(event); - } -} - - -void ImageView::mouseMoveEvent(QMouseEvent* event) { - if (d->mTool) { - d->mTool->mouseMoveEvent(event); - } -} - - -void ImageView::mouseReleaseEvent(QMouseEvent* event) { - if (d->mTool) { - d->mTool->mouseReleaseEvent(event); - } -} - - -void ImageView::wheelEvent(QWheelEvent* event) { - if (d->mTool) { - d->mTool->wheelEvent(event); - } -} - - -void ImageView::keyPressEvent(QKeyEvent* event) { - if (d->mTool) { - d->mTool->keyPressEvent(event); - } - QAbstractScrollArea::keyPressEvent(event); -} - - -void ImageView::keyReleaseEvent(QKeyEvent* event) { - if (d->mTool) { - d->mTool->keyReleaseEvent(event); - } - QAbstractScrollArea::keyReleaseEvent(event); -} - -} // namespace diff --git a/lib/imageview.h b/lib/imageview.h deleted file mode 100644 index 1a2eafbc..00000000 --- a/lib/imageview.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -Gwenview: an image viewer -Copyright 2007 Aurélien Gâteau - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -#ifndef IMAGEVIEW_H -#define IMAGEVIEW_H - -#include - -// Qt -#include - -// Local -#include - -namespace Gwenview { - -class AbstractImageViewTool; - -struct ImageViewPrivate; -class GWENVIEWLIB_EXPORT ImageView : public QAbstractScrollArea { - Q_OBJECT -public: - enum AlphaBackgroundMode { - AlphaBackgroundCheckBoard, - AlphaBackgroundSolid - }; - - ImageView(QWidget* parent=0); - ~ImageView(); - - /** - * Defines the tool to display on the view. if @p tool is 0, fallback to - * the default tool. - * @see setDefaultTool - */ - void setCurrentTool(AbstractImageViewTool* tool); - AbstractImageViewTool* currentTool() const; - - /** - * This is the tool which the view will fallback to if one calls - * setCurrentTool(0) - */ - void setDefaultTool(AbstractImageViewTool*); - AbstractImageViewTool* defaultTool() const; - - void setAlphaBackgroundMode(AlphaBackgroundMode mode); - - void setAlphaBackgroundColor(const QColor& color); - - void setEnlargeSmallerImages(bool value); - - void setDocument(Document::Ptr document); - - Document::Ptr document() const; - - /** - * Change zoom level, making sure the point at @p center stays at the - * same position after zooming, if possible. - * @param zoom the zoom level - * @param center the center point, in viewport coordinates - */ - void setZoom(qreal zoom, const QPoint& center = QPoint(-1, -1)); - - qreal zoom() const; - - bool zoomToFit() const; - - QPoint imageOffset() const; - - QPoint mapToViewport(const QPoint& src) const; - QPoint mapToImage(const QPoint& src) const; - - QRect mapToViewport(const QRect& src) const; - QRect mapToImage(const QRect& src) const; - - QPointF mapToViewportF(const QPointF& src) const; - QPointF mapToImageF(const QPointF& src) const; - - QRectF mapToViewportF(const QRectF& src) const; - QRectF mapToImageF(const QRectF& src) const; - - qreal computeZoomToFit() const; - qreal computeZoomToFitWidth() const; - qreal computeZoomToFitHeight() const; - -Q_SIGNALS: - void zoomChanged(qreal); - -public Q_SLOTS: - void setZoomToFit(bool on); - -protected: - virtual void paintEvent(QPaintEvent*); - - virtual void resizeEvent(QResizeEvent*); - - virtual void scrollContentsBy(int dx, int dy); - - virtual void showEvent(QShowEvent*); - virtual void hideEvent(QHideEvent*); - - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent*); - virtual void wheelEvent(QWheelEvent*); - virtual void keyPressEvent(QKeyEvent*); - virtual void keyReleaseEvent(QKeyEvent*); - -private Q_SLOTS: - void slotDocumentMetaInfoLoaded(); - void slotDocumentIsAnimatedUpdated(); - void updateZoomToFit(); - - /** - * This method performs the necessary adjustments to get the view ready to - * display the document set with setDocument(). It needs to be postponed - * because setDocument() can be called with a document which has not been - * loaded yet and whose size is unknown. - */ - void finishSetDocument(); - void updateFromScaler(int left, int top, const QImage& image); - void updateImageRect(const QRect&); - -private: - void updateScrollBars(); - - ImageViewPrivate* const d; -}; - -} // namespace - -#endif /* IMAGEVIEW_H */