File indexing completed on 2025-01-19 03:51:13
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-02-17 0007 * Description : a tool to change image perspective . 0008 * 0009 * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2006-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "perspectivetool.h" 0017 0018 // Qt includes 0019 0020 #include <QCheckBox> 0021 #include <QFrame> 0022 #include <QGridLayout> 0023 #include <QGroupBox> 0024 #include <QLabel> 0025 #include <QPushButton> 0026 #include <QSpinBox> 0027 #include <QVBoxLayout> 0028 #include <QApplication> 0029 0030 // KDE includes 0031 0032 #include <klocalizedstring.h> 0033 #include <ksharedconfig.h> 0034 #include <kconfiggroup.h> 0035 0036 // Local includes 0037 0038 #include "dimg.h" 0039 #include "editortoolsettings.h" 0040 #include "imageiface.h" 0041 #include "perspectivewidget.h" 0042 #include "dexpanderbox.h" 0043 0044 namespace DigikamEditorPerspectiveToolPlugin 0045 { 0046 0047 class Q_DECL_HIDDEN PerspectiveTool::Private 0048 { 0049 public: 0050 0051 explicit Private() 0052 : newWidthLabel (nullptr), 0053 newHeightLabel (nullptr), 0054 topLeftAngleLabel (nullptr), 0055 topRightAngleLabel (nullptr), 0056 bottomLeftAngleLabel (nullptr), 0057 bottomRightAngleLabel (nullptr), 0058 drawWhileMovingCheckBox (nullptr), 0059 drawGridCheckBox (nullptr), 0060 inverseTransformation (nullptr), 0061 previewWidget (nullptr), 0062 gboxSettings (nullptr) 0063 { 0064 } 0065 0066 static const QString configGroupName; 0067 static const QString configDrawWhileMovingEntry; 0068 static const QString configDrawGridEntry; 0069 static const QString configInverseTransformationEntry; 0070 0071 QLabel* newWidthLabel; 0072 QLabel* newHeightLabel; 0073 QLabel* topLeftAngleLabel; 0074 QLabel* topRightAngleLabel; 0075 QLabel* bottomLeftAngleLabel; 0076 QLabel* bottomRightAngleLabel; 0077 0078 QCheckBox* drawWhileMovingCheckBox; 0079 QCheckBox* drawGridCheckBox; 0080 QCheckBox* inverseTransformation; 0081 0082 PerspectiveWidget* previewWidget; 0083 EditorToolSettings* gboxSettings; 0084 }; 0085 0086 const QString PerspectiveTool::Private::configGroupName(QLatin1String("perspective Tool")); 0087 const QString PerspectiveTool::Private::configDrawWhileMovingEntry(QLatin1String("Draw While Moving")); 0088 const QString PerspectiveTool::Private::configDrawGridEntry(QLatin1String("Draw Grid")); 0089 const QString PerspectiveTool::Private::configInverseTransformationEntry(QLatin1String("Inverse Transformation")); 0090 0091 // -------------------------------------------------------- 0092 0093 PerspectiveTool::PerspectiveTool(QObject* const parent) 0094 : EditorTool(parent), 0095 d (new Private) 0096 { 0097 setObjectName(QLatin1String("perspective")); 0098 0099 // ------------------------------------------------------------- 0100 0101 QFrame* const frame = new QFrame(nullptr); 0102 frame->setFrameStyle(QFrame::Panel|QFrame::Sunken); 0103 QVBoxLayout* const l = new QVBoxLayout(frame); 0104 d->previewWidget = new PerspectiveWidget(525, 350, frame); 0105 l->addWidget(d->previewWidget); 0106 d->previewWidget->setWhatsThis(i18n("This is the perspective transformation operation preview. " 0107 "You can use the mouse for dragging the corner to adjust the " 0108 "perspective transformation area.")); 0109 setToolView(frame); 0110 0111 // ------------------------------------------------------------- 0112 0113 QString temp; 0114 ImageIface iface; 0115 0116 d->gboxSettings = new EditorToolSettings(nullptr); 0117 d->gboxSettings->setTools(EditorToolSettings::ColorGuide); 0118 0119 // ------------------------------------------------------------- 0120 0121 QLabel* const label1 = new QLabel(i18n("New width:")); 0122 d->newWidthLabel = new QLabel(temp.setNum( iface.originalSize().width()) + i18n(" px")); 0123 d->newWidthLabel->setAlignment( Qt::AlignBottom | Qt::AlignRight ); 0124 0125 QLabel* const label2 = new QLabel(i18n("New height:")); 0126 d->newHeightLabel = new QLabel(temp.setNum( iface.originalSize().height()) + i18n(" px")); 0127 d->newHeightLabel->setAlignment( Qt::AlignBottom | Qt::AlignRight ); 0128 0129 // ------------------------------------------------------------- 0130 0131 DLineWidget* const line = new DLineWidget (Qt::Horizontal); 0132 QLabel* const angleLabel = new QLabel(i18n("Angles (in degrees):")); 0133 QLabel* const label3 = new QLabel(i18n(" Top left:")); 0134 d->topLeftAngleLabel = new QLabel; 0135 QLabel* const label4 = new QLabel(i18n(" Top right:")); 0136 d->topRightAngleLabel = new QLabel; 0137 QLabel* const label5 = new QLabel(i18n(" Bottom left:")); 0138 d->bottomLeftAngleLabel = new QLabel; 0139 QLabel* const label6 = new QLabel(i18n(" Bottom right:")); 0140 d->bottomRightAngleLabel = new QLabel; 0141 0142 // ------------------------------------------------------------- 0143 0144 DLineWidget* const line2 = new DLineWidget (Qt::Horizontal); 0145 d->drawWhileMovingCheckBox = new QCheckBox(i18n("Draw preview while moving")); 0146 d->drawGridCheckBox = new QCheckBox(i18n("Draw grid")); 0147 d->inverseTransformation = new QCheckBox(i18n("Inverse transformation")); 0148 0149 // ------------------------------------------------------------- 0150 0151 const int spacing = d->gboxSettings->spacingHint(); 0152 0153 QGridLayout* const grid = new QGridLayout; 0154 grid->addWidget(label1, 0, 0, 1, 1); 0155 grid->addWidget(d->newWidthLabel, 0, 1, 1, 2); 0156 grid->addWidget(label2, 1, 0, 1, 1); 0157 grid->addWidget(d->newHeightLabel, 1, 1, 1, 2); 0158 grid->addWidget(line, 2, 0, 1, 3); 0159 grid->addWidget(angleLabel, 3, 0, 1, 3); 0160 grid->addWidget(label3, 4, 0, 1, 1); 0161 grid->addWidget(d->topLeftAngleLabel, 4, 1, 1, 2); 0162 grid->addWidget(label4, 5, 0, 1, 1); 0163 grid->addWidget(d->topRightAngleLabel, 5, 1, 1, 2); 0164 grid->addWidget(label5, 6, 0, 1, 1); 0165 grid->addWidget(d->bottomLeftAngleLabel, 6, 1, 1, 2); 0166 grid->addWidget(label6, 7, 0, 1, 1); 0167 grid->addWidget(d->bottomRightAngleLabel, 7, 1, 1, 2); 0168 grid->addWidget(line2, 8, 0, 1, 3); 0169 grid->addWidget(d->drawWhileMovingCheckBox, 9, 0, 1, 3); 0170 grid->addWidget(d->drawGridCheckBox, 10, 0, 1, 3); 0171 grid->addWidget(d->inverseTransformation, 11, 0, 1, 3); 0172 grid->setColumnStretch(1, 10); 0173 grid->setRowStretch(12, 10); 0174 grid->setContentsMargins(spacing, spacing, spacing, spacing); 0175 grid->setSpacing(spacing); 0176 d->gboxSettings->plainPage()->setLayout(grid); 0177 0178 // ------------------------------------------------------------- 0179 0180 setToolSettings(d->gboxSettings); 0181 0182 // ------------------------------------------------------------- 0183 0184 connect(d->previewWidget, SIGNAL(signalPerspectiveChanged(QRect,float,float,float,float,bool)), 0185 this, SLOT(slotUpdateInfo(QRect,float,float,float,float,bool))); 0186 0187 connect(d->drawWhileMovingCheckBox, SIGNAL(toggled(bool)), 0188 d->previewWidget, SLOT(slotToggleDrawWhileMoving(bool))); 0189 0190 connect(d->drawGridCheckBox, SIGNAL(toggled(bool)), 0191 d->previewWidget, SLOT(slotToggleDrawGrid(bool))); 0192 0193 connect(d->inverseTransformation, SIGNAL(toggled(bool)), 0194 this, SLOT(slotInverseTransformationChanged(bool))); 0195 0196 connect(d->gboxSettings, SIGNAL(signalColorGuideChanged()), 0197 this, SLOT(slotColorGuideChanged())); 0198 } 0199 0200 PerspectiveTool::~PerspectiveTool() 0201 { 0202 delete d; 0203 } 0204 0205 void PerspectiveTool::slotColorGuideChanged() 0206 { 0207 d->previewWidget->slotChangeGuideColor(d->gboxSettings->guideColor()); 0208 d->previewWidget->slotChangeGuideSize(d->gboxSettings->guideSize()); 0209 } 0210 0211 void PerspectiveTool::readSettings() 0212 { 0213 QColor defaultGuideColor(Qt::red); 0214 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0215 KConfigGroup group = config->group(d->configGroupName); 0216 0217 d->drawWhileMovingCheckBox->setChecked(group.readEntry( d->configDrawWhileMovingEntry, true)); 0218 d->drawGridCheckBox->setChecked(group.readEntry( d->configDrawGridEntry, false)); 0219 d->inverseTransformation->setChecked(group.readEntry( d->configInverseTransformationEntry, false)); 0220 0221 d->previewWidget->slotToggleDrawWhileMoving(d->drawWhileMovingCheckBox->isChecked()); 0222 d->previewWidget->slotToggleDrawGrid(d->drawGridCheckBox->isChecked()); 0223 } 0224 0225 void PerspectiveTool::writeSettings() 0226 { 0227 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0228 KConfigGroup group = config->group(d->configGroupName); 0229 0230 group.writeEntry(d->configDrawWhileMovingEntry, d->drawWhileMovingCheckBox->isChecked()); 0231 group.writeEntry(d->configDrawGridEntry, d->drawGridCheckBox->isChecked()); 0232 group.writeEntry(d->configInverseTransformationEntry, d->inverseTransformation->isChecked()); 0233 config->sync(); 0234 } 0235 0236 void PerspectiveTool::slotResetSettings() 0237 { 0238 d->previewWidget->reset(); 0239 } 0240 0241 void PerspectiveTool::finalRendering() 0242 { 0243 qApp->setOverrideCursor(Qt::WaitCursor); 0244 d->previewWidget->applyPerspectiveAdjustment(); 0245 qApp->restoreOverrideCursor(); 0246 } 0247 0248 void PerspectiveTool::slotUpdateInfo(const QRect& newSize, float topLeftAngle, float topRightAngle, 0249 float bottomLeftAngle, float bottomRightAngle, bool valid) 0250 { 0251 QString temp; 0252 d->newWidthLabel->setText(temp.setNum(newSize.width()) + i18n(" px")); 0253 d->newHeightLabel->setText(temp.setNum(newSize.height()) + i18n(" px")); 0254 0255 d->topLeftAngleLabel->setText(temp.setNum(topLeftAngle, 'f', 1)); 0256 d->topRightAngleLabel->setText(temp.setNum(topRightAngle, 'f', 1)); 0257 d->bottomLeftAngleLabel->setText(temp.setNum(bottomLeftAngle, 'f', 1)); 0258 d->bottomRightAngleLabel->setText(temp.setNum(bottomRightAngle, 'f', 1)); 0259 0260 d->gboxSettings->button(EditorToolSettings::Ok)->setEnabled(valid); 0261 } 0262 0263 void PerspectiveTool::slotInverseTransformationChanged(bool b) 0264 { 0265 d->drawWhileMovingCheckBox->setEnabled(!b); 0266 d->drawGridCheckBox->setEnabled(!b); 0267 d->previewWidget->slotInverseTransformationChanged(b); 0268 } 0269 0270 void PerspectiveTool::setBackgroundColor(const QColor& bg) 0271 { 0272 d->previewWidget->setBackgroundColor(bg); 0273 } 0274 0275 } // namespace DigikamEditorPerspectiveToolPlugin 0276 0277 #include "moc_perspectivetool.cpp"