Commit aa7d2c54 authored by Denis Mingulov's avatar Denis Mingulov Committed by Thorbjørn Lindeijer

ImageViewer: Reimplemented as a new plugin

Merge-request: 2165
Reviewed-by: default avatarThorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com>
parent fc3fd82e
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="image/bmp">
<sub-class-of type="application/octet-stream"/>
<comment>BMP image</comment>
<glob pattern="*.bmp"/>
</mime-type>
<mime-type type="image/gif">
<sub-class-of type="application/octet-stream"/>
<comment>GIF image</comment>
<glob pattern="*.gif"/>
</mime-type>
<mime-type type="image/x-icon">
<sub-class-of type="application/octet-stream"/>
<comment>ICO image</comment>
<glob pattern="*.ico"/>
</mime-type>
<mime-type type="image/jpeg">
<sub-class-of type="application/octet-stream"/>
<comment>JPEG image</comment>
<glob pattern="*.jpg"/>
<glob pattern="*.jpeg"/>
</mime-type>
<mime-type type="video/x-mng">
<sub-class-of type="application/octet-stream"/>
<comment>MNG video</comment>
<glob pattern="*.mng"/>
</mime-type>
<mime-type type="image/x-portable-bitmap">
<sub-class-of type="application/octet-stream"/>
<comment>PBM image</comment>
<glob pattern="*.pbm"/>
</mime-type>
<mime-type type="image/x-portable-graymap">
<sub-class-of type="application/octet-stream"/>
<comment>PGM image</comment>
<glob pattern="*.pgm"/>
</mime-type>
<mime-type type="image/png">
<sub-class-of type="application/octet-stream"/>
<comment>PNG image</comment>
<glob pattern="*.png"/>
</mime-type>
<mime-type type="image/x-portable-pixmap">
<sub-class-of type="application/octet-stream"/>
<comment>PPM image</comment>
<glob pattern="*.ppm"/>
</mime-type>
<mime-type type="image/svg+xml">
<sub-class-of type="application/octet-stream"/>
<comment>SVG image</comment>
<glob pattern="*.svg"/>
</mime-type>
<mime-type type="image/tiff">
<sub-class-of type="application/octet-stream"/>
<comment>TIFF image</comment>
<glob pattern="*.tif"/>
<glob pattern="*.tiff"/>
</mime-type>
<mime-type type="image/xbm">
<sub-class-of type="application/octet-stream"/>
<comment>XBM image</comment>
<glob pattern="*.xbm"/>
</mime-type>
<mime-type type="image/xpm">
<sub-class-of type="application/octet-stream"/>
<comment>XPM image</comment>
<glob pattern="*.xpm"/>
</mime-type>
</mime-info>
<plugin name="ImageViewer" version="2.1.80" compatVersion="2.1.80">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2010 Denis Mingulov</copyright>
<license>
Commercial Usage
Licensees holding valid Qt Commercial licenses may use this plugin 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 plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 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.
</license>
<category>Qt Creator</category>
<description>Image Viewer component.</description>
<url>http://qt.nokia.com</url>
<dependencyList>
<dependency name="Core" version="2.1.80"/>
</dependencyList>
</plugin>
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Copyright (c) 2010 Denis Mingulov.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of Qt Creator.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "imageview.h"
#include <QtCore/QFile>
#include <QtGui/QWheelEvent>
#include <QtGui/QMouseEvent>
#include <QtGui/QGraphicsRectItem>
#include <QtGui/QPixmap>
#include <QtSvg/QGraphicsSvgItem>
#include <QtGui/QImageReader>
#include <qmath.h>
namespace ImageViewer {
namespace Constants {
const qreal DEFAULT_SCALE_FACTOR = 1.2;
}
namespace Internal {
struct ImageViewPrivate
{
ImageViewPrivate() : imageItem(0), backgroundItem(0), outlineItem(0) {}
QGraphicsItem *imageItem;
QGraphicsRectItem *backgroundItem;
QGraphicsRectItem *outlineItem;
};
ImageView::ImageView(QWidget *parent)
: QGraphicsView(parent),
d_ptr(new ImageViewPrivate())
{
setScene(new QGraphicsScene(this));
setTransformationAnchor(AnchorUnderMouse);
setDragMode(ScrollHandDrag);
setViewportUpdateMode(FullViewportUpdate);
// 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, 0x20, 0x20, color);
tilePainter.fillRect(0x20, 0x20, 0x20, 0x20, color);
tilePainter.end();
setBackgroundBrush(tilePixmap);
}
ImageView::~ImageView()
{
}
void ImageView::drawBackground(QPainter *p, const QRectF &)
{
p->save();
p->resetTransform();
p->drawTiledPixmap(viewport()->rect(), backgroundBrush().texture());
p->restore();
}
bool ImageView::openFile(QString fileName)
{
bool isSvg = false;
QByteArray format = QImageReader::imageFormat(fileName);
// if it is impossible to recognize a file format - file will not be open correctly
if (format.isEmpty())
return false;
if (format.startsWith("svg"))
isSvg = true;
QGraphicsScene *s = scene();
bool drawBackground = (d_ptr->backgroundItem ? d_ptr->backgroundItem->isVisible() : false);
bool drawOutline = (d_ptr->outlineItem ? d_ptr->outlineItem->isVisible() : true);
s->clear();
resetTransform();
// image
if (isSvg) {
d_ptr->imageItem = new QGraphicsSvgItem(fileName);
} else {
QPixmap pixmap(fileName);
d_ptr->imageItem = new QGraphicsPixmapItem(pixmap);
}
d_ptr->imageItem->setFlags(QGraphicsItem::ItemClipsToShape);
d_ptr->imageItem->setCacheMode(QGraphicsItem::NoCache);
d_ptr->imageItem->setZValue(0);
// background item
d_ptr->backgroundItem = new QGraphicsRectItem(d_ptr->imageItem->boundingRect());
d_ptr->backgroundItem->setBrush(Qt::white);
d_ptr->backgroundItem->setPen(Qt::NoPen);
d_ptr->backgroundItem->setVisible(drawBackground);
d_ptr->backgroundItem->setZValue(-1);
// outline
d_ptr->outlineItem = new QGraphicsRectItem(d_ptr->imageItem->boundingRect());
QPen outline(Qt::black, 2, Qt::DashLine);
outline.setCosmetic(true);
d_ptr->outlineItem->setPen(outline);
d_ptr->outlineItem->setBrush(Qt::NoBrush);
d_ptr->outlineItem->setVisible(drawOutline);
d_ptr->outlineItem->setZValue(1);
s->addItem(d_ptr->backgroundItem);
s->addItem(d_ptr->imageItem);
s->addItem(d_ptr->outlineItem);
// if image size is 0x0, then it is not loaded
if (d_ptr->imageItem->boundingRect().height() == 0 && d_ptr->imageItem->boundingRect().width() == 0)
return false;
emitScaleFactor();
return true;
}
void ImageView::setViewBackground(bool enable)
{
if (!d_ptr->backgroundItem)
return;
d_ptr->backgroundItem->setVisible(enable);
}
void ImageView::setViewOutline(bool enable)
{
if (!d_ptr->outlineItem)
return;
d_ptr->outlineItem->setVisible(enable);
}
void ImageView::doScale(qreal factor)
{
scale(factor, factor);
emitScaleFactor();
}
void ImageView::wheelEvent(QWheelEvent *event)
{
qreal factor = qPow(Constants::DEFAULT_SCALE_FACTOR, event->delta() / 240.0);
doScale(factor);
event->accept();
}
void ImageView::zoomIn()
{
doScale(Constants::DEFAULT_SCALE_FACTOR);
}
void ImageView::zoomOut()
{
doScale(1. / Constants::DEFAULT_SCALE_FACTOR);
}
void ImageView::resetToOriginalSize()
{
resetTransform();
emitScaleFactor();
}
void ImageView::fitToScreen()
{
fitInView(d_ptr->imageItem, Qt::KeepAspectRatio);
emitScaleFactor();
}
void ImageView::emitScaleFactor()
{
// get scale factor directly from the transform matrix
qreal factor = transform().m11();
emit scaleFactorChanged(factor);
}
} // namespace Internal
} // namespace ImageView
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Copyright (c) 2010 Denis Mingulov.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of Qt Creator.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef IMAGEVIEW_H
#define IMAGEVIEW_H
#include <QtGui/QGraphicsView>
#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE
class QWheelEvent;
QT_END_NAMESPACE
namespace ImageViewer {
namespace Internal {
class ImageView : public QGraphicsView
{
Q_OBJECT
public:
ImageView(QWidget *parent = 0);
~ImageView();
bool openFile(QString fileName);
signals:
void scaleFactorChanged(qreal factor);
public slots:
void setViewBackground(bool enable);
void setViewOutline(bool enable);
void zoomIn();
void zoomOut();
void resetToOriginalSize();
void fitToScreen();
private slots:
void emitScaleFactor();
void doScale(qreal factor);
protected:
void drawBackground(QPainter *p, const QRectF &rect);
void wheelEvent(QWheelEvent *event);
private:
QScopedPointer<struct ImageViewPrivate> d_ptr;
};
} // namespace Internal
} // namespace ImageViewer
#endif // IMAGEVIEW_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
** Copyright (c) 2010 Denis Mingulov.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "imageviewer.h"
#include "imageviewerfile.h"
#include "imageviewerconstants.h"
#include "imageview.h"
#include "ui_imageviewertoolbar.h"
#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <QtCore/QMap>
#include <QtCore/QFileInfo>
#include <QtGui/QWidget>
#include <QtCore/QtDebug>
namespace ImageViewer {
namespace Internal {
struct ImageViewerPrivate
{
QList<int> context;
QString displayName;
ImageViewerFile *file;
ImageView *imageView;
QWidget *toolbar;
Ui::ImageViewerToolbar ui_toolbar;
};
ImageViewer::ImageViewer(QWidget *parent)
: IEditor(parent),
d_ptr(new ImageViewerPrivate)
{
d_ptr->file = new ImageViewerFile(this);
d_ptr->context << Core::ICore::instance()->uniqueIDManager()
->uniqueIdentifier(Constants::IMAGEVIEWER_ID);
d_ptr->imageView = new ImageView();
// toolbar
d_ptr->toolbar = new QWidget();
d_ptr->ui_toolbar.setupUi(d_ptr->toolbar);
// connections
connect(d_ptr->file, SIGNAL(changed()), this, SIGNAL(changed()));
connect(d_ptr->ui_toolbar.toolButtonZoomIn, SIGNAL(clicked()),
d_ptr->imageView, SLOT(zoomIn()));
connect(d_ptr->ui_toolbar.toolButtonZoomOut, SIGNAL(clicked()),
d_ptr->imageView, SLOT(zoomOut()));
connect(d_ptr->ui_toolbar.toolButtonFitToScreen, SIGNAL(clicked()),
d_ptr->imageView, SLOT(fitToScreen()));
connect(d_ptr->ui_toolbar.toolButtonOriginalSize, SIGNAL(clicked()),
d_ptr->imageView, SLOT(resetToOriginalSize()));
connect(d_ptr->ui_toolbar.toolButtonBackground, SIGNAL(toggled(bool)),
d_ptr->imageView, SLOT(setViewBackground(bool)));
connect(d_ptr->ui_toolbar.toolButtonOutline, SIGNAL(toggled(bool)),
d_ptr->imageView, SLOT(setViewOutline(bool)));
connect(d_ptr->imageView, SIGNAL(scaleFactorChanged(qreal)),
this, SLOT(scaleFactorUpdate(qreal)));
}
ImageViewer::~ImageViewer()
{
delete d_ptr->imageView;
delete d_ptr->toolbar;
}
QList<int> ImageViewer::context() const
{
return d_ptr->context;
}
QWidget *ImageViewer::widget()
{
return d_ptr->imageView;
}
bool ImageViewer::createNew(const QString &contents)
{
Q_UNUSED(contents)
return false;
}
bool ImageViewer::open(const QString &fileName)
{
if (!d_ptr->imageView->openFile(fileName))
return false;
setDisplayName(QFileInfo(fileName).fileName());
d_ptr->file->setFileName(fileName);
// d_ptr->file->setMimeType
emit changed();
return true;
}
Core::IFile *ImageViewer::file()
{
return d_ptr->file;
}
QString ImageViewer::id() const
{
return QLatin1String(Constants::IMAGEVIEWER_ID);
}
QString ImageViewer::displayName() const
{
return d_ptr->displayName;
}
void ImageViewer::setDisplayName(const QString &title)
{
d_ptr->displayName = title;
emit changed();
}
bool ImageViewer::duplicateSupported() const
{
return false;
}
Core::IEditor *ImageViewer::duplicate(QWidget *parent)
{
Q_UNUSED(parent);
return 0;
}
QByteArray ImageViewer::saveState() const
{
return QByteArray();
}
bool ImageViewer::restoreState(const QByteArray &state)
{
Q_UNUSED(state);
return true;
}
int ImageViewer::currentLine() const
{
return 0;
}
int ImageViewer::currentColumn() const
{
return 0;
}
bool ImageViewer::isTemporary() const
{
return false;
}
QWidget *ImageViewer::toolBar()
{
return d_ptr->toolbar;
}
void ImageViewer::scaleFactorUpdate(qreal factor)
{
QString info = tr("%1%").arg(QString::number(factor * 100, 'f', 2));
d_ptr->ui_toolbar.labelInfo->setText(info);
}
} // namespace Internal
} // namespace ImageViewer
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
** Copyright (c) 2010 Denis Mingulov.
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/ifile.h>
#include <QtCore/QScopedPointer>
#include <QtCore/QStringList>
namespace ImageViewer {
namespace Internal {
class ImageViewerFile;
class ImageViewer : public Core::IEditor
{
Q_OBJECT
Q_DISABLE_COPY(ImageViewer)
public:
explicit ImageViewer(QWidget *parent = 0);
~ImageViewer();
QList<int> context() const;
QWidget *widget();
bool createNew(const QString &contents = QString());
bool open(const QString &fileName = QString());
Core::IFile *file();
QString id() const;
QString displayName() const;
void setDisplayName(const QString &title);
bool duplicateSupported() const;