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"