File indexing completed on 2025-01-19 13:26:34

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
0003  * Copyright (C) 2019 Dag Andersen <danders@get2net.dk>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 
0021 #include "ImageExportOptionsWidget.h"
0022 
0023 #include <KarbonDocument.h>
0024 #include <KoPAPageBase.h>
0025 
0026 #include <KoUnit.h> // for POINT_TO_INCH
0027 #include <KoDpi.h>
0028 #include <KoShapePainter.h>
0029 #include <KoZoomHandler.h>
0030 
0031 ImageExportOptionsWidget::ImageExportOptionsWidget(KarbonDocument *doc, QWidget * parent)
0032     : QWidget(parent), m_doc(doc)
0033 {
0034     KoUnit unit;
0035 
0036     widget.setupUi(this);
0037 
0038     widget.pxWidth->setRange(1, 10000);
0039     widget.pxWidth->setAlignment(Qt::AlignRight);
0040     widget.pxWidth->setSuffix(" px");
0041     widget.pxHeight->setRange(1, 10000);
0042     widget.pxHeight->setAlignment(Qt::AlignRight);
0043     widget.pxHeight->setSuffix(" px");
0044     widget.unitWidth->setMinMaxStep(0, 10000, 1);
0045     widget.unitHeight->setMinMaxStep(0, 10000, 1);
0046     widget.dpi->setRange(1, 10000);
0047     widget.dpi->setValue(KoDpi::dpiX());
0048     widget.dpi->setAlignment(Qt::AlignRight);
0049     widget.dpi->setSuffix(" DPI");
0050     widget.pxAspect->setKeepAspectRatio(true);
0051     widget.unitAspect->setKeepAspectRatio(true);
0052     widget.unit->addItems(KoUnit::listOfUnitNameForUi(KoUnit::HidePixel));
0053     widget.unit->setCurrentIndex(unit.indexInListForUi(KoUnit::HidePixel));
0054     widget.backColor->setColor(Qt::white);
0055     widget.opacity->setMinimum(0.0);
0056     widget.opacity->setMaximum(100.0);
0057     widget.opacity->setValue(0.0);
0058 
0059     for (int i = 0; i < doc->pageCount(); ++i) {
0060         widget.pageCombo->addItem(i18n("Page %1", i+1));
0061     }
0062     setPage(0);
0063 
0064     widget.unitWidth->changeValue(m_pointSize.width());
0065     widget.unitHeight->changeValue(m_pointSize.height());
0066 
0067     connect(widget.unitWidth, SIGNAL(valueChangedPt(qreal)), this, SLOT(unitWidthChanged(qreal)));
0068     connect(widget.unitHeight, SIGNAL(valueChangedPt(qreal)), this, SLOT(unitHeightChanged(qreal)));
0069     connect(widget.pxWidth, SIGNAL(valueChanged(int)), this, SLOT(pxWidthChanged(int)));
0070     connect(widget.pxHeight, SIGNAL(valueChanged(int)), this, SLOT(pxHeightChanged(int)));
0071     connect(widget.dpi, SIGNAL(valueChanged(int)), this, SLOT(dpiChanged(int)));
0072     connect(widget.unit, SIGNAL(activated(int)), this, SLOT(unitChanged(int)));
0073     connect(widget.pxAspect, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(aspectChanged(bool)));
0074     connect(widget.unitAspect, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(aspectChanged(bool)));
0075     connect(widget.pageCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setPage(int)));
0076 }
0077 
0078 void ImageExportOptionsWidget::setPage(int idx)
0079 {
0080     KoPAPageBase *page = m_doc->pages().value(idx);
0081     if (!page) {
0082         page = m_doc->pages().first();
0083     }
0084     KoShapePainter painter;
0085     painter.setShapes(page->shapes());
0086     // get the bounding rect of the content
0087     QRectF shapesRect = painter.contentRect();
0088     // get the size in point
0089     m_pointSize = shapesRect.size();
0090     updateFromPointSize(m_pointSize);
0091 }
0092 
0093 KoPAPageBase *ImageExportOptionsWidget::page() const
0094 {
0095     return m_doc->pages().value(widget.pageCombo->currentIndex());
0096 }
0097 
0098 void ImageExportOptionsWidget::setUnit(const KoUnit &unit)
0099 {
0100     widget.unitWidth->setUnit(unit);
0101     widget.unitHeight->setUnit(unit);
0102     widget.unit->setCurrentIndex(unit.indexInListForUi(KoUnit::HidePixel));
0103 }
0104 
0105 QSize ImageExportOptionsWidget::pixelSize() const
0106 {
0107     return QSize(widget.pxWidth->value(), widget.pxHeight->value());
0108 }
0109 
0110 QSizeF ImageExportOptionsWidget::pointSize() const
0111 {
0112     return QSizeF(widget.unitWidth->value(), widget.unitHeight->value());
0113 }
0114 
0115 void ImageExportOptionsWidget::setBackgroundColor(const QColor &color)
0116 {
0117     blockChildSignals(true);
0118 
0119     widget.backColor->setColor(color);
0120     widget.opacity->setValue(color.alphaF() * 100.0);
0121 
0122     blockChildSignals(false);
0123 }
0124 
0125 QColor ImageExportOptionsWidget::backgroundColor() const
0126 {
0127     QColor color = widget.backColor->color();
0128     color.setAlphaF(0.01 * widget.opacity->value());
0129     return color;
0130 }
0131 
0132 void ImageExportOptionsWidget::updateFromPointSize(const QSizeF &pointSize)
0133 {
0134     blockChildSignals(true);
0135     widget.pxWidth->setValue(qRound(POINT_TO_INCH(pointSize.width()) * widget.dpi->value()));
0136     widget.pxHeight->setValue(qRound(POINT_TO_INCH(pointSize.height()) * widget.dpi->value()));
0137     blockChildSignals(false);
0138 }
0139 
0140 void ImageExportOptionsWidget::updateFromPixelSize(const QSize &pixelSize)
0141 {
0142     blockChildSignals(true);
0143     double inchWidth = static_cast<double>(pixelSize.width()) / static_cast<double>(widget.dpi->value());
0144     double inchHeight = static_cast<double>(pixelSize.height()) / static_cast<double>(widget.dpi->value());
0145     widget.unitWidth->changeValue(INCH_TO_POINT(inchWidth));
0146     widget.unitHeight->changeValue(INCH_TO_POINT(inchHeight));
0147     blockChildSignals(false);
0148 }
0149 
0150 void ImageExportOptionsWidget::blockChildSignals(bool block)
0151 {
0152     widget.pxWidth->blockSignals(block);
0153     widget.pxHeight->blockSignals(block);
0154     widget.unitWidth->blockSignals(block);
0155     widget.unitHeight->blockSignals(block);
0156     widget.dpi->blockSignals(block);
0157     widget.backColor->blockSignals(block);
0158     widget.opacity->blockSignals(block);
0159 }
0160 
0161 void ImageExportOptionsWidget::unitWidthChanged(qreal newWidth)
0162 {
0163     blockChildSignals(true);
0164 
0165     double newHeight = widget.unitHeight->value();
0166     if (widget.unitAspect->keepAspectRatio()) {
0167         newHeight = newWidth * m_pointSize.height() / m_pointSize.width();
0168         widget.unitHeight->changeValue(newHeight);
0169     }
0170     updateFromPointSize(QSizeF(newWidth, newHeight));
0171 
0172     blockChildSignals(false);
0173 }
0174 
0175 void ImageExportOptionsWidget::unitHeightChanged(qreal newHeight)
0176 {
0177     blockChildSignals(true);
0178 
0179     double newWidth = widget.unitWidth->value();
0180     if (widget.unitAspect->keepAspectRatio()) {
0181         newWidth = newHeight * m_pointSize.width() / m_pointSize.height();
0182         widget.unitWidth->changeValue(newWidth);
0183     }
0184     updateFromPointSize(QSizeF(newWidth, newHeight));
0185 
0186     blockChildSignals(false);
0187 }
0188 
0189 void ImageExportOptionsWidget::pxWidthChanged(int newWidth)
0190 {
0191     blockChildSignals(true);
0192 
0193     int newHeight = widget.pxHeight->value();
0194     if (widget.pxAspect->keepAspectRatio()) {
0195         newHeight = qRound(newWidth * m_pointSize.height() / m_pointSize.width());
0196         widget.pxHeight->setValue(newHeight);
0197     }
0198     updateFromPixelSize(QSize(newWidth, newHeight));
0199 
0200     blockChildSignals(false);
0201 }
0202 
0203 void ImageExportOptionsWidget::pxHeightChanged(int newHeight)
0204 {
0205     blockChildSignals(true);
0206 
0207     int newWidth = widget.pxWidth->value();
0208     if (widget.pxAspect->keepAspectRatio()) {
0209         newWidth = qRound(newHeight * m_pointSize.width() / m_pointSize.height());
0210         widget.pxWidth->setValue(newWidth);
0211     }
0212     updateFromPixelSize(QSize(newWidth, newHeight));
0213 
0214     blockChildSignals(false);
0215 }
0216 
0217 void ImageExportOptionsWidget::dpiChanged(int)
0218 {
0219     blockChildSignals(true);
0220 
0221     updateFromPointSize(QSizeF(widget.unitWidth->value(), widget.unitHeight->value()));
0222 
0223     blockChildSignals(false);
0224 }
0225 
0226 void ImageExportOptionsWidget::unitChanged(int newUnit)
0227 {
0228     blockChildSignals(true);
0229 
0230     const KoUnit unit = KoUnit::fromListForUi(newUnit, KoUnit::HidePixel);
0231     widget.unitWidth->setUnit(unit);
0232     widget.unitHeight->setUnit(unit);
0233 
0234     blockChildSignals(false);
0235 }
0236 
0237 void ImageExportOptionsWidget::aspectChanged(bool keepAspect)
0238 {
0239     blockChildSignals(true);
0240 
0241     widget.pxAspect->setKeepAspectRatio(keepAspect);
0242     widget.unitAspect->setKeepAspectRatio(keepAspect);
0243 
0244     blockChildSignals(false);
0245 
0246     if (keepAspect)
0247         unitWidthChanged(widget.unitWidth->value());
0248 }
0249 
0250 void ImageExportOptionsWidget::enableBackgroundOpacity(bool enable)
0251 {
0252     widget.opacity->setVisible(enable);
0253     widget.labelOpacity->setVisible(enable);
0254 }