Commit 6c36a2a9 authored by Alessandro Portale's avatar Alessandro Portale
Browse files

Cropping the examples screen shots to "Areas of interest".



The cropping coordinates are stored in a file
images_areasofinterest.xml. A tool to create/maintain the cropping
coordinates is included in this patch.

Then changes to Delegate.qml prevent QML from scaling the image.
If scaling is needed it is now the job of the Image provider.
dropshadow.png had to be adjusted because the border had different
widths and heights.

Change-Id: Ib25db896d40eeec0e0a373c971931dc5cabf3cbe
Reviewed-by: default avatarThomas Hartmann <Thomas.Hartmann@nokia.com>
parent 9e0cae5d
<?xml version="1.0" encoding="UTF-8"?>
<areas>
<area image="2dpainting-example.png" x="270" y="90" width="118" height="92"/>
<area image="addressbook-example.png" x="4" y="50" width="138" height="111"/>
<area image="addressbook-tutorial-part1-screenshot.png" x="9" y="25" width="112" height="93"/>
<area image="analogclock-example.png" x="82" y="98" width="125" height="89"/>
<area image="animatedtiles-example.png" x="191" y="197" width="128" height="121"/>
<area image="appchooser-example.png" x="189" y="214" width="119" height="117"/>
<area image="application.png" x="4" y="9" width="145" height="117"/>
<area image="audiodevices-example.png" x="36" y="119" width="173" height="101"/>
<area image="audioinput-example.png" x="0" y="0" width="120" height="120"/>
<area image="audiooutput-example.png" x="16" y="39" width="152" height="56"/>
<area image="basicdrawing-example.png" x="155" y="190" width="160" height="133"/>
<area image="basiclayouts-example.png" x="8" y="44" width="173" height="97"/>
<area image="basicsortfiltermodel-example.png" x="9" y="25" width="125" height="93"/>
<area image="borderlayout-example.png" x="1" y="26" width="151" height="128"/>
<area image="broadcastreceiver-example.png" x="73" y="36" width="145" height="57"/>
<area image="broadcastsender-example.png" x="99" y="34" width="130" height="64"/>
<area image="cachedtable-example.png" x="12" y="33" width="140" height="107"/>
<area image="calculator-example.png" x="205" y="27" width="126" height="122"/>
<area image="calculatorbuilder-example.png" x="20" y="41" width="131" height="82"/>
<area image="calculatorform-example.png" x="14" y="33" width="155" height="72"/>
<area image="calendar-example.png" x="12" y="34" width="162" height="124"/>
<area image="calendarwidgetexample.png" x="105" y="66" width="142" height="110"/>
<area image="charactermap-example.png" x="13" y="56" width="171" height="108"/>
<area image="chart-example.png" x="419" y="59" width="150" height="117"/>
<area image="classwizard.png" x="24" y="111" width="152" height="126"/>
<area image="codecs-example.png" x="163" y="98" width="134" height="94"/>
<area image="codeeditor-example.png" x="14" y="48" width="143" height="107"/>
<area image="collidingmice-example.png" x="45" y="86" width="171" height="133"/>
<area image="coloreditorfactoryimage.png" x="50" y="35" width="155" height="109"/>
<area image="combowidgetmapper-example.png" x="38" y="168" width="131" height="89"/>
<area image="completer-example.png" x="11" y="141" width="159" height="107"/>
<area image="concentriccircles-example.png" x="306" y="321" width="50" height="43"/>
<area image="configdialog-example.png" x="94" y="27" width="122" height="122"/>
<area image="containerextension-example.png" x="30" y="21" width="110" height="97"/>
<area image="customcompleter-example.png" x="3" y="69" width="151" height="112"/>
<area image="customsortfiltermodel-example.png" x="10" y="27" width="152" height="117"/>
<area image="customwidgetplugin-example.png" x="16" y="18" width="129" height="124"/>
<area image="defaultprototypes-example.png" x="2" y="15" width="104" height="111"/>
<area image="diagramscene.png" x="1" y="47" width="164" height="138"/>
<area image="digitalclock-example.png" x="57" y="37" width="129" height="96"/>
<area image="dirview-example.png" x="21" y="96" width="122" height="90"/>
<area image="dockwidgets-example.png" x="498" y="262" width="180" height="109"/>
<area image="dombookmarks-example.png" x="2" y="53" width="131" height="129"/>
<area image="draganddroppuzzle-example.png" x="183" y="230" width="145" height="127"/>
<area image="dragdroprobot-example.png" x="119" y="101" width="115" height="129"/>
<area image="draggableicons-example.png" x="181" y="67" width="111" height="124"/>
<area image="draggabletext-example.png" x="48" y="78" width="96" height="90"/>
<area image="drilldown-example.png" x="119" y="34" width="162" height="132"/>
<area image="dropsite-example.png" x="32" y="319" width="181" height="91"/>
<area image="elasticnodes-example.png" x="72" y="71" width="120" height="107"/>
<area image="extension-example.png" x="15" y="31" width="198" height="84"/>
<area image="fancybrowser-example.png" x="385" y="201" width="170" height="94"/>
<area image="fetchmore-example.png" x="11" y="35" width="129" height="99"/>
<area image="findfiles-example.png" x="61" y="5" width="158" height="138"/>
<area image="flowlayout-example.png" x="14" y="34" width="165" height="92"/>
<area image="fontsampler-example.png" x="4" y="42" width="148" height="104"/>
<area image="formextractor-example.png" x="56" y="137" width="144" height="108"/>
<area image="fortuneclient-example.png" x="7" y="31" width="172" height="102"/>
<area image="fortuneserver-example.png" x="72" y="29" width="121" height="86"/>
<area image="framebufferobject-example.png" x="147" y="114" width="178" height="131"/>
<area image="framebufferobject2-example.png" x="194" y="152" width="127" height="133"/>
<area image="fridgemagnets-example.png" x="211" y="51" width="114" height="111"/>
<area image="frozencolumn-example.png" x="6" y="22" width="127" height="97"/>
<area image="googlechat-example.png" x="384" y="416" width="177" height="120"/>
<area image="googlesuggest-example.png" x="18" y="18" width="129" height="109"/>
<area image="grabber-example.png" x="180" y="105" width="158" height="142"/>
<area image="groupbox-example.png" x="11" y="30" width="163" height="101"/>
<area image="hellogl-example.png" x="93" y="96" width="118" height="144"/>
<area image="http-example.png" x="17" y="33" width="179" height="87"/>
<area image="i18n-example.png" x="15" y="103" width="130" height="108"/>
<area image="icons-example.png" x="243" y="87" width="160" height="114"/>
<area image="imagecomposition-example.png" x="618" y="72" width="137" height="127"/>
<area image="imageviewer-example.png" x="10" y="24" width="154" height="145"/>
<area image="inputpanel-example.png" x="59" y="131" width="163" height="140"/>
<area image="itemviewspuzzle-example.png" x="410" y="141" width="129" height="99"/>
<area image="licensewizard-example.png" x="147" y="40" width="176" height="117"/>
<area image="lineedits-example.png" x="236" y="26" width="125" height="118"/>
<area image="linguist-arrowpad_en.png" x="12" y="52" width="149" height="98"/>
<area image="linguist-hellotr_en.png" x="28" y="2" width="118" height="61"/>
<area image="linguist-trollprint_10_en.png" x="0" y="0" width="120" height="120"/>
<area image="localfortuneclient-example.png" x="8" y="27" width="161" height="86"/>
<area image="localfortuneserver-example.png" x="13" y="29" width="159" height="88"/>
<area image="loopback-example.png" x="11" y="35" width="122" height="116"/>
<area image="mandelbrot-example.png" x="67" y="77" width="161" height="123"/>
<area image="masterdetail-example.png" x="7" y="15" width="114" height="114"/>
<area image="mdi-example.png" x="134" y="46" width="147" height="127"/>
<area image="menus-example.png" x="0" y="0" width="120" height="120"/>
<area image="moveblocks-example.png" x="35" y="59" width="86" height="89"/>
<area image="movie-example.png" x="14" y="306" width="168" height="126"/>
<area image="network-chat-example.png" x="58" y="68" width="166" height="115"/>
<area image="orderform-example.png" x="247" y="212" width="157" height="106"/>
<area image="overpainting-example.png" x="119" y="69" width="172" height="139"/>
<area image="padnavigator-example.png" x="14" y="15" width="325" height="301"/>
<area image="painterpaths-example.png" x="9" y="286" width="172" height="113"/>
<area image="pbuffers-example.png" x="100" y="262" width="145" height="141"/>
<area image="pbuffers2-example.png" x="196" y="95" width="156" height="131"/>
<area image="pixelator-example.png" x="242" y="127" width="119" height="110"/>
<area image="plugandpaint.png" x="42" y="83" width="183" height="97"/>
<area image="portedasteroids-example.png" x="487" y="8" width="161" height="109"/>
<area image="portedcanvas-example.png" x="393" y="178" width="151" height="133"/>
<area image="previewer-example.png" x="108" y="62" width="186" height="119"/>
<area image="qml-clocks-example.png" x="244" y="90" width="157" height="133"/>
<area image="qml-corkboards-example.png" x="37" y="22" width="133" height="124"/>
<area image="qml-dialcontrol-example.png" x="84" y="70" width="123" height="104"/>
<area image="qml-dynamicscene-example.png" x="31" y="191" width="117" height="122"/>
<area image="qml-flipable-example.png" x="253" y="121" width="146" height="85"/>
<area image="qml-progressbar-example.png" x="2" y="11" width="158" height="96"/>
<area image="qml-scrollbar-example.png" x="1" y="2" width="490" height="348"/>
<area image="qml-searchbox-example.png" x="119" y="61" width="153" height="123"/>
<area image="qml-slideswitch-example.png" x="119" y="86" width="161" height="71"/>
<area image="qml-spinner-example.png" x="59" y="95" width="121" height="109"/>
<area image="qml-tabwidget-example.png" x="65" y="5" width="169" height="61"/>
<area image="qml-tic-tac-toe-example.png" x="26" y="48" width="381" height="372"/>
<area image="qml-tvtennis-example.png" x="225" y="249" width="134" height="111"/>
<area image="qobjectxmlmodel-example.png" x="9" y="41" width="139" height="119"/>
<area image="querymodel-example.png" x="462" y="48" width="129" height="113"/>
<area image="recentfiles-example.png" x="0" y="0" width="173" height="138"/>
<area image="recipes-example.png" x="3" y="139" width="154" height="103"/>
<area image="regexp-example.png" x="12" y="34" width="166" height="114"/>
<area image="relationaltablemodel-example.png" x="3" y="28" width="172" height="85"/>
<area image="rogue-example.png" x="7" y="30" width="115" height="100"/>
<area image="rsslistingexample.png" x="13" y="30" width="157" height="110"/>
<area image="samplebuffers-example.png" x="88" y="279" width="174" height="116"/>
<area image="saxbookmarks-example.png" x="4" y="53" width="143" height="114"/>
<area image="schema-example.png" x="55" y="104" width="169" height="98"/>
<area image="screenshot-example.png" x="7" y="169" width="176" height="135"/>
<area image="scribble-example.png" x="152" y="126" width="206" height="161"/>
<area image="sdi-example.png" x="3" y="9" width="150" height="132"/>
<area image="securesocketclient.png" x="10" y="25" width="148" height="101"/>
<area image="settingseditor-example.png" x="13" y="152" width="165" height="121"/>
<area image="shapedclock-example.png" x="107" y="36" width="131" height="115"/>
<area image="sharedmemory-example_1.png" x="149" y="18" width="164" height="79"/>
<area image="simpledommodel-example.png" x="7" y="84" width="134" height="111"/>
<area image="simpletreemodel-example.png" x="3" y="33" width="172" height="118"/>
<area image="simplewidgetmapper-example.png" x="11" y="36" width="160" height="91"/>
<area image="sliders-example.png" x="461" y="42" width="182" height="127"/>
<area image="spinboxdelegate-example.png" x="82" y="86" width="152" height="96"/>
<area image="spinboxes-example.png" x="263" y="65" width="169" height="113"/>
<area image="standarddialogs-example.png" x="187" y="33" width="178" height="149"/>
<area image="stardelegate.png" x="220" y="21" width="180" height="95"/>
<area image="states-example.png" x="236" y="258" width="176" height="77"/>
<area image="stickman-example.png" x="1" y="1" width="467" height="510"/>
<area image="styles-enabledwood.png" x="12" y="24" width="185" height="95"/>
<area image="stylesheet-coffee-plastique.png" x="40" y="64" width="180" height="115"/>
<area image="svggenerator-example.png" x="162" y="64" width="90" height="72"/>
<area image="svgviewer-example.png" x="193" y="245" width="102" height="91"/>
<area image="syntaxhighlighter-example.png" x="4" y="67" width="153" height="101"/>
<area image="systemtray-example.png" x="163" y="36" width="181" height="113"/>
<area image="t1.png" x="0" y="0" width="108" height="56"/>
<area image="tabdialog-example.png" x="7" y="30" width="168" height="105"/>
<area image="tablemodel-example.png" x="342" y="44" width="157" height="116"/>
<area image="tabletexample.png" x="26" y="70" width="167" height="112"/>
<area image="tetrix-example.png" x="46" y="72" width="112" height="112"/>
<area image="textobject-example.png" x="86" y="73" width="99" height="80"/>
<area image="textures-example.png" x="245" y="70" width="154" height="137"/>
<area image="threadedfortuneserver-example.png" x="100" y="30" width="122" height="85"/>
<area image="tooltips-example.png" x="96" y="63" width="128" height="129"/>
<area image="torrent-example.png" x="5" y="29" width="175" height="126"/>
<area image="trafficinfo-example.png" x="45" y="1" width="207" height="62"/>
<area image="trafficlight-example.png" x="8" y="219" width="112" height="104"/>
<area image="transformations-example.png" x="484" y="92" width="128" height="125"/>
<area image="treemodelcompleter-example.png" x="11" y="319" width="181" height="109"/>
<area image="trivialwizard-example-introduction.png" x="248" y="333" width="170" height="61"/>
<area image="undoframeworkexample.png" x="176" y="1" width="136" height="121"/>
<area image="wiggly-example.png" x="10" y="58" width="155" height="113"/>
<area image="windowflags-example.png" x="9" y="82" width="140" height="119"/>
<area image="worldtimeclockbuilder-example.png" x="99" y="57" width="154" height="93"/>
<area image="worldtimeclockplugin-example.png" x="109" y="34" width="141" height="116"/>
<area image="xmlstreamexample-screenshot.png" x="2" y="54" width="139" height="98"/>
</areas>
......@@ -75,7 +75,7 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
border.bottom: 4
border.right: 4
border.top: 5
border.top: 4
border.left: 4
source: "images/dropshadow.png"
......@@ -83,13 +83,11 @@ Rectangle {
id: imageItem
visible: !delegate.isVideo
anchors.rightMargin: 4
anchors.leftMargin: 4
anchors.bottomMargin: 4
anchors.topMargin: 4
anchors.fill: parent
anchors.centerIn: parent
asynchronous: true
sourceSize.height: 145
sourceSize.width: 188
fillMode: Image.Center
}
Image {
......
......@@ -33,6 +33,7 @@
#include "gettingstartedwelcomepage.h"
#include "exampleslistmodel.h"
#include "screenshotcropper.h"
#include <utils/pathchooser.h>
#include <utils/fileutils.h>
......@@ -170,12 +171,13 @@ public:
// gets called by declarative in separate thread
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
Q_UNUSED(size)
QMutexLocker lock(&m_mutex);
QUrl url = QUrl::fromEncoded(id.toAscii());
if (!m_fetcher.asynchronousFetchData(url))
return QImage();
if (!m_fetcher.asynchronousFetchData(url))
return QImage();
if (m_fetcher.data().isEmpty())
return QImage();
......@@ -184,11 +186,9 @@ public:
imgBuffer.open(QIODevice::ReadOnly);
QImageReader reader(&imgBuffer);
QImage img = reader.read();
if (size && requestedSize != *size)
img = img.scaled(requestedSize);
m_fetcher.clearData();
return img;
return ScreenshotCropper::croppedImage(img, id, requestedSize);
}
private:
Fetcher m_fetcher;
......
......@@ -25,7 +25,8 @@ HEADERS += \
profilereader.h \
qtparser.h \
gettingstartedwelcomepage.h \
exampleslistmodel.h
exampleslistmodel.h \
screenshotcropper.h
SOURCES += \
qtsupportplugin.cpp \
......@@ -41,7 +42,8 @@ SOURCES += \
profilereader.cpp \
qtparser.cpp \
gettingstartedwelcomepage.cpp \
exampleslistmodel.cpp
exampleslistmodel.cpp \
screenshotcropper.cpp
FORMS += \
showbuildlog.ui \
......
#include "screenshotcropper.h"
#include <coreplugin/icore.h>
#include <QtCore/QXmlStreamReader>
#include <QtCore/QXmlStreamWriter>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtGui/QPainter>
namespace QtSupport {
namespace Internal {
#ifdef QT_CREATOR
Q_GLOBAL_STATIC_WITH_INITIALIZER(AreasOfInterest, areasOfInterest, {
*x = ScreenshotCropper::loadAreasOfInterest(Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/images_areaofinterest.xml"));
})
#else
Q_GLOBAL_STATIC(AreasOfInterest, areasOfInterest)
#endif // QT_CREATOR
static inline QString fileNameForPath(const QString &path)
{
return QFileInfo(path).fileName();
}
static QRect cropRectForAreaOfInterest(const QSize &imageSize, const QSize &cropSize, const QRect &areaOfInterest)
{
QRect result;
const qreal cropSizeToAreaSizeFactor = qMin(cropSize.width() / qreal(areaOfInterest.width()),
cropSize.height() / qreal(areaOfInterest.height()));
if (cropSizeToAreaSizeFactor >= 1) {
const QPoint areaOfInterestCenter = areaOfInterest.center();
const int cropX = qBound(0,
areaOfInterestCenter.x() - cropSize.width() / 2,
imageSize.width() - cropSize.width());
const int cropY = qBound(0,
areaOfInterestCenter.y() - cropSize.height() / 2,
imageSize.height() - cropSize.height());
const int cropWidth = qMin(imageSize.width(), cropSize.width());
const int cropHeight = qMin(imageSize.height(), cropSize.height());
result = QRect(cropX, cropY, cropWidth, cropHeight);
} else {
QSize resultSize = cropSize.expandedTo(areaOfInterest.size());
result = QRect(QPoint(), resultSize);
}
return result;
}
QImage ScreenshotCropper::croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize)
{
const QRect areaOfInterest = areasOfInterest()->value(fileNameForPath(filePath));
if (areaOfInterest.isValid()) {
const QRect cropRect = cropRectForAreaOfInterest(sourceImage.size(), cropSize, areaOfInterest);
const QSize cropRectSize = cropRect.size();
const QImage result = sourceImage.copy(cropRect);
if (cropRectSize.width() > cropSize.width() || cropRectSize.height() > cropSize.height())
return result.scaled(cropSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
else
return result;
}
return sourceImage.scaled(cropSize, Qt::KeepAspectRatio);
}
static int areaAttribute(const QXmlStreamAttributes &attributes, const QString &name)
{
bool ok;
const int result = attributes.value(name).toString().toInt(&ok);
if (!ok)
qWarning() << Q_FUNC_INFO << "Could not parse" << name << "for" << attributes.value(QLatin1String("image")).toString();
return result;
}
static const QString xmlTagAreas = QLatin1String("areas");
static const QString xmlTagArea = QLatin1String("area");
static const QString xmlAttributeImage = QLatin1String("image");
static const QString xmlAttributeX = QLatin1String("x");
static const QString xmlAttributeY = QLatin1String("y");
static const QString xmlAttributeWidth = QLatin1String("width");
static const QString xmlAttributeHeight = QLatin1String("height");
AreasOfInterest ScreenshotCropper::loadAreasOfInterest(const QString &areasXmlFile)
{
AreasOfInterest areasOfInterest;
QFile xmlFile(areasXmlFile);
if (!xmlFile.open(QIODevice::ReadOnly)) {
qWarning() << Q_FUNC_INFO << "Could not open file" << areasXmlFile;
return areasOfInterest;
}
QXmlStreamReader reader(&xmlFile);
while (!reader.atEnd()) {
switch (reader.readNext()) {
case QXmlStreamReader::StartElement:
if (reader.name() == xmlTagArea) {
const QXmlStreamAttributes attributes = reader.attributes();
const QString imageName = attributes.value(xmlAttributeImage).toString();
if (imageName.isEmpty())
qWarning() << Q_FUNC_INFO << "Could not parse name";
const QRect area(areaAttribute(attributes, xmlAttributeX), areaAttribute(attributes, xmlAttributeY),
areaAttribute(attributes, xmlAttributeWidth), areaAttribute(attributes, xmlAttributeHeight));
areasOfInterest.insert(imageName, area);
}
break;
default: // nothing
break;
}
}
return areasOfInterest;
}
bool ScreenshotCropper::saveAreasOfInterest(const QString &areasXmlFile, AreasOfInterest &areas)
{
QFile file(areasXmlFile);
if (!file.open(QIODevice::WriteOnly))
return false;
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement(xmlTagAreas);
QMapIterator<QString, QRect> i(areas);
while (i.hasNext()) {
i.next();
writer.writeStartElement(xmlTagArea);
writer.writeAttribute(xmlAttributeImage, i.key());
writer.writeAttribute(xmlAttributeX, QString::number(i.value().x()));
writer.writeAttribute(xmlAttributeY, QString::number(i.value().y()));
writer.writeAttribute(xmlAttributeWidth, QString::number(i.value().width()));
writer.writeAttribute(xmlAttributeHeight, QString::number(i.value().height()));
writer.writeEndElement(); // xmlTagArea
}
writer.writeEndElement(); // xmlTagAreas
writer.writeEndDocument();
return true;
}
} // namespace Internal
} // namespace QtSupport
#ifndef SCREENSHOTCROPPER_H
#define SCREENSHOTCROPPER_H
#include <QtCore/QMap>
#include <QtCore/QRect>
#include <QtGui/QImage>
namespace QtSupport {
namespace Internal {
typedef QMap<QString, QRect> AreasOfInterest;
class ScreenshotCropper
{
public:
static QImage croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize);
static AreasOfInterest loadAreasOfInterest(const QString &areasXmlFile);
static bool saveAreasOfInterest(const QString &areasXmlFile, AreasOfInterest &areas);
};
} // namespace Internal
} // namespace QtSupport
#endif // SCREENSHOTCROPPER_H
#include "cropimageview.h"
#include <QtGui/QPainter>
#include <QtGui/QMouseEvent>
CropImageView::CropImageView(QWidget *parent)
: QWidget(parent)
{
}
void CropImageView::mousePressEvent(QMouseEvent *event)
{
setArea(QRect(event->pos(), m_area.bottomRight()));
update();
}
void CropImageView::mouseMoveEvent(QMouseEvent *event)
{
setArea(QRect(m_area.topLeft(), event->pos()));
update();
}
void CropImageView::mouseReleaseEvent(QMouseEvent *event)
{
mouseMoveEvent(event);
}
void CropImageView::setImage(const QImage &image)
{
m_image = image;
setMinimumSize(image.size());
update();
}
void CropImageView::setArea(const QRect &area)
{
m_area = m_image.rect().intersected(area);
emit cropAreaChanged(m_area);
update();
}
void CropImageView::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter p(this);
if (!m_image.isNull())
p.drawImage(0, 0, m_image);
if (!m_area.isNull()) {
p.setPen(Qt::white);
p.drawRect(m_area);
QPen redDashes;
redDashes.setColor(Qt::red);
redDashes.setStyle(Qt::DashLine);
p.setPen(redDashes);
p.drawRect(m_area);
}
}
#ifndef CROPIMAGEVIEW_H
#define CROPIMAGEVIEW_H
#include <QWidget>
class CropImageView : public QWidget
{
Q_OBJECT
public:
explicit CropImageView(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
public slots:
void setImage(const QImage &image);
void setArea(const QRect &area);
signals:
void cropAreaChanged(const QRect &area);
private:
QImage m_image;
QRect m_area;
};
#endif // CROPIMAGEVIEW_H
#include <QtGui>
#include "screenshotcropperwindow.h"
using namespace QtSupport::Internal;
const QString settingsKeyAreasXmlFile = QLatin1String("areasXmlFile");
const QString settingsKeyImagesFolder = QLatin1String("imagesFolder");
static void promptPaths(QString &areasXmlFile, QString &imagesFolder)
{
QSettings settings(QLatin1String("Nokia"), QLatin1String("Qt Creator Screenshot Cropper"));
areasXmlFile = settings.value(settingsKeyAreasXmlFile).toString();
areasXmlFile = QFileDialog::getOpenFileName(0, QLatin1String("Select the 'images_areaofinterest.xml' file in Qt Creator's sources"), areasXmlFile);
settings.setValue(settingsKeyAreasXmlFile, areasXmlFile);
imagesFolder = settings.value(settingsKeyImagesFolder).toString();
imagesFolder = QFileDialog::getExistingDirectory(0, QLatin1String("Select the 'doc/src/images' folder in Qt's sources"), imagesFolder);
settings.setValue(settingsKeyImagesFolder, imagesFolder);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString areasXmlFile;
QString imagesFolder;
promptPaths(areasXmlFile, imagesFolder);
ScreenShotCropperWindow w;
w.show();
w.loadData(areasXmlFile, imagesFolder);
w.selectImage(0);
return a.exec();
}
SOURCES += \
main.cpp\
screenshotcropperwindow.cpp \
cropimageview.cpp \
../../plugins/qtsupport/screenshotcropper.cpp
HEADERS += \
screenshotcropperwindow.h \
cropimageview.h \
../../plugins/qtsupport/screenshotcropper.h