File indexing completed on 2025-01-26 04:08:10

0001 /*
0002  *
0003  *  SPDX-FileCopyrightText: 2009 Edward Apap <schumifer@hotmail.com>
0004  *  SPDX-FileCopyrightText: 2013 Juan Palacios <jpalaciosdev@gmail.com>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "dlg_canvassize.h"
0010 #include "kcanvaspreview.h"
0011 
0012 #include <kis_config.h>
0013 #include <KoUnit.h>
0014 #include <kis_icon.h>
0015 #include <kis_size_group.h>
0016 #include <klocalizedstring.h>
0017 
0018 #include <kis_document_aware_spin_box_unit_manager.h>
0019 
0020 #include <QComboBox>
0021 #include <QButtonGroup>
0022 
0023 const QString DlgCanvasSize::PARAM_PREFIX = "canvasizedlg";
0024 const QString DlgCanvasSize::PARAM_WIDTH_UNIT = DlgCanvasSize::PARAM_PREFIX + "_widthunit";
0025 const QString DlgCanvasSize::PARAM_HEIGHT_UNIT = DlgCanvasSize::PARAM_PREFIX + "_heightunit";
0026 const QString DlgCanvasSize::PARAM_XOFFSET_UNIT = DlgCanvasSize::PARAM_PREFIX + "_xoffsetunit";
0027 const QString DlgCanvasSize::PARAM_YOFFSET_UNIT = DlgCanvasSize::PARAM_PREFIX + "_yoffsetunit";
0028 
0029 DlgCanvasSize::DlgCanvasSize(QWidget *parent, int width, int height, double resolution)
0030     : KoDialog(parent)
0031     , m_keepAspect(true)
0032     , m_aspectRatio((double)width / height)
0033     , m_resolution(resolution)
0034     , m_originalWidth(width)
0035     , m_originalHeight(height)
0036     , m_newWidth(width)
0037     , m_newHeight(height)
0038     , m_xOffset(0)
0039     , m_yOffset(0)
0040 {
0041     setCaption(i18n("Resize Canvas"));
0042     setButtons(Ok | Cancel);
0043     setDefaultButton(Ok);
0044 
0045     m_page = new WdgCanvasSize(this);
0046     Q_CHECK_PTR(m_page);
0047     m_page->layout()->setMargin(0);
0048     m_page->setObjectName("canvas_size");
0049 
0050     _widthUnitManager = new KisDocumentAwareSpinBoxUnitManager(this);
0051     _heightUnitManager = new KisDocumentAwareSpinBoxUnitManager(this, KisDocumentAwareSpinBoxUnitManager::PIX_DIR_Y);
0052 
0053     KisConfig cfg(true);
0054 
0055     _widthUnitManager->setApparentUnitFromSymbol("px");
0056     _heightUnitManager->setApparentUnitFromSymbol("px");
0057 
0058     m_page->newWidthDouble->setUnitManager(_widthUnitManager);
0059     m_page->newHeightDouble->setUnitManager(_heightUnitManager);
0060     m_page->newWidthDouble->setDecimals(2);
0061     m_page->newHeightDouble->setDecimals(2);
0062     m_page->newWidthDouble->setDisplayUnit(false);
0063     m_page->newHeightDouble->setDisplayUnit(false);
0064 
0065     m_page->newWidthDouble->setValue(width);
0066     m_page->newWidthDouble->setFocus();
0067     m_page->newHeightDouble->setValue(height);
0068 
0069     m_page->widthUnit->setModel(_widthUnitManager);
0070     m_page->heightUnit->setModel(_heightUnitManager);
0071 
0072     QString unitw = cfg.readEntry<QString>(PARAM_WIDTH_UNIT, "px");
0073     QString unith = cfg.readEntry<QString>(PARAM_HEIGHT_UNIT, "px");
0074 
0075     _widthUnitManager->setApparentUnitFromSymbol(unitw);
0076     _heightUnitManager->setApparentUnitFromSymbol(unith);
0077 
0078     const int wUnitIndex = _widthUnitManager->getsUnitSymbolList().indexOf(unitw);
0079     const int hUnitIndex = _widthUnitManager->getsUnitSymbolList().indexOf(unith);
0080 
0081     m_page->widthUnit->setCurrentIndex(wUnitIndex);
0082     m_page->heightUnit->setCurrentIndex(hUnitIndex);
0083 
0084     _xOffsetUnitManager = new KisDocumentAwareSpinBoxUnitManager(this);
0085     _yOffsetUnitManager = new KisDocumentAwareSpinBoxUnitManager(this, KisDocumentAwareSpinBoxUnitManager::PIX_DIR_Y);
0086 
0087     _xOffsetUnitManager->setApparentUnitFromSymbol("px");
0088     _yOffsetUnitManager->setApparentUnitFromSymbol("px");
0089 
0090     m_page->xOffsetDouble->setUnitManager(_xOffsetUnitManager);
0091     m_page->yOffsetDouble->setUnitManager(_yOffsetUnitManager);
0092     m_page->xOffsetDouble->setDecimals(2);
0093     m_page->yOffsetDouble->setDecimals(2);
0094     m_page->xOffsetDouble->setDisplayUnit(false);
0095     m_page->yOffsetDouble->setDisplayUnit(false);
0096 
0097     m_page->xOffUnit->setModel(_xOffsetUnitManager);
0098     m_page->yOffUnit->setModel(_yOffsetUnitManager);
0099 
0100     m_page->xOffsetDouble->changeValue(m_xOffset);
0101     m_page->yOffsetDouble->changeValue(m_yOffset);
0102 
0103     QString unitx = cfg.readEntry<QString>(PARAM_XOFFSET_UNIT, "px");
0104     QString unity = cfg.readEntry<QString>(PARAM_YOFFSET_UNIT, "px");
0105 
0106     _xOffsetUnitManager->setApparentUnitFromSymbol(unitx);
0107     _yOffsetUnitManager->setApparentUnitFromSymbol(unity);
0108 
0109     const int xUnitIndex = _xOffsetUnitManager->getsUnitSymbolList().indexOf(unitx);
0110     const int yUnitIndex = _yOffsetUnitManager->getsUnitSymbolList().indexOf(unity);
0111 
0112     m_page->xOffUnit->setCurrentIndex(xUnitIndex);
0113     m_page->yOffUnit->setCurrentIndex(yUnitIndex);
0114 
0115     QIcon lockedIcon = KisIconUtils::loadIcon("locked");
0116     QIcon unlockedIcon = KisIconUtils::loadIcon("unlocked");
0117     m_page->lockxOffset->setCheckable(true);
0118     m_page->lockyOffset->setCheckable(true);
0119     m_page->lockxOffset->setChecked(false);
0120     m_page->lockyOffset->setChecked(false);
0121     m_page->lockxOffset-> setIcon(m_page->lockxOffset->isChecked() ? lockedIcon : unlockedIcon);
0122     m_page->lockyOffset-> setIcon(m_page->lockyOffset->isChecked() ? lockedIcon : unlockedIcon);
0123 
0124     m_page->canvasPreview->setImageSize(m_originalWidth, m_originalHeight);
0125     m_page->canvasPreview->setCanvasSize(m_originalWidth, m_originalHeight);
0126     m_page->canvasPreview->setImageOffset(m_xOffset, m_yOffset);
0127 
0128     m_page->aspectRatioBtn->setKeepAspectRatio(cfg.readEntry("CanvasSize/KeepAspectRatio", false));
0129     m_page->constrainProportionsCkb->setChecked(cfg.readEntry("CanvasSize/ConstrainProportions", false));
0130     m_keepAspect = cfg.readEntry("CanvasSize/KeepAspectRatio", false);
0131 
0132 
0133     m_group = new QButtonGroup(m_page);
0134     m_group->addButton(m_page->topLeft, NORTH_WEST);
0135     m_group->addButton(m_page->topCenter, NORTH);
0136     m_group->addButton(m_page->topRight, NORTH_EAST);
0137 
0138     m_group->addButton(m_page->middleLeft, WEST);
0139     m_group->addButton(m_page->middleCenter, CENTER);
0140     m_group->addButton(m_page->middleRight, EAST);
0141 
0142     m_group->addButton(m_page->bottomLeft, SOUTH_WEST);
0143     m_group->addButton(m_page->bottomCenter, SOUTH);
0144     m_group->addButton(m_page->bottomRight, SOUTH_EAST);
0145 
0146     loadAnchorIcons();
0147     m_group->button(CENTER)->setChecked(true);
0148     updateAnchorIcons(CENTER);
0149 
0150     KisSizeGroup *labelsGroup = new KisSizeGroup(this);
0151     labelsGroup->addWidget(m_page->lblNewWidth);
0152     labelsGroup->addWidget(m_page->lblNewHeight);
0153     labelsGroup->addWidget(m_page->lblXOff);
0154     labelsGroup->addWidget(m_page->lblYOff);
0155     labelsGroup->addWidget(m_page->lblAnchor);
0156 
0157     KisSizeGroup *spinboxesGroup = new KisSizeGroup(this);
0158     spinboxesGroup->addWidget(m_page->newWidthDouble);
0159     spinboxesGroup->addWidget(m_page->newHeightDouble);
0160     spinboxesGroup->addWidget(m_page->xOffsetDouble);
0161     spinboxesGroup->addWidget(m_page->yOffsetDouble);
0162 
0163     KisSizeGroup *comboboxesGroup = new KisSizeGroup(this);
0164     comboboxesGroup->addWidget(m_page->widthUnit);
0165     comboboxesGroup->addWidget(m_page->heightUnit);
0166     comboboxesGroup->addWidget(m_page->xOffUnit);
0167     comboboxesGroup->addWidget(m_page->yOffUnit);
0168 
0169     setMainWidget(m_page);
0170     connect(this, SIGNAL(okClicked()), this, SLOT(accept()));
0171 
0172     connect(m_page->newWidthDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotWidthChanged(double)));
0173     connect(m_page->newHeightDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotHeightChanged(double)));
0174     connect(m_page->widthUnit, SIGNAL(currentIndexChanged(int)), _widthUnitManager, SLOT(selectApparentUnitFromIndex(int)));
0175     connect(m_page->heightUnit, SIGNAL(currentIndexChanged(int)), _heightUnitManager, SLOT(selectApparentUnitFromIndex(int)));
0176     connect(_widthUnitManager, SIGNAL(unitChanged(int)), m_page->widthUnit, SLOT(setCurrentIndex(int)));
0177     connect(_heightUnitManager, SIGNAL(unitChanged(int)), m_page->heightUnit, SLOT(setCurrentIndex(int)));
0178 
0179     connect(m_page->xOffsetDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotXOffsetChanged(double)));
0180     connect(m_page->yOffsetDouble, SIGNAL(valueChangedPt(double)), this, SLOT(slotYOffsetChanged(double)));
0181     connect(m_page->xOffUnit, SIGNAL(currentIndexChanged(int)), _xOffsetUnitManager, SLOT(selectApparentUnitFromIndex(int)));
0182     connect(m_page->yOffUnit, SIGNAL(currentIndexChanged(int)), _yOffsetUnitManager, SLOT(selectApparentUnitFromIndex(int)));
0183     connect(_xOffsetUnitManager, SIGNAL(unitChanged(int)), m_page->xOffUnit, SLOT(setCurrentIndex(int)));
0184     connect(_yOffsetUnitManager, SIGNAL(unitChanged(int)), m_page->yOffUnit, SLOT(setCurrentIndex(int)));
0185 
0186     connect(m_page->lockxOffset, SIGNAL(toggled(bool)), this, SLOT(updatexOffsetIcon(bool)));
0187     connect(m_page->lockyOffset, SIGNAL(toggled(bool)), this, SLOT(updateyOffsetIcon(bool)));
0188     connect(m_page->lockxOffset, SIGNAL(toggled(bool)), m_page->canvasPreview , SLOT(setxOffsetLock(bool)));
0189     connect(m_page->lockyOffset, SIGNAL(toggled(bool)), m_page->canvasPreview , SLOT(setyOffsetLock(bool)));
0190 
0191     connect(m_page->constrainProportionsCkb, SIGNAL(toggled(bool)), this, SLOT(slotAspectChanged(bool)));
0192     connect(m_page->aspectRatioBtn, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(slotAspectChanged(bool)));
0193 
0194     connect(m_group, SIGNAL(buttonClicked(int)), SLOT(slotAnchorButtonClicked(int)));
0195     connect(m_page->canvasPreview, SIGNAL(sigModifiedXOffset(int)), this, SLOT(slotCanvasPreviewXOffsetChanged(int)));
0196     connect(m_page->canvasPreview, SIGNAL(sigModifiedYOffset(int)), this, SLOT(slotCanvasPreviewYOffsetChanged(int)));
0197 }
0198 
0199 DlgCanvasSize::~DlgCanvasSize()
0200 {
0201     KisConfig cfg(false);
0202     cfg.writeEntry<bool>("CanvasSize/KeepAspectRatio", m_page->aspectRatioBtn->keepAspectRatio());
0203     cfg.writeEntry<bool>("CanvasSize/ConstrainProportions", m_page->constrainProportionsCkb->isChecked());
0204 
0205     cfg.writeEntry<QString>(PARAM_WIDTH_UNIT, _widthUnitManager->getApparentUnitSymbol());
0206     cfg.writeEntry<QString>(PARAM_HEIGHT_UNIT, _heightUnitManager->getApparentUnitSymbol());
0207 
0208     cfg.writeEntry<QString>(PARAM_XOFFSET_UNIT, _xOffsetUnitManager->getApparentUnitSymbol());
0209     cfg.writeEntry<QString>(PARAM_YOFFSET_UNIT, _yOffsetUnitManager->getApparentUnitSymbol());
0210 
0211     delete m_page;
0212 }
0213 
0214 qint32 DlgCanvasSize::width()
0215 {
0216     return (qint32) m_newWidth;
0217 }
0218 
0219 qint32 DlgCanvasSize::height()
0220 {
0221     return (qint32) m_newHeight;
0222 }
0223 
0224 qint32 DlgCanvasSize::xOffset()
0225 {
0226     return (qint32) m_xOffset;
0227 }
0228 
0229 qint32 DlgCanvasSize::yOffset()
0230 {
0231     return (qint32) m_yOffset;
0232 }
0233 
0234 void DlgCanvasSize::slotAspectChanged(bool keep)
0235 {
0236     m_page->aspectRatioBtn->blockSignals(true);
0237     m_page->constrainProportionsCkb->blockSignals(true);
0238 
0239     m_page->aspectRatioBtn->setKeepAspectRatio(keep);
0240     m_page->constrainProportionsCkb->setChecked(keep);
0241 
0242     m_page->aspectRatioBtn->blockSignals(false);
0243     m_page->constrainProportionsCkb->blockSignals(false);
0244 
0245     m_keepAspect = keep;
0246 
0247 
0248     if (keep) {
0249         // size values may be out of sync, so we need to reset it to defaults
0250         m_newWidth = m_originalWidth;
0251         m_newHeight = m_originalHeight;
0252         m_xOffset = 0;
0253         m_yOffset = 0;
0254 
0255         m_page->canvasPreview->blockSignals(true);
0256         m_page->canvasPreview->setCanvasSize(m_newWidth, m_newHeight);
0257         m_page->canvasPreview->setImageOffset(m_xOffset, m_yOffset);
0258         m_page->canvasPreview->blockSignals(false);
0259         updateOffset(CENTER);
0260         updateButtons(CENTER);
0261     }
0262 }
0263 
0264 void DlgCanvasSize::slotAnchorButtonClicked(int id)
0265 {
0266     updateOffset(id);
0267     updateButtons(id);
0268 }
0269 
0270 void DlgCanvasSize::slotWidthChanged(double v)
0271 {
0272     //this slot receiv values in pt from the unitspinbox, so just use the resolution.
0273     const double resValue = v*_widthUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0274     m_newWidth = qRound(resValue);
0275 
0276     if (m_keepAspect) {
0277         m_newHeight = qRound(m_newWidth / m_aspectRatio);
0278         m_page->newHeightDouble->blockSignals(true);
0279         m_page->newHeightDouble->changeValue(v / m_aspectRatio);
0280         m_page->newHeightDouble->blockSignals(false);
0281     }
0282 
0283     int savedId = m_group->checkedId();
0284     m_page->canvasPreview->blockSignals(true);
0285     m_page->canvasPreview->setCanvasSize(m_newWidth, m_newHeight);
0286     m_page->canvasPreview->blockSignals(false);
0287     updateOffset(savedId);
0288     updateButtons(savedId);
0289 }
0290 
0291 void DlgCanvasSize::slotHeightChanged(double v)
0292 {
0293     //this slot receiv values in pt from the unitspinbox, so just use the resolution.
0294     const double resValue = v*_heightUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0295     m_newHeight = qRound(resValue);
0296 
0297     if (m_keepAspect) {
0298         m_newWidth = qRound(m_newHeight * m_aspectRatio);
0299         m_page->newWidthDouble->blockSignals(true);
0300         m_page->newWidthDouble->changeValue(v * m_aspectRatio);
0301         m_page->newWidthDouble->blockSignals(false);
0302     }
0303 
0304     int savedId = m_group->checkedId();
0305     m_page->canvasPreview->blockSignals(true);
0306     m_page->canvasPreview->setCanvasSize(m_newWidth, m_newHeight);
0307     m_page->canvasPreview->blockSignals(false);
0308     updateOffset(savedId);
0309     updateButtons(savedId);
0310 }
0311 
0312 void DlgCanvasSize::slotXOffsetChanged(double v)
0313 {
0314     //this slot receiv values in pt from the unitspinbox, so just use the resolution.
0315     const double resValue = v*_xOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0316     m_xOffset = qRound(resValue);
0317 
0318     m_page->canvasPreview->blockSignals(true);
0319     m_page->canvasPreview->setImageOffset(m_xOffset, m_yOffset);
0320     m_page->canvasPreview->blockSignals(false);
0321 
0322     updateButtons(-1);
0323 }
0324 
0325 void DlgCanvasSize::slotYOffsetChanged(double v)
0326 {
0327     //this slot receiv values in pt from the unitspinbox, so just use the resolution.
0328     const double resValue = v*_xOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0329     m_yOffset = qRound(resValue);
0330 
0331 
0332     m_page->canvasPreview->blockSignals(true);
0333     m_page->canvasPreview->setImageOffset(m_xOffset, m_yOffset);
0334     m_page->canvasPreview->blockSignals(false);
0335 
0336     updateButtons(-1);
0337 }
0338 
0339 void DlgCanvasSize::slotCanvasPreviewXOffsetChanged(int v)
0340 {
0341     double newVal = v / _xOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0342     m_page->xOffsetDouble->changeValue(newVal);
0343 }
0344 
0345 void DlgCanvasSize::slotCanvasPreviewYOffsetChanged(int v)
0346 {
0347 
0348     double newVal = v / _yOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0349     m_page->yOffsetDouble->changeValue(newVal);
0350 }
0351 
0352 void DlgCanvasSize::loadAnchorIcons()
0353 {
0354 
0355     m_anchorIcons[NORTH_WEST] =  KisIconUtils::loadIcon("arrow-topleft");
0356     m_anchorIcons[NORTH] = KisIconUtils::loadIcon("arrow-up");
0357     m_anchorIcons[NORTH_EAST] = KisIconUtils::loadIcon("arrow-topright");
0358     m_anchorIcons[EAST] = KisIconUtils::loadIcon("arrow-right");
0359     m_anchorIcons[CENTER] = KisIconUtils::loadIcon("arrow_center");
0360     m_anchorIcons[WEST] = KisIconUtils::loadIcon("arrow-left");
0361     m_anchorIcons[SOUTH_WEST] = KisIconUtils::loadIcon("arrow-downleft");
0362     m_anchorIcons[SOUTH] = KisIconUtils::loadIcon("arrow-down");
0363     m_anchorIcons[SOUTH_EAST] = KisIconUtils::loadIcon("arrow-downright");
0364 
0365 }
0366 
0367 void DlgCanvasSize::updateAnchorIcons(int id)
0368 {
0369     anchor iconLayout[10][9] = {
0370         {NONE, EAST,  NONE, SOUTH, SOUTH_EAST, NONE, NONE, NONE, NONE},
0371         {WEST, NONE, EAST, SOUTH_WEST, SOUTH, SOUTH_EAST, NONE, NONE, NONE},
0372         {NONE, WEST, NONE, NONE, SOUTH_WEST, SOUTH, NONE, NONE, NONE},
0373         {NORTH, NORTH_EAST, NONE, NONE, EAST, NONE, SOUTH, SOUTH_EAST, NONE},
0374         {NORTH_WEST, NORTH, NORTH_EAST, WEST, NONE, EAST, SOUTH_WEST, SOUTH, SOUTH_EAST},
0375         {NONE, NORTH_WEST, NORTH, NONE, WEST, NONE, NONE, SOUTH_WEST, SOUTH},
0376         {NONE, NONE, NONE, NORTH, NORTH_EAST, NONE, NONE, EAST, NONE},
0377         {NONE, NONE, NONE, NORTH_WEST, NORTH, NORTH_EAST, WEST, NONE, EAST},
0378         {NONE, NONE, NONE, NONE, NORTH_WEST, NORTH, NONE, WEST, NONE},
0379         {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE}
0380     };
0381 
0382     if (id == -1) {
0383         id = SOUTH_EAST + 1;
0384     }
0385 
0386     // we are going to swap arrows direction based on width and height shrinking
0387     bool shrinkWidth = (m_newWidth < m_originalWidth) ? true : false;
0388     bool shrinkHeight = (m_newHeight < m_originalHeight) ? true : false;
0389 
0390     for (int i = NORTH_WEST; i <= SOUTH_EAST; i++) {
0391         anchor iconId = iconLayout[id][i];
0392 
0393         // all corner arrows represents shrinking in some direction
0394         if (shrinkWidth || shrinkHeight) {
0395             switch (iconId) {
0396             case NORTH_WEST: iconId = SOUTH_EAST; break;
0397             case NORTH_EAST: iconId = SOUTH_WEST; break;
0398             case SOUTH_WEST: iconId = NORTH_EAST; break;
0399             case SOUTH_EAST: iconId = NORTH_WEST; break;
0400             default: break;
0401             }
0402         }
0403 
0404         if (shrinkWidth) {
0405             switch (iconId) {
0406             case WEST: iconId = EAST; break;
0407             case EAST: iconId = WEST; break;
0408             default: break;
0409             }
0410         }
0411 
0412         if (shrinkHeight) {
0413             switch (iconId) {
0414             case NORTH: iconId = SOUTH; break;
0415             case SOUTH: iconId = NORTH; break;
0416             default: break;
0417             }
0418         }
0419 
0420         QAbstractButton *button = m_group->button(i);
0421 
0422         if (iconId == NONE) {
0423             button->setIcon(QIcon());
0424         } else {
0425             button->setIcon(m_anchorIcons[iconId]);
0426         }
0427     }
0428 
0429 }
0430 
0431 void DlgCanvasSize::updateButtons(int forceId)
0432 {
0433     int id = m_group->checkedId();
0434 
0435     if (forceId != -1) {
0436         m_group->setExclusive(true);
0437         m_group->button(forceId)->setChecked(true);
0438         updateAnchorIcons(forceId);
0439     } else if (id != -1) {
0440         double xOffset, yOffset;
0441         expectedOffset(id, xOffset, yOffset);
0442 
0443         // convert values to internal unit
0444         int internalXOffset = 0;
0445         int internalYOffset = 0;
0446         const KoUnit xOffsetUnit = KoUnit::fromListForUi(m_page->xOffUnit->currentIndex());
0447         internalXOffset = qRound(xOffsetUnit.fromUserValue(xOffset));
0448         const KoUnit yOffsetUnit = KoUnit::fromListForUi(m_page->yOffUnit->currentIndex());
0449         internalYOffset = qRound(yOffsetUnit.fromUserValue(yOffset));
0450 
0451         bool offsetAsExpected =
0452                 internalXOffset == m_xOffset &&
0453                 internalYOffset == m_yOffset;
0454 
0455         if (offsetAsExpected) {
0456             m_group->setExclusive(true);
0457         } else {
0458             m_group->setExclusive(false);
0459             m_group->button(id)->setChecked(false);
0460             id = -1;
0461         }
0462 
0463         updateAnchorIcons(id);
0464     } else {
0465         updateAnchorIcons(id);
0466     }
0467 }
0468 
0469 void DlgCanvasSize::updateOffset(int id)
0470 {
0471     if (id == -1) return;
0472 
0473     double xOffset;
0474     double yOffset;
0475     expectedOffset(id, xOffset, yOffset);
0476 
0477     m_page->xOffsetDouble->changeValue(xOffset);
0478     m_page->yOffsetDouble->changeValue(yOffset);
0479 }
0480 void DlgCanvasSize::updatexOffsetIcon(bool v)
0481 {
0482     if (v) {
0483       m_page->xOffsetDouble->setReadOnly(true);
0484       m_page->lockxOffset->setIcon(KisIconUtils::loadIcon("locked"));
0485     } else {
0486       m_page->xOffsetDouble->setReadOnly(false);
0487       m_page->lockxOffset->setIcon(KisIconUtils::loadIcon("unlocked"));
0488     }
0489 }
0490 void DlgCanvasSize::updateyOffsetIcon(bool v)
0491 {
0492     if (v) {
0493       m_page->yOffsetDouble->setReadOnly(true);
0494       m_page->lockyOffset->setIcon(KisIconUtils::loadIcon("locked"));
0495     } else {
0496       m_page->yOffsetDouble->setReadOnly(false);
0497       m_page->lockyOffset->setIcon(KisIconUtils::loadIcon("unlocked"));
0498     }
0499 }
0500 void DlgCanvasSize::expectedOffset(int id, double &xOffset, double &yOffset)
0501 {
0502     const double xCoeff = (id % 3) * 0.5;
0503     const double yCoeff = (int)(id / 3.0) * 0.5;
0504 
0505     const int xDiff = m_newWidth - m_originalWidth;
0506     const int yDiff = m_newHeight - m_originalHeight;
0507 
0508     //convert to unitmanager default unit.
0509     xOffset = xDiff * xCoeff / _xOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0510     yOffset = yDiff * yCoeff / _yOffsetUnitManager->getConversionFactor(KisSpinBoxUnitManager::LENGTH, "px");
0511 }