summaryrefslogtreecommitdiff
path: root/src/plugins/qtsupport/screenshotcropper.cpp
diff options
context:
space:
mode:
authorAlessandro Portale <alessandro.portale@nokia.com>2011-11-24 15:14:53 +0100
committerAlessandro Portale <alessandro.portale@nokia.com>2011-11-25 17:12:58 +0100
commit6c36a2a9ad5e495d31c2e20e7e76e57a0ede684f (patch)
tree99e1d8ce8543fa6982b37826f8dadb0ed1979cd9 /src/plugins/qtsupport/screenshotcropper.cpp
parent9e0cae5dac4d388caa948205a8e72cda199a213f (diff)
downloadqt-creator-6c36a2a9ad5e495d31c2e20e7e76e57a0ede684f.tar.gz
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: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Diffstat (limited to 'src/plugins/qtsupport/screenshotcropper.cpp')
-rw-r--r--src/plugins/qtsupport/screenshotcropper.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/plugins/qtsupport/screenshotcropper.cpp b/src/plugins/qtsupport/screenshotcropper.cpp
new file mode 100644
index 0000000000..e678e40cf0
--- /dev/null
+++ b/src/plugins/qtsupport/screenshotcropper.cpp
@@ -0,0 +1,141 @@
+#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