1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-03-09
7 * Description : Local Contrast settings view.
8 * LDR ToneMapper <zynaddsubfx.sourceforge.net/other/tonemapping>
9 *
10 * Copyright (C) 2010-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "localcontrastsettings.h"
26
27 // Qt includes
28
29 #include <QString>
30 #include <QButtonGroup>
31 #include <QFile>
32 #include <QFrame>
33 #include <QGridLayout>
34 #include <QCheckBox>
35 #include <QHBoxLayout>
36 #include <QLabel>
37 #include <QRegExp>
38 #include <QTextStream>
39 #include <QToolButton>
40 #include <QVBoxLayout>
41 #include <QStandardPaths>
42 #include <QApplication>
43 #include <QStyle>
44 #include <QUrl>
45 #include <QIcon>
46 #include <QMessageBox>
47
48 // KDE includes
49
50 #include <kconfiggroup.h>
51 #include <klocalizedstring.h>
52
53 // Local includes
54
55 #include "dexpanderbox.h"
56 #include "dfiledialog.h"
57 #include "dnuminput.h"
58 #include "digikam_debug.h"
59 #include "dcombobox.h"
60
61 namespace Digikam
62 {
63
64 class Q_DECL_HIDDEN LocalContrastSettings::Private
65 {
66
67 public:
68
Private()69 explicit Private()
70 : stretchContrastCheck(nullptr),
71 label4 (nullptr),
72 label5 (nullptr),
73 label6 (nullptr),
74 label7 (nullptr),
75 label8 (nullptr),
76 label9 (nullptr),
77 label10 (nullptr),
78 label11 (nullptr),
79 lowSaturationInput (nullptr),
80 highSaturationInput (nullptr),
81 functionInput (nullptr),
82 powerInput1 (nullptr),
83 blurInput1 (nullptr),
84 powerInput2 (nullptr),
85 blurInput2 (nullptr),
86 powerInput3 (nullptr),
87 blurInput3 (nullptr),
88 powerInput4 (nullptr),
89 blurInput4 (nullptr),
90 expanderBox (nullptr)
91 {
92 }
93
94 static const QString configLowSaturationEntry;
95 static const QString configHighSaturationEntry;
96 static const QString configPower1Entry;
97 static const QString configBlur1Entry;
98 static const QString configPower2Entry;
99 static const QString configBlur2Entry;
100 static const QString configPower3Entry;
101 static const QString configBlur3Entry;
102 static const QString configPower4Entry;
103 static const QString configBlur4Entry;
104 static const QString configStretchContrastEntry;
105 static const QString configFastModeEntry;
106 static const QString configStageOneEntry;
107 static const QString configStageTwoEntry;
108 static const QString configStageThreeEntry;
109 static const QString configStageFourEntry;
110 static const QString configFunctionInputEntry;
111
112 QCheckBox* stretchContrastCheck;
113
114 QLabel* label4;
115 QLabel* label5;
116 QLabel* label6;
117 QLabel* label7;
118 QLabel* label8;
119 QLabel* label9;
120 QLabel* label10;
121 QLabel* label11;
122
123 DIntNumInput* lowSaturationInput;
124 DIntNumInput* highSaturationInput;
125
126 DComboBox* functionInput;
127
128 DDoubleNumInput* powerInput1;
129 DDoubleNumInput* blurInput1;
130 DDoubleNumInput* powerInput2;
131 DDoubleNumInput* blurInput2;
132 DDoubleNumInput* powerInput3;
133 DDoubleNumInput* blurInput3;
134 DDoubleNumInput* powerInput4;
135 DDoubleNumInput* blurInput4;
136
137 DExpanderBox* expanderBox;
138 };
139
140 const QString LocalContrastSettings::Private::configLowSaturationEntry(QLatin1String("LowSaturation"));
141 const QString LocalContrastSettings::Private::configHighSaturationEntry(QLatin1String("HighSaturation"));
142 const QString LocalContrastSettings::Private::configPower1Entry(QLatin1String("Power1"));
143 const QString LocalContrastSettings::Private::configBlur1Entry(QLatin1String("Blur1"));
144 const QString LocalContrastSettings::Private::configPower2Entry(QLatin1String("Power2"));
145 const QString LocalContrastSettings::Private::configBlur2Entry(QLatin1String("Blur2"));
146 const QString LocalContrastSettings::Private::configPower3Entry(QLatin1String("Power3"));
147 const QString LocalContrastSettings::Private::configBlur3Entry(QLatin1String("Blur3"));
148 const QString LocalContrastSettings::Private::configPower4Entry(QLatin1String("Power4"));
149 const QString LocalContrastSettings::Private::configBlur4Entry(QLatin1String("Blur4"));
150 const QString LocalContrastSettings::Private::configStretchContrastEntry(QLatin1String("StretchContrast"));
151 const QString LocalContrastSettings::Private::configStageOneEntry(QLatin1String("StageOne"));
152 const QString LocalContrastSettings::Private::configStageTwoEntry(QLatin1String("StageTwo"));
153 const QString LocalContrastSettings::Private::configStageThreeEntry(QLatin1String("StageThree"));
154 const QString LocalContrastSettings::Private::configStageFourEntry(QLatin1String("StageFour"));
155 const QString LocalContrastSettings::Private::configFunctionInputEntry(QLatin1String("FunctionInput"));
156
157 // --------------------------------------------------------
158
LocalContrastSettings(QWidget * const parent)159 LocalContrastSettings::LocalContrastSettings(QWidget* const parent)
160 : QWidget(parent),
161 d (new Private)
162 {
163 const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
164
165 QGridLayout* const grid = new QGridLayout(parent);
166
167 QWidget* const firstPage = new QWidget();
168 QGridLayout* const grid1 = new QGridLayout(firstPage);
169
170 QLabel* const label1 = new QLabel(i18n("Function:"), firstPage);
171 d->functionInput = new DComboBox(firstPage);
172 d->functionInput->addItem(i18nc("@item: function type", "Power"));
173 d->functionInput->addItem(i18nc("@item: function type", "Linear"));
174 d->functionInput->setDefaultIndex(0);
175 d->functionInput->setWhatsThis(i18n("<b>Function</b>: This function combines the original RGB "
176 "channels with the desaturated blurred image. This function is used in each of "
177 "the tonemapping stages. It can be linear or power. Basically, this function "
178 "increases the values where both the original and blurred image's value are low "
179 "and do the opposite on high values."));
180
181 // -------------------------------------------------------------
182
183 d->stretchContrastCheck = new QCheckBox(i18n("Stretch contrast"), firstPage);
184 d->stretchContrastCheck->setWhatsThis(i18n("<b>Stretch contrast</b>: This stretches the contrast of the original image. "
185 "It is applied before the tonemapping process."));
186 d->stretchContrastCheck->setChecked(true);
187
188 // -------------------------------------------------------------
189
190 QLabel* const label2 = new QLabel(i18n("Highlights saturation:"), firstPage);
191 d->highSaturationInput = new DIntNumInput(firstPage);
192 d->highSaturationInput->setRange(0, 100, 1);
193 d->highSaturationInput->setDefaultValue(100);
194 d->highSaturationInput->setObjectName(QLatin1String("highSaturationInput"));
195 d->highSaturationInput->setWhatsThis(i18n("<b>Highlights saturation</b>: Usually the (perceived) saturation is "
196 "increased. The user can choose to lower the saturation on original highlight "
197 "and shadows from the image with these parameters."));
198
199 // -------------------------------------------------------------
200
201 QLabel* const label3 = new QLabel(i18n("Shadow saturation:"), firstPage);
202 d->lowSaturationInput = new DIntNumInput(firstPage);
203 d->lowSaturationInput->setRange(0, 100, 1);
204 d->lowSaturationInput->setDefaultValue(100);
205 d->lowSaturationInput->setObjectName(QLatin1String("lowSaturationInput"));
206 d->lowSaturationInput->setWhatsThis(i18n("<b>Shadow saturation</b>: Usually the (perceived) saturation is "
207 "increased. The user can choose to lower the saturation on original highlight "
208 "and shadows from the image with these parameters."));
209
210 // -------------------------------------------------------------
211
212 grid1->addWidget(label1, 0, 0, 1, 2);
213 grid1->addWidget(d->functionInput, 0, 1, 1, 1);
214 grid1->addWidget(d->stretchContrastCheck, 1, 0, 1, 1);
215 grid1->addWidget(label2, 2, 0, 1, 2);
216 grid1->addWidget(d->highSaturationInput, 3, 0, 1, 2);
217 grid1->addWidget(label3, 4, 0, 1, 2);
218 grid1->addWidget(d->lowSaturationInput, 5, 0, 1, 2);
219 grid1->setContentsMargins(spacing, spacing, spacing, spacing);
220 grid1->setSpacing(spacing);
221
222 // -------------------------------------------------------------
223
224 QWidget* const secondPage = new QWidget();
225 QGridLayout* const grid2 = new QGridLayout(secondPage);
226
227 // -------------------------------------------------------------
228
229 d->label4 = new QLabel(i18n("Power:"), secondPage);
230 d->powerInput1 = new DDoubleNumInput(firstPage);
231 d->powerInput1->setRange(0.0, 100.0, 1.0);
232 d->powerInput1->setDefaultValue(30.0);
233 d->powerInput1->setObjectName(QLatin1String("powerInput1"));
234 d->powerInput1->setWhatsThis(i18n("<b>Power</b>: How strong the effect is applied."));
235
236 // -------------------------------------------------------------
237
238 d->label5 = new QLabel(i18n("Blur:"), secondPage);
239 d->blurInput1 = new DDoubleNumInput(firstPage);
240 d->blurInput1->setRange(0.0, 1000.0, 1.0);
241 d->blurInput1->setDefaultValue(80.0);
242 d->blurInput1->setObjectName(QLatin1String("blurInput1"));
243 d->blurInput1->setWhatsThis(i18n("<b>Blur</b>: How strong the image is blurred before combining with the original "
244 "image and with the tonemapping function."));
245
246 grid2->addWidget(d->label4, 0, 0, 1, 1);
247 grid2->addWidget(d->powerInput1, 0, 1, 1, 1);
248 grid2->addWidget(d->label5, 1, 0, 1, 1);
249 grid2->addWidget(d->blurInput1, 1, 1, 1, 1);
250 grid2->setContentsMargins(spacing, spacing, spacing, spacing);
251 grid2->setSpacing(spacing);
252
253 // -------------------------------------------------------------
254
255 QWidget* const thirdPage = new QWidget();
256 QGridLayout* const grid3 = new QGridLayout(thirdPage);
257
258 // -------------------------------------------------------------
259
260 d->label6 = new QLabel(i18n("Power:"), thirdPage);
261 d->powerInput2 = new DDoubleNumInput(thirdPage);
262 d->powerInput2->setRange(0.0, 100.0, 1.0);
263 d->powerInput2->setDefaultValue(30.0);
264 d->powerInput2->setObjectName(QLatin1String("powerInput2"));
265 d->powerInput2->setWhatsThis(i18n("<b>Power</b>: How strong the effect is applied."));
266
267 // -------------------------------------------------------------
268
269 d->label7 = new QLabel(i18n("Blur:"), thirdPage);
270 d->blurInput2 = new DDoubleNumInput(thirdPage);
271 d->blurInput2->setRange(0.0, 1000.0, 1.0);
272 d->blurInput2->setDefaultValue(80.0);
273 d->blurInput2->setObjectName(QLatin1String("blurInput2"));
274 d->blurInput2->setWhatsThis(i18n("<b>Blur</b>: How strong the image is blurred before combining with the original "
275 "image and with the tonemapping function."));
276
277 grid3->addWidget(d->label6, 0, 0, 1, 1);
278 grid3->addWidget(d->powerInput2, 0, 1, 1, 1);
279 grid3->addWidget(d->label7, 1, 0, 1, 1);
280 grid3->addWidget(d->blurInput2, 1, 1, 1, 1);
281 grid3->setContentsMargins(spacing, spacing, spacing, spacing);
282 grid3->setSpacing(spacing);
283
284 // -------------------------------------------------------------
285
286 QWidget* const fourthPage = new QWidget();
287 QGridLayout* const grid4 = new QGridLayout(fourthPage);
288
289 // -------------------------------------------------------------
290
291 d->label8 = new QLabel(i18n("Power:"), fourthPage);
292 d->powerInput3 = new DDoubleNumInput(fourthPage);
293 d->powerInput3->setRange(0.0, 100.0, 1.0);
294 d->powerInput3->setDefaultValue(30.0);
295 d->powerInput3->setObjectName(QLatin1String("powerInput3"));
296 d->powerInput3->setWhatsThis(i18n("<b>Power</b>: How strong the effect is applied."));
297
298 // -------------------------------------------------------------
299
300 d->label9 = new QLabel(i18n("Blur:"), fourthPage);
301 d->blurInput3 = new DDoubleNumInput(fourthPage);
302 d->blurInput3->setRange(0.0, 1000.0, 1.0);
303 d->blurInput3->setDefaultValue(80.0);
304 d->blurInput3->setObjectName(QLatin1String("blurInput3"));
305 d->blurInput3->setWhatsThis(i18n("<b>Blur</b>: How strong the image is blurred before combining with the original "
306 "image and with the tonemapping function."));
307
308 grid4->addWidget(d->label8, 0, 0, 1, 1);
309 grid4->addWidget(d->powerInput3, 0, 1, 1, 1);
310 grid4->addWidget(d->label9, 1, 0, 1, 1);
311 grid4->addWidget(d->blurInput3, 1, 1, 1, 1);
312 grid4->setContentsMargins(spacing, spacing, spacing, spacing);
313 grid4->setSpacing(spacing);
314
315 // -------------------------------------------------------------
316
317 QWidget* const fifthPage = new QWidget();
318 QGridLayout* const grid5 = new QGridLayout(fifthPage);
319
320 // -------------------------------------------------------------
321
322 d->label10 = new QLabel(i18n("Power:"), fifthPage);
323 d->powerInput4 = new DDoubleNumInput(fifthPage);
324 d->powerInput4->setRange(0.0, 100.0, 1.0);
325 d->powerInput4->setDefaultValue(30.0);
326 d->powerInput4->setObjectName(QLatin1String("powerInput4"));
327 d->powerInput4->setWhatsThis(i18n("<b>Power</b>: How strong the effect is applied."));
328
329 // -------------------------------------------------------------
330
331 d->label11 = new QLabel(i18n("Blur:"), fifthPage);
332 d->blurInput4 = new DDoubleNumInput(fifthPage);
333 d->blurInput4->setRange(0.0, 1000.0, 1.0);
334 d->blurInput4->setDefaultValue(80.0);
335 d->blurInput4->setObjectName(QLatin1String("blurInput4"));
336 d->blurInput4->setWhatsThis(i18n("<b>Blur</b>: How strong the image is blurred before combining with the original "
337 "image and with the tonemapping function."));
338
339 grid5->addWidget(d->label10, 0, 0, 1, 1);
340 grid5->addWidget(d->powerInput4, 0, 1, 1, 1);
341 grid5->addWidget(d->label11, 1, 0, 1, 1);
342 grid5->addWidget(d->blurInput4, 1, 1, 1, 1);
343 grid5->setContentsMargins(spacing, spacing, spacing, spacing);
344 grid5->setSpacing(spacing);
345
346 // -------------------------------------------------------------
347
348 d->expanderBox = new DExpanderBox;
349 d->expanderBox->setObjectName(QLatin1String("LocalContrastTool Expander"));
350 d->expanderBox->addItem(firstPage, QIcon::fromTheme(QLatin1String("contrast")), i18n("General settings"),
351 QLatin1String("GeneralSettingsContainer"), true);
352 d->expanderBox->addItem(secondPage, QIcon::fromTheme(QLatin1String("contrast")), i18n("Stage 1"),
353 QLatin1String("Stage1SettingsContainer"), true);
354 d->expanderBox->addItem(thirdPage, QIcon::fromTheme(QLatin1String("contrast")), i18n("Stage 2"),
355 QLatin1String("Stage2SettingsContainer"), true);
356 d->expanderBox->addItem(fourthPage, QIcon::fromTheme(QLatin1String("contrast")), i18n("Stage 3"),
357 QLatin1String("Stage3SettingsContainer"), true);
358 d->expanderBox->addItem(fifthPage, QIcon::fromTheme(QLatin1String("contrast")), i18n("Stage 4"),
359 QLatin1String("Stage4SettingsContainer"), true);
360 d->expanderBox->addStretch();
361 d->expanderBox->setCheckBoxVisible(1, true);
362 d->expanderBox->setCheckBoxVisible(2, true);
363 d->expanderBox->setCheckBoxVisible(3, true);
364 d->expanderBox->setCheckBoxVisible(4, true);
365
366 grid->addWidget(d->expanderBox, 0, 0, 1, 1);
367 grid->setRowStretch(0, 10);
368 grid->setContentsMargins(spacing, spacing, spacing, spacing);
369 grid->setSpacing(spacing);
370
371 // -------------------------------------------------------------
372
373 connect(d->expanderBox, SIGNAL(signalItemToggled(int,bool)),
374 this, SLOT(slotStageEnabled(int,bool)));
375
376 connect(d->lowSaturationInput, SIGNAL(valueChanged(int)),
377 this, SIGNAL(signalSettingsChanged()));
378
379 connect(d->highSaturationInput, SIGNAL(valueChanged(int)),
380 this, SIGNAL(signalSettingsChanged()));
381
382 connect(d->powerInput1, SIGNAL(valueChanged(double)),
383 this, SIGNAL(signalSettingsChanged()));
384
385 connect(d->blurInput1, SIGNAL(valueChanged(double)),
386 this, SIGNAL(signalSettingsChanged()));
387
388 connect(d->powerInput2, SIGNAL(valueChanged(double)),
389 this, SIGNAL(signalSettingsChanged()));
390
391 connect(d->blurInput2, SIGNAL(valueChanged(double)),
392 this, SIGNAL(signalSettingsChanged()));
393
394 connect(d->powerInput3, SIGNAL(valueChanged(double)),
395 this, SIGNAL(signalSettingsChanged()));
396
397 connect(d->blurInput3, SIGNAL(valueChanged(double)),
398 this, SIGNAL(signalSettingsChanged()));
399
400 connect(d->powerInput4, SIGNAL(valueChanged(double)),
401 this, SIGNAL(signalSettingsChanged()));
402
403 connect(d->blurInput4, SIGNAL(valueChanged(double)),
404 this, SIGNAL(signalSettingsChanged()));
405
406 connect(d->functionInput, SIGNAL(currentIndexChanged(int)),
407 this, SIGNAL(signalSettingsChanged()));
408
409 connect(d->stretchContrastCheck, SIGNAL(toggled(bool)),
410 this, SIGNAL(signalSettingsChanged()));
411 }
412
~LocalContrastSettings()413 LocalContrastSettings::~LocalContrastSettings()
414 {
415 delete d;
416 }
417
slotStageEnabled(int index,bool b)418 void LocalContrastSettings::slotStageEnabled(int index, bool b)
419 {
420 switch (index)
421 {
422 case 1:
423 {
424 d->label4->setEnabled(b);
425 d->powerInput1->setEnabled(b);
426 d->label5->setEnabled(b);
427 d->blurInput1->setEnabled(b);
428 break;
429 }
430
431 case 2:
432 {
433 d->label6->setEnabled(b);
434 d->powerInput2->setEnabled(b);
435 d->label7->setEnabled(b);
436 d->blurInput2->setEnabled(b);
437 break;
438 }
439
440 case 3:
441 {
442 d->label8->setEnabled(b);
443 d->powerInput3->setEnabled(b);
444 d->label9->setEnabled(b);
445 d->blurInput3->setEnabled(b);
446 break;
447 }
448
449 case 4:
450 {
451 d->label10->setEnabled(b);
452 d->powerInput4->setEnabled(b);
453 d->label11->setEnabled(b);
454 d->blurInput4->setEnabled(b);
455 break;
456 }
457 }
458
459 emit signalSettingsChanged();
460 }
461
settings() const462 LocalContrastContainer LocalContrastSettings::settings() const
463 {
464 LocalContrastContainer prm;
465
466 prm.stretchContrast = d->stretchContrastCheck->isChecked();
467 prm.lowSaturation = d->lowSaturationInput->value();
468 prm.highSaturation = d->highSaturationInput->value();
469 prm.functionId = d->functionInput->currentIndex();
470
471 prm.stage[0].enabled = d->expanderBox->isChecked(1);
472 prm.stage[0].power = d->powerInput1->value();
473 prm.stage[0].blur = d->blurInput1->value();
474
475 prm.stage[1].enabled = d->expanderBox->isChecked(2);
476 prm.stage[1].power = d->powerInput2->value();
477 prm.stage[1].blur = d->blurInput2->value();
478
479 prm.stage[2].enabled = d->expanderBox->isChecked(3);
480 prm.stage[2].power = d->powerInput3->value();
481 prm.stage[2].blur = d->blurInput3->value();
482
483 prm.stage[3].enabled = d->expanderBox->isChecked(4);
484 prm.stage[3].power = d->powerInput4->value();
485 prm.stage[3].blur = d->blurInput4->value();
486
487 return prm;
488 }
489
setSettings(const LocalContrastContainer & settings)490 void LocalContrastSettings::setSettings(const LocalContrastContainer& settings)
491 {
492 blockSignals(true);
493 d->expanderBox->setEnabled(false);
494
495 d->stretchContrastCheck->setChecked(settings.stretchContrast);
496 d->lowSaturationInput->setValue(settings.lowSaturation);
497 d->highSaturationInput->setValue(settings.highSaturation);
498 d->functionInput->setCurrentIndex(settings.functionId);
499
500 d->expanderBox->setChecked(1, settings.stage[0].enabled);
501 d->powerInput1->setValue(settings.stage[0].power);
502 d->blurInput1->setValue(settings.stage[0].blur);
503
504 d->expanderBox->setChecked(2, settings.stage[1].enabled);
505 d->powerInput2->setValue(settings.stage[1].power);
506 d->blurInput2->setValue(settings.stage[1].blur);
507
508 d->expanderBox->setChecked(3, settings.stage[2].enabled);
509 d->powerInput3->setValue(settings.stage[2].power);
510 d->blurInput3->setValue(settings.stage[2].blur);
511
512 d->expanderBox->setChecked(4, settings.stage[3].enabled);
513 d->powerInput4->setValue(settings.stage[3].power);
514 d->blurInput4->setValue(settings.stage[3].blur);
515
516 /*
517 slotStage1Enabled(d->stageOne->isChecked());
518 slotStage2Enabled(d->stageTwo->isChecked());
519 slotStage3Enabled(d->stageThree->isChecked());
520 slotStage4Enabled(d->stageFour->isChecked());
521 */
522
523 d->expanderBox->setEnabled(true);
524 blockSignals(false);
525 }
526
resetToDefault()527 void LocalContrastSettings::resetToDefault()
528 {
529 blockSignals(true);
530
531 d->stretchContrastCheck->setChecked(true);
532 d->lowSaturationInput->slotReset();
533 d->highSaturationInput->slotReset();
534 d->functionInput->slotReset();
535
536 d->expanderBox->setChecked(1, true);
537 d->powerInput1->slotReset();
538 d->blurInput1->slotReset();
539
540 d->expanderBox->setChecked(2, false);
541 d->powerInput2->slotReset();
542 d->blurInput2->slotReset();
543
544 d->expanderBox->setChecked(3, false);
545 d->powerInput3->slotReset();
546 d->blurInput3->slotReset();
547
548 d->expanderBox->setChecked(4, false);
549 d->powerInput4->slotReset();
550 d->blurInput4->slotReset();
551
552 blockSignals(false);
553 }
554
defaultSettings() const555 LocalContrastContainer LocalContrastSettings::defaultSettings() const
556 {
557 LocalContrastContainer prm;
558
559 prm.stretchContrast = true;
560 prm.lowSaturation = d->lowSaturationInput->defaultValue();
561 prm.highSaturation = d->highSaturationInput->defaultValue();
562 prm.functionId = d->functionInput->defaultIndex();
563
564 prm.stage[0].enabled = true;
565 prm.stage[0].power = d->powerInput1->defaultValue();
566 prm.stage[0].blur = d->blurInput1->defaultValue();
567
568 prm.stage[1].enabled = false;
569 prm.stage[1].power = d->powerInput2->defaultValue();
570 prm.stage[1].blur = d->blurInput2->defaultValue();
571
572 prm.stage[2].enabled = false;
573 prm.stage[2].power = d->powerInput3->defaultValue();
574 prm.stage[2].blur = d->blurInput3->defaultValue();
575
576 prm.stage[3].enabled = false;
577 prm.stage[3].power = d->powerInput4->defaultValue();
578 prm.stage[3].blur = d->blurInput4->defaultValue();
579
580 return prm;
581 }
582
readSettings(KConfigGroup & group)583 void LocalContrastSettings::readSettings(KConfigGroup& group)
584 {
585 LocalContrastContainer prm;
586 LocalContrastContainer defaultPrm = defaultSettings();
587
588 prm.stretchContrast = group.readEntry(d->configStretchContrastEntry, defaultPrm.stretchContrast);
589 prm.lowSaturation = group.readEntry(d->configLowSaturationEntry, defaultPrm.lowSaturation);
590 prm.highSaturation = group.readEntry(d->configHighSaturationEntry, defaultPrm.highSaturation);
591 prm.functionId = group.readEntry(d->configFunctionInputEntry, defaultPrm.functionId);
592
593 prm.stage[0].enabled = group.readEntry(d->configStageOneEntry, defaultPrm.stage[0].enabled);
594 prm.stage[0].power = group.readEntry(d->configPower1Entry, defaultPrm.stage[0].power);
595 prm.stage[0].blur = group.readEntry(d->configBlur1Entry, defaultPrm.stage[0].blur);
596
597 prm.stage[1].enabled = group.readEntry(d->configStageTwoEntry, defaultPrm.stage[1].enabled);
598 prm.stage[1].power = group.readEntry(d->configPower2Entry, defaultPrm.stage[1].power);
599 prm.stage[1].blur = group.readEntry(d->configBlur2Entry, defaultPrm.stage[1].blur);
600
601 prm.stage[2].enabled = group.readEntry(d->configStageThreeEntry, defaultPrm.stage[2].enabled);
602 prm.stage[2].power = group.readEntry(d->configPower3Entry, defaultPrm.stage[2].power);
603 prm.stage[2].blur = group.readEntry(d->configBlur3Entry, defaultPrm.stage[2].blur);
604
605 prm.stage[3].enabled = group.readEntry(d->configStageFourEntry, defaultPrm.stage[3].enabled);
606 prm.stage[3].power = group.readEntry(d->configPower4Entry, defaultPrm.stage[3].power);
607 prm.stage[3].blur = group.readEntry(d->configBlur4Entry, defaultPrm.stage[3].blur);
608
609 setSettings(prm);
610
611 d->expanderBox->readSettings(group);
612
613 d->expanderBox->setEnabled(true);
614 }
615
writeSettings(KConfigGroup & group)616 void LocalContrastSettings::writeSettings(KConfigGroup& group)
617 {
618 LocalContrastContainer prm = settings();
619
620 group.writeEntry(d->configStretchContrastEntry, prm.stretchContrast);
621 group.writeEntry(d->configLowSaturationEntry, prm.lowSaturation);
622 group.writeEntry(d->configHighSaturationEntry, prm.highSaturation);
623 group.writeEntry(d->configFunctionInputEntry, prm.functionId);
624
625 group.writeEntry(d->configStageOneEntry, prm.stage[0].enabled);
626 group.writeEntry(d->configPower1Entry, prm.stage[0].power);
627 group.writeEntry(d->configBlur1Entry, prm.stage[0].blur);
628
629 group.writeEntry(d->configStageTwoEntry, prm.stage[1].enabled);
630 group.writeEntry(d->configPower2Entry, prm.stage[1].power);
631 group.writeEntry(d->configBlur2Entry, prm.stage[1].blur);
632
633 group.writeEntry(d->configStageThreeEntry, prm.stage[2].enabled);
634 group.writeEntry(d->configPower3Entry, prm.stage[2].power);
635 group.writeEntry(d->configBlur3Entry, prm.stage[2].blur);
636
637 group.writeEntry(d->configStageFourEntry, prm.stage[3].enabled);
638 group.writeEntry(d->configPower4Entry, prm.stage[3].power);
639 group.writeEntry(d->configBlur4Entry, prm.stage[3].blur);
640
641 d->expanderBox->writeSettings(group);
642 }
643
loadSettings()644 void LocalContrastSettings::loadSettings()
645 {
646 QUrl loadFile = DFileDialog::getOpenFileUrl(qApp->activeWindow(), i18n("Photograph Local Contrast Settings File to Load"),
647 QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)),
648 QLatin1String("*"));
649
650 if (loadFile.isEmpty())
651 {
652 return;
653 }
654
655 QFile file(loadFile.toLocalFile());
656
657 if (file.open(QIODevice::ReadOnly))
658 {
659 QTextStream stream(&file);
660
661 if (stream.readLine() != QLatin1String("# Photograph Local Contrast Configuration File"))
662 {
663 QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(),
664 i18n("\"%1\" is not a Photograph Local Contrast settings text file.",
665 loadFile.fileName()));
666 file.close();
667 return;
668 }
669
670 blockSignals(true);
671 d->stretchContrastCheck->setChecked(stream.readLine().toInt());
672 d->expanderBox->setChecked(1, stream.readLine().toInt());
673 d->expanderBox->setChecked(2, stream.readLine().toInt());
674 d->expanderBox->setChecked(3, stream.readLine().toInt());
675 d->expanderBox->setChecked(4, stream.readLine().toInt());
676 d->lowSaturationInput->setValue(stream.readLine().toInt());
677 d->highSaturationInput->setValue(stream.readLine().toInt());
678 d->functionInput->setCurrentIndex(stream.readLine().toInt());
679 d->powerInput1->setValue(stream.readLine().toDouble());
680 d->blurInput1->setValue(stream.readLine().toDouble());
681 d->powerInput2->setValue(stream.readLine().toDouble());
682 d->blurInput2->setValue(stream.readLine().toDouble());
683 d->powerInput3->setValue(stream.readLine().toDouble());
684 d->blurInput3->setValue(stream.readLine().toDouble());
685 d->powerInput4->setValue(stream.readLine().toDouble());
686 d->blurInput4->setValue(stream.readLine().toDouble());
687 blockSignals(false);
688 }
689 else
690 {
691 QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(),
692 i18n("Cannot load settings from the Photograph Local Contrast text file."));
693 }
694
695 file.close();
696 }
697
saveAsSettings()698 void LocalContrastSettings::saveAsSettings()
699 {
700 QUrl saveFile = DFileDialog::getSaveFileUrl(qApp->activeWindow(), i18n("Photograph Local Contrast Settings File to Save"),
701 QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)),
702 QLatin1String("*"));
703
704 if (saveFile.isEmpty())
705 {
706 return;
707 }
708
709 QFile file(saveFile.toLocalFile());
710
711 if (file.open(QIODevice::WriteOnly))
712 {
713 QTextStream stream(&file);
714 stream << QLatin1String("# Photograph Local Contrast Configuration File\n");
715
716 stream << d->stretchContrastCheck->isChecked() << QLatin1Char('\n');
717 stream << d->expanderBox->isChecked(1) << QLatin1Char('\n');
718 stream << d->expanderBox->isChecked(2) << QLatin1Char('\n');
719 stream << d->expanderBox->isChecked(3) << QLatin1Char('\n');
720 stream << d->expanderBox->isChecked(4) << QLatin1Char('\n');
721 stream << d->lowSaturationInput->value() << QLatin1Char('\n');
722 stream << d->highSaturationInput->value() << QLatin1Char('\n');
723 stream << d->functionInput->currentIndex() << QLatin1Char('\n');
724 stream << d->powerInput1->value() << QLatin1Char('\n');
725 stream << d->blurInput1->value() << QLatin1Char('\n');
726 stream << d->powerInput2->value() << QLatin1Char('\n');
727 stream << d->blurInput2->value() << QLatin1Char('\n');
728 stream << d->powerInput3->value() << QLatin1Char('\n');
729 stream << d->blurInput3->value() << QLatin1Char('\n');
730 stream << d->powerInput4->value() << QLatin1Char('\n');
731 stream << d->blurInput4->value() << QLatin1Char('\n');
732 }
733 else
734 {
735 QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(),
736 i18n("Cannot save settings to the Photograph Local Contrast text file."));
737 }
738
739 file.close();
740 }
741
742 } // namespace Digikam
743