/*************************************************************************** * This file is part of the Lime Report project * * Copyright (C) 2021 by Alexander Arin * * arin_a@bk.ru * * * ** GNU General Public License Usage ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ** GNU Lesser General Public License ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public * * License along with this library. * * If not, see . * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * ****************************************************************************/ #include "lrimageitem.h" #include "lrdatasourcemanager.h" #include "lrdesignelementsfactory.h" #include "lrglobal.h" #include "lrimageitemeditor.h" #include "lrpagedesignintf.h" namespace { const QString xmlTag = "ImageItem"; LimeReport::BaseDesignIntf* createImageItem(QObject* owner, LimeReport::BaseDesignIntf* parent) { return new LimeReport::ImageItem(owner, parent); } bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, LimeReport::ItemAttribs(QObject::tr("Image Item"), "Item"), createImageItem); } // namespace namespace LimeReport { ImageItem::ImageItem(QObject* owner, QGraphicsItem* parent): ItemDesignIntf(xmlTag, owner, parent), m_useExternalPainter(false), m_externalPainter(0), m_autoSize(false), m_scale(true), m_keepAspectRatio(true), m_center(true), m_format(Binary) { } BaseDesignIntf* ImageItem::createSameTypeItem(QObject* owner, QGraphicsItem* parent) { ImageItem* result = new ImageItem(owner, parent); result->setExternalPainter(m_externalPainter); return result; } void ImageItem::loadPictureFromVariant(QVariant& data) { // TODO: Migrate to QMetaType if (data.isValid()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) if (data.typeId() == QMetaType::QImage) { #else if (data.type() == QVariant::Image) { #endif m_picture = data.value(); } else { switch (m_format) { default: case Binary: m_picture.loadFromData(data.toByteArray()); break; case Hex: m_picture.loadFromData(QByteArray::fromHex(data.toByteArray())); break; case Base64: m_picture.loadFromData(QByteArray::fromBase64(data.toByteArray())); break; } } } } void ImageItem::preparePopUpMenu(QMenu& menu) { QAction* editAction = menu.addAction(QIcon(":/report/images/edit_pecil2.png"), tr("Edit")); menu.insertAction(menu.actions().at(0), editAction); menu.insertSeparator(menu.actions().at(1)); menu.addSeparator(); QAction* action = menu.addAction(tr("Watermark")); action->setCheckable(true); action->setChecked(isWatermark()); } void ImageItem::processPopUpAction(QAction* action) { if (action->text().compare(tr("Watermark")) == 0) { page()->setPropertyToSelectedItems("watermark", action->isChecked()); } if (action->text().compare(tr("Edit")) == 0) { this->showEditorDialog(); } ItemDesignIntf::processPopUpAction(action); } QImage getFileByResourcePath(QString resourcePath) { QFileInfo resourceFile(resourcePath); if (resourceFile.exists()) return QImage(resourcePath); return QImage(); } QImage ImageItem::drawImage() const { if (image().isNull()) return getFileByResourcePath(m_resourcePath); return image(); } bool ImageItem::useExternalPainter() const { return m_useExternalPainter; } void ImageItem::setUseExternalPainter(bool value) { if (m_useExternalPainter != value) { m_useExternalPainter = value; notify("useExternalPainter", !value, value); update(); } } QWidget* ImageItem::defaultEditor() { ImageItemEditor* editor = new ImageItemEditor(this); editor->setAttribute(Qt::WA_DeleteOnClose); return editor; } QByteArray ImageItem::imageAsByteArray() const { QByteArray result; QBuffer buffer(&result); buffer.open(QIODevice::WriteOnly); m_picture.save(&buffer, "PNG"); return result; } void ImageItem::setImageAsByteArray(QByteArray image) { QImage value; value.loadFromData(image); setImage(value); } QString ImageItem::fileFilter() const { return tr("Images (*.gif *.icns *.ico *.jpeg *.tga *.tiff *.wbmp *.webp *.png *.jpg " "*.bmp);;All(*.*)"); } void ImageItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) { if (m_picture.isNull()) { if (!m_datasource.isEmpty() && !m_field.isEmpty()) { IDataSource* ds = dataManager->dataSource(m_datasource); if (ds) { QVariant data = ds->data(m_field); loadPictureFromVariant(data); } } else if (!m_resourcePath.isEmpty()) { m_resourcePath = expandUserVariables(m_resourcePath, pass, NoEscapeSymbols, dataManager); m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager); m_picture = QImage(m_resourcePath); } else if (!m_variable.isEmpty()) { // TODO: Migrate to QMetaType QVariant data = dataManager->variable(m_variable); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) if (data.typeId() == QMetaType::QString) { #else if (data.type() == QVariant::String) { #endif m_picture = QImage(data.toString()); } else { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) if (data.typeId() == QMetaType::QImage) { #else if (data.type() == QVariant::Image) { #endif loadPictureFromVariant(data); } } } } if (m_autoSize) { setWidth(m_picture.width()); setHeight(m_picture.height()); } BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); } bool ImageItem::isNeedUpdateSize(RenderPass) const { return m_picture.isNull() || m_autoSize; } QString ImageItem::resourcePath() const { return m_resourcePath; } qreal ImageItem::minHeight() const { if (!m_picture.isNull() && autoSize()) { return m_picture.height(); } else { return 0; } } void ImageItem::setVariable(const QString& content) { if (m_variable != content) { QString oldValue = m_variable; m_variable = content; update(); notify("variable", oldValue, m_variable); } } bool ImageItem::center() const { return m_center; } void ImageItem::setCenter(bool center) { if (m_center != center) { m_center = center; update(); notify("center", !center, center); } } bool ImageItem::keepAspectRatio() const { return m_keepAspectRatio; } void ImageItem::setKeepAspectRatio(bool keepAspectRatio) { if (m_keepAspectRatio != keepAspectRatio) { m_keepAspectRatio = keepAspectRatio; update(); notify("keepAspectRatio", !keepAspectRatio, keepAspectRatio); } } bool ImageItem::scale() const { return m_scale; } void ImageItem::setScale(bool scale) { if (m_scale != scale) { m_scale = scale; update(); notify("scale", !scale, scale); } } bool ImageItem::autoSize() const { return m_autoSize; } void ImageItem::setAutoSize(bool autoSize) { if (m_autoSize != autoSize) { m_autoSize = autoSize; if (m_autoSize && !m_picture.isNull()) { setWidth(drawImage().width()); setHeight(drawImage().height()); setPossibleResizeDirectionFlags(Fixed); } else { setPossibleResizeDirectionFlags(AllDirections); } update(); notify("autoSize", !autoSize, autoSize); } } QString ImageItem::field() const { return m_field; } void ImageItem::setField(const QString& field) { if (m_field != field) { QString oldValue = m_field; m_field = field; update(); notify("field", oldValue, field); } } QString ImageItem::datasource() const { return m_datasource; } void ImageItem::setDatasource(const QString& datasource) { if (m_datasource != datasource) { QString oldValue = m_datasource; m_datasource = datasource; update(); notify("datasource", oldValue, datasource); } } void ImageItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->save(); if (isSelected()) painter->setOpacity(Const::SELECTION_OPACITY); else painter->setOpacity(qreal(opacity()) / 100); QPointF point = rect().topLeft(); QImage img; if (m_scale && !drawImage().isNull()) { img = drawImage().scaled(rect().width(), rect().height(), keepAspectRatio() ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } else { img = drawImage(); } qreal shiftHeight = rect().height() - img.height(); qreal shiftWidth = rect().width() - img.width(); if (m_center) { if (shiftHeight < 0 || shiftWidth < 0) { qreal cutX = 0; qreal cutY = 0; qreal cutWidth = img.width(); qreal cutHeigth = img.height(); if (shiftWidth > 0) { point.setX(point.x() + shiftWidth / 2); } else { cutX = fabs(shiftWidth / 2); cutWidth += shiftWidth; } if (shiftHeight > 0) { point.setY(point.y() + shiftHeight / 2); } else { cutY = fabs(shiftHeight / 2); cutHeigth += shiftHeight; } img = img.copy(cutX, cutY, cutWidth, cutHeigth); } else { point.setX(point.x() + shiftWidth / 2); point.setY(point.y() + shiftHeight / 2); } } if (img.isNull() && itemMode() == DesignMode) { QString text; painter->setFont(transformToSceneFont(QFont("Arial", 10))); painter->setPen(Qt::black); if (!datasource().isEmpty() && !field().isEmpty()) text = datasource() + "." + field(); else if (m_useExternalPainter) text = tr("Ext."); else text = tr("Image"); painter->drawText(rect().adjusted(4, 4, -4, -4), Qt::AlignCenter, text); } else { if (m_externalPainter && m_useExternalPainter) m_externalPainter->paintByExternalPainter(this->patternName(), painter, option); else painter->drawImage(point, img); } ItemDesignIntf::paint(painter, option, widget); painter->restore(); } void ImageItem::setImage(QImage value) { if (m_picture != value) { QImage oldValue = m_picture; m_picture = value; if (m_autoSize) { setWidth(m_picture.width()); setHeight(m_picture.height()); } update(); notify("image", oldValue, value); } } QImage ImageItem::image() const { return m_picture; } void ImageItem::setResourcePath(const QString& value) { if (m_resourcePath != value) { QString oldValue = m_resourcePath; m_resourcePath = value; update(); notify("resourcePath", oldValue, value); } } ImageItem::Format ImageItem::format() const { return m_format; } void ImageItem::setFormat(Format format) { if (m_format != format) { Format oldValue = m_format; m_format = format; update(); notify("format", oldValue, format); } } } // namespace LimeReport bool LimeReport::ImageItem::isEmpty() const { return drawImage().isNull(); }