File indexing completed on 2025-03-09 03:50:36
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-12-06 0007 * Description : digiKam image editor Ratio Crop tool 0008 * 0009 * SPDX-FileCopyrightText: 2007 by Jaromir Malenko <malenko at email dot cz> 0010 * SPDX-FileCopyrightText: 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com> 0011 * SPDX-FileCopyrightText: 2004-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "ratiocroptool.h" 0018 0019 // Qt includes 0020 0021 #include <QCheckBox> 0022 #include <QFrame> 0023 #include <QGridLayout> 0024 #include <QGroupBox> 0025 #include <QImage> 0026 #include <QLabel> 0027 #include <QPixmap> 0028 #include <QSpinBox> 0029 #include <QTimer> 0030 #include <QToolButton> 0031 #include <QVBoxLayout> 0032 #include <QPushButton> 0033 #include <QApplication> 0034 #include <QStandardPaths> 0035 #include <QStyle> 0036 0037 // KDE includes 0038 0039 #include <klocalizedstring.h> 0040 #include <ksharedconfig.h> 0041 #include <kconfiggroup.h> 0042 0043 // Local includes 0044 0045 #include "dlayoutbox.h" 0046 #include "dexpanderbox.h" 0047 #include "dnuminput.h" 0048 #include "editortoolsettings.h" 0049 #include "dcombobox.h" 0050 #include "imageiface.h" 0051 #include "ratiocropwidget.h" 0052 #include "histogrambox.h" 0053 #include "histogramwidget.h" 0054 #include "dcolorselector.h" 0055 0056 namespace DigikamEditorRatioCropToolPlugin 0057 { 0058 0059 class Q_DECL_HIDDEN RatioCropTool::Private 0060 { 0061 public: 0062 0063 explicit Private() 0064 : originalIsLandscape (false), 0065 customLabel (nullptr), 0066 orientLabel (nullptr), 0067 colorGuideLabel (nullptr), 0068 resLabel (nullptr), 0069 centerWidth (nullptr), 0070 centerHeight (nullptr), 0071 goldenSectionBox (nullptr), 0072 goldenSpiralSectionBox (nullptr), 0073 goldenSpiralBox (nullptr), 0074 goldenTriangleBox (nullptr), 0075 flipHorBox (nullptr), 0076 flipVerBox (nullptr), 0077 autoOrientation (nullptr), 0078 preciseCrop (nullptr), 0079 ratioCB (nullptr), 0080 orientCB (nullptr), 0081 guideLinesCB (nullptr), 0082 customRatioDInput (nullptr), 0083 customRatioNInput (nullptr), 0084 guideSize (nullptr), 0085 heightInput (nullptr), 0086 widthInput (nullptr), 0087 xInput (nullptr), 0088 yInput (nullptr), 0089 guideColorBt (nullptr), 0090 ratioCropWidget (nullptr), 0091 expbox (nullptr), 0092 gboxSettings (nullptr), 0093 histogramBox (nullptr) 0094 { 0095 } 0096 0097 static const QString configGroupName; 0098 static const QString configHorOrientedAspectRatioEntry; 0099 static const QString configHorOrientedAspectRatioOrientationEntry; 0100 static const QString configHorOrientedCustomAspectRatioNumEntry; 0101 static const QString configHorOrientedCustomAspectRatioDenEntry; 0102 static const QString configHorOrientedCustomAspectRatioXposEntry; 0103 static const QString configHorOrientedCustomAspectRatioYposEntry; 0104 static const QString configHorOrientedCustomAspectRatioWidthEntry; 0105 static const QString configHorOrientedCustomAspectRatioHeightEntry; 0106 static const QString configVerOrientedAspectRatioEntry; 0107 static const QString configVerOrientedAspectRatioOrientationEntry; 0108 static const QString configVerOrientedCustomAspectRatioNumEntry; 0109 static const QString configVerOrientedCustomAspectRatioDenEntry; 0110 static const QString configVerOrientedCustomAspectRatioXposEntry; 0111 static const QString configVerOrientedCustomAspectRatioYposEntry; 0112 static const QString configVerOrientedCustomAspectRatioWidthEntry; 0113 static const QString configVerOrientedCustomAspectRatioHeightEntry; 0114 static const QString configPreciseAspectRatioCropEntry; 0115 static const QString configAutoOrientationEntry; 0116 static const QString configGuideLinesTypeEntry; 0117 static const QString configGoldenSectionEntry; 0118 static const QString configGoldenSpiralSectionEntry; 0119 static const QString configGoldenSpiralEntry; 0120 static const QString configGoldenTriangleEntry; 0121 static const QString configGoldenFlipHorizontalEntry; 0122 static const QString configGoldenFlipVerticalEntry; 0123 static const QString configGuideColorEntry; 0124 static const QString configGuideWidthEntry; 0125 static const QString configHistogramChannelEntry; 0126 static const QString configHistogramScaleEntry; 0127 0128 bool originalIsLandscape; 0129 0130 QLabel* customLabel; 0131 QLabel* orientLabel; 0132 QLabel* colorGuideLabel; 0133 QLabel* resLabel; 0134 0135 QToolButton* centerWidth; 0136 QToolButton* centerHeight; 0137 0138 QCheckBox* goldenSectionBox; 0139 QCheckBox* goldenSpiralSectionBox; 0140 QCheckBox* goldenSpiralBox; 0141 QCheckBox* goldenTriangleBox; 0142 QCheckBox* flipHorBox; 0143 QCheckBox* flipVerBox; 0144 QCheckBox* autoOrientation; 0145 QCheckBox* preciseCrop; 0146 0147 DComboBox* ratioCB; 0148 DComboBox* orientCB; 0149 DComboBox* guideLinesCB; 0150 0151 DIntNumInput* customRatioDInput; 0152 DIntNumInput* customRatioNInput; 0153 DIntNumInput* guideSize; 0154 DIntNumInput* heightInput; 0155 DIntNumInput* widthInput; 0156 DIntNumInput* xInput; 0157 DIntNumInput* yInput; 0158 0159 DColorSelector* guideColorBt; 0160 0161 RatioCropWidget* ratioCropWidget; 0162 DExpanderBox* expbox; 0163 EditorToolSettings* gboxSettings; 0164 HistogramBox* histogramBox; 0165 DImg imageSelection; 0166 }; 0167 0168 const QString RatioCropTool::Private::configGroupName(QLatin1String("aspectratiocrop Tool")); 0169 const QString RatioCropTool::Private::configHorOrientedAspectRatioEntry(QLatin1String("Hor.Oriented Aspect Ratio")); 0170 const QString RatioCropTool::Private::configHorOrientedAspectRatioOrientationEntry(QLatin1String("Hor.Oriented Aspect Ratio Orientation")); 0171 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioNumEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Num")); 0172 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioDenEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Den")); 0173 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioXposEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Xpos")); 0174 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioYposEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Ypos")); 0175 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioWidthEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Width")); 0176 const QString RatioCropTool::Private::configHorOrientedCustomAspectRatioHeightEntry(QLatin1String("Hor.Oriented Custom Aspect Ratio Height")); 0177 const QString RatioCropTool::Private::configVerOrientedAspectRatioEntry(QLatin1String("Ver.Oriented Aspect Ratio")); 0178 const QString RatioCropTool::Private::configVerOrientedAspectRatioOrientationEntry(QLatin1String("Ver.Oriented Aspect Ratio Orientation")); 0179 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioNumEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Num")); 0180 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioDenEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Den")); 0181 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioXposEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Xpos")); 0182 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioYposEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Ypos")); 0183 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioWidthEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Width")); 0184 const QString RatioCropTool::Private::configVerOrientedCustomAspectRatioHeightEntry(QLatin1String("Ver.Oriented Custom Aspect Ratio Height")); 0185 const QString RatioCropTool::Private::configPreciseAspectRatioCropEntry(QLatin1String("Precise Aspect Ratio Crop")); 0186 const QString RatioCropTool::Private::configAutoOrientationEntry(QLatin1String("Auto Orientation")); 0187 const QString RatioCropTool::Private::configGuideLinesTypeEntry(QLatin1String("Guide Lines Type")); 0188 const QString RatioCropTool::Private::configGoldenSectionEntry(QLatin1String("Golden Section")); 0189 const QString RatioCropTool::Private::configGoldenSpiralSectionEntry(QLatin1String("Golden Spiral Section")); 0190 const QString RatioCropTool::Private::configGoldenSpiralEntry(QLatin1String("Golden Spiral")); 0191 const QString RatioCropTool::Private::configGoldenTriangleEntry(QLatin1String("Golden Triangle")); 0192 const QString RatioCropTool::Private::configGoldenFlipHorizontalEntry(QLatin1String("Golden Flip Horizontal")); 0193 const QString RatioCropTool::Private::configGoldenFlipVerticalEntry(QLatin1String("Golden Flip Vertical")); 0194 const QString RatioCropTool::Private::configGuideColorEntry(QLatin1String("Guide Color")); 0195 const QString RatioCropTool::Private::configGuideWidthEntry(QLatin1String("Guide Width")); 0196 const QString RatioCropTool::Private::configHistogramChannelEntry(QLatin1String("Histogram Channel")); 0197 const QString RatioCropTool::Private::configHistogramScaleEntry(QLatin1String("Histogram Scale")); 0198 0199 // -------------------------------------------------------- 0200 0201 RatioCropTool::RatioCropTool(QObject* const parent) 0202 : EditorTool(parent), 0203 d (new Private) 0204 { 0205 setObjectName(QLatin1String("aspectratiocrop")); 0206 setToolName(i18n("Aspect Ratio Crop")); 0207 setToolIcon(QIcon::fromTheme(QLatin1String("transform-crop"))); 0208 setToolHelp(QLatin1String("ratiocroptool.anchor")); 0209 0210 // ------------------------------------------------------------- 0211 0212 // Important: Deactivate drawing of the selection now, we will enable it later. 0213 d->ratioCropWidget = new RatioCropWidget(480, 320, false); 0214 d->ratioCropWidget->setWhatsThis(i18n("<p>Here you can see the aspect ratio selection preview " 0215 "used for cropping. You can use the mouse to move and " 0216 "resize the crop area.</p>" 0217 "<p>Press and hold the <b>CTRL</b> key to move the opposite corner too.</p>" 0218 "<p>Press and hold the <b>SHIFT</b> key to move the closest corner to the " 0219 "mouse pointer.</p>")); 0220 0221 d->originalIsLandscape = (d->ratioCropWidget->getOriginalImageWidth() > 0222 d->ratioCropWidget->getOriginalImageHeight()); 0223 0224 setToolView(d->ratioCropWidget); 0225 0226 // ------------------------------------------------------------- 0227 0228 d->gboxSettings = new EditorToolSettings(nullptr); 0229 d->gboxSettings->setButtons(EditorToolSettings::Default | 0230 EditorToolSettings::Ok | 0231 EditorToolSettings::Try | 0232 EditorToolSettings::Cancel); 0233 0234 // ------------------------------------------------------------- 0235 0236 QPushButton* const tryBtn = d->gboxSettings->button(EditorToolSettings::Try); 0237 tryBtn->setText(i18n("Max. Aspect")); 0238 tryBtn->setToolTip(i18n("Set selection area to the maximum size according " 0239 "to the current ratio.")); 0240 0241 // ------------------------------------------------------------- 0242 0243 QVBoxLayout* const vlay = new QVBoxLayout(d->gboxSettings->plainPage()); 0244 d->expbox = new DExpanderBox(d->gboxSettings->plainPage()); 0245 d->expbox->setObjectName(QLatin1String("RatioCropTool Expander")); 0246 0247 // ------------------------------------------------------------- 0248 0249 QWidget* const cropInfo = new QWidget(d->expbox); 0250 QGridLayout* const grid3 = new QGridLayout(cropInfo); 0251 0252 d->histogramBox = new HistogramBox(cropInfo, Digikam::LRGBAC); 0253 0254 QLabel* const resolution = new QLabel(i18n("Resolution:"), cropInfo); 0255 d->resLabel = new QLabel(cropInfo); 0256 d->resLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 0257 0258 const int spacing = d->gboxSettings->spacingHint(); 0259 const int iconSize = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 0260 0261 grid3->addWidget(d->histogramBox, 0, 0, 1, 3); 0262 grid3->addWidget(resolution, 1, 0, 1, 1); 0263 grid3->addWidget(d->resLabel, 1, 1, 1, 2); 0264 grid3->setContentsMargins(spacing, spacing, spacing, spacing); 0265 grid3->setSpacing(spacing); 0266 0267 d->expbox->addItem(cropInfo, QIcon::fromTheme(QLatin1String("help-about")).pixmap(iconSize), 0268 i18n("Crop Information"), QLatin1String("CropInformation"), true); 0269 0270 // ------------------------------------------------------------- 0271 0272 QWidget* const cropSelection = new QWidget(d->expbox); 0273 0274 QLabel* const label = new QLabel(i18n("Aspect ratio:"), cropSelection); 0275 d->ratioCB = new DComboBox(cropSelection); 0276 d->ratioCB->addItem(i18nc("custom aspect ratio crop settings", "Custom")); 0277 // NOTE: Order is important there. Look RatioCropWidget::RatioAspect for details. 0278 d->ratioCB->addItem(QLatin1String("1:1")); 0279 d->ratioCB->addItem(QLatin1String("2:1")); 0280 d->ratioCB->addItem(QLatin1String("2:3")); 0281 d->ratioCB->addItem(QLatin1String("3:1")); 0282 d->ratioCB->addItem(QLatin1String("3:4")); 0283 d->ratioCB->addItem(QLatin1String("4:1")); 0284 d->ratioCB->addItem(QLatin1String("4:5")); 0285 d->ratioCB->addItem(QLatin1String("5:7")); 0286 d->ratioCB->addItem(QLatin1String("7:10")); 0287 d->ratioCB->addItem(QLatin1String("8:5")); 0288 d->ratioCB->addItem(QLatin1String("16:9")); 0289 d->ratioCB->addItem(i18n("Format DIN A")); 0290 d->ratioCB->addItem(i18n("Golden Ratio")); 0291 d->ratioCB->addItem(i18n("Current Aspect Ratio")); 0292 d->ratioCB->addItem(i18nc("no aspect ratio", "None")); 0293 d->ratioCB->setDefaultIndex(RatioCropWidget::RATIO03X04); 0294 setRatioCBText(RatioCropWidget::Landscape); 0295 d->ratioCB->setWhatsThis(i18n("<p>Select your constrained aspect ratio for cropping. " 0296 "Aspect Ratio Crop tool uses a relative ratio. That means it " 0297 "is the same if you use centimeters or inches and it does not " 0298 "specify the physical size.</p>" 0299 "<p>You can see below a correspondence list of traditional photographic " 0300 "paper sizes and aspect ratio crop:</p>" 0301 "<p><b>2:3</b>: 10x15cm, 20x30cm, 30x45cm, 4x6\", 8x12\", " 0302 "12x18\", 16x24\", 20x30\"</p>" 0303 "<p><b>3:4</b>: 6x8cm, 15x20cm, 18x24cm, 30x40cm, 3.75x5\", 4.5x6\", " 0304 "6x8\", 7.5x10\", 9x12\"</p>" 0305 "<p><b>4:5</b>: 20x25cm, 40x50cm, 8x10\", 16x20\"</p>" 0306 "<p><b>5:7</b>: 15x21cm, 30x42cm, 5x7\"</p>" 0307 "<p><b>7:10</b>: 21x30cm, 42x60cm, 3.5x5\"</p>" 0308 "<p><b>8:5</b>: common wide-screen monitor (as 1680x1050)</p>" 0309 "<p><b>2:1</b>, <b>3:1</b>, <b>4:1</b>: common panoramic sizes</p>" 0310 "<p><b>16:9</b>: common tv-screen (as HDTV or Full-HD)</p>" 0311 "<p>The paper <b>Format DIN A</b> use the ratio 1:1.414</p>" 0312 "<p>The <b>Golden Ratio</b> is 1:1.618. A composition following this rule " 0313 "is considered visually harmonious but may not be suitable to print on " 0314 "standard photographic paper.</p>" 0315 "<p>The <b>Current Aspect Ratio</b> takes aspect ratio from the currently " 0316 "opened image.</p>")); 0317 0318 d->preciseCrop = new QCheckBox(cropSelection); 0319 d->preciseCrop->setToolTip(i18n("Exact aspect")); 0320 d->preciseCrop->setWhatsThis(i18n("Enable this option to force exact aspect ratio crop.")); 0321 0322 d->orientLabel = new QLabel(i18n("Orientation:"), cropSelection); 0323 d->orientCB = new DComboBox(cropSelection); 0324 d->orientCB->addItem(i18n("Landscape")); 0325 d->orientCB->addItem(i18n("Portrait")); 0326 d->orientCB->setWhatsThis(i18n("Select constrained aspect ratio orientation.")); 0327 0328 d->autoOrientation = new QCheckBox(cropSelection); 0329 d->autoOrientation->setToolTip(i18n("Auto")); 0330 d->autoOrientation->setWhatsThis(i18n("Enable this option to automatically set the orientation.")); 0331 0332 // ------------------------------------------------------------- 0333 0334 d->customLabel = new QLabel(i18n("Custom ratio:"), cropSelection); 0335 d->customLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); 0336 d->customRatioNInput = new DIntNumInput(cropSelection); 0337 d->customRatioNInput->setRange(1, 10000, 1); 0338 d->customRatioNInput->setDefaultValue(1); 0339 d->customRatioNInput->setWhatsThis(i18n("Set here the desired custom aspect numerator value.")); 0340 0341 d->customRatioDInput = new DIntNumInput(cropSelection); 0342 d->customRatioDInput->setRange(1, 10000, 1); 0343 d->customRatioDInput->setDefaultValue(1); 0344 d->customRatioDInput->setWhatsThis(i18n("Set here the desired custom aspect denominator value.")); 0345 0346 // ------------------------------------------------------------- 0347 0348 QLabel* const positionLabel = new QLabel(i18n("Position:"), cropSelection); 0349 positionLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); 0350 0351 d->xInput = new DIntNumInput(cropSelection); 0352 d->xInput->setWhatsThis(i18n("Set here the top left selection corner position for cropping.")); 0353 d->xInput->setRange(0, d->ratioCropWidget->getOriginalImageWidth(), 1); 0354 d->xInput->setDefaultValue(50); 0355 0356 d->yInput = new DIntNumInput(cropSelection); 0357 d->yInput->setWhatsThis(i18n("Set here the top left selection corner position for cropping.")); 0358 d->yInput->setRange(0, d->ratioCropWidget->getOriginalImageWidth(), 1); 0359 d->yInput->setDefaultValue(50); 0360 0361 // ------------------------------------------------------------- 0362 0363 QLabel* const sizeLabel = new QLabel(i18n("Size:"), cropSelection); 0364 sizeLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); 0365 0366 d->widthInput = new DIntNumInput(cropSelection); 0367 d->widthInput->setWhatsThis(i18n("Set here the width selection for cropping.")); 0368 d->widthInput->setRange(d->ratioCropWidget->getMinWidthRange(), 0369 d->ratioCropWidget->getMaxWidthRange(), 0370 d->ratioCropWidget->getWidthStep()); 0371 d->widthInput->setDefaultValue(800); 0372 0373 d->centerWidth = new QToolButton(cropSelection); 0374 d->centerWidth->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0375 QLatin1String("digikam/data/centerwidth.png")))); 0376 d->centerWidth->setWhatsThis(i18n("Set width position to center.")); 0377 0378 d->heightInput = new DIntNumInput(cropSelection); 0379 d->heightInput->setWhatsThis(i18n("Set here the height selection for cropping.")); 0380 d->heightInput->setRange(d->ratioCropWidget->getMinHeightRange(), 0381 d->ratioCropWidget->getMaxHeightRange(), 0382 d->ratioCropWidget->getHeightStep()); 0383 d->heightInput->setDefaultValue(600); 0384 0385 d->centerHeight = new QToolButton(cropSelection); 0386 d->centerHeight->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0387 QLatin1String("digikam/data/centerheight.png")))); 0388 d->centerHeight->setWhatsThis(i18n("Set height position to center.")); 0389 0390 // ------------------------------------------------------------- 0391 0392 QGridLayout* const mainLayout = new QGridLayout(cropSelection); 0393 mainLayout->addWidget(label, 0, 0, 1, 1); 0394 mainLayout->addWidget(d->ratioCB, 0, 1, 1, 3); 0395 mainLayout->addWidget(d->preciseCrop, 0, 4, 1, 1); 0396 mainLayout->addWidget(d->customLabel, 1, 0, 1, 1); 0397 mainLayout->addWidget(d->customRatioNInput, 1, 1, 1, 3); 0398 mainLayout->addWidget(d->customRatioDInput, 2, 1, 1, 3); 0399 mainLayout->addWidget(d->orientLabel, 3, 0, 1, 1); 0400 mainLayout->addWidget(d->orientCB, 3, 1, 1, 3); 0401 mainLayout->addWidget(d->autoOrientation, 3, 4, 1, 1); 0402 mainLayout->addWidget(positionLabel, 4, 0, 1, 1); 0403 mainLayout->addWidget(d->xInput, 4, 1, 1, 3); 0404 mainLayout->addWidget(d->yInput, 5, 1, 1, 3); 0405 mainLayout->addWidget(sizeLabel, 6, 0, 1, 1); 0406 mainLayout->addWidget(d->widthInput, 6, 1, 1, 3); 0407 mainLayout->addWidget(d->centerWidth, 6, 4, 1, 1); 0408 mainLayout->addWidget(d->heightInput, 7, 1, 1, 3); 0409 mainLayout->addWidget(d->centerHeight, 7, 4, 1, 1); 0410 mainLayout->setContentsMargins(spacing, spacing, spacing, spacing); 0411 mainLayout->setSpacing(spacing); 0412 0413 d->expbox->addItem(cropSelection, QIcon::fromTheme(QLatin1String("transform-crop-and-resize")).pixmap(iconSize), 0414 i18n("Crop Settings"), QLatin1String("CropSelection"), true); 0415 0416 // ------------------------------------------------------------- 0417 0418 QWidget* const compositionGuide = new QWidget(d->expbox); 0419 QGridLayout* const grid2 = new QGridLayout(compositionGuide); 0420 0421 QLabel* const labelGuideLines = new QLabel(i18nc("@label: guide lines", "Form:"), compositionGuide); 0422 d->guideLinesCB = new DComboBox(compositionGuide); 0423 d->guideLinesCB->addItem(i18n("Rules of Thirds")); 0424 d->guideLinesCB->addItem(i18n("Diagonal Method")); 0425 d->guideLinesCB->addItem(i18n("Harmonious Triangles")); 0426 d->guideLinesCB->addItem(i18n("Golden Mean")); 0427 d->guideLinesCB->addItem(i18n("Center Lines")); 0428 d->guideLinesCB->addItem(i18nc("no geometric form", "None")); 0429 d->guideLinesCB->setDefaultIndex(RatioCropWidget::GuideNone); 0430 d->guideLinesCB->setCurrentIndex(3); 0431 d->guideLinesCB->setWhatsThis(i18n("With this option, you can display guide lines " 0432 "to help compose your photograph.")); 0433 0434 d->goldenSectionBox = new QCheckBox(i18n("Golden sections"), compositionGuide); 0435 d->goldenSectionBox->setWhatsThis(i18n("Enable this option to show golden sections.")); 0436 0437 d->goldenSpiralSectionBox = new QCheckBox(i18n("Golden spiral sections"), compositionGuide); 0438 d->goldenSpiralSectionBox->setWhatsThis(i18n("Enable this option to show golden spiral sections.")); 0439 0440 d->goldenSpiralBox = new QCheckBox(i18n("Golden spiral"), compositionGuide); 0441 d->goldenSpiralBox->setWhatsThis(i18n("Enable this option to show a golden spiral guide.")); 0442 0443 d->goldenTriangleBox = new QCheckBox(i18n("Golden triangles"), compositionGuide); 0444 d->goldenTriangleBox->setWhatsThis(i18n("Enable this option to show golden triangles.")); 0445 0446 d->flipHorBox = new QCheckBox(i18n("Flip horizontally"), compositionGuide); 0447 d->flipHorBox->setWhatsThis(i18n("Enable this option to flip the guidelines horizontally.")); 0448 0449 d->flipVerBox = new QCheckBox(i18n("Flip vertically"), compositionGuide); 0450 d->flipVerBox->setWhatsThis(i18n("Enable this option to flip the guidelines vertically.")); 0451 0452 d->colorGuideLabel = new QLabel(i18n("Color and width:"), compositionGuide); 0453 d->guideColorBt = new DColorSelector(compositionGuide); 0454 d->guideColorBt->setColor(QColor(250, 250, 255)); 0455 d->guideSize = new DIntNumInput(compositionGuide); 0456 d->guideSize->setRange(1, 5, 1); 0457 d->guideSize->setDefaultValue(1); 0458 d->guideColorBt->setWhatsThis(i18n("Set here the color used to draw composition guides.")); 0459 d->guideSize->setWhatsThis(i18n("Set here the width in pixels used to draw composition guides.")); 0460 0461 // ------------------------------------------------------------- 0462 0463 grid2->addWidget(labelGuideLines, 0, 0, 1, 1); 0464 grid2->addWidget(d->guideLinesCB, 0, 1, 1, 2); 0465 grid2->addWidget(d->goldenSectionBox, 1, 0, 1, 3); 0466 grid2->addWidget(d->goldenSpiralSectionBox, 2, 0, 1, 3); 0467 grid2->addWidget(d->goldenSpiralBox, 3, 0, 1, 3); 0468 grid2->addWidget(d->goldenTriangleBox, 4, 0, 1, 3); 0469 grid2->addWidget(d->flipHorBox, 5, 0, 1, 3); 0470 grid2->addWidget(d->flipVerBox, 6, 0, 1, 3); 0471 grid2->addWidget(d->colorGuideLabel, 7, 0, 1, 1); 0472 grid2->addWidget(d->guideColorBt, 7, 1, 1, 1); 0473 grid2->addWidget(d->guideSize, 7, 2, 1, 1); 0474 grid2->setContentsMargins(spacing, spacing, spacing, spacing); 0475 grid2->setSpacing(spacing); 0476 0477 d->expbox->addItem(compositionGuide, QIcon::fromTheme(QLatin1String("tools-wizard")).pixmap(iconSize), 0478 i18n("Composition Guides"), QLatin1String("CompositionGuide"), true); 0479 0480 d->expbox->addStretch(); 0481 0482 // ------------------------------------------------------------- 0483 0484 vlay->addWidget(d->expbox, 10); 0485 vlay->addStretch(); 0486 vlay->setContentsMargins(QMargins()); 0487 vlay->setSpacing(0); 0488 0489 // ------------------------------------------------------------- 0490 0491 setToolSettings(d->gboxSettings); 0492 0493 // ------------------------------------------------------------- 0494 0495 connect(d->ratioCB, SIGNAL(activated(int)), 0496 this, SLOT(slotRatioChanged(int))); 0497 0498 connect(d->preciseCrop, SIGNAL(toggled(bool)), 0499 this, SLOT(slotPreciseCropChanged(bool))); 0500 0501 connect(d->orientCB, SIGNAL(activated(int)), 0502 this, SLOT(slotOrientChanged(int))); 0503 0504 connect(d->autoOrientation, SIGNAL(toggled(bool)), 0505 this, SLOT(slotAutoOrientChanged(bool))); 0506 0507 connect(d->xInput, SIGNAL(valueChanged(int)), 0508 this, SLOT(slotXChanged(int))); 0509 0510 connect(d->yInput, SIGNAL(valueChanged(int)), 0511 this, SLOT(slotYChanged(int))); 0512 0513 connect(d->customRatioNInput, SIGNAL(valueChanged(int)), 0514 this, SLOT(slotCustomRatioChanged())); 0515 0516 connect(d->customRatioDInput, SIGNAL(valueChanged(int)), 0517 this, SLOT(slotCustomRatioChanged())); 0518 0519 connect(d->guideLinesCB, SIGNAL(activated(int)), 0520 this, SLOT(slotGuideTypeChanged(int))); 0521 0522 connect(d->goldenSectionBox, SIGNAL(toggled(bool)), 0523 this, SLOT(slotGoldenGuideTypeChanged())); 0524 0525 connect(d->goldenSpiralSectionBox, SIGNAL(toggled(bool)), 0526 this, SLOT(slotGoldenGuideTypeChanged())); 0527 0528 connect(d->goldenSpiralBox, SIGNAL(toggled(bool)), 0529 this, SLOT(slotGoldenGuideTypeChanged())); 0530 0531 connect(d->goldenTriangleBox, SIGNAL(toggled(bool)), 0532 this, SLOT(slotGoldenGuideTypeChanged())); 0533 0534 connect(d->flipHorBox, SIGNAL(toggled(bool)), 0535 this, SLOT(slotGoldenGuideTypeChanged())); 0536 0537 connect(d->flipVerBox, SIGNAL(toggled(bool)), 0538 this, SLOT(slotGoldenGuideTypeChanged())); 0539 0540 connect(d->guideColorBt, SIGNAL(signalColorSelected(QColor)), 0541 d->ratioCropWidget, SLOT(slotChangeGuideColor(QColor))); 0542 0543 connect(d->guideSize, SIGNAL(valueChanged(int)), 0544 d->ratioCropWidget, SLOT(slotChangeGuideSize(int))); 0545 0546 connect(d->widthInput, SIGNAL(valueChanged(int)), 0547 this, SLOT(slotWidthChanged(int))); 0548 0549 connect(d->heightInput, SIGNAL(valueChanged(int)), 0550 this, SLOT(slotHeightChanged(int))); 0551 0552 connect(d->ratioCropWidget, SIGNAL(signalSelectionChanged(QRect)), 0553 this, SLOT(slotSelectionChanged(QRect))); 0554 0555 connect(d->ratioCropWidget, SIGNAL(signalSelectionMoved(QRect)), 0556 this, SLOT(slotSelectionChanged(QRect))); 0557 0558 connect(d->ratioCropWidget, SIGNAL(signalSelectionOrientationChanged(int)), 0559 this, SLOT(slotSelectionOrientationChanged(int))); 0560 0561 connect(d->centerWidth, SIGNAL(clicked()), 0562 this, SLOT(slotCenterWidth())); 0563 0564 connect(d->centerHeight, SIGNAL(clicked()), 0565 this, SLOT(slotCenterHeight())); 0566 0567 // we need to disconnect the standard connection of the Try button first 0568 disconnect(d->gboxSettings, SIGNAL(signalTryClicked()), 0569 this, SLOT(slotPreview())); 0570 0571 connect(d->gboxSettings, SIGNAL(signalTryClicked()), 0572 this, SLOT(slotMaxAspectRatio())); 0573 } 0574 0575 RatioCropTool::~RatioCropTool() 0576 { 0577 d->histogramBox->histogram()->stopHistogramComputation(); 0578 delete d; 0579 } 0580 0581 void RatioCropTool::readSettings() 0582 { 0583 QColor defaultGuideColor(250, 250, 255); 0584 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0585 KConfigGroup group = config->group(d->configGroupName); 0586 0587 // -------------------------------------------------------- 0588 0589 // Note: the selection widget has been setup to NOT draw the selection at the moment. 0590 // This is necessary to avoid jumping of the selection when reading the settings. 0591 // The drawing must be activated later on in this method to have a working selection. 0592 0593 d->expbox->readSettings(group); 0594 0595 // No guide lines per default. 0596 d->guideLinesCB->setCurrentIndex(group.readEntry(d->configGuideLinesTypeEntry, 0597 (int)RatioCropWidget::GuideNone)); 0598 d->goldenSectionBox->setChecked(group.readEntry(d->configGoldenSectionEntry, true)); 0599 d->goldenSpiralSectionBox->setChecked(group.readEntry(d->configGoldenSpiralSectionEntry, false)); 0600 d->goldenSpiralBox->setChecked(group.readEntry(d->configGoldenSpiralEntry, false)); 0601 d->goldenTriangleBox->setChecked(group.readEntry(d->configGoldenTriangleEntry, false)); 0602 d->flipHorBox->setChecked(group.readEntry(d->configGoldenFlipHorizontalEntry, false)); 0603 d->flipVerBox->setChecked(group.readEntry(d->configGoldenFlipVerticalEntry, false)); 0604 d->autoOrientation->setChecked(group.readEntry(d->configAutoOrientationEntry, false)); 0605 d->preciseCrop->setChecked(group.readEntry(d->configPreciseAspectRatioCropEntry, false)); 0606 d->guideColorBt->setColor(group.readEntry(d->configGuideColorEntry, defaultGuideColor)); 0607 d->guideSize->setValue(group.readEntry(d->configGuideWidthEntry, d->guideSize->defaultValue())); 0608 0609 d->ratioCropWidget->slotGuideLines(d->guideLinesCB->currentIndex()); 0610 d->ratioCropWidget->slotChangeGuideColor(d->guideColorBt->color()); 0611 d->ratioCropWidget->setPreciseCrop(d->preciseCrop->isChecked()); 0612 0613 if (d->originalIsLandscape) 0614 { 0615 d->ratioCB->setCurrentIndex(group.readEntry(d->configHorOrientedAspectRatioEntry, 0616 d->ratioCB->defaultIndex())); 0617 d->orientCB->setDefaultIndex(RatioCropWidget::Landscape); 0618 d->orientCB->setCurrentIndex(group.readEntry(d->configHorOrientedAspectRatioOrientationEntry, 0619 (int)RatioCropWidget::Landscape)); 0620 d->customRatioNInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioNumEntry, 0621 d->customRatioNInput->defaultValue())); 0622 d->customRatioDInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioDenEntry, 0623 d->customRatioDInput->defaultValue())); 0624 0625 d->ratioCropWidget->setSelectionOrientation(d->orientCB->currentIndex()); 0626 slotAutoOrientChanged(d->autoOrientation->isChecked()); 0627 applyRatioChanges(d->ratioCB->currentIndex()); 0628 slotHeightChanged(1); 0629 slotWidthChanged(1); 0630 0631 setInputRange(d->ratioCropWidget->getRegionSelection()); 0632 0633 d->xInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioXposEntry, 0634 d->xInput->defaultValue())); 0635 d->yInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioYposEntry, 0636 d->yInput->defaultValue())); 0637 0638 setInputRange(d->ratioCropWidget->getRegionSelection()); 0639 0640 d->widthInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioWidthEntry, 0641 d->widthInput->defaultValue())); 0642 d->heightInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioHeightEntry, 0643 d->heightInput->defaultValue())); 0644 } 0645 else 0646 { 0647 d->ratioCB->setCurrentIndex(group.readEntry(d->configVerOrientedAspectRatioEntry, 0648 d->ratioCB->defaultIndex())); 0649 d->orientCB->setDefaultIndex(RatioCropWidget::Portrait); 0650 d->orientCB->setCurrentIndex(group.readEntry(d->configVerOrientedAspectRatioOrientationEntry, 0651 (int)RatioCropWidget::Portrait)); 0652 d->customRatioNInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioNumEntry, 0653 d->customRatioNInput->defaultValue())); 0654 d->customRatioDInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioDenEntry, 0655 d->customRatioDInput->defaultValue())); 0656 0657 d->ratioCropWidget->setSelectionOrientation(d->orientCB->currentIndex()); 0658 slotAutoOrientChanged(d->autoOrientation->isChecked()); 0659 applyRatioChanges(d->ratioCB->currentIndex()); 0660 slotHeightChanged(1); 0661 slotWidthChanged(1); 0662 0663 setInputRange(d->ratioCropWidget->getRegionSelection()); 0664 0665 d->xInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioXposEntry, 0666 d->xInput->defaultValue())); 0667 d->yInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioYposEntry, 0668 d->yInput->defaultValue())); 0669 0670 setInputRange(d->ratioCropWidget->getRegionSelection()); 0671 0672 d->widthInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioWidthEntry, 0673 d->widthInput->defaultValue())); 0674 d->heightInput->setValue(group.readEntry(d->configVerOrientedCustomAspectRatioHeightEntry, 0675 d->heightInput->defaultValue())); 0676 } 0677 0678 setInputRange(d->ratioCropWidget->getRegionSelection()); 0679 0680 // For the last setting to be applied, activate drawing in 0681 // the selectionWidget, so that we can see the results. 0682 0683 d->ratioCropWidget->setIsDrawingSelection(true); 0684 0685 slotGuideTypeChanged(d->guideLinesCB->currentIndex()); 0686 0687 updateCropInfo(); 0688 0689 d->histogramBox->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry, (int)Digikam::LuminosityChannel)); 0690 d->histogramBox->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry, (int)LogScaleHistogram)); 0691 } 0692 0693 void RatioCropTool::writeSettings() 0694 { 0695 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0696 KConfigGroup group = config->group(d->configGroupName); 0697 0698 if (d->originalIsLandscape) 0699 { 0700 group.writeEntry(d->configHorOrientedAspectRatioEntry, d->ratioCB->currentIndex()); 0701 group.writeEntry(d->configHorOrientedAspectRatioOrientationEntry, d->orientCB->currentIndex()); 0702 group.writeEntry(d->configHorOrientedCustomAspectRatioNumEntry, d->customRatioNInput->value()); 0703 group.writeEntry(d->configHorOrientedCustomAspectRatioDenEntry, d->customRatioDInput->value()); 0704 0705 group.writeEntry(d->configHorOrientedCustomAspectRatioXposEntry, d->xInput->value()); 0706 group.writeEntry(d->configHorOrientedCustomAspectRatioYposEntry, d->yInput->value()); 0707 group.writeEntry(d->configHorOrientedCustomAspectRatioWidthEntry, d->widthInput->value()); 0708 group.writeEntry(d->configHorOrientedCustomAspectRatioHeightEntry, d->heightInput->value()); 0709 } 0710 else 0711 { 0712 group.writeEntry(d->configVerOrientedAspectRatioEntry, d->ratioCB->currentIndex()); 0713 group.writeEntry(d->configVerOrientedAspectRatioOrientationEntry, d->orientCB->currentIndex()); 0714 group.writeEntry(d->configVerOrientedCustomAspectRatioNumEntry, d->customRatioNInput->value()); 0715 group.writeEntry(d->configVerOrientedCustomAspectRatioDenEntry, d->customRatioDInput->value()); 0716 0717 group.writeEntry(d->configVerOrientedCustomAspectRatioXposEntry, d->xInput->value()); 0718 group.writeEntry(d->configVerOrientedCustomAspectRatioYposEntry, d->yInput->value()); 0719 group.writeEntry(d->configVerOrientedCustomAspectRatioWidthEntry, d->widthInput->value()); 0720 group.writeEntry(d->configVerOrientedCustomAspectRatioHeightEntry, d->heightInput->value()); 0721 } 0722 0723 group.writeEntry(d->configPreciseAspectRatioCropEntry, d->preciseCrop->isChecked()); 0724 group.writeEntry(d->configAutoOrientationEntry, d->autoOrientation->isChecked()); 0725 group.writeEntry(d->configGuideLinesTypeEntry, d->guideLinesCB->currentIndex()); 0726 group.writeEntry(d->configGoldenSectionEntry, d->goldenSectionBox->isChecked()); 0727 group.writeEntry(d->configGoldenSpiralSectionEntry, d->goldenSpiralSectionBox->isChecked()); 0728 group.writeEntry(d->configGoldenSpiralEntry, d->goldenSpiralBox->isChecked()); 0729 group.writeEntry(d->configGoldenTriangleEntry, d->goldenTriangleBox->isChecked()); 0730 group.writeEntry(d->configGoldenFlipHorizontalEntry, d->flipHorBox->isChecked()); 0731 group.writeEntry(d->configGoldenFlipVerticalEntry, d->flipVerBox->isChecked()); 0732 group.writeEntry(d->configGuideColorEntry, d->guideColorBt->color()); 0733 group.writeEntry(d->configGuideWidthEntry, d->guideSize->value()); 0734 group.writeEntry(d->configHistogramChannelEntry, (int)d->histogramBox->channel()); 0735 group.writeEntry(d->configHistogramScaleEntry, (int)d->histogramBox->scale()); 0736 0737 d->expbox->writeSettings(group); 0738 0739 group.sync(); 0740 } 0741 0742 void RatioCropTool::slotResetSelection() 0743 { 0744 d->ratioCropWidget->resetSelection(); 0745 } 0746 0747 void RatioCropTool::slotResetSettings() 0748 { 0749 d->guideLinesCB->setCurrentIndex(RatioCropWidget::GuideNone); 0750 d->goldenSectionBox->setChecked(true); 0751 d->goldenSpiralSectionBox->setChecked(false); 0752 d->goldenSpiralBox->setChecked(false); 0753 d->goldenTriangleBox->setChecked(false); 0754 d->flipHorBox->setChecked(false); 0755 d->flipVerBox->setChecked(false); 0756 d->autoOrientation->setChecked(false); 0757 d->preciseCrop->setChecked(false); 0758 d->guideColorBt->setColor(QColor(250, 250, 255)); 0759 d->guideSize->setValue(d->guideSize->defaultValue()); 0760 0761 d->ratioCropWidget->slotGuideLines(d->guideLinesCB->currentIndex()); 0762 d->ratioCropWidget->slotChangeGuideColor(d->guideColorBt->color()); 0763 d->ratioCropWidget->setPreciseCrop(d->preciseCrop->isChecked()); 0764 d->ratioCB->setCurrentIndex(d->ratioCB->defaultIndex()); 0765 0766 if (d->originalIsLandscape) 0767 { 0768 d->orientCB->setDefaultIndex(RatioCropWidget::Landscape); 0769 d->orientCB->setCurrentIndex(RatioCropWidget::Landscape); 0770 } 0771 else 0772 { 0773 d->orientCB->setDefaultIndex(RatioCropWidget::Portrait); 0774 d->orientCB->setCurrentIndex(RatioCropWidget::Portrait); 0775 } 0776 0777 d->customRatioNInput->setValue(d->customRatioNInput->defaultValue()); 0778 d->customRatioDInput->setValue(d->customRatioDInput->defaultValue()); 0779 0780 d->ratioCropWidget->setSelectionOrientation(d->orientCB->currentIndex()); 0781 slotAutoOrientChanged(d->autoOrientation->isChecked()); 0782 applyRatioChanges(d->ratioCB->currentIndex()); 0783 0784 // For the last setting to be applied, activate drawing in 0785 // the selectionWidget, so that we can see the results. 0786 0787 d->ratioCropWidget->setIsDrawingSelection(true); 0788 0789 QTimer::singleShot(0, this, SLOT(slotResetSelection())); 0790 } 0791 0792 void RatioCropTool::slotMaxAspectRatio() 0793 { 0794 d->ratioCropWidget->maxAspectSelection(); 0795 } 0796 0797 void RatioCropTool::slotCenterWidth() 0798 { 0799 d->ratioCropWidget->setCenterSelection(RatioCropWidget::CenterWidth); 0800 } 0801 0802 void RatioCropTool::slotCenterHeight() 0803 { 0804 d->ratioCropWidget->setCenterSelection(RatioCropWidget::CenterHeight); 0805 } 0806 0807 void RatioCropTool::slotSelectionChanged(const QRect& rect) 0808 { 0809 blockWidgetSignals(true); 0810 0811 setInputRange(rect); 0812 d->xInput->setValue(rect.x()); 0813 d->yInput->setValue(rect.y()); 0814 d->widthInput->setValue(rect.width()); 0815 d->heightInput->setValue(rect.height()); 0816 0817 d->gboxSettings->enableButton(EditorToolSettings::Ok, rect.isValid()); 0818 0819 d->preciseCrop->setEnabled(d->ratioCropWidget->preciseCropAvailable()); 0820 0821 updateCropInfo(); 0822 0823 blockWidgetSignals(false); 0824 } 0825 0826 void RatioCropTool::setRatioCBText(int orientation) 0827 { 0828 int item = d->ratioCB->currentIndex(); 0829 d->ratioCB->blockSignals(true); 0830 d->ratioCB->combo()->clear(); 0831 d->ratioCB->addItem(i18nc("custom ratio crop settings", "Custom")); 0832 d->ratioCB->addItem(QLatin1String("1:1")); 0833 0834 if (orientation == RatioCropWidget::Landscape) 0835 { 0836 d->ratioCB->addItem(QLatin1String("1:2")); 0837 d->ratioCB->addItem(QLatin1String("3:2")); 0838 d->ratioCB->addItem(QLatin1String("1:3")); 0839 d->ratioCB->addItem(QLatin1String("4:3")); 0840 d->ratioCB->addItem(QLatin1String("1:4")); 0841 d->ratioCB->addItem(QLatin1String("5:4")); 0842 d->ratioCB->addItem(QLatin1String("7:5")); 0843 d->ratioCB->addItem(QLatin1String("10:7")); 0844 d->ratioCB->addItem(QLatin1String("5:8")); 0845 d->ratioCB->addItem(QLatin1String("9:16")); 0846 } 0847 else 0848 { 0849 d->ratioCB->addItem(QLatin1String("2:1")); 0850 d->ratioCB->addItem(QLatin1String("2:3")); 0851 d->ratioCB->addItem(QLatin1String("3:1")); 0852 d->ratioCB->addItem(QLatin1String("3:4")); 0853 d->ratioCB->addItem(QLatin1String("4:1")); 0854 d->ratioCB->addItem(QLatin1String("4:5")); 0855 d->ratioCB->addItem(QLatin1String("5:7")); 0856 d->ratioCB->addItem(QLatin1String("7:10")); 0857 d->ratioCB->addItem(QLatin1String("8:5")); 0858 d->ratioCB->addItem(QLatin1String("16:9")); 0859 } 0860 0861 d->ratioCB->addItem(i18n("Format DIN A")); 0862 d->ratioCB->addItem(i18n("Golden Ratio")); 0863 d->ratioCB->addItem(i18n("Current Aspect Ratio")); 0864 d->ratioCB->addItem(i18nc("no aspect ratio", "None")); 0865 d->ratioCB->setCurrentIndex(item); 0866 d->ratioCB->blockSignals(false); 0867 } 0868 0869 void RatioCropTool::setInputRange(const QRect& rect) 0870 { 0871 d->xInput->setRange(0, d->ratioCropWidget->getOriginalImageWidth() - rect.width(), 1); 0872 d->yInput->setRange(0, d->ratioCropWidget->getOriginalImageHeight() - rect.height(), 1); 0873 d->widthInput->setRange(d->ratioCropWidget->getMinWidthRange(), 0874 d->ratioCropWidget->getMaxWidthRange(), 0875 d->ratioCropWidget->getWidthStep()); 0876 d->heightInput->setRange(d->ratioCropWidget->getMinHeightRange(), 0877 d->ratioCropWidget->getMaxHeightRange(), 0878 d->ratioCropWidget->getHeightStep()); 0879 } 0880 0881 void RatioCropTool::slotSelectionOrientationChanged(int newOrientation) 0882 { 0883 // Change text for Aspect ratio ComboBox 0884 0885 setRatioCBText(newOrientation); 0886 0887 // Change Orientation ComboBox 0888 0889 d->orientCB->setCurrentIndex(newOrientation); 0890 0891 // Reverse custom values 0892 0893 if ((d->customRatioNInput->value() < d->customRatioDInput->value() && 0894 newOrientation == RatioCropWidget::Landscape) || 0895 (d->customRatioNInput->value() > d->customRatioDInput->value() && 0896 newOrientation == RatioCropWidget::Portrait)) 0897 { 0898 d->customRatioNInput->blockSignals(true); 0899 d->customRatioDInput->blockSignals(true); 0900 0901 int tmp = d->customRatioNInput->value(); 0902 d->customRatioNInput->setValue(d->customRatioDInput->value()); 0903 d->customRatioDInput->setValue(tmp); 0904 0905 d->customRatioNInput->blockSignals(false); 0906 d->customRatioDInput->blockSignals(false); 0907 } 0908 } 0909 0910 void RatioCropTool::slotXChanged(int x) 0911 { 0912 d->ratioCropWidget->setSelectionX(x); 0913 } 0914 0915 void RatioCropTool::slotYChanged(int y) 0916 { 0917 d->ratioCropWidget->setSelectionY(y); 0918 } 0919 0920 void RatioCropTool::slotWidthChanged(int w) 0921 { 0922 d->ratioCropWidget->setSelectionWidth(w); 0923 } 0924 0925 void RatioCropTool::slotHeightChanged(int h) 0926 { 0927 d->ratioCropWidget->setSelectionHeight(h); 0928 } 0929 0930 void RatioCropTool::slotPreciseCropChanged(bool a) 0931 { 0932 d->ratioCropWidget->setPreciseCrop(a); 0933 } 0934 0935 void RatioCropTool::slotOrientChanged(int o) 0936 { 0937 d->ratioCropWidget->setSelectionOrientation(o); 0938 0939 // Reset selection area. 0940 slotResetSelection(); 0941 } 0942 0943 void RatioCropTool::slotAutoOrientChanged(bool a) 0944 { 0945 d->orientCB->setEnabled(!a); 0946 d->ratioCropWidget->setAutoOrientation(a); 0947 } 0948 0949 void RatioCropTool::slotRatioChanged(int a) 0950 { 0951 applyRatioChanges(a); 0952 0953 // Reset selection area. 0954 slotResetSelection(); 0955 } 0956 0957 void RatioCropTool::applyRatioChanges(int a) 0958 { 0959 d->ratioCropWidget->setSelectionAspectRatioType(a); 0960 0961 if (a == RatioCropWidget::RATIOCUSTOM) 0962 { 0963 d->customLabel->setEnabled(true); 0964 d->customRatioNInput->setEnabled(true); 0965 d->customRatioDInput->setEnabled(true); 0966 d->orientLabel->setEnabled(true); 0967 d->orientCB->setEnabled(!d->autoOrientation->isChecked()); 0968 d->autoOrientation->setEnabled(true); 0969 slotCustomRatioChanged(); 0970 } 0971 else if (a == RatioCropWidget::RATIONONE) 0972 { 0973 d->orientLabel->setEnabled(false); 0974 d->orientCB->setEnabled(false); 0975 d->autoOrientation->setEnabled(false); 0976 d->customLabel->setEnabled(false); 0977 d->customRatioNInput->setEnabled(false); 0978 d->customRatioDInput->setEnabled(false); 0979 } 0980 else // Pre-config ratio selected. 0981 { 0982 d->orientLabel->setEnabled(true); 0983 d->orientCB->setEnabled(!d->autoOrientation->isChecked()); 0984 d->autoOrientation->setEnabled(true); 0985 d->customLabel->setEnabled(false); 0986 d->customRatioNInput->setEnabled(false); 0987 d->customRatioDInput->setEnabled(false); 0988 } 0989 } 0990 0991 void RatioCropTool::slotGuideTypeChanged(int t) 0992 { 0993 d->goldenSectionBox->setEnabled(false); 0994 d->goldenSpiralSectionBox->setEnabled(false); 0995 d->goldenSpiralBox->setEnabled(false); 0996 d->goldenTriangleBox->setEnabled(false); 0997 d->flipHorBox->setEnabled(false); 0998 d->flipVerBox->setEnabled(false); 0999 d->colorGuideLabel->setEnabled(true); 1000 d->guideColorBt->setEnabled(true); 1001 d->guideSize->setEnabled(true); 1002 1003 switch (t) 1004 { 1005 case RatioCropWidget::GuideNone: 1006 d->colorGuideLabel->setEnabled(false); 1007 d->guideColorBt->setEnabled(false); 1008 d->guideSize->setEnabled(false); 1009 break; 1010 1011 case RatioCropWidget::HarmoniousTriangles: 1012 d->flipHorBox->setEnabled(true); 1013 d->flipVerBox->setEnabled(true); 1014 break; 1015 1016 case RatioCropWidget::GoldenMean: 1017 d->flipHorBox->setEnabled(true); 1018 d->flipVerBox->setEnabled(true); 1019 d->goldenSectionBox->setEnabled(true); 1020 d->goldenSpiralSectionBox->setEnabled(true); 1021 d->goldenSpiralBox->setEnabled(true); 1022 d->goldenTriangleBox->setEnabled(true); 1023 break; 1024 } 1025 1026 d->ratioCropWidget->setGoldenGuideTypes(d->goldenSectionBox->isChecked(), 1027 d->goldenSpiralSectionBox->isChecked(), 1028 d->goldenSpiralBox->isChecked(), 1029 d->goldenTriangleBox->isChecked(), 1030 d->flipHorBox->isChecked(), 1031 d->flipVerBox->isChecked()); 1032 d->ratioCropWidget->slotGuideLines(t); 1033 } 1034 1035 void RatioCropTool::slotGoldenGuideTypeChanged() 1036 { 1037 slotGuideTypeChanged(d->guideLinesCB->currentIndex()); 1038 } 1039 1040 void RatioCropTool::slotCustomNRatioChanged(int a) 1041 { 1042 if (!d->autoOrientation->isChecked()) 1043 { 1044 if ((d->orientCB->currentIndex() == RatioCropWidget::Portrait && 1045 d->customRatioDInput->value() < a) || 1046 (d->orientCB->currentIndex() == RatioCropWidget::Landscape && 1047 d->customRatioDInput->value() > a)) 1048 { 1049 d->customRatioDInput->blockSignals(true); 1050 d->customRatioDInput->setValue(a); 1051 d->customRatioDInput->blockSignals(false); 1052 } 1053 } 1054 1055 slotCustomRatioChanged(); 1056 } 1057 1058 void RatioCropTool::slotCustomDRatioChanged(int a) 1059 { 1060 if (!d->autoOrientation->isChecked()) 1061 { 1062 if ((d->orientCB->currentIndex() == RatioCropWidget::Landscape && 1063 d->customRatioNInput->value() < a) || 1064 (d->orientCB->currentIndex() == RatioCropWidget::Portrait && 1065 d->customRatioNInput->value() > a)) 1066 { 1067 d->customRatioNInput->blockSignals(true); 1068 d->customRatioNInput->setValue(a); 1069 d->customRatioNInput->blockSignals(false); 1070 } 1071 } 1072 1073 slotCustomRatioChanged(); 1074 } 1075 1076 void RatioCropTool::slotCustomRatioChanged() 1077 { 1078 d->ratioCropWidget->setSelectionAspectRatioValue(d->customRatioNInput->value(), d->customRatioDInput->value()); 1079 1080 // Reset selection area. 1081 slotResetSelection(); 1082 } 1083 1084 void RatioCropTool::updateCropInfo() 1085 { 1086 d->histogramBox->histogram()->stopHistogramComputation(); 1087 DImg* const img = d->ratioCropWidget->imageIface()->original(); 1088 d->imageSelection = img->copy(getNormalizedRegion()); 1089 d->histogramBox->histogram()->updateData(d->imageSelection); 1090 1091 QString mpixels = QLocale().toString(d->widthInput->value() * d->heightInput->value() / 1000000.0, 'f', 1); 1092 d->resLabel->setText(i18nc("width x height (megapixels Mpx)", "%1x%2 (%3Mpx)", 1093 d->widthInput->value(), d->heightInput->value(), mpixels)); 1094 } 1095 1096 QRect RatioCropTool::getNormalizedRegion() const 1097 { 1098 QRect currentRegion = d->ratioCropWidget->getRegionSelection(); 1099 ImageIface* const iface = d->ratioCropWidget->imageIface(); 1100 int w = iface->originalSize().width(); 1101 int h = iface->originalSize().height(); 1102 QRect normalizedRegion = currentRegion.normalized(); 1103 1104 if (normalizedRegion.right() > w) 1105 { 1106 normalizedRegion.setRight(w); 1107 } 1108 1109 if (normalizedRegion.bottom() > h) 1110 { 1111 normalizedRegion.setBottom(h); 1112 } 1113 1114 return normalizedRegion; 1115 } 1116 1117 void RatioCropTool::finalRendering() 1118 { 1119 qApp->setOverrideCursor(Qt::WaitCursor); 1120 1121 QRect currentRegion = d->ratioCropWidget->getRegionSelection(); 1122 ImageIface* const iface = d->ratioCropWidget->imageIface(); 1123 QRect normalizedRegion = getNormalizedRegion(); 1124 DImg imOrg = iface->original()->copy(); 1125 1126 imOrg.crop(normalizedRegion); 1127 FilterAction action(QLatin1String("digikam:RatioCrop"), 1); 1128 1129 action.setDisplayableName(i18n("Aspect Ratio Crop")); 1130 action.addParameter(QLatin1String("x"), currentRegion.x()); 1131 action.addParameter(QLatin1String("y"), currentRegion.y()); 1132 action.addParameter(QLatin1String("width"), currentRegion.width()); 1133 action.addParameter(QLatin1String("height"), currentRegion.height()); 1134 1135 iface->setOriginal(i18n("Aspect Ratio Crop"), action, imOrg); 1136 1137 qApp->restoreOverrideCursor(); 1138 writeSettings(); 1139 } 1140 1141 void RatioCropTool::blockWidgetSignals(bool b) 1142 { 1143 d->customRatioDInput->blockSignals(b); 1144 d->customRatioNInput->blockSignals(b); 1145 d->flipHorBox->blockSignals(b); 1146 d->flipVerBox->blockSignals(b); 1147 d->goldenSectionBox->blockSignals(b); 1148 d->goldenSpiralBox->blockSignals(b); 1149 d->goldenSpiralSectionBox->blockSignals(b); 1150 d->goldenTriangleBox->blockSignals(b); 1151 d->guideLinesCB->blockSignals(b); 1152 d->heightInput->blockSignals(b); 1153 d->ratioCropWidget->blockSignals(b); 1154 d->preciseCrop->blockSignals(b); 1155 d->widthInput->blockSignals(b); 1156 d->xInput->blockSignals(b); 1157 d->yInput->blockSignals(b); 1158 } 1159 1160 void RatioCropTool::setBackgroundColor(const QColor& bg) 1161 { 1162 d->ratioCropWidget->setBackgroundColor(bg); 1163 } 1164 1165 } // namespace DigikamEditorRatioCropToolPlugin 1166 1167 #include "moc_ratiocroptool.cpp"