1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2008-08-21
7 * Description : Editor tool settings template box
8 *
9 * Copyright (C) 2008-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 * Copyright (C) 2008-2011 by Andi Clemens <andi dot clemens 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) 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 "editortoolsettings.h"
25
26 // Qt includes
27
28 #include <QButtonGroup>
29 #include <QLabel>
30 #include <QPixmap>
31 #include <QLayout>
32 #include <QMap>
33 #include <QPair>
34 #include <QString>
35 #include <QToolButton>
36 #include <QVariant>
37 #include <QScrollBar>
38 #include <QPushButton>
39 #include <QApplication>
40 #include <QScreen>
41 #include <QWindow>
42 #include <QStyle>
43
44 // KDE includes
45
46 #include <klocalizedstring.h>
47
48 // Local includes
49
50 #include "dlayoutbox.h"
51 #include "dnuminput.h"
52 #include "colorgradientwidget.h"
53 #include "histogramwidget.h"
54 #include "histogrambox.h"
55 #include "digikam_globals.h"
56 #include "dcolorselector.h"
57 #include "dpluginaboutdlg.h"
58 #include "dplugineditor.h"
59 #include "editortool.h"
60
61 namespace Digikam
62 {
63
64 class Q_DECL_HIDDEN EditorToolSettings::Private
65 {
66
67 public:
68
Private()69 explicit Private()
70 : scaleBG (nullptr),
71 linHistoButton (nullptr),
72 logHistoButton (nullptr),
73 settingsArea (nullptr),
74 plainPage (nullptr),
75 toolName (nullptr),
76 toolIcon (nullptr),
77 toolAbout (nullptr),
78 guideBox (nullptr),
79 okBtn (nullptr),
80 cancelBtn (nullptr),
81 tryBtn (nullptr),
82 defaultBtn (nullptr),
83 saveAsBtn (nullptr),
84 loadBtn (nullptr),
85 guideColorBt (nullptr),
86 hGradient (nullptr),
87 histogramBox (nullptr),
88 guideSize (nullptr),
89 tool (nullptr)
90 {
91 }
92
93 QButtonGroup* scaleBG;
94
95 QToolButton* linHistoButton;
96 QToolButton* logHistoButton;
97
98 QWidget* settingsArea;
99 QWidget* plainPage;
100
101 QLabel* toolName;
102 QLabel* toolIcon;
103 QPushButton* toolAbout;
104
105 DHBox* guideBox;
106
107 QPushButton* okBtn;
108 QPushButton* cancelBtn;
109 QPushButton* tryBtn;
110 QPushButton* defaultBtn;
111 QPushButton* saveAsBtn;
112 QPushButton* loadBtn;
113
114 DColorSelector* guideColorBt;
115
116 ColorGradientWidget* hGradient;
117
118 HistogramBox* histogramBox;
119
120 DIntNumInput* guideSize;
121
122 EditorTool* tool;
123 };
124
EditorToolSettings(QWidget * const parent)125 EditorToolSettings::EditorToolSettings(QWidget* const parent)
126 : QScrollArea(parent),
127 d (new Private)
128 {
129 setFrameStyle(QFrame::NoFrame);
130 setWidgetResizable(true);
131
132 d->settingsArea = new QWidget;
133
134 // ---------------------------------------------------------------
135
136 QGridLayout* const gridSettings = new QGridLayout(d->settingsArea);
137 d->plainPage = new QWidget;
138 d->guideBox = new DHBox;
139 d->histogramBox = new HistogramBox;
140
141 // ---------------------------------------------------------------
142
143 QFrame* const toolDescriptor = new QFrame;
144 d->toolName = new QLabel();
145 d->toolIcon = new QLabel();
146 QFont font = d->toolName->font();
147 font.setBold(true);
148 d->toolName->setFont(font);
149
150 d->toolAbout = new QPushButton();
151 d->toolAbout->setIcon(QIcon::fromTheme(QLatin1String("help-about")));
152 d->toolAbout->setToolTip(i18n("About this tool..."));
153
154 QString frameStyle = QString::fromLatin1("QFrame {"
155 "color: %1;"
156 "border: 1px solid %2;"
157 "border-radius: 5px;"
158 "background-color: %3;"
159 "}")
160 .arg(QApplication::palette().color(QPalette::HighlightedText).name())
161 .arg(QApplication::palette().color(QPalette::HighlightedText).name())
162 .arg(QApplication::palette().color(QPalette::Highlight).name());
163
164 QString noFrameStyle(QLatin1String("QFrame {"
165 "border: none;"
166 "}"));
167
168 toolDescriptor->setStyleSheet(frameStyle);
169 d->toolName->setStyleSheet(noFrameStyle);
170 d->toolIcon->setStyleSheet(noFrameStyle);
171 d->toolAbout->setStyleSheet(noFrameStyle);
172
173 QGridLayout* const descrLayout = new QGridLayout();
174 descrLayout->addWidget(d->toolIcon, 0, 0, 1, 1);
175 descrLayout->addWidget(d->toolName, 0, 1, 1, 1);
176 descrLayout->addWidget(d->toolAbout, 0, 2, 1, 1);
177 descrLayout->setColumnStretch(1, 10);
178 toolDescriptor->setLayout(descrLayout);
179
180 // ---------------------------------------------------------------
181
182 new QLabel(i18n("Guide:"), d->guideBox);
183 QLabel* const space4 = new QLabel(d->guideBox);
184 d->guideColorBt = new DColorSelector(d->guideBox);
185 d->guideColorBt->setColor(QColor(Qt::red));
186 d->guideColorBt->setWhatsThis(i18n("Set here the color used to draw dashed guide lines."));
187 d->guideSize = new DIntNumInput(d->guideBox);
188 d->guideSize->setSuffix(QLatin1String("px"));
189 d->guideSize->setRange(1, 5, 1);
190 d->guideSize->setDefaultValue(1);
191 d->guideSize->setWhatsThis(i18n("Set here the width in pixels used to draw dashed guide lines."));
192
193 d->guideBox->setStretchFactor(space4, 10);
194 d->guideBox->setContentsMargins(QMargins());
195 d->guideBox->setSpacing(spacingHint());
196
197 // ---------------------------------------------------------------
198
199 d->defaultBtn = new QPushButton(i18n("Defaults"));
200 d->defaultBtn->setIcon(QIcon::fromTheme(QLatin1String("document-revert")));
201 d->defaultBtn->setToolTip(i18n("Reset all settings to their default values."));
202
203 d->okBtn = new QPushButton(i18n("OK"));
204 d->okBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-ok-apply")));
205 d->okBtn->setDefault(true);
206
207 d->cancelBtn = new QPushButton(i18n("Cancel"));
208 d->cancelBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel")));
209
210 QHBoxLayout* const hbox1 = new QHBoxLayout;
211 hbox1->addWidget(d->defaultBtn);
212 hbox1->addStretch(1);
213 hbox1->addWidget(d->okBtn);
214 hbox1->addWidget(d->cancelBtn);
215
216 // ---------------------------------------------------------------
217
218 d->loadBtn = new QPushButton(i18nc("@action: load previously saved filter settings", "Load..."));
219 d->loadBtn->setIcon(QIcon::fromTheme(QLatin1String("document-open")));
220 d->loadBtn->setToolTip(i18n("Load all parameters from settings text file."));
221
222 d->saveAsBtn = new QPushButton(i18nc("@action: save current filter settings", "Save As..."));
223 d->saveAsBtn->setIcon(QIcon::fromTheme(QLatin1String("document-save-as")));
224 d->saveAsBtn->setToolTip(i18n("Save all parameters to settings text file."));
225
226 d->tryBtn = new QPushButton(i18nc("@action: try current filter settings", "Try"));
227 d->tryBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-ok-apply")));
228 d->tryBtn->setToolTip(i18n("Try all settings."));
229
230 QHBoxLayout* const hbox2 = new QHBoxLayout;
231 hbox2->addWidget(d->loadBtn);
232 hbox2->addWidget(d->saveAsBtn);
233 hbox2->addStretch(1);
234 hbox2->addWidget(d->tryBtn);
235
236 // ---------------------------------------------------------------
237
238 const int spacing = spacingHint();
239
240 gridSettings->addWidget(toolDescriptor, 0, 0, 1, -1);
241 gridSettings->addWidget(d->histogramBox, 1, 0, 2, 2);
242 gridSettings->addWidget(d->plainPage, 4, 0, 1, 2);
243 gridSettings->addWidget(d->guideBox, 5, 0, 1, 2);
244 gridSettings->addLayout(hbox2, 6, 0, 1, 2);
245 gridSettings->addLayout(hbox1, 7, 0, 1, 2);
246 gridSettings->setContentsMargins(spacing, spacing, spacing, spacing);
247 gridSettings->setSpacing(spacing);
248
249 // ---------------------------------------------------------------
250
251 setWidget(d->settingsArea);
252
253 // ---------------------------------------------------------------
254
255 connect(d->okBtn, SIGNAL(clicked()),
256 this, SIGNAL(signalOkClicked()));
257
258 connect(d->cancelBtn, SIGNAL(clicked()),
259 this, SIGNAL(signalCancelClicked()));
260
261 connect(d->tryBtn, SIGNAL(clicked()),
262 this, SIGNAL(signalTryClicked()));
263
264 connect(d->defaultBtn, SIGNAL(clicked()),
265 this, SIGNAL(signalDefaultClicked()));
266
267 connect(d->saveAsBtn, SIGNAL(clicked()),
268 this, SIGNAL(signalSaveAsClicked()));
269
270 connect(d->loadBtn, SIGNAL(clicked()),
271 this, SIGNAL(signalLoadClicked()));
272
273 connect(d->guideColorBt, SIGNAL(signalColorSelected(QColor)),
274 this, SIGNAL(signalColorGuideChanged()));
275
276 connect(d->guideSize, SIGNAL(valueChanged(int)),
277 this, SIGNAL(signalColorGuideChanged()));
278
279 connect(d->histogramBox, SIGNAL(signalChannelChanged(ChannelType)),
280 this, SIGNAL(signalChannelChanged()));
281
282 connect(d->histogramBox, SIGNAL(signalScaleChanged(HistogramScale)),
283 this, SIGNAL(signalScaleChanged()));
284
285 connect(d->toolAbout, SIGNAL(clicked()),
286 this, SLOT(slotAboutPlugin()));
287
288 // --------------------------------------------------------
289
290 setTabOrder(d->tryBtn, d->okBtn);
291 setTabOrder(d->okBtn, d->cancelBtn);
292 setTabOrder(d->cancelBtn, d->defaultBtn);
293 setTabOrder(d->defaultBtn, d->loadBtn);
294 setTabOrder(d->loadBtn, d->saveAsBtn);
295
296 // ---------------------------------------------------------------
297
298 setButtons(Default | Ok | Cancel);
299 setTools(NoTool);
300 }
301
~EditorToolSettings()302 EditorToolSettings::~EditorToolSettings()
303 {
304 delete d;
305 }
306
minimumSizeHint() const307 QSize EditorToolSettings::minimumSizeHint() const
308 {
309 // Editor Tools usually require a larger horizontal space than other widgets in right side bar
310 // Set scroll area to a horizontal minimum size sufficient for the settings.
311 // Do not touch vertical size hint.
312 // Limit to 40% of the desktop width.
313
314 QScreen* screen = qApp->primaryScreen();
315
316 if (QWidget* const widget = d->settingsArea->nativeParentWidget())
317 {
318 if (QWindow* const window = widget->windowHandle())
319 {
320 screen = window->screen();
321 }
322 }
323
324 QRect desktopRect = screen->geometry();
325 QSize hint = QScrollArea::minimumSizeHint();
326 int wSB = verticalScrollBar()->sizeHint().width();
327 hint.setWidth(qMin(d->settingsArea->sizeHint().width() + wSB, desktopRect.width() * 2 / 5));
328
329 return hint;
330 }
331
marginHint()332 int EditorToolSettings::marginHint()
333 {
334 return QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin);
335 }
336
spacingHint()337 int EditorToolSettings::spacingHint()
338 {
339 return QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
340 }
341
plainPage() const342 QWidget* EditorToolSettings::plainPage() const
343 {
344 return d->plainPage;
345 }
346
histogramBox() const347 HistogramBox* EditorToolSettings::histogramBox() const
348 {
349 return d->histogramBox;
350 }
351
button(int buttonCode) const352 QPushButton* EditorToolSettings::button(int buttonCode) const
353 {
354 if (buttonCode & Default)
355 {
356 return d->defaultBtn;
357 }
358
359 if (buttonCode & Try)
360 {
361 return d->tryBtn;
362 }
363
364 if (buttonCode & Ok)
365 {
366 return d->okBtn;
367 }
368
369 if (buttonCode & Cancel)
370 {
371 return d->cancelBtn;
372 }
373
374 if (buttonCode & Load)
375 {
376 return d->loadBtn;
377 }
378
379 if (buttonCode & SaveAs)
380 {
381 return d->saveAsBtn;
382 }
383
384 return nullptr;
385 }
386
enableButton(int buttonCode,bool state)387 void EditorToolSettings::enableButton(int buttonCode, bool state)
388 {
389 QPushButton* const btn = button(buttonCode);
390
391 if (btn)
392 {
393 btn->setEnabled(state);
394 }
395 }
396
guideColor() const397 QColor EditorToolSettings::guideColor() const
398 {
399 return d->guideColorBt->color();
400 }
401
setGuideColor(const QColor & color)402 void EditorToolSettings::setGuideColor(const QColor& color)
403 {
404 d->guideColorBt->setColor(color);
405 }
406
guideSize() const407 int EditorToolSettings::guideSize() const
408 {
409 return d->guideSize->value();
410 }
411
setGuideSize(int size)412 void EditorToolSettings::setGuideSize(int size)
413 {
414 d->guideSize->setValue(size);
415 }
416
setButtons(Buttons buttonMask)417 void EditorToolSettings::setButtons(Buttons buttonMask)
418 {
419 d->okBtn->setVisible(buttonMask & Ok);
420 d->cancelBtn->setVisible(buttonMask & Cancel);
421 d->defaultBtn->setVisible(buttonMask & Default);
422
423 d->loadBtn->setVisible(buttonMask & Load);
424 d->saveAsBtn->setVisible(buttonMask & SaveAs);
425 d->tryBtn->setVisible(buttonMask & Try);
426 }
427
setTools(Tools toolMask)428 void EditorToolSettings::setTools(Tools toolMask)
429 {
430 d->histogramBox->setVisible(toolMask & Histogram);
431 d->guideBox->setVisible(toolMask & ColorGuide);
432 }
433
setHistogramType(HistogramBoxType type)434 void EditorToolSettings::setHistogramType(HistogramBoxType type)
435 {
436 d->histogramBox->setHistogramType(type);
437 }
438
setTool(EditorTool * const tool)439 void EditorToolSettings::setTool(EditorTool* const tool)
440 {
441 d->tool = tool;
442 d->toolName->setText(d->tool->toolName());
443 d->toolIcon->setPixmap(d->tool->toolIcon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)));
444 }
445
slotAboutPlugin()446 void EditorToolSettings::slotAboutPlugin()
447 {
448 if (d->tool)
449 {
450 if (d->tool->plugin())
451 {
452 DPlugin* const p = dynamic_cast<DPlugin*>(d->tool->plugin());
453
454 if (p)
455 {
456 QPointer<DPluginAboutDlg> dlg = new DPluginAboutDlg(p);
457 dlg->exec();
458 delete dlg;
459 }
460 }
461 }
462 }
463
464 } // namespace Digikam
465