1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : digiKam image editor Ratio Crop tool
9
* Copyright (C) 2007 by Jaromir Malenko <malenko at email dot cz>
10
* Copyright (C) 2008 by Roberto Castagnola <roberto dot castagnola at gmail dot com>
11
* Copyright (C) 2004-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
13
* This program is free software; you can redistribute it
14
* and/or modify it under the terms of the GNU General
15
* Public License as published by the Free Software Foundation;
16
* either version 2, or (at your option)
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* ============================================================ */
26
#include "ratiocroptool.moc"
32
#include <QGridLayout>
40
#include <QToolButton>
41
#include <QVBoxLayout>
45
#include <kapplication.h>
46
#include <kcolorbutton.h>
48
#include <kconfiggroup.h>
51
#include <kpushbutton.h>
52
#include <kstandarddirs.h>
53
#include <kstandardguiitem.h>
57
#include <libkdcraw/rcombobox.h>
58
#include <libkdcraw/rnuminput.h>
59
#include <libkdcraw/rexpanderbox.h>
63
#include "editortoolsettings.h"
64
#include "imageiface.h"
65
#include "imageselectionwidget.h"
67
using namespace KDcrawIface;
69
namespace DigikamTransformImagePlugin
72
class RatioCropTool::RatioCropToolPriv
77
originalIsLandscape(false),
84
goldenSpiralSectionBox(0),
102
imageSelectionWidget(0),
107
static const QString configGroupName;
108
static const QString configHorOrientedAspectRatioEntry;
109
static const QString configHorOrientedAspectRatioOrientationEntry;
110
static const QString configHorOrientedCustomAspectRatioNumEntry;
111
static const QString configHorOrientedCustomAspectRatioDenEntry;
112
static const QString configHorOrientedCustomAspectRatioXposEntry;
113
static const QString configHorOrientedCustomAspectRatioYposEntry;
114
static const QString configHorOrientedCustomAspectRatioWidthEntry;
115
static const QString configHorOrientedCustomAspectRatioHeightEntry;
116
static const QString configVerOrientedAspectRatioEntry;
117
static const QString configVerOrientedAspectRatioOrientationEntry;
118
static const QString configVerOrientedCustomAspectRatioNumEntry;
119
static const QString configVerOrientedCustomAspectRatioDenEntry;
120
static const QString configVerOrientedCustomAspectRatioXposEntry;
121
static const QString configVerOrientedCustomAspectRatioYposEntry;
122
static const QString configVerOrientedCustomAspectRatioWidthEntry;
123
static const QString configVerOrientedCustomAspectRatioHeightEntry;
124
static const QString configPreciseAspectRatioCropEntry;
125
static const QString configAutoOrientationEntry;
126
static const QString configGuideLinesTypeEntry;
127
static const QString configGoldenSectionEntry;
128
static const QString configGoldenSpiralSectionEntry;
129
static const QString configGoldenSpiralEntry;
130
static const QString configGoldenTriangleEntry;
131
static const QString configGoldenFlipHorizontalEntry;
132
static const QString configGoldenFlipVerticalEntry;
133
static const QString configGuideColorEntry;
134
static const QString configGuideWidthEntry;
136
bool originalIsLandscape;
140
QLabel* colorGuideLabel;
142
QToolButton* centerWidth;
143
QToolButton* centerHeight;
145
QCheckBox* goldenSectionBox;
146
QCheckBox* goldenSpiralSectionBox;
147
QCheckBox* goldenSpiralBox;
148
QCheckBox* goldenTriangleBox;
149
QCheckBox* flipHorBox;
150
QCheckBox* flipVerBox;
151
QCheckBox* autoOrientation;
152
QCheckBox* preciseCrop;
156
RComboBox* guideLinesCB;
158
RIntNumInput* customRatioDInput;
159
RIntNumInput* customRatioNInput;
160
RIntNumInput* guideSize;
161
RIntNumInput* heightInput;
162
RIntNumInput* widthInput;
163
RIntNumInput* xInput;
164
RIntNumInput* yInput;
166
KColorButton* guideColorBt;
168
ImageSelectionWidget* imageSelectionWidget;
169
RExpanderBox* expbox;
170
EditorToolSettings* gboxSettings;
172
const QString RatioCropTool::RatioCropToolPriv::configGroupName("aspectratiocrop Tool");
173
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedAspectRatioEntry("Hor.Oriented Aspect Ratio");
174
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedAspectRatioOrientationEntry("Hor.Oriented Aspect Ratio Orientation");
175
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioNumEntry("Hor.Oriented Custom Aspect Ratio Num");
176
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioDenEntry("Hor.Oriented Custom Aspect Ratio Den");
177
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioXposEntry("Hor.Oriented Custom Aspect Ratio Xpos");
178
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioYposEntry("Hor.Oriented Custom Aspect Ratio Ypos");
179
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioWidthEntry("Hor.Oriented Custom Aspect Ratio Width");
180
const QString RatioCropTool::RatioCropToolPriv::configHorOrientedCustomAspectRatioHeightEntry("Hor.Oriented Custom Aspect Ratio Height");
181
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedAspectRatioEntry("Ver.Oriented Aspect Ratio");
182
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedAspectRatioOrientationEntry("Ver.Oriented Aspect Ratio Orientation");
183
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioNumEntry("Ver.Oriented Custom Aspect Ratio Num");
184
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioDenEntry("Ver.Oriented Custom Aspect Ratio Den");
185
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioXposEntry("Ver.Oriented Custom Aspect Ratio Xpos");
186
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioYposEntry("Ver.Oriented Custom Aspect Ratio Ypos");
187
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioWidthEntry("Ver.Oriented Custom Aspect Ratio Width");
188
const QString RatioCropTool::RatioCropToolPriv::configVerOrientedCustomAspectRatioHeightEntry("Ver.Oriented Custom Aspect Ratio Height");
189
const QString RatioCropTool::RatioCropToolPriv::configPreciseAspectRatioCropEntry("Precise Aspect Ratio Crop");
190
const QString RatioCropTool::RatioCropToolPriv::configAutoOrientationEntry("Auto Orientation");
191
const QString RatioCropTool::RatioCropToolPriv::configGuideLinesTypeEntry("Guide Lines Type");
192
const QString RatioCropTool::RatioCropToolPriv::configGoldenSectionEntry("Golden Section");
193
const QString RatioCropTool::RatioCropToolPriv::configGoldenSpiralSectionEntry("Golden Spiral Section");
194
const QString RatioCropTool::RatioCropToolPriv::configGoldenSpiralEntry("Golden Spiral");
195
const QString RatioCropTool::RatioCropToolPriv::configGoldenTriangleEntry("Golden Triangle");
196
const QString RatioCropTool::RatioCropToolPriv::configGoldenFlipHorizontalEntry("Golden Flip Horizontal");
197
const QString RatioCropTool::RatioCropToolPriv::configGoldenFlipVerticalEntry("Golden Flip Vertical");
198
const QString RatioCropTool::RatioCropToolPriv::configGuideColorEntry("Guide Color");
199
const QString RatioCropTool::RatioCropToolPriv::configGuideWidthEntry("Guide Width");
201
// --------------------------------------------------------
203
RatioCropTool::RatioCropTool(QObject* parent)
204
: EditorTool(parent),
205
d(new RatioCropToolPriv)
207
setObjectName("aspectratiocrop");
208
setToolName(i18n("Aspect Ratio Crop"));
209
setToolIcon(SmallIcon("ratiocrop"));
210
setToolHelp("ratiocroptool.anchor");
212
// -------------------------------------------------------------
214
// Important: Deactivate drawing of the selection now, we will enable it later.
215
d->imageSelectionWidget = new ImageSelectionWidget(480, 320, false);
216
d->imageSelectionWidget->setWhatsThis(i18n("<p>Here you can see the aspect ratio selection preview "
217
"used for cropping. You can use the mouse to move and "
218
"resize the crop area.</p>"
219
"<p>Press and hold the <b>CTRL</b> key to move the opposite corner too.</p>"
220
"<p>Press and hold the <b>SHIFT</b> key to move the closest corner to the "
221
"mouse pointer.</p>"));
223
d->originalIsLandscape = ((d->imageSelectionWidget->getOriginalImageWidth()) >
224
(d->imageSelectionWidget->getOriginalImageHeight()));
226
setToolView(d->imageSelectionWidget);
228
// -------------------------------------------------------------
230
d->gboxSettings = new EditorToolSettings;
231
d->gboxSettings->setButtons(EditorToolSettings::Default|
232
EditorToolSettings::Ok|
233
EditorToolSettings::Try|
234
EditorToolSettings::Cancel);
236
// -------------------------------------------------------------
238
// need to set the button to a KStdGuiItem that has no icon
239
KPushButton* tryBtn = d->gboxSettings->button(EditorToolSettings::Try);
240
tryBtn->setGuiItem(KStandardGuiItem::Test);
241
tryBtn->setText(i18n("Max. Aspect"));
242
tryBtn->setToolTip(i18n("Set selection area to the maximum size according "
243
"to the current ratio."));
245
// -------------------------------------------------------------
247
QVBoxLayout* vlay = new QVBoxLayout(d->gboxSettings->plainPage());
248
d->expbox = new RExpanderBox(d->gboxSettings->plainPage());
249
d->expbox->setObjectName("RatioCropTool Expander");
250
QWidget* cropSelection = new QWidget(d->expbox);
252
QLabel* label = new QLabel(i18n("Aspect ratio:"), cropSelection);
253
d->ratioCB = new RComboBox(cropSelection);
254
d->ratioCB->addItem(i18nc("custom aspect ratio crop settings", "Custom"));
255
// NOTE: Order is important there. Look ImageSelectionWidget::RatioAspect for details.
256
d->ratioCB->addItem("1:1");
257
d->ratioCB->addItem("2:3");
258
d->ratioCB->addItem("3:4");
259
d->ratioCB->addItem("4:5");
260
d->ratioCB->addItem("5:7");
261
d->ratioCB->addItem("7:10");
262
d->ratioCB->addItem("8:5");
263
d->ratioCB->addItem(i18n("Golden Ratio"));
264
d->ratioCB->addItem(i18n("Current Image Aspect Ratio"));
265
d->ratioCB->addItem(i18nc("no crop mode", "None"));
266
d->ratioCB->setDefaultIndex(ImageSelectionWidget::RATIO03X04);
267
setRatioCBText(ImageSelectionWidget::Landscape);
268
d->ratioCB->setWhatsThis( i18n("<p>Select your constrained aspect ratio for cropping. "
269
"Aspect Ratio Crop tool uses a relative ratio. That means it "
270
"is the same if you use centimeters or inches and it does not "
271
"specify the physical size.</p>"
272
"<p>You can see below a correspondence list of traditional photographic "
273
"paper sizes and aspect ratio crop:</p>"
274
"<p><b>2:3</b>: 10x15cm, 20x30cm, 30x45cm, 4x6\", 8x12\", "
275
"12x18\", 16x24\", 20x30\"</p>"
276
"<p><b>3:4</b>: 6x8cm, 15x20cm, 18x24cm, 30x40cm, 3.75x5\", 4.5x6\", "
277
"6x8\", 7.5x10\", 9x12\"</p>"
278
"<p><b>4:5</b>: 20x25cm, 40x50cm, 8x10\", 16x20\"</p>"
279
"<p><b>5:7</b>: 15x21cm, 30x42cm, 5x7\"</p>"
280
"<p><b>7:10</b>: 21x30cm, 42x60cm, 3.5x5\"</p>"
281
"<p><b>8:5</b>: common widescreen monitor (as 1680x1050)</p>"
282
"<p>The <b>Golden Ratio</b> is 1:1.618. A composition following this rule "
283
"is considered visually harmonious but can be unadapted to print on "
284
"standard photographic paper.</p>"
285
"<p>The <b>Current Aspect Ratio</b> takes aspect ratio from the currently "
286
"opened image.</p>"));
288
d->preciseCrop = new QCheckBox(cropSelection);
289
d->preciseCrop->setToolTip(i18n("Exact aspect"));
290
d->preciseCrop->setWhatsThis(i18n("Enable this option to force exact aspect ratio crop."));
292
d->orientLabel = new QLabel(i18n("Orientation:"), cropSelection);
293
d->orientCB = new RComboBox( cropSelection );
294
d->orientCB->addItem( i18n("Landscape") );
295
d->orientCB->addItem( i18n("Portrait") );
296
d->orientCB->setWhatsThis(i18n("Select constrained aspect ratio orientation."));
298
d->autoOrientation = new QCheckBox(cropSelection);
299
d->autoOrientation->setToolTip(i18n("Auto"));
300
d->autoOrientation->setWhatsThis( i18n("Enable this option to automatically set the orientation."));
302
// -------------------------------------------------------------
304
d->customLabel = new QLabel(i18n("Custom ratio:"), cropSelection);
305
d->customLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
306
d->customRatioNInput = new RIntNumInput(cropSelection);
307
d->customRatioNInput->setRange(1, 10000, 1);
308
d->customRatioNInput->setDefaultValue(1);
309
d->customRatioNInput->setSliderEnabled(false);
310
d->customRatioNInput->setWhatsThis( i18n("Set here the desired custom aspect numerator value."));
312
d->customRatioDInput = new RIntNumInput(cropSelection);
313
d->customRatioDInput->setRange(1, 10000, 1);
314
d->customRatioDInput->setDefaultValue(1);
315
d->customRatioDInput->setSliderEnabled(false);
316
d->customRatioDInput->setWhatsThis( i18n("Set here the desired custom aspect denominator value."));
318
// -------------------------------------------------------------
320
d->xInput = new RIntNumInput(cropSelection);
321
d->xInput->setWhatsThis( i18n("Set here the top left selection corner position for cropping."));
322
d->xInput->input()->setLabel(i18nc("top left corner position for cropping", "X:"), Qt::AlignLeft|Qt::AlignVCenter);
323
d->xInput->setRange(0, d->imageSelectionWidget->getOriginalImageWidth(), 1);
324
d->xInput->setSliderEnabled(true);
325
d->xInput->setDefaultValue(50);
327
d->widthInput = new RIntNumInput(cropSelection);
328
d->widthInput->input()->setLabel(i18n("Width:"), Qt::AlignLeft|Qt::AlignVCenter);
329
d->widthInput->setWhatsThis( i18n("Set here the width selection for cropping."));
330
d->widthInput->setRange(d->imageSelectionWidget->getMinWidthRange(),
331
d->imageSelectionWidget->getMaxWidthRange(),
332
d->imageSelectionWidget->getWidthStep());
333
d->widthInput->setSliderEnabled(true);
334
d->widthInput->setDefaultValue(800);
336
d->centerWidth = new QToolButton(cropSelection);
337
d->centerWidth->setIcon(QPixmap(KStandardDirs::locate("data", "digikam/data/centerwidth.png")));
338
d->centerWidth->setWhatsThis( i18n("Set width position to center."));
340
// -------------------------------------------------------------
342
d->yInput = new RIntNumInput(cropSelection);
343
d->yInput->input()->setLabel(i18n("Y:"), Qt::AlignLeft|Qt::AlignVCenter);
344
d->yInput->setWhatsThis( i18n("Set here the top left selection corner position for cropping."));
345
d->yInput->setRange(0, d->imageSelectionWidget->getOriginalImageWidth(), 1);
346
d->yInput->setSliderEnabled(true);
347
d->yInput->setDefaultValue(50);
349
d->heightInput = new RIntNumInput(cropSelection);
350
d->heightInput->input()->setLabel(i18n("Height:"), Qt::AlignLeft|Qt::AlignVCenter);
351
d->heightInput->setWhatsThis( i18n("Set here the height selection for cropping."));
352
d->heightInput->setRange(d->imageSelectionWidget->getMinHeightRange(),
353
d->imageSelectionWidget->getMaxHeightRange(),
354
d->imageSelectionWidget->getHeightStep());
355
d->heightInput->setSliderEnabled(true);
356
d->heightInput->setDefaultValue(600);
358
d->centerHeight = new QToolButton(cropSelection);
359
d->centerHeight->setIcon(QPixmap(KStandardDirs::locate("data", "digikam/data/centerheight.png")));
360
d->centerHeight->setWhatsThis( i18n("Set height position to center."));
362
// -------------------------------------------------------------
364
QGridLayout* mainLayout = new QGridLayout(cropSelection);
365
mainLayout->addWidget(label, 0, 0, 1, 1);
366
mainLayout->addWidget(d->ratioCB, 0, 1, 1, 3);
367
mainLayout->addWidget(d->preciseCrop, 0, 4, 1, 1);
368
mainLayout->addWidget(d->customLabel, 1, 0, 1, 1);
369
mainLayout->addWidget(d->customRatioNInput, 1, 1, 1, 1);
370
mainLayout->addWidget(d->customRatioDInput, 2, 1, 1, 1);
371
mainLayout->addWidget(d->orientLabel, 3, 0, 1, 1);
372
mainLayout->addWidget(d->orientCB, 3, 1, 1, 3);
373
mainLayout->addWidget(d->autoOrientation, 3, 4, 1, 1);
374
mainLayout->addWidget(d->xInput, 4, 0, 1, 4);
375
mainLayout->addWidget(d->widthInput, 5, 0, 1, 4);
376
mainLayout->addWidget(d->centerWidth, 5, 4, 1, 1);
377
mainLayout->addWidget(d->yInput, 6, 0, 1, 4);
378
mainLayout->addWidget(d->heightInput, 7, 0, 1, 4);
379
mainLayout->addWidget(d->centerHeight, 7, 4, 1, 1);
380
mainLayout->setMargin(d->gboxSettings->spacingHint());
381
mainLayout->setSpacing(d->gboxSettings->spacingHint());
383
d->expbox->addItem(cropSelection, SmallIcon("transform-crop-and-resize"),
384
i18n("Crop Settings"), QString("CropSelection"), true);
386
// -------------------------------------------------------------
388
QWidget* compositionGuide = new QWidget(d->expbox);
389
QGridLayout* grid2 = new QGridLayout(compositionGuide);
391
QLabel* labelGuideLines = new QLabel(i18n("Geometric form:"), compositionGuide);
392
d->guideLinesCB = new RComboBox(compositionGuide);
393
d->guideLinesCB->addItem(i18n("Rules of Thirds"));
394
d->guideLinesCB->addItem(i18n("Diagonal Method"));
395
d->guideLinesCB->addItem(i18n("Harmonious Triangles"));
396
d->guideLinesCB->addItem(i18n("Golden Mean"));
397
d->guideLinesCB->addItem(i18nc("no geometric form", "None"));
398
d->guideLinesCB->setDefaultIndex(ImageSelectionWidget::GuideNone);
399
d->guideLinesCB->setCurrentIndex(3);
400
d->guideLinesCB->setWhatsThis( i18n("With this option, you can display guide lines "
401
"to help compose your photograph."));
403
d->goldenSectionBox = new QCheckBox(i18n("Golden sections"), compositionGuide);
404
d->goldenSectionBox->setWhatsThis(i18n("Enable this option to show golden sections."));
406
d->goldenSpiralSectionBox = new QCheckBox(i18n("Golden spiral sections"), compositionGuide);
407
d->goldenSpiralSectionBox->setWhatsThis(i18n("Enable this option to show golden spiral sections."));
409
d->goldenSpiralBox = new QCheckBox(i18n("Golden spiral"), compositionGuide);
410
d->goldenSpiralBox->setWhatsThis(i18n("Enable this option to show a golden spiral guide."));
412
d->goldenTriangleBox = new QCheckBox(i18n("Golden triangles"), compositionGuide);
413
d->goldenTriangleBox->setWhatsThis(i18n("Enable this option to show golden triangles."));
415
d->flipHorBox = new QCheckBox(i18n("Flip horizontally"), compositionGuide);
416
d->flipHorBox->setWhatsThis(i18n("Enable this option to flip the guidelines horizontally."));
418
d->flipVerBox = new QCheckBox(i18n("Flip vertically"), compositionGuide);
419
d->flipVerBox->setWhatsThis(i18n("Enable this option to flip the guidelines vertically."));
421
d->colorGuideLabel = new QLabel(i18n("Color and width:"), compositionGuide);
422
d->guideColorBt = new KColorButton( QColor( 250, 250, 255 ), compositionGuide );
423
d->guideSize = new RIntNumInput(compositionGuide);
424
d->guideSize->setRange(1, 5, 1);
425
d->guideSize->setSliderEnabled(false);
426
d->guideSize->setDefaultValue(1);
427
d->guideColorBt->setWhatsThis(i18n("Set here the color used to draw composition guides."));
428
d->guideSize->setWhatsThis(i18n("Set here the width in pixels used to draw composition guides."));
430
// -------------------------------------------------------------
432
grid2->addWidget(labelGuideLines, 0, 0, 1, 1);
433
grid2->addWidget(d->guideLinesCB, 0, 1, 1, 2);
434
grid2->addWidget(d->goldenSectionBox, 1, 0, 1, 3);
435
grid2->addWidget(d->goldenSpiralSectionBox, 2, 0, 1, 3);
436
grid2->addWidget(d->goldenSpiralBox, 3, 0, 1, 3);
437
grid2->addWidget(d->goldenTriangleBox, 4, 0, 1, 3);
438
grid2->addWidget(d->flipHorBox, 5, 0, 1, 3);
439
grid2->addWidget(d->flipVerBox, 6, 0, 1, 3);
440
grid2->addWidget(d->colorGuideLabel, 7, 0, 1, 1);
441
grid2->addWidget(d->guideColorBt, 7, 1, 1, 1);
442
grid2->addWidget(d->guideSize, 7, 2, 1, 1);
443
grid2->setMargin(d->gboxSettings->spacingHint());
444
grid2->setSpacing(d->gboxSettings->spacingHint());
446
d->expbox->addItem(compositionGuide, SmallIcon("tools-wizard"),
447
i18n("Composition Guides"), QString("CompositionGuide"), true);
448
d->expbox->addStretch();
450
// -------------------------------------------------------------
452
vlay->addWidget(d->expbox, 10);
457
// -------------------------------------------------------------
459
setToolSettings(d->gboxSettings);
462
// -------------------------------------------------------------
464
connect(d->ratioCB, SIGNAL(activated(int)),
465
this, SLOT(slotRatioChanged(int)));
467
connect(d->preciseCrop, SIGNAL(toggled(bool)),
468
this, SLOT(slotPreciseCropChanged(bool)));
470
connect(d->orientCB, SIGNAL(activated(int)),
471
this, SLOT(slotOrientChanged(int)));
473
connect(d->autoOrientation, SIGNAL(toggled(bool)),
474
this, SLOT(slotAutoOrientChanged(bool)));
476
connect(d->xInput, SIGNAL(valueChanged(int)),
477
this, SLOT(slotXChanged(int)));
479
connect(d->yInput, SIGNAL(valueChanged(int)),
480
this, SLOT(slotYChanged(int)));
482
connect(d->customRatioNInput, SIGNAL(valueChanged(int)),
483
this, SLOT(slotCustomRatioChanged()));
485
connect(d->customRatioDInput, SIGNAL(valueChanged(int)),
486
this, SLOT(slotCustomRatioChanged()));
488
connect(d->guideLinesCB, SIGNAL(activated(int)),
489
this, SLOT(slotGuideTypeChanged(int)));
491
connect(d->goldenSectionBox, SIGNAL(toggled(bool)),
492
this, SLOT(slotGoldenGuideTypeChanged()));
494
connect(d->goldenSpiralSectionBox, SIGNAL(toggled(bool)),
495
this, SLOT(slotGoldenGuideTypeChanged()));
497
connect(d->goldenSpiralBox, SIGNAL(toggled(bool)),
498
this, SLOT(slotGoldenGuideTypeChanged()));
500
connect(d->goldenTriangleBox, SIGNAL(toggled(bool)),
501
this, SLOT(slotGoldenGuideTypeChanged()));
503
connect(d->flipHorBox, SIGNAL(toggled(bool)),
504
this, SLOT(slotGoldenGuideTypeChanged()));
506
connect(d->flipVerBox, SIGNAL(toggled(bool)),
507
this, SLOT(slotGoldenGuideTypeChanged()));
509
connect(d->guideColorBt, SIGNAL(changed(const QColor&)),
510
d->imageSelectionWidget, SLOT(slotChangeGuideColor(const QColor&)));
512
connect(d->guideSize, SIGNAL(valueChanged(int)),
513
d->imageSelectionWidget, SLOT(slotChangeGuideSize(int)));
515
connect(d->widthInput, SIGNAL(valueChanged(int)),
516
this, SLOT(slotWidthChanged(int)));
518
connect(d->heightInput, SIGNAL(valueChanged(int)),
519
this, SLOT(slotHeightChanged(int)));
521
connect(d->imageSelectionWidget, SIGNAL(signalSelectionChanged(const QRect&)),
522
this, SLOT(slotSelectionChanged(const QRect&)));
524
connect(d->imageSelectionWidget, SIGNAL(signalSelectionMoved(const QRect&)),
525
this, SLOT(slotSelectionChanged(const QRect&)));
527
connect(d->imageSelectionWidget, SIGNAL(signalSelectionOrientationChanged(int)),
528
this, SLOT(slotSelectionOrientationChanged(int)));
530
connect(d->centerWidth, SIGNAL(clicked()),
531
this, SLOT(slotCenterWidth()));
533
connect(d->centerHeight, SIGNAL(clicked()),
534
this, SLOT(slotCenterHeight()));
536
// we need to disconnect the standard connection of the Try button first
537
disconnect(d->gboxSettings, SIGNAL(signalTryClicked()),
538
this, SLOT(slotEffect()));
540
connect(d->gboxSettings, SIGNAL(signalTryClicked()),
541
this, SLOT(slotMaxAspectRatio()));
544
RatioCropTool::~RatioCropTool()
549
void RatioCropTool::readSettings()
551
QColor defaultGuideColor(250, 250, 255);
552
KSharedConfig::Ptr config = KGlobal::config();
553
KConfigGroup group = config->group(d->configGroupName);
555
// --------------------------------------------------------
557
// Note: the selection widget has been setup to NOT draw the selection at the moment.
558
// This is necessary to avoid jumping of the selection when reading the settings.
559
// The drawing must be activated later on in this method to have a working selection.
561
d->expbox->readSettings();
563
// No guide lines per default.
564
d->guideLinesCB->setCurrentIndex(group.readEntry(d->configGuideLinesTypeEntry,
565
(int)ImageSelectionWidget::GuideNone));
566
d->goldenSectionBox->setChecked(group.readEntry(d->configGoldenSectionEntry, true));
567
d->goldenSpiralSectionBox->setChecked(group.readEntry(d->configGoldenSpiralSectionEntry, false));
568
d->goldenSpiralBox->setChecked(group.readEntry(d->configGoldenSpiralEntry, false));
569
d->goldenTriangleBox->setChecked(group.readEntry(d->configGoldenTriangleEntry, false));
570
d->flipHorBox->setChecked(group.readEntry(d->configGoldenFlipHorizontalEntry, false));
571
d->flipVerBox->setChecked(group.readEntry(d->configGoldenFlipVerticalEntry, false));
572
d->guideColorBt->setColor(group.readEntry(d->configGuideColorEntry, defaultGuideColor));
573
d->guideSize->setValue(group.readEntry(d->configGuideWidthEntry, d->guideSize->defaultValue()));
575
d->imageSelectionWidget->slotGuideLines(d->guideLinesCB->currentIndex());
576
d->imageSelectionWidget->slotChangeGuideColor(d->guideColorBt->color());
578
d->preciseCrop->setChecked( group.readEntry(d->configPreciseAspectRatioCropEntry, false) );
579
d->imageSelectionWidget->setPreciseCrop( d->preciseCrop->isChecked() );
581
// Empty selection so it can be moved w/out size constraint
582
d->widthInput->setValue(0);
583
d->heightInput->setValue(0);
585
d->xInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioXposEntry,
586
d->xInput->defaultValue()));
587
d->yInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioYposEntry,
588
d->yInput->defaultValue()));
590
d->widthInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioWidthEntry,
591
d->widthInput->defaultValue()));
592
d->heightInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioHeightEntry,
593
d->heightInput->defaultValue()));
595
d->imageSelectionWidget->setSelectionOrientation(d->orientCB->currentIndex());
597
d->customRatioNInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioNumEntry,
598
d->customRatioNInput->defaultValue()));
599
d->customRatioDInput->setValue(group.readEntry(d->configHorOrientedCustomAspectRatioDenEntry,
600
d->customRatioDInput->defaultValue()));
601
d->ratioCB->setCurrentIndex(group.readEntry(d->configHorOrientedAspectRatioEntry,
602
d->ratioCB->defaultIndex()));
604
if (d->originalIsLandscape)
606
d->orientCB->setCurrentIndex(group.readEntry(d->configHorOrientedAspectRatioOrientationEntry,
607
(int)ImageSelectionWidget::Landscape));
608
d->orientCB->setDefaultIndex(ImageSelectionWidget::Landscape);
612
d->orientCB->setCurrentIndex(group.readEntry(d->configVerOrientedAspectRatioOrientationEntry,
613
(int)ImageSelectionWidget::Portrait));
614
d->orientCB->setDefaultIndex(ImageSelectionWidget::Portrait);
617
d->autoOrientation->setChecked(group.readEntry(d->configAutoOrientationEntry, false));
618
slotAutoOrientChanged( d->autoOrientation->isChecked() );
619
applyRatioChanges(d->ratioCB->currentIndex());
621
slotXChanged(d->xInput->value());
622
slotYChanged(d->yInput->value());
623
slotWidthChanged(d->widthInput->value());
625
// For the last setting to be applied, activate drawing in the selectionWidget,
626
// so that we can see the results.
627
d->imageSelectionWidget->setIsDrawingSelection(true);
628
slotHeightChanged(d->heightInput->value());
630
slotGuideTypeChanged(d->guideLinesCB->currentIndex());
633
void RatioCropTool::writeSettings()
635
KSharedConfig::Ptr config = KGlobal::config();
636
KConfigGroup group = config->group(d->configGroupName);
638
if (d->originalIsLandscape)
640
group.writeEntry(d->configHorOrientedAspectRatioEntry, d->ratioCB->currentIndex());
641
group.writeEntry(d->configHorOrientedAspectRatioOrientationEntry, d->orientCB->currentIndex());
642
group.writeEntry(d->configHorOrientedCustomAspectRatioNumEntry, d->customRatioNInput->value());
643
group.writeEntry(d->configHorOrientedCustomAspectRatioDenEntry, d->customRatioDInput->value());
645
group.writeEntry(d->configHorOrientedCustomAspectRatioXposEntry, d->xInput->value());
646
group.writeEntry(d->configHorOrientedCustomAspectRatioYposEntry, d->yInput->value());
647
group.writeEntry(d->configHorOrientedCustomAspectRatioWidthEntry, d->widthInput->value());
648
group.writeEntry(d->configHorOrientedCustomAspectRatioHeightEntry, d->heightInput->value());
652
group.writeEntry(d->configVerOrientedAspectRatioEntry, d->ratioCB->currentIndex());
653
group.writeEntry(d->configVerOrientedAspectRatioOrientationEntry, d->orientCB->currentIndex());
654
group.writeEntry(d->configVerOrientedCustomAspectRatioNumEntry, d->customRatioNInput->value());
655
group.writeEntry(d->configVerOrientedCustomAspectRatioDenEntry, d->customRatioDInput->value());
657
group.writeEntry(d->configVerOrientedCustomAspectRatioXposEntry, d->xInput->value());
658
group.writeEntry(d->configVerOrientedCustomAspectRatioYposEntry, d->yInput->value());
659
group.writeEntry(d->configVerOrientedCustomAspectRatioWidthEntry, d->widthInput->value());
660
group.writeEntry(d->configVerOrientedCustomAspectRatioHeightEntry, d->heightInput->value());
663
group.writeEntry(d->configPreciseAspectRatioCropEntry, d->preciseCrop->isChecked());
664
group.writeEntry(d->configAutoOrientationEntry, d->autoOrientation->isChecked());
665
group.writeEntry(d->configGuideLinesTypeEntry, d->guideLinesCB->currentIndex());
666
group.writeEntry(d->configGoldenSectionEntry, d->goldenSectionBox->isChecked());
667
group.writeEntry(d->configGoldenSpiralSectionEntry, d->goldenSpiralSectionBox->isChecked());
668
group.writeEntry(d->configGoldenSpiralEntry, d->goldenSpiralBox->isChecked());
669
group.writeEntry(d->configGoldenTriangleEntry, d->goldenTriangleBox->isChecked());
670
group.writeEntry(d->configGoldenFlipHorizontalEntry, d->flipHorBox->isChecked());
671
group.writeEntry(d->configGoldenFlipVerticalEntry, d->flipVerBox->isChecked());
672
group.writeEntry(d->configGuideColorEntry, d->guideColorBt->color());
673
group.writeEntry(d->configGuideWidthEntry, d->guideSize->value());
677
void RatioCropTool::slotResetSettings()
679
d->imageSelectionWidget->resetSelection();
682
void RatioCropTool::slotMaxAspectRatio()
684
d->imageSelectionWidget->maxAspectSelection();
687
void RatioCropTool::slotCenterWidth()
689
d->imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterWidth);
692
void RatioCropTool::slotCenterHeight()
694
d->imageSelectionWidget->setCenterSelection(ImageSelectionWidget::CenterHeight);
697
void RatioCropTool::slotSelectionChanged(const QRect& rect)
699
blockWidgetSignals(true);
701
d->xInput->setRange(0, d->imageSelectionWidget->getOriginalImageWidth() - rect.width(), 1);
702
d->yInput->setRange(0, d->imageSelectionWidget->getOriginalImageHeight() - rect.height(), 1);
703
d->widthInput->setRange(d->imageSelectionWidget->getMinWidthRange(),
704
d->imageSelectionWidget->getMaxWidthRange(),
705
d->imageSelectionWidget->getWidthStep());
706
d->heightInput->setRange(d->imageSelectionWidget->getMinHeightRange(),
707
d->imageSelectionWidget->getMaxHeightRange(),
708
d->imageSelectionWidget->getHeightStep());
710
d->xInput->setValue(rect.x());
711
d->yInput->setValue(rect.y());
712
d->widthInput->setValue(rect.width());
713
d->heightInput->setValue(rect.height());
715
d->gboxSettings->enableButton(EditorToolSettings::Ok,
718
d->preciseCrop->setEnabled(d->imageSelectionWidget->preciseCropAvailable());
720
blockWidgetSignals(false);
723
void RatioCropTool::setRatioCBText(int orientation)
725
int item = d->ratioCB->currentIndex();
726
d->ratioCB->blockSignals(true);
727
d->ratioCB->combo()->clear();
728
d->ratioCB->addItem(i18nc("custom ratio crop settings", "Custom"));
729
d->ratioCB->addItem("1:1");
731
if (orientation == ImageSelectionWidget::Landscape)
733
d->ratioCB->addItem("3:2");
734
d->ratioCB->addItem("4:3");
735
d->ratioCB->addItem("5:4");
736
d->ratioCB->addItem("7:5");
737
d->ratioCB->addItem("10:7");
738
d->ratioCB->addItem("5:8");
742
d->ratioCB->addItem("2:3");
743
d->ratioCB->addItem("3:4");
744
d->ratioCB->addItem("4:5");
745
d->ratioCB->addItem("5:7");
746
d->ratioCB->addItem("7:10");
747
d->ratioCB->addItem("8:5");
750
d->ratioCB->addItem(i18n("Golden Ratio"));
751
d->ratioCB->addItem(i18n("Current aspect ratio"));
752
d->ratioCB->addItem(i18nc("no aspect ratio", "None"));
753
d->ratioCB->setCurrentIndex(item);
754
d->ratioCB->blockSignals(false);
757
void RatioCropTool::slotSelectionOrientationChanged(int newOrientation)
759
// Change text for Aspect ratio ComboBox
761
setRatioCBText(newOrientation);
763
// Change Orientation ComboBox
765
d->orientCB->setCurrentIndex(newOrientation);
767
// Reverse custom values
769
if ( ( d->customRatioNInput->value() < d->customRatioDInput->value() &&
770
newOrientation == ImageSelectionWidget::Landscape ) ||
771
( d->customRatioNInput->value() > d->customRatioDInput->value() &&
772
newOrientation == ImageSelectionWidget::Portrait ) )
774
d->customRatioNInput->blockSignals(true);
775
d->customRatioDInput->blockSignals(true);
777
int tmp = d->customRatioNInput->value();
778
d->customRatioNInput->setValue(d->customRatioDInput->value());
779
d->customRatioDInput->setValue(tmp);
781
d->customRatioNInput->blockSignals(false);
782
d->customRatioDInput->blockSignals(false);
786
void RatioCropTool::slotXChanged(int x)
788
d->imageSelectionWidget->setSelectionX(x);
791
void RatioCropTool::slotYChanged(int y)
793
d->imageSelectionWidget->setSelectionY(y);
796
void RatioCropTool::slotWidthChanged(int w)
798
d->imageSelectionWidget->setSelectionWidth(w);
801
void RatioCropTool::slotHeightChanged(int h)
803
d->imageSelectionWidget->setSelectionHeight(h);
806
void RatioCropTool::slotPreciseCropChanged(bool a)
808
d->imageSelectionWidget->setPreciseCrop(a);
811
void RatioCropTool::slotOrientChanged(int o)
813
d->imageSelectionWidget->setSelectionOrientation(o);
815
// Reset selection area.
819
void RatioCropTool::slotAutoOrientChanged(bool a)
821
d->orientCB->setEnabled(!a /*|| d->ratioCB->currentIndex() == ImageSelectionWidget::RATIONONE*/);
822
d->imageSelectionWidget->setAutoOrientation(a);
825
void RatioCropTool::slotRatioChanged(int a)
827
applyRatioChanges(a);
829
// Reset selection area.
833
void RatioCropTool::applyRatioChanges(int a)
835
d->imageSelectionWidget->setSelectionAspectRatioType(a);
837
if (a == ImageSelectionWidget::RATIOCUSTOM)
839
d->customLabel->setEnabled(true);
840
d->customRatioNInput->setEnabled(true);
841
d->customRatioDInput->setEnabled(true);
842
d->orientLabel->setEnabled(true);
843
d->orientCB->setEnabled(!d->autoOrientation->isChecked());
844
d->autoOrientation->setEnabled(true);
845
slotCustomRatioChanged();
847
else if (a == ImageSelectionWidget::RATIONONE)
849
d->orientLabel->setEnabled(false);
850
d->orientCB->setEnabled(false);
851
d->autoOrientation->setEnabled(false);
852
d->customLabel->setEnabled(false);
853
d->customRatioNInput->setEnabled(false);
854
d->customRatioDInput->setEnabled(false);
856
else // Pre-config ratio selected.
858
d->orientLabel->setEnabled(true);
859
d->orientCB->setEnabled(!d->autoOrientation->isChecked());
860
d->autoOrientation->setEnabled(true);
861
d->customLabel->setEnabled(false);
862
d->customRatioNInput->setEnabled(false);
863
d->customRatioDInput->setEnabled(false);
867
void RatioCropTool::slotGuideTypeChanged(int t)
869
d->goldenSectionBox->setEnabled(false);
870
d->goldenSpiralSectionBox->setEnabled(false);
871
d->goldenSpiralBox->setEnabled(false);
872
d->goldenTriangleBox->setEnabled(false);
873
d->flipHorBox->setEnabled(false);
874
d->flipVerBox->setEnabled(false);
875
d->colorGuideLabel->setEnabled(true);
876
d->guideColorBt->setEnabled(true);
877
d->guideSize->setEnabled(true);
881
case ImageSelectionWidget::GuideNone:
882
d->colorGuideLabel->setEnabled(false);
883
d->guideColorBt->setEnabled(false);
884
d->guideSize->setEnabled(false);
886
case ImageSelectionWidget::HarmoniousTriangles:
887
d->flipHorBox->setEnabled(true);
888
d->flipVerBox->setEnabled(true);
890
case ImageSelectionWidget::GoldenMean:
891
d->flipHorBox->setEnabled(true);
892
d->flipVerBox->setEnabled(true);
893
d->goldenSectionBox->setEnabled(true);
894
d->goldenSpiralSectionBox->setEnabled(true);
895
d->goldenSpiralBox->setEnabled(true);
896
d->goldenTriangleBox->setEnabled(true);
900
d->imageSelectionWidget->setGoldenGuideTypes(d->goldenSectionBox->isChecked(),
901
d->goldenSpiralSectionBox->isChecked(),
902
d->goldenSpiralBox->isChecked(),
903
d->goldenTriangleBox->isChecked(),
904
d->flipHorBox->isChecked(),
905
d->flipVerBox->isChecked());
906
d->imageSelectionWidget->slotGuideLines(t);
909
void RatioCropTool::slotGoldenGuideTypeChanged()
911
slotGuideTypeChanged(d->guideLinesCB->currentIndex());
914
void RatioCropTool::slotCustomNRatioChanged(int a)
916
if ( ! d->autoOrientation->isChecked() )
918
if ( ( d->orientCB->currentIndex() == ImageSelectionWidget::Portrait &&
919
d->customRatioDInput->value() < a ) ||
920
( d->orientCB->currentIndex() == ImageSelectionWidget::Landscape &&
921
d->customRatioDInput->value() > a ) )
923
d->customRatioDInput->blockSignals(true);
924
d->customRatioDInput->setValue(a);
925
d->customRatioDInput->blockSignals(false);
929
slotCustomRatioChanged();
932
void RatioCropTool::slotCustomDRatioChanged(int a)
934
if ( ! d->autoOrientation->isChecked() )
936
if ( ( d->orientCB->currentIndex() == ImageSelectionWidget::Landscape &&
937
d->customRatioNInput->value() < a ) ||
938
( d->orientCB->currentIndex() == ImageSelectionWidget::Portrait &&
939
d->customRatioNInput->value() > a ) )
941
d->customRatioNInput->blockSignals(true);
942
d->customRatioNInput->setValue(a);
943
d->customRatioNInput->blockSignals(false);
947
slotCustomRatioChanged();
950
void RatioCropTool::slotCustomRatioChanged()
952
d->imageSelectionWidget->setSelectionAspectRatioValue(d->customRatioNInput->value(),
953
d->customRatioDInput->value());
955
// Reset selection area.
959
void RatioCropTool::finalRendering()
961
kapp->setOverrideCursor( Qt::WaitCursor );
963
QRect currentRegion = d->imageSelectionWidget->getRegionSelection();
964
ImageIface* iface = d->imageSelectionWidget->imageIface();
965
uchar* data = iface->getOriginalImage();
966
int w = iface->originalWidth();
967
int h = iface->originalHeight();
968
bool a = iface->originalHasAlpha();
969
bool sb = iface->originalSixteenBit();
970
QRect normalizedRegion = currentRegion.normalized();
972
if (normalizedRegion.right() > w)
974
normalizedRegion.setRight(w);
977
if (normalizedRegion.bottom() > h)
979
normalizedRegion.setBottom(h);
982
DImg imOrg(w, h, sb, a, data);
984
imOrg.crop(normalizedRegion);
986
iface->putOriginalImage(i18n("Aspect Ratio Crop"), imOrg.bits(), imOrg.width(), imOrg.height());
988
kapp->restoreOverrideCursor();
992
void RatioCropTool::blockWidgetSignals(bool b)
994
d->customRatioDInput->blockSignals(b);
995
d->customRatioNInput->blockSignals(b);
996
d->flipHorBox->blockSignals(b);
997
d->flipVerBox->blockSignals(b);
998
d->goldenSectionBox->blockSignals(b);
999
d->goldenSpiralBox->blockSignals(b);
1000
d->goldenSpiralSectionBox->blockSignals(b);
1001
d->goldenTriangleBox->blockSignals(b);
1002
d->guideLinesCB->blockSignals(b);
1003
d->heightInput->blockSignals(b);
1004
d->imageSelectionWidget->blockSignals(b);
1005
d->preciseCrop->blockSignals(b);
1006
d->widthInput->blockSignals(b);
1007
d->xInput->blockSignals(b);
1008
d->yInput->blockSignals(b);
1011
} // namespace DigikamTransformImagePlugin