File indexing completed on 2025-02-23 04:09:11
0001 /* 0002 * dlg_layersize.cc - part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org> 0005 * SPDX-FileCopyrightText: 2005 Sven Langkamp <sven.langkamp@gmail.com> 0006 * SPDX-FileCopyrightText: 2013 Juan Palacios <jpalaciosdev@gmail.com> 0007 * 0008 * SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "dlg_layersize.h" 0012 0013 #include <KoUnit.h> 0014 #include <kis_config.h> 0015 0016 #include <klocalizedstring.h> 0017 0018 #include <kis_document_aware_spin_box_unit_manager.h> 0019 0020 #include <kis_filter_strategy.h>// XXX: I'm really real bad at arithmetic, let alone math. Here 0021 // be rounding errors. (Boudewijn) 0022 0023 const QString DlgLayerSize::PARAM_PREFIX = "layersizedlg"; 0024 0025 const QString DlgLayerSize::PARAM_WIDTH_UNIT = DlgLayerSize::PARAM_PREFIX + "_widthunit"; 0026 const QString DlgLayerSize::PARAM_HEIGHT_UNIT = DlgLayerSize::PARAM_PREFIX + "_heightunit"; 0027 0028 const QString DlgLayerSize::PARAM_KEEP_AR = DlgLayerSize::PARAM_PREFIX + "_keepar"; 0029 const QString DlgLayerSize::PARAM_KEEP_PROP = DlgLayerSize::PARAM_PREFIX + "_keepprop"; 0030 0031 static KisFilterStrategy *lastUsedFilter = nullptr; 0032 0033 DlgLayerSize::DlgLayerSize(QWidget * parent, const char * name, 0034 int width, int height, double resolution) 0035 : KoDialog(parent) 0036 , m_aspectRatio(((double) width) / height) 0037 , m_originalWidth(width) 0038 , m_originalHeight(height) 0039 , m_width(width) 0040 , m_height(height) 0041 , m_resolution(resolution) 0042 , m_keepAspect(true) 0043 { 0044 setCaption(i18n("Layer Size")); 0045 setObjectName(name); 0046 setButtons(Ok | Cancel); 0047 setDefaultButton(Ok); 0048 0049 m_page = new WdgLayerSize(this); 0050 Q_CHECK_PTR(m_page); 0051 m_page->layout()->setMargin(0); 0052 m_page->setObjectName(name); 0053 0054 KisConfig cfg(true); 0055 0056 _widthUnitManager = new KisDocumentAwareSpinBoxUnitManager(this); 0057 _heightUnitManager = new KisDocumentAwareSpinBoxUnitManager(this, KisDocumentAwareSpinBoxUnitManager::PIX_DIR_Y); 0058 0059 _widthUnitManager->setApparentUnitFromSymbol("px"); 0060 _heightUnitManager->setApparentUnitFromSymbol("px"); 0061 0062 m_page->newWidthDouble->setUnitManager(_widthUnitManager); 0063 m_page->newHeightDouble->setUnitManager(_heightUnitManager); 0064 m_page->newWidthDouble->setDecimals(2); 0065 m_page->newHeightDouble->setDecimals(2); 0066 m_page->newWidthDouble->setDisplayUnit(false); 0067 m_page->newHeightDouble->setDisplayUnit(false); 0068 0069 m_page->newWidthDouble->setValue(width); 0070 m_page->newWidthDouble->setFocus(); 0071 m_page->newHeightDouble->setValue(height); 0072 0073 m_page->filterCmb->setIDList(KisFilterStrategyRegistry::instance()->listKeys()); 0074 m_page->filterCmb->setToolTip(KisFilterStrategyRegistry::instance()->formattedDescriptions()); 0075 m_page->filterCmb->allowAuto(true); 0076 0077 if (lastUsedFilter) { // Restore or Init.. 0078 m_page->filterCmb->setCurrent(lastUsedFilter->id()); 0079 } else { 0080 m_page->filterCmb->setCurrent(KisCmbIDList::AutoOptionID); 0081 } 0082 0083 m_page->newWidthUnit->setModel(_widthUnitManager); 0084 m_page->newHeightUnit->setModel(_heightUnitManager); 0085 0086 QString unitw = cfg.readEntry<QString>(PARAM_WIDTH_UNIT, "px"); 0087 QString unith = cfg.readEntry<QString>(PARAM_HEIGHT_UNIT, "px"); 0088 0089 _widthUnitManager->setApparentUnitFromSymbol(unitw); 0090 _heightUnitManager->setApparentUnitFromSymbol(unith); 0091 0092 const int wUnitIndex = _widthUnitManager->getsUnitSymbolList().indexOf(unitw); 0093 const int hUnitIndex = _widthUnitManager->getsUnitSymbolList().indexOf(unith); 0094 0095 m_page->newWidthUnit->setCurrentIndex(wUnitIndex); 0096 m_page->newHeightUnit->setCurrentIndex(hUnitIndex); 0097 0098 m_keepAspect = cfg.readEntry(PARAM_KEEP_AR,true); 0099 m_page->aspectRatioBtn->setKeepAspectRatio(m_keepAspect); 0100 m_page->constrainProportionsCkb->setChecked(cfg.readEntry(PARAM_KEEP_PROP,true)); 0101 0102 setMainWidget(m_page); 0103 connect(this, SIGNAL(okClicked()), this, SLOT(accept())); 0104 0105 connect(m_page->aspectRatioBtn, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(slotAspectChanged(bool))); 0106 connect(m_page->constrainProportionsCkb, SIGNAL(toggled(bool)), this, SLOT(slotAspectChanged(bool))); 0107 0108 connect(m_page->newWidthDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotWidthChanged(double))); 0109 connect(m_page->newHeightDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotHeightChanged(double))); 0110 0111 connect(m_page->newWidthUnit, SIGNAL(currentIndexChanged(int)), _widthUnitManager, SLOT(selectApparentUnitFromIndex(int))); 0112 connect(m_page->newHeightUnit, SIGNAL(currentIndexChanged(int)), _heightUnitManager, SLOT(selectApparentUnitFromIndex(int))); 0113 connect(_widthUnitManager, SIGNAL(unitChanged(int)), m_page->newWidthUnit, SLOT(setCurrentIndex(int))); 0114 connect(_heightUnitManager, SIGNAL(unitChanged(int)), m_page->newHeightUnit, SLOT(setCurrentIndex(int))); 0115 0116 connect(this, &DlgLayerSize::sigDesiredSizeChanged, [this](qint32 width, qint32 height, double){ 0117 KisFilterStrategy *filterStrategy = KisFilterStrategyRegistry::instance()->autoFilterStrategy(QSize(m_originalWidth, m_originalHeight), QSize(width, height)); 0118 m_page->filterCmb->setAutoHint(filterStrategy->name()); 0119 }); 0120 } 0121 0122 DlgLayerSize::~DlgLayerSize() 0123 { 0124 0125 KisConfig cfg(false); 0126 0127 cfg.writeEntry<bool>(PARAM_KEEP_AR, m_page->aspectRatioBtn->keepAspectRatio()); 0128 cfg.writeEntry<bool>(PARAM_KEEP_PROP, m_page->constrainProportionsCkb->isChecked()); 0129 0130 cfg.writeEntry<QString>(PARAM_WIDTH_UNIT, _widthUnitManager->getApparentUnitSymbol()); 0131 cfg.writeEntry<QString>(PARAM_HEIGHT_UNIT, _heightUnitManager->getApparentUnitSymbol()); 0132 0133 delete m_page; 0134 } 0135 0136 qint32 DlgLayerSize::desiredWidth() 0137 { 0138 return (qint32)m_width; 0139 } 0140 0141 qint32 DlgLayerSize::desiredHeight() 0142 { 0143 return (qint32)m_height; 0144 } 0145 0146 KisFilterStrategy *DlgLayerSize::filterType() 0147 { 0148 KoID filterID = m_page->filterCmb->currentItem(); 0149 0150 KisFilterStrategy *filter; 0151 if (filterID == KisCmbIDList::AutoOptionID) { 0152 filter = KisFilterStrategyRegistry::instance()->autoFilterStrategy(QSize(m_originalWidth, m_originalHeight), QSize(desiredWidth(), desiredHeight())); 0153 } else { 0154 filter = KisFilterStrategyRegistry::instance()->value(filterID.id()); 0155 lastUsedFilter = filter; // Save for next time! 0156 } 0157 0158 return filter; 0159 } 0160 0161 // SLOTS 0162 0163 void DlgLayerSize::slotWidthChanged(double w) 0164 { 0165 0166 //this slot receiv values in pt from the unitspinbox, so just use the resolution. 0167 const double resValue = w*_widthUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px"); 0168 m_width = qRound(resValue); 0169 0170 if (m_keepAspect) { 0171 m_height = qRound(m_width / m_aspectRatio); 0172 m_page->newHeightDouble->blockSignals(true); 0173 m_page->newHeightDouble->changeValue(w / m_aspectRatio); 0174 m_page->newHeightDouble->blockSignals(false); 0175 } 0176 0177 emit sigDesiredSizeChanged(desiredWidth(), desiredHeight(), m_resolution); 0178 } 0179 0180 void DlgLayerSize::slotHeightChanged(double h) 0181 { 0182 0183 //this slot receiv values in pt from the unitspinbox, so just use the resolution. 0184 const double resValue = h*_heightUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px"); 0185 m_height = qRound(resValue); 0186 0187 if (m_keepAspect) { 0188 m_width = qRound(m_height * m_aspectRatio); 0189 m_page->newWidthDouble->blockSignals(true); 0190 m_page->newWidthDouble->changeValue(h * m_aspectRatio); 0191 m_page->newWidthDouble->blockSignals(false); 0192 } 0193 0194 emit sigDesiredSizeChanged(desiredWidth(), desiredHeight(), m_resolution); 0195 } 0196 0197 void DlgLayerSize::slotAspectChanged(bool keep) 0198 { 0199 m_page->aspectRatioBtn->blockSignals(true); 0200 m_page->constrainProportionsCkb->blockSignals(true); 0201 0202 m_page->aspectRatioBtn->setKeepAspectRatio(keep); 0203 m_page->constrainProportionsCkb->setChecked(keep); 0204 0205 m_page->aspectRatioBtn->blockSignals(false); 0206 m_page->constrainProportionsCkb->blockSignals(false); 0207 0208 m_keepAspect = keep; 0209 0210 if (keep) { 0211 // values may be out of sync, so we need to reset it to defaults 0212 m_width = m_originalWidth; 0213 m_height = m_originalHeight; 0214 0215 updateWidthUIValue(m_width); 0216 updateHeightUIValue(m_height); 0217 } 0218 } 0219 0220 void DlgLayerSize::updateWidthUIValue(double value) 0221 { 0222 m_page->newWidthDouble->blockSignals(true); 0223 const double resValue = value/_widthUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px"); 0224 m_page->newWidthDouble->changeValue(resValue); 0225 m_page->newWidthDouble->blockSignals(false); 0226 } 0227 0228 void DlgLayerSize::updateHeightUIValue(double value) 0229 { 0230 m_page->newHeightDouble->blockSignals(true); 0231 const double resValue = value/_heightUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px"); 0232 m_page->newHeightDouble->changeValue(resValue); 0233 m_page->newHeightDouble->blockSignals(false); 0234 } 0235