File indexing completed on 2024-05-12 04:19:40
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0019 0020 */ 0021 // Self 0022 #include "svgviewadapter.h" 0023 0024 // Qt 0025 #include <QCursor> 0026 #include <QGraphicsSceneEvent> 0027 #include <QGraphicsSvgItem> 0028 #include <QGraphicsTextItem> 0029 #include <QSvgRenderer> 0030 0031 // KF 0032 0033 // Local 0034 #include "alphabackgrounditem.h" 0035 #include "gwenview_lib_debug.h" 0036 #include <lib/gvdebug.h> 0037 #include <lib/gwenviewconfig.h> 0038 0039 namespace Gwenview 0040 { 0041 /// SvgImageView //// 0042 SvgImageView::SvgImageView(QGraphicsItem *parent) 0043 : AbstractImageView(parent) 0044 , mSvgItem(new QGraphicsSvgItem(this)) 0045 { 0046 // At certain scales, the SVG can render outside its own bounds up to 1 pixel 0047 // This clips it so it isn't drawn outside the background or over the selection rect 0048 mSvgItem->setFlag(ItemClipsToShape); 0049 0050 // So we aren't unnecessarily drawing the background for every paint() 0051 setCacheMode(QGraphicsItem::DeviceCoordinateCache); 0052 } 0053 0054 void SvgImageView::loadFromDocument() 0055 { 0056 Document::Ptr doc = document(); 0057 GV_RETURN_IF_FAIL(doc); 0058 0059 if (doc->loadingState() == Document::Loaded) { 0060 QMetaObject::invokeMethod(this, &SvgImageView::finishLoadFromDocument, Qt::QueuedConnection); 0061 } 0062 0063 // Ensure finishLoadFromDocument is also called when 0064 // - loadFromDocument was called before the document was fully loaded 0065 // - reloading is triggered (e.g. via F5) 0066 connect(doc.data(), &Document::loaded, this, &SvgImageView::finishLoadFromDocument); 0067 } 0068 0069 void SvgImageView::finishLoadFromDocument() 0070 { 0071 QSvgRenderer *renderer = document()->svgRenderer(); 0072 GV_RETURN_IF_FAIL(renderer); 0073 mSvgItem->setSharedRenderer(renderer); 0074 if (zoomToFit()) { 0075 setZoom(computeZoomToFit(), QPointF(-1, -1), ForceUpdate); 0076 } else if (zoomToFill()) { 0077 setZoom(computeZoomToFill(), QPointF(-1, -1), ForceUpdate); 0078 } else { 0079 mSvgItem->setScale(zoom()); 0080 } 0081 applyPendingScrollPos(); 0082 Q_EMIT completed(); 0083 backgroundItem()->setVisible(true); 0084 } 0085 0086 void SvgImageView::onZoomChanged() 0087 { 0088 mSvgItem->setScale(zoom()); 0089 adjustItemPos(); 0090 } 0091 0092 void SvgImageView::onImageOffsetChanged() 0093 { 0094 adjustItemPos(); 0095 } 0096 0097 void SvgImageView::onScrollPosChanged(const QPointF & /* oldPos */) 0098 { 0099 adjustItemPos(); 0100 } 0101 0102 void SvgImageView::adjustItemPos() 0103 { 0104 mSvgItem->setPos((imageOffset() - scrollPos()).toPoint()); 0105 update(); 0106 } 0107 0108 //// SvgViewAdapter //// 0109 struct SvgViewAdapterPrivate { 0110 SvgImageView *mView; 0111 }; 0112 0113 SvgViewAdapter::SvgViewAdapter() 0114 : d(new SvgViewAdapterPrivate) 0115 { 0116 d->mView = new SvgImageView; 0117 setWidget(d->mView); 0118 connect(d->mView, &SvgImageView::zoomChanged, this, &SvgViewAdapter::zoomChanged); 0119 connect(d->mView, &SvgImageView::zoomToFitChanged, this, &SvgViewAdapter::zoomToFitChanged); 0120 connect(d->mView, &SvgImageView::zoomToFillChanged, this, &SvgViewAdapter::zoomToFillChanged); 0121 connect(d->mView, &SvgImageView::zoomInRequested, this, &SvgViewAdapter::zoomInRequested); 0122 connect(d->mView, &SvgImageView::zoomOutRequested, this, &SvgViewAdapter::zoomOutRequested); 0123 connect(d->mView, &SvgImageView::scrollPosChanged, this, &SvgViewAdapter::scrollPosChanged); 0124 connect(d->mView, &SvgImageView::completed, this, &SvgViewAdapter::completed); 0125 connect(d->mView, &SvgImageView::previousImageRequested, this, &SvgViewAdapter::previousImageRequested); 0126 connect(d->mView, &SvgImageView::nextImageRequested, this, &SvgViewAdapter::nextImageRequested); 0127 connect(d->mView, &SvgImageView::toggleFullScreenRequested, this, &SvgViewAdapter::toggleFullScreenRequested); 0128 } 0129 0130 SvgViewAdapter::~SvgViewAdapter() 0131 { 0132 delete d; 0133 } 0134 0135 QCursor SvgViewAdapter::cursor() const 0136 { 0137 return widget()->cursor(); 0138 } 0139 0140 void SvgViewAdapter::setCursor(const QCursor &cursor) 0141 { 0142 widget()->setCursor(cursor); 0143 } 0144 0145 void SvgViewAdapter::setDocument(const Document::Ptr &doc) 0146 { 0147 d->mView->setDocument(doc); 0148 } 0149 0150 Document::Ptr SvgViewAdapter::document() const 0151 { 0152 return d->mView->document(); 0153 } 0154 0155 void SvgViewAdapter::loadConfig() 0156 { 0157 d->mView->backgroundItem()->setMode(GwenviewConfig::alphaBackgroundMode()); 0158 d->mView->backgroundItem()->setColor(GwenviewConfig::alphaBackgroundColor()); 0159 d->mView->setEnlargeSmallerImages(GwenviewConfig::enlargeSmallerImages()); 0160 } 0161 0162 void SvgViewAdapter::setZoomToFit(bool on) 0163 { 0164 d->mView->setZoomToFit(on); 0165 } 0166 0167 void SvgViewAdapter::setZoomToFill(bool on, const QPointF ¢er) 0168 { 0169 d->mView->setZoomToFill(on, center); 0170 } 0171 0172 bool SvgViewAdapter::zoomToFit() const 0173 { 0174 return d->mView->zoomToFit(); 0175 } 0176 0177 bool SvgViewAdapter::zoomToFill() const 0178 { 0179 return d->mView->zoomToFill(); 0180 } 0181 0182 qreal SvgViewAdapter::zoom() const 0183 { 0184 return d->mView->zoom(); 0185 } 0186 0187 void SvgViewAdapter::setZoom(qreal zoom, const QPointF ¢er) 0188 { 0189 d->mView->setZoom(zoom, center); 0190 } 0191 0192 qreal SvgViewAdapter::computeZoomToFit() const 0193 { 0194 return d->mView->computeZoomToFit(); 0195 } 0196 0197 qreal SvgViewAdapter::computeZoomToFill() const 0198 { 0199 return d->mView->computeZoomToFill(); 0200 } 0201 0202 QPointF SvgViewAdapter::scrollPos() const 0203 { 0204 return d->mView->scrollPos(); 0205 } 0206 0207 void SvgViewAdapter::setScrollPos(const QPointF &pos) 0208 { 0209 d->mView->setScrollPos(pos); 0210 } 0211 0212 QRectF SvgViewAdapter::visibleDocumentRect() const 0213 { 0214 return QRectF(d->mView->imageOffset(), d->mView->visibleImageSize()); 0215 } 0216 0217 AbstractImageView *SvgViewAdapter::imageView() const 0218 { 0219 return d->mView; 0220 } 0221 0222 } // namespace 0223 0224 #include "moc_svgviewadapter.cpp"