1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-03-17
7 * Description : Border settings view.
8 *
9 * Copyright (C) 2010-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 *
11 * This program is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU General
13 * Public License as published by the Free Software Foundation;
14 * either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * ============================================================ */
23
24 #include "bordersettings.h"
25
26 // Qt includes
27
28 #include <QGridLayout>
29 #include <QLabel>
30 #include <QString>
31 #include <QFile>
32 #include <QTextStream>
33 #include <QCheckBox>
34 #include <QUrl>
35 #include <QApplication>
36 #include <QStyle>
37
38 // KDE includes
39
40 #include <kconfiggroup.h>
41 #include <klocalizedstring.h>
42
43 // Local includes
44
45 #include "dlayoutbox.h"
46 #include "dexpanderbox.h"
47 #include "dnuminput.h"
48 #include "dcombobox.h"
49 #include "dcolorselector.h"
50 #include "digikam_debug.h"
51
52 namespace Digikam
53 {
54
55 class Q_DECL_HIDDEN BorderSettings::Private
56 {
57 public:
58
Private()59 explicit Private()
60 : preserveAspectRatio (nullptr),
61 labelBackground (nullptr),
62 labelBorderPercent (nullptr),
63 labelBorderWidth (nullptr),
64 labelForeground (nullptr),
65 firstColorButton (nullptr),
66 secondColorButton (nullptr),
67 borderType (nullptr),
68 borderPercent (nullptr),
69 borderWidth (nullptr)
70 {
71 }
72
73 static const QString configBorderTypeEntry;
74 static const QString configBorderPercentEntry;
75 static const QString configBorderWidthEntry;
76 static const QString configPreserveAspectRatioEntry;
77 static const QString configSolidColorEntry;
78 static const QString configNiepceBorderColorEntry;
79 static const QString configNiepceLineColorEntry;
80 static const QString configBevelUpperLeftColorEntry;
81 static const QString configBevelLowerRightColorEntry;
82 static const QString configDecorativeFirstColorEntry;
83 static const QString configDecorativeSecondColorEntry;
84
85 QCheckBox* preserveAspectRatio;
86
87 QLabel* labelBackground;
88 QLabel* labelBorderPercent;
89 QLabel* labelBorderWidth;
90 QLabel* labelForeground;
91
92 QColor bevelLowerRightColor;
93 QColor bevelUpperLeftColor;
94 QColor decorativeFirstColor;
95 QColor decorativeSecondColor;
96 QColor niepceBorderColor;
97 QColor niepceLineColor;
98 QColor solidColor;
99
100 DColorSelector* firstColorButton;
101 DColorSelector* secondColorButton;
102
103 DComboBox* borderType;
104 DIntNumInput* borderPercent;
105 DIntNumInput* borderWidth;
106 };
107
108 const QString BorderSettings::Private::configBorderTypeEntry(QLatin1String("Border Type"));
109 const QString BorderSettings::Private::configBorderPercentEntry(QLatin1String("Border Percent"));
110 const QString BorderSettings::Private::configBorderWidthEntry(QLatin1String("Border Width"));
111 const QString BorderSettings::Private::configPreserveAspectRatioEntry(QLatin1String("Preserve Aspect Ratio"));
112 const QString BorderSettings::Private::configSolidColorEntry(QLatin1String("Solid Color"));
113 const QString BorderSettings::Private::configNiepceBorderColorEntry(QLatin1String("Niepce Border Color"));
114 const QString BorderSettings::Private::configNiepceLineColorEntry(QLatin1String("Niepce Line Color"));
115 const QString BorderSettings::Private::configBevelUpperLeftColorEntry(QLatin1String("Bevel Upper Left Color"));
116 const QString BorderSettings::Private::configBevelLowerRightColorEntry(QLatin1String("Bevel Lower Right Color"));
117 const QString BorderSettings::Private::configDecorativeFirstColorEntry(QLatin1String("Decorative First Color"));
118 const QString BorderSettings::Private::configDecorativeSecondColorEntry(QLatin1String("Decorative Second Color"));
119
120 // --------------------------------------------------------
121
BorderSettings(QWidget * const parent)122 BorderSettings::BorderSettings(QWidget* const parent)
123 : QWidget(parent),
124 d (new Private)
125 {
126 const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
127
128 QGridLayout* const grid = new QGridLayout(parent);
129
130 QLabel* const label1 = new QLabel(i18n("Type:"));
131 d->borderType = new DComboBox();
132 d->borderType->addItem(i18nc("solid border type", "Solid"));
133
134 // NOTE: Niepce is a real name. This is the first guy in the world to have built a camera.
135
136 d->borderType->addItem(QLatin1String("Niepce"));
137
138 d->borderType->addItem(i18nc("beveled border type", "Beveled"));
139 d->borderType->addItem(i18n("Decorative Pine"));
140 d->borderType->addItem(i18n("Decorative Wood"));
141 d->borderType->addItem(i18n("Decorative Paper"));
142 d->borderType->addItem(i18n("Decorative Parquet"));
143 d->borderType->addItem(i18n("Decorative Ice"));
144 d->borderType->addItem(i18n("Decorative Leaf"));
145 d->borderType->addItem(i18n("Decorative Marble"));
146 d->borderType->addItem(i18n("Decorative Rain"));
147 d->borderType->addItem(i18n("Decorative Craters"));
148 d->borderType->addItem(i18n("Decorative Dried"));
149 d->borderType->addItem(i18n("Decorative Pink"));
150 d->borderType->addItem(i18n("Decorative Stone"));
151 d->borderType->addItem(i18n("Decorative Chalk"));
152 d->borderType->addItem(i18n("Decorative Granite"));
153 d->borderType->addItem(i18n("Decorative Rock"));
154 d->borderType->addItem(i18n("Decorative Wall"));
155 d->borderType->setDefaultIndex(BorderContainer::SolidBorder);
156 d->borderType->setWhatsThis(i18n("Select the border type to add around the image here."));
157
158 DLineWidget* const line1 = new DLineWidget(Qt::Horizontal);
159
160 // -------------------------------------------------------------------
161
162 d->preserveAspectRatio = new QCheckBox();
163 d->preserveAspectRatio->setText(i18n("Preserve Aspect Ratio"));
164 d->preserveAspectRatio->setWhatsThis(i18n("Enable this option if you want to preserve the aspect "
165 "ratio of image. If enabled, the border width will be "
166 "a percentage of the image size, else the border width will be "
167 "in pixels."));
168
169 d->labelBorderPercent = new QLabel(i18n("Width (%):"));
170 d->borderPercent = new DIntNumInput();
171 d->borderPercent->setRange(1, 50, 1);
172 d->borderPercent->setDefaultValue(10);
173 d->borderPercent->setWhatsThis(i18n("Set here the border width as a percentage of the image size."));
174
175 d->labelBorderWidth = new QLabel(i18n("Width (pixels):"));
176 d->borderWidth = new DIntNumInput();
177 d->borderWidth->setRange(1, 1000, 1);
178 d->borderWidth->setDefaultValue(100);
179 d->borderWidth->setWhatsThis(i18n("Set here the border width in pixels to add around the image."));
180
181 DLineWidget* const line2 = new DLineWidget(Qt::Horizontal);
182
183 // -------------------------------------------------------------------
184
185 d->labelForeground = new QLabel();
186 d->firstColorButton = new DColorSelector();
187 d->firstColorButton->setColor(QColor(192, 192, 192));
188 d->labelBackground = new QLabel();
189 d->secondColorButton = new DColorSelector();
190 d->secondColorButton->setColor(QColor(128, 128, 128));
191
192 // -------------------------------------------------------------------
193
194 grid->addWidget(label1, 0, 0, 1, 3);
195 grid->addWidget(d->borderType, 1, 0, 1, 3);
196 grid->addWidget(line1, 2, 0, 1, 3);
197 grid->addWidget(d->preserveAspectRatio, 3, 0, 1, 3);
198 grid->addWidget(d->labelBorderPercent, 4, 0, 1, 3);
199 grid->addWidget(d->borderPercent, 5, 0, 1, 3);
200 grid->addWidget(d->labelBorderWidth, 6, 0, 1, 3);
201 grid->addWidget(d->borderWidth, 7, 0, 1, 3);
202 grid->addWidget(line2, 8, 0, 1, 3);
203 grid->addWidget(d->labelForeground, 9, 0, 1, 1);
204 grid->addWidget(d->firstColorButton, 9, 1, 1, 2);
205 grid->addWidget(d->labelBackground, 10, 0, 1, 1);
206 grid->addWidget(d->secondColorButton, 10, 1, 1, 2);
207 grid->setRowStretch(11, 10);
208 grid->setContentsMargins(spacing, spacing, spacing, spacing);
209 grid->setSpacing(spacing);
210
211 // -------------------------------------------------------------
212
213 connect(d->preserveAspectRatio, SIGNAL(toggled(bool)),
214 this, SLOT(slotPreserveAspectRatioToggled(bool)));
215
216 connect(d->borderType, SIGNAL(activated(int)),
217 this, SLOT(slotBorderTypeChanged(int)));
218
219 connect(d->borderPercent, SIGNAL(valueChanged(int)),
220 this, SIGNAL(signalSettingsChanged()));
221
222 connect(d->borderWidth, SIGNAL(valueChanged(int)),
223 this, SIGNAL(signalSettingsChanged()));
224
225 connect(d->firstColorButton, SIGNAL(signalColorSelected(QColor)),
226 this, SLOT(slotColorForegroundChanged(QColor)));
227
228 connect(d->secondColorButton, SIGNAL(signalColorSelected(QColor)),
229 this, SLOT(slotColorBackgroundChanged(QColor)));
230 }
231
~BorderSettings()232 BorderSettings::~BorderSettings()
233 {
234 delete d;
235 }
236
settings() const237 BorderContainer BorderSettings::settings() const
238 {
239 BorderContainer prm;
240
241 prm.preserveAspectRatio = d->preserveAspectRatio->isChecked();
242 prm.borderType = d->borderType->currentIndex();
243 prm.borderWidth1 = d->borderWidth->value();
244 prm.borderWidth2 = 15;
245 prm.borderWidth3 = 15;
246 prm.borderWidth4 = 10;
247 prm.borderPercent = d->borderPercent->value() / 100.0;
248 prm.borderPath = BorderContainer::getBorderPath(d->borderType->currentIndex());
249 prm.solidColor = d->solidColor;
250 prm.niepceBorderColor = d->niepceBorderColor;
251 prm.niepceLineColor = d->niepceLineColor;
252 prm.bevelUpperLeftColor = d->bevelUpperLeftColor;
253 prm.bevelLowerRightColor = d->bevelLowerRightColor;
254 prm.decorativeFirstColor = d->decorativeFirstColor;
255 prm.decorativeSecondColor = d->decorativeSecondColor;
256
257 return prm;
258 }
259
setSettings(const BorderContainer & settings)260 void BorderSettings::setSettings(const BorderContainer& settings)
261 {
262 blockSignals(true);
263
264 d->preserveAspectRatio->setChecked(settings.preserveAspectRatio);
265 d->borderType->setCurrentIndex(settings.borderType);
266 d->borderWidth->setValue(settings.borderWidth1);
267 d->borderPercent->setValue((int)(settings.borderPercent * 100.0));
268
269 d->solidColor = settings.solidColor;
270 d->niepceBorderColor = settings.niepceBorderColor;
271 d->niepceLineColor = settings.niepceLineColor;
272 d->bevelUpperLeftColor = settings.bevelUpperLeftColor;
273 d->bevelLowerRightColor = settings.bevelLowerRightColor;
274 d->decorativeFirstColor = settings.decorativeFirstColor;
275 d->decorativeSecondColor = settings.decorativeSecondColor;
276
277 slotBorderTypeChanged(settings.borderType);
278
279 blockSignals(false);
280 }
281
resetToDefault()282 void BorderSettings::resetToDefault()
283 {
284 setSettings(defaultSettings());
285 }
286
defaultSettings() const287 BorderContainer BorderSettings::defaultSettings() const
288 {
289 BorderContainer prm;
290 return prm;
291 }
292
readSettings(KConfigGroup & group)293 void BorderSettings::readSettings(KConfigGroup& group)
294 {
295 blockSignals(true);
296
297 d->borderType->setCurrentIndex(group.readEntry(d->configBorderTypeEntry, d->borderType->defaultIndex()));
298 d->borderPercent->setValue(group.readEntry(d->configBorderPercentEntry, d->borderPercent->defaultValue()));
299 d->borderWidth->setValue(group.readEntry(d->configBorderWidthEntry, d->borderWidth->defaultValue()));
300 d->preserveAspectRatio->setChecked(group.readEntry(d->configPreserveAspectRatioEntry, true));
301
302 d->solidColor = group.readEntry(d->configSolidColorEntry, QColor(0, 0, 0));
303 d->niepceBorderColor = group.readEntry(d->configNiepceBorderColorEntry, QColor(255, 255, 255));
304 d->niepceLineColor = group.readEntry(d->configNiepceLineColorEntry, QColor(0, 0, 0));
305 d->bevelUpperLeftColor = group.readEntry(d->configBevelUpperLeftColorEntry, QColor(192, 192, 192));
306 d->bevelLowerRightColor = group.readEntry(d->configBevelLowerRightColorEntry, QColor(128, 128, 128));
307 d->decorativeFirstColor = group.readEntry(d->configDecorativeFirstColorEntry, QColor(0, 0, 0));
308 d->decorativeSecondColor = group.readEntry(d->configDecorativeSecondColorEntry, QColor(0, 0, 0));
309
310 blockSignals(false);
311 slotBorderTypeChanged(d->borderType->currentIndex());
312 }
313
writeSettings(KConfigGroup & group)314 void BorderSettings::writeSettings(KConfigGroup& group)
315 {
316 group.writeEntry(d->configBorderTypeEntry, d->borderType->currentIndex());
317 group.writeEntry(d->configBorderPercentEntry, d->borderPercent->value());
318 group.writeEntry(d->configBorderWidthEntry, d->borderWidth->value());
319 group.writeEntry(d->configPreserveAspectRatioEntry, d->preserveAspectRatio->isChecked());
320 group.writeEntry(d->configSolidColorEntry, d->solidColor);
321 group.writeEntry(d->configNiepceBorderColorEntry, d->niepceBorderColor);
322 group.writeEntry(d->configNiepceLineColorEntry, d->niepceLineColor);
323 group.writeEntry(d->configBevelUpperLeftColorEntry, d->bevelUpperLeftColor);
324 group.writeEntry(d->configBevelLowerRightColorEntry, d->bevelLowerRightColor);
325 group.writeEntry(d->configDecorativeFirstColorEntry, d->decorativeFirstColor);
326 group.writeEntry(d->configDecorativeSecondColorEntry, d->decorativeSecondColor);
327 }
328
slotColorForegroundChanged(const QColor & color)329 void BorderSettings::slotColorForegroundChanged(const QColor& color)
330 {
331 switch (d->borderType->currentIndex())
332 {
333 case BorderContainer::SolidBorder:
334 d->solidColor = color;
335 break;
336
337 case BorderContainer::NiepceBorder:
338 d->niepceBorderColor = color;
339 break;
340
341 case BorderContainer::BeveledBorder:
342 d->bevelUpperLeftColor = color;
343 break;
344
345 case BorderContainer::PineBorder:
346 case BorderContainer::WoodBorder:
347 case BorderContainer::PaperBorder:
348 case BorderContainer::ParqueBorder:
349 case BorderContainer::IceBorder:
350 case BorderContainer::LeafBorder:
351 case BorderContainer::MarbleBorder:
352 case BorderContainer::RainBorder:
353 case BorderContainer::CratersBorder:
354 case BorderContainer::DriedBorder:
355 case BorderContainer::PinkBorder:
356 case BorderContainer::StoneBorder:
357 case BorderContainer::ChalkBorder:
358 case BorderContainer::GraniteBorder:
359 case BorderContainer::RockBorder:
360 case BorderContainer::WallBorder:
361 d->decorativeFirstColor = color;
362 break;
363 }
364
365 emit signalSettingsChanged();
366 }
367
slotColorBackgroundChanged(const QColor & color)368 void BorderSettings::slotColorBackgroundChanged(const QColor& color)
369 {
370 switch (d->borderType->currentIndex())
371 {
372 case BorderContainer::SolidBorder:
373 d->solidColor = color;
374 break;
375
376 case BorderContainer::NiepceBorder:
377 d->niepceLineColor = color;
378 break;
379
380 case BorderContainer::BeveledBorder:
381 d->bevelLowerRightColor = color;
382 break;
383
384 case BorderContainer::PineBorder:
385 case BorderContainer::WoodBorder:
386 case BorderContainer::PaperBorder:
387 case BorderContainer::ParqueBorder:
388 case BorderContainer::IceBorder:
389 case BorderContainer::LeafBorder:
390 case BorderContainer::MarbleBorder:
391 case BorderContainer::RainBorder:
392 case BorderContainer::CratersBorder:
393 case BorderContainer::DriedBorder:
394 case BorderContainer::PinkBorder:
395 case BorderContainer::StoneBorder:
396 case BorderContainer::ChalkBorder:
397 case BorderContainer::GraniteBorder:
398 case BorderContainer::RockBorder:
399 case BorderContainer::WallBorder:
400 d->decorativeSecondColor = color;
401 break;
402 }
403
404 emit signalSettingsChanged();
405 }
406
slotBorderTypeChanged(int borderType)407 void BorderSettings::slotBorderTypeChanged(int borderType)
408 {
409 d->labelForeground->setText(i18nc("first color for border effect", "First:"));
410 d->labelBackground->setText(i18nc("second color for border effect", "Second:"));
411 d->firstColorButton->setWhatsThis(i18n("Set here the foreground color of the border."));
412 d->secondColorButton->setWhatsThis(i18n("Set here the Background color of the border."));
413 d->firstColorButton->setEnabled(true);
414 d->secondColorButton->setEnabled(true);
415 d->labelForeground->setEnabled(true);
416 d->labelBackground->setEnabled(true);
417 d->borderPercent->setEnabled(true);
418
419 switch (borderType)
420 {
421 case BorderContainer::SolidBorder:
422 d->firstColorButton->setColor(d->solidColor);
423 d->secondColorButton->setEnabled(false);
424 d->labelBackground->setEnabled(false);
425 break;
426
427 case BorderContainer::NiepceBorder:
428 d->firstColorButton->setWhatsThis(i18n("Set here the color of the main border."));
429 d->secondColorButton->setWhatsThis(i18n("Set here the color of the line."));
430 d->firstColorButton->setColor(d->niepceBorderColor);
431 d->secondColorButton->setColor(d->niepceLineColor);
432 break;
433
434 case BorderContainer::BeveledBorder:
435 d->firstColorButton->setWhatsThis(i18n("Set here the color of the upper left area."));
436 d->secondColorButton->setWhatsThis(i18n("Set here the color of the lower right area."));
437 d->firstColorButton->setColor(d->bevelUpperLeftColor);
438 d->secondColorButton->setColor(d->bevelLowerRightColor);
439 break;
440
441 case BorderContainer::PineBorder:
442 case BorderContainer::WoodBorder:
443 case BorderContainer::PaperBorder:
444 case BorderContainer::ParqueBorder:
445 case BorderContainer::IceBorder:
446 case BorderContainer::LeafBorder:
447 case BorderContainer::MarbleBorder:
448 case BorderContainer::RainBorder:
449 case BorderContainer::CratersBorder:
450 case BorderContainer::DriedBorder:
451 case BorderContainer::PinkBorder:
452 case BorderContainer::StoneBorder:
453 case BorderContainer::ChalkBorder:
454 case BorderContainer::GraniteBorder:
455 case BorderContainer::RockBorder:
456 case BorderContainer::WallBorder:
457 d->firstColorButton->setWhatsThis(i18n("Set here the color of the first line."));
458 d->secondColorButton->setWhatsThis(i18n("Set here the color of the second line."));
459 d->firstColorButton->setColor(d->decorativeFirstColor);
460 d->secondColorButton->setColor(d->decorativeSecondColor);
461 break;
462 }
463
464 emit signalSettingsChanged();
465 }
466
slotPreserveAspectRatioToggled(bool b)467 void BorderSettings::slotPreserveAspectRatioToggled(bool b)
468 {
469 toggleBorderSlider(b);
470 emit signalSettingsChanged();
471 }
472
toggleBorderSlider(bool b)473 void BorderSettings::toggleBorderSlider(bool b)
474 {
475 d->borderPercent->setEnabled(b);
476 d->borderWidth->setEnabled(!b);
477 d->labelBorderPercent->setEnabled(b);
478 d->labelBorderWidth->setEnabled(!b);
479 }
480
481 } // namespace Digikam
482