Mega Code Archive

 
Categories / C++ / Qt
 

Svg viewer

/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights.  These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SVGVIEW_H #define SVGVIEW_H #include <QGraphicsView> QT_BEGIN_NAMESPACE class QWheelEvent; class QPaintEvent; class QFile; QT_END_NAMESPACE class SvgView : public QGraphicsView {     Q_OBJECT public:     enum RendererType { Native, OpenGL, Image };     SvgView(QWidget *parent = 0);     void openFile(const QFile &file);     void setRenderer(RendererType type = Native);     void drawBackground(QPainter *p, const QRectF &rect); public slots:     void setHighQualityAntialiasing(bool highQualityAntialiasing);     void setViewBackground(bool enable);     void setViewOutline(bool enable); protected:     void wheelEvent(QWheelEvent *event);     void paintEvent(QPaintEvent *event); private:     RendererType m_renderer;     QGraphicsItem *m_svgItem;     QGraphicsRectItem *m_backgroundItem;     QGraphicsRectItem *m_outlineItem;     QImage m_image; }; #end #include "svgview.h" #include <QFile> #include <QWheelEvent> #include <QMouseEvent> #include <QGraphicsRectItem> #include <QGraphicsSvgItem> #include <QPaintEvent> #include <qmath.h> #ifndef QT_NO_OPENGL #include <QGLWidget> #endif SvgView::SvgView(QWidget *parent)     : QGraphicsView(parent)     , m_renderer(Native)     , m_svgItem(0)     , m_backgroundItem(0)     , m_outlineItem(0) {     setScene(new QGraphicsScene(this));     setTransformationAnchor(AnchorUnderMouse);     setDragMode(ScrollHandDrag);     // Prepare background check-board pattern     QPixmap tilePixmap(64, 64);     tilePixmap.fill(Qt::white);     QPainter tilePainter(&tilePixmap);     QColor color(220, 220, 220);     tilePainter.fillRect(0, 0, 32, 32, color);     tilePainter.fillRect(32, 32, 32, 32, color);     tilePainter.end();     setBackgroundBrush(tilePixmap); } void SvgView::drawBackground(QPainter *p, const QRectF &) {     p->save();     p->resetTransform();     p->drawTiledPixmap(viewport()->rect(), backgroundBrush().texture());     p->restore(); } void SvgView::openFile(const QFile &file) {     if (!file.exists())         return;     QGraphicsScene *s = scene();     bool drawBackground = (m_backgroundItem ? m_backgroundItem->isVisible() : false);     bool drawOutline = (m_outlineItem ? m_outlineItem->isVisible() : true);     s->clear();     resetTransform();     m_svgItem = new QGraphicsSvgItem(file.fileName());     m_svgItem->setFlags(QGraphicsItem::ItemClipsToShape);     m_svgItem->setCacheMode(QGraphicsItem::NoCache);     m_svgItem->setZValue(0);     m_backgroundItem = new QGraphicsRectItem(m_svgItem->boundingRect());     m_backgroundItem->setBrush(Qt::white);     m_backgroundItem->setPen(Qt::NoPen);     m_backgroundItem->setVisible(drawBackground);     m_backgroundItem->setZValue(-1);     m_outlineItem = new QGraphicsRectItem(m_svgItem->boundingRect());     QPen outline(Qt::black, 2, Qt::DashLine);     outline.setCosmetic(true);     m_outlineItem->setPen(outline);     m_outlineItem->setBrush(Qt::NoBrush);     m_outlineItem->setVisible(drawOutline);     m_outlineItem->setZValue(1);     s->addItem(m_backgroundItem);     s->addItem(m_svgItem);     s->addItem(m_outlineItem);     s->setSceneRect(m_outlineItem->boundingRect().adjusted(-10, -10, 10, 10)); } void SvgView::setRenderer(RendererType type) {     m_renderer = type;     if (m_renderer == OpenGL) { #ifndef QT_NO_OPENGL         setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); #endif     } else {         setViewport(new QWidget);     } } void SvgView::setHighQualityAntialiasing(bool highQualityAntialiasing) { #ifndef QT_NO_OPENGL     setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); #else     Q_UNUSED(highQualityAntialiasing); #endif } void SvgView::setViewBackground(bool enable) {     if (!m_backgroundItem)           return;     m_backgroundItem->setVisible(enable); } void SvgView::setViewOutline(bool enable) {     if (!m_outlineItem)         return;     m_outlineItem->setVisible(enable); } void SvgView::paintEvent(QPaintEvent *event) {     if (m_renderer == Image) {         if (m_image.size() != viewport()->size()) {             m_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied);         }         QPainter imagePainter(&m_image);         QGraphicsView::render(&imagePainter);         imagePainter.end();         QPainter p(viewport());         p.drawImage(0, 0, m_image);     } else {         QGraphicsView::paintEvent(event);     } } void SvgView::wheelEvent(QWheelEvent *event) {     qreal factor = qPow(1.2, event->delta() / 240.0);     scale(factor, factor);     event->accept(); } #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QString> class SvgView; QT_BEGIN_NAMESPACE class QAction; class QGraphicsView; class QGraphicsScene; class QGraphicsRectItem; QT_END_NAMESPACE class MainWindow : public QMainWindow {     Q_OBJECT public:     MainWindow(); public slots:     void openFile(const QString &path = QString());     void setRenderer(QAction *action); private:     QAction *m_nativeAction;     QAction *m_glAction;     QAction *m_imageAction;     QAction *m_highQualityAntialiasingAction;     QAction *m_backgroundAction;     QAction *m_outlineAction;     SvgView *m_view;     QString m_currentPath; }; #endif #include "mainwindow.h" #include <QtGui> #include "svgview.h" MainWindow::MainWindow()     : QMainWindow()     , m_view(new SvgView) {     QMenu *fileMenu = new QMenu(tr("&File"), this);     QAction *openAction = fileMenu->addAction(tr("&Open..."));     openAction->setShortcut(QKeySequence(tr("Ctrl+O")));     QAction *quitAction = fileMenu->addAction(tr("E&xit"));     quitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));     menuBar()->addMenu(fileMenu);     QMenu *viewMenu = new QMenu(tr("&View"), this);     m_backgroundAction = viewMenu->addAction(tr("&Background"));     m_backgroundAction->setEnabled(false);     m_backgroundAction->setCheckable(true);     m_backgroundAction->setChecked(false);     connect(m_backgroundAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewBackground(bool)));     m_outlineAction = viewMenu->addAction(tr("&Outline"));     m_outlineAction->setEnabled(false);     m_outlineAction->setCheckable(true);     m_outlineAction->setChecked(true);     connect(m_outlineAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewOutline(bool)));     menuBar()->addMenu(viewMenu);     QMenu *rendererMenu = new QMenu(tr("&Renderer"), this);     m_nativeAction = rendererMenu->addAction(tr("&Native"));     m_nativeAction->setCheckable(true);     m_nativeAction->setChecked(true); #ifndef QT_NO_OPENGL     m_glAction = rendererMenu->addAction(tr("&OpenGL"));     m_glAction->setCheckable(true); #endif     m_imageAction = rendererMenu->addAction(tr("&Image"));     m_imageAction->setCheckable(true); #ifndef QT_NO_OPENGL     rendererMenu->addSeparator();     m_highQualityAntialiasingAction = rendererMenu->addAction(tr("&High Quality Antialiasing"));     m_highQualityAntialiasingAction->setEnabled(false);     m_highQualityAntialiasingAction->setCheckable(true);     m_highQualityAntialiasingAction->setChecked(false);     connect(m_highQualityAntialiasingAction, SIGNAL(toggled(bool)), m_view, SLOT(setHighQualityAntialiasing(bool))); #endif     QActionGroup *rendererGroup = new QActionGroup(this);     rendererGroup->addAction(m_nativeAction); #ifndef QT_NO_OPENGL     rendererGroup->addAction(m_glAction); #endif     rendererGroup->addAction(m_imageAction);     menuBar()->addMenu(rendererMenu);     connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));     connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));     connect(rendererGroup, SIGNAL(triggered(QAction *)),             this, SLOT(setRenderer(QAction *)));     setCentralWidget(m_view);     setWindowTitle(tr("SVG Viewer")); } void MainWindow::openFile(const QString &path) {     QString fileName;     if (path.isNull())         fileName = QFileDialog::getOpenFileName(this, tr("Open SVG File"),                 m_currentPath, "SVG files (*.svg *.svgz *.svg.gz)");     else         fileName = path;     if (!fileName.isEmpty()) {         QFile file(fileName);         if (!file.exists()) {             QMessageBox::critical(this, tr("Open SVG File"),                            QString("Could not open file '%1'.").arg(fileName));             m_outlineAction->setEnabled(false);             m_backgroundAction->setEnabled(false);             return;         }         m_view->openFile(file);         if (!fileName.startsWith(":/")) {             m_currentPath = fileName;             setWindowTitle(tr("%1 - SVGViewer").arg(m_currentPath));         }         m_outlineAction->setEnabled(true);         m_backgroundAction->setEnabled(true);         resize(m_view->sizeHint() + QSize(80, 80 + menuBar()->height()));     } } void MainWindow::setRenderer(QAction *action) { #ifndef QT_NO_OPENGL     m_highQualityAntialiasingAction->setEnabled(false); #endif     if (action == m_nativeAction)         m_view->setRenderer(SvgView::Native); #ifndef QT_NO_OPENGL     else if (action == m_glAction) {         m_highQualityAntialiasingAction->setEnabled(true);         m_view->setRenderer(SvgView::OpenGL);     } #endif     else if (action == m_imageAction) {         m_view->setRenderer(SvgView::Image);     } } #include <QApplication> #include <QString> #ifndef QT_NO_OPENGL #include <QGLFormat> #endif #include "mainwindow.h" int main(int argc, char **argv) {     Q_INIT_RESOURCE(svgviewer);     QApplication app(argc, argv);     MainWindow window;     if (argc == 2)         window.openFile(argv[1]);     else         window.openFile(":/files/bubbles.svg");     window.show();     return app.exec(); }