File indexing completed on 2025-01-19 03:59:14

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-08-21
0007  * Description : Editor tool settings template box
0008  *
0009  * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2008-2011 by Andi Clemens <andi dot clemens at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "editortoolsettings.h"
0017 
0018 // Qt includes
0019 
0020 #include <QButtonGroup>
0021 #include <QLabel>
0022 #include <QPixmap>
0023 #include <QLayout>
0024 #include <QMap>
0025 #include <QPair>
0026 #include <QString>
0027 #include <QToolButton>
0028 #include <QVariant>
0029 #include <QScrollBar>
0030 #include <QPushButton>
0031 #include <QApplication>
0032 #include <QScreen>
0033 #include <QWindow>
0034 #include <QStyle>
0035 
0036 // KDE includes
0037 
0038 #include <klocalizedstring.h>
0039 
0040 // Local includes
0041 
0042 #include "dlayoutbox.h"
0043 #include "dnuminput.h"
0044 #include "colorgradientwidget.h"
0045 #include "histogramwidget.h"
0046 #include "dcolorselector.h"
0047 #include "dpluginaboutdlg.h"
0048 #include "dplugineditor.h"
0049 #include "editortool.h"
0050 #include "dxmlguiwindow.h"
0051 
0052 namespace Digikam
0053 {
0054 
0055 class Q_DECL_HIDDEN EditorToolSettings::Private
0056 {
0057 
0058 public:
0059 
0060     explicit Private()
0061       : scaleBG         (nullptr),
0062         linHistoButton  (nullptr),
0063         logHistoButton  (nullptr),
0064         settingsArea    (nullptr),
0065         plainPage       (nullptr),
0066         toolName        (nullptr),
0067         toolIcon        (nullptr),
0068         toolHelp        (nullptr),
0069         toolAbout       (nullptr),
0070         guideBox        (nullptr),
0071         okBtn           (nullptr),
0072         cancelBtn       (nullptr),
0073         tryBtn          (nullptr),
0074         defaultBtn      (nullptr),
0075         saveAsBtn       (nullptr),
0076         loadBtn         (nullptr),
0077         guideColorBt    (nullptr),
0078         hGradient       (nullptr),
0079         histogramBox    (nullptr),
0080         guideSize       (nullptr),
0081         tool            (nullptr)
0082     {
0083     }
0084 
0085     QButtonGroup*        scaleBG;
0086 
0087     QToolButton*         linHistoButton;
0088     QToolButton*         logHistoButton;
0089 
0090     QWidget*             settingsArea;
0091     QWidget*             plainPage;
0092 
0093     QLabel*              toolName;
0094     QLabel*              toolIcon;
0095     QPushButton*         toolHelp;
0096     QPushButton*         toolAbout;
0097 
0098     DHBox*               guideBox;
0099 
0100     QPushButton*         okBtn;
0101     QPushButton*         cancelBtn;
0102     QPushButton*         tryBtn;
0103     QPushButton*         defaultBtn;
0104     QPushButton*         saveAsBtn;
0105     QPushButton*         loadBtn;
0106 
0107     DColorSelector*      guideColorBt;
0108 
0109     ColorGradientWidget* hGradient;
0110 
0111     HistogramBox*        histogramBox;
0112 
0113     DIntNumInput*        guideSize;
0114 
0115     EditorTool*          tool;
0116 };
0117 
0118 EditorToolSettings::EditorToolSettings(QWidget* const parent)
0119     : QScrollArea(parent),
0120       d          (new Private)
0121 {
0122     setFrameStyle(QFrame::NoFrame);
0123     setWidgetResizable(true);
0124 
0125     d->settingsArea                 = new QWidget;
0126 
0127     // ---------------------------------------------------------------
0128 
0129     QGridLayout* const gridSettings = new QGridLayout(d->settingsArea);
0130     d->plainPage                    = new QWidget;
0131     d->guideBox                     = new DHBox;
0132     d->histogramBox                 = new HistogramBox;
0133 
0134     // ---------------------------------------------------------------
0135 
0136     QFrame* const toolDescriptor    = new QFrame;
0137     d->toolName                     = new QLabel();
0138     d->toolIcon                     = new QLabel();
0139     QFont font                      = d->toolName->font();
0140     font.setBold(true);
0141     d->toolName->setFont(font);
0142 
0143     d->toolAbout                    = new QPushButton();
0144     d->toolAbout->setIcon(QIcon::fromTheme(QLatin1String("help-about")));
0145     d->toolAbout->setToolTip(i18n("About this tool..."));
0146 
0147     d->toolHelp                     = new QPushButton();
0148     d->toolHelp->setIcon(QIcon::fromTheme(QLatin1String("globe")));
0149     d->toolHelp->setToolTip(i18n("Tool online handbook..."));
0150 
0151     QString frameStyle = QString::fromLatin1("QFrame {"
0152                                              "color: %1;"
0153                                              "border: 1px solid %2;"
0154                                              "border-radius: 5px;"
0155                                              "background-color: %3;"
0156                                              "}")
0157                          .arg(QApplication::palette().color(QPalette::HighlightedText).name())
0158                          .arg(QApplication::palette().color(QPalette::HighlightedText).name())
0159                          .arg(QApplication::palette().color(QPalette::Highlight).name());
0160 
0161     QString noFrameStyle(QLatin1String("QFrame {"
0162                                        "border: none;"
0163                                        "}"));
0164 
0165     toolDescriptor->setStyleSheet(frameStyle);
0166     d->toolName->setStyleSheet(noFrameStyle);
0167     d->toolIcon->setStyleSheet(noFrameStyle);
0168     d->toolHelp->setStyleSheet(noFrameStyle);
0169     d->toolAbout->setStyleSheet(noFrameStyle);
0170 
0171     QGridLayout* const descrLayout = new QGridLayout();
0172     descrLayout->addWidget(d->toolIcon,  0, 0, 1, 1);
0173     descrLayout->addWidget(d->toolName,  0, 1, 1, 1);
0174     descrLayout->addWidget(d->toolHelp,  0, 2, 1, 1);
0175     descrLayout->addWidget(d->toolAbout, 0, 3, 1, 1);
0176     descrLayout->setColumnStretch(1, 10);
0177     toolDescriptor->setLayout(descrLayout);
0178 
0179     // ---------------------------------------------------------------
0180 
0181     new QLabel(i18n("Guide:"), d->guideBox);
0182     QLabel* const space4 = new QLabel(d->guideBox);
0183     d->guideColorBt      = new DColorSelector(d->guideBox);
0184     d->guideColorBt->setColor(QColor(Qt::red));
0185     d->guideColorBt->setWhatsThis(i18n("Set here the color used to draw dashed guide lines."));
0186     d->guideSize         = new DIntNumInput(d->guideBox);
0187     d->guideSize->setSuffix(QLatin1String("px"));
0188     d->guideSize->setRange(1, 5, 1);
0189     d->guideSize->setDefaultValue(1);
0190     d->guideSize->setWhatsThis(i18n("Set here the width in pixels used to draw dashed guide lines."));
0191 
0192     d->guideBox->setStretchFactor(space4, 10);
0193     d->guideBox->setContentsMargins(QMargins());
0194     d->guideBox->setSpacing(spacingHint());
0195 
0196     // ---------------------------------------------------------------
0197 
0198     d->defaultBtn = new QPushButton(i18n("Defaults"));
0199     d->defaultBtn->setIcon(QIcon::fromTheme(QLatin1String("document-revert")));
0200     d->defaultBtn->setToolTip(i18n("Reset all settings to their default values."));
0201 
0202     d->okBtn = new QPushButton(i18n("OK"));
0203     d->okBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-ok-apply")));
0204     d->okBtn->setDefault(true);
0205 
0206     d->cancelBtn = new QPushButton(i18n("Cancel"));
0207     d->cancelBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel")));
0208 
0209     QHBoxLayout* const hbox1 = new QHBoxLayout;
0210     hbox1->addWidget(d->defaultBtn);
0211     hbox1->addStretch(1);
0212     hbox1->addWidget(d->okBtn);
0213     hbox1->addWidget(d->cancelBtn);
0214 
0215     // ---------------------------------------------------------------
0216 
0217     d->loadBtn = new QPushButton(i18nc("@action: load previously saved filter settings", "Load..."));
0218     d->loadBtn->setIcon(QIcon::fromTheme(QLatin1String("document-open")));
0219     d->loadBtn->setToolTip(i18n("Load all parameters from settings text file."));
0220 
0221     d->saveAsBtn = new QPushButton(i18nc("@action: save current filter settings", "Save As..."));
0222     d->saveAsBtn->setIcon(QIcon::fromTheme(QLatin1String("document-save-as")));
0223     d->saveAsBtn->setToolTip(i18n("Save all parameters to settings text file."));
0224 
0225     d->tryBtn = new QPushButton(i18nc("@action: try current filter settings", "Try"));
0226     d->tryBtn->setIcon(QIcon::fromTheme(QLatin1String("dialog-ok-apply")));
0227     d->tryBtn->setToolTip(i18n("Try all settings."));
0228 
0229     QHBoxLayout* const hbox2 = new QHBoxLayout;
0230     hbox2->addWidget(d->loadBtn);
0231     hbox2->addWidget(d->saveAsBtn);
0232     hbox2->addStretch(1);
0233     hbox2->addWidget(d->tryBtn);
0234 
0235     // ---------------------------------------------------------------
0236 
0237     const int spacing = spacingHint();
0238 
0239     gridSettings->addWidget(toolDescriptor,  0, 0, 1, -1);
0240     gridSettings->addWidget(d->histogramBox, 1, 0, 2, 2);
0241     gridSettings->addWidget(d->plainPage,    4, 0, 1, 2);
0242     gridSettings->addWidget(d->guideBox,     5, 0, 1, 2);
0243     gridSettings->addLayout(hbox2,           6, 0, 1, 2);
0244     gridSettings->addLayout(hbox1,           7, 0, 1, 2);
0245     gridSettings->setContentsMargins(spacing, spacing, spacing, spacing);
0246     gridSettings->setSpacing(spacing);
0247 
0248     // ---------------------------------------------------------------
0249 
0250     setWidget(d->settingsArea);
0251 
0252     // ---------------------------------------------------------------
0253 
0254     connect(d->okBtn, SIGNAL(clicked()),
0255             this, SIGNAL(signalOkClicked()));
0256 
0257     connect(d->cancelBtn, SIGNAL(clicked()),
0258             this, SIGNAL(signalCancelClicked()));
0259 
0260     connect(d->tryBtn, SIGNAL(clicked()),
0261             this, SIGNAL(signalTryClicked()));
0262 
0263     connect(d->defaultBtn, SIGNAL(clicked()),
0264             this, SIGNAL(signalDefaultClicked()));
0265 
0266     connect(d->saveAsBtn, SIGNAL(clicked()),
0267             this, SIGNAL(signalSaveAsClicked()));
0268 
0269     connect(d->loadBtn, SIGNAL(clicked()),
0270             this, SIGNAL(signalLoadClicked()));
0271 
0272     connect(d->guideColorBt, SIGNAL(signalColorSelected(QColor)),
0273             this, SIGNAL(signalColorGuideChanged()));
0274 
0275     connect(d->guideSize, SIGNAL(valueChanged(int)),
0276             this, SIGNAL(signalColorGuideChanged()));
0277 
0278     connect(d->histogramBox, SIGNAL(signalChannelChanged(ChannelType)),
0279             this, SIGNAL(signalChannelChanged()));
0280 
0281     connect(d->histogramBox, SIGNAL(signalScaleChanged(HistogramScale)),
0282             this, SIGNAL(signalScaleChanged()));
0283 
0284     connect(d->toolAbout, SIGNAL(clicked()),
0285             this, SLOT(slotAboutPlugin()));
0286 
0287     connect(d->toolHelp, SIGNAL(clicked()),
0288             this, SLOT(slotHelpPlugin()));
0289 
0290     // --------------------------------------------------------
0291 
0292     setTabOrder(d->tryBtn,     d->okBtn);
0293     setTabOrder(d->okBtn,      d->cancelBtn);
0294     setTabOrder(d->cancelBtn,  d->defaultBtn);
0295     setTabOrder(d->defaultBtn, d->loadBtn);
0296     setTabOrder(d->loadBtn,    d->saveAsBtn);
0297 
0298     // ---------------------------------------------------------------
0299 
0300     setButtons(Default | Ok | Cancel);
0301     setTools(NoTool);
0302 }
0303 
0304 EditorToolSettings::~EditorToolSettings()
0305 {
0306     delete d;
0307 }
0308 
0309 QSize EditorToolSettings::minimumSizeHint() const
0310 {
0311     // Editor Tools usually require a larger horizontal space than other widgets in right side bar
0312     // Set scroll area to a horizontal minimum size sufficient for the settings.
0313     // Do not touch vertical size hint.
0314     // Limit to 40% of the desktop width.
0315 
0316     QScreen* screen = qApp->primaryScreen();
0317 
0318     if (QWidget* const widget = d->settingsArea->nativeParentWidget())
0319     {
0320         if (QWindow* const window = widget->windowHandle())
0321         {
0322             screen = window->screen();
0323         }
0324     }
0325 
0326     QRect desktopRect = screen->geometry();
0327     QSize hint        = QScrollArea::minimumSizeHint();
0328     int wSB           = verticalScrollBar()->sizeHint().width();
0329     hint.setWidth(qMin(d->settingsArea->sizeHint().width() + wSB, desktopRect.width() * 2 / 5));
0330 
0331     return hint;
0332 }
0333 
0334 int EditorToolSettings::marginHint()
0335 {
0336     const int cmargin = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
0337                                 qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutTopMargin),
0338                                     qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin),
0339                                          QApplication::style()->pixelMetric(QStyle::PM_LayoutBottomMargin))));
0340     return cmargin;
0341 }
0342 
0343 int EditorToolSettings::spacingHint()
0344 {
0345     return qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0346                 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0347 }
0348 
0349 QWidget* EditorToolSettings::plainPage() const
0350 {
0351     return d->plainPage;
0352 }
0353 
0354 HistogramBox* EditorToolSettings::histogramBox() const
0355 {
0356     return d->histogramBox;
0357 }
0358 
0359 QPushButton* EditorToolSettings::button(int buttonCode) const
0360 {
0361     if (buttonCode & Default)
0362     {
0363         return d->defaultBtn;
0364     }
0365 
0366     if (buttonCode & Try)
0367     {
0368         return d->tryBtn;
0369     }
0370 
0371     if (buttonCode & Ok)
0372     {
0373         return d->okBtn;
0374     }
0375 
0376     if (buttonCode & Cancel)
0377     {
0378         return d->cancelBtn;
0379     }
0380 
0381     if (buttonCode & Load)
0382     {
0383         return d->loadBtn;
0384     }
0385 
0386     if (buttonCode & SaveAs)
0387     {
0388         return d->saveAsBtn;
0389     }
0390 
0391     return nullptr;
0392 }
0393 
0394 void EditorToolSettings::enableButton(int buttonCode, bool state)
0395 {
0396     QPushButton* const btn = button(buttonCode);
0397 
0398     if (btn)
0399     {
0400         btn->setEnabled(state);
0401     }
0402 }
0403 
0404 QColor EditorToolSettings::guideColor() const
0405 {
0406     return d->guideColorBt->color();
0407 }
0408 
0409 void EditorToolSettings::setGuideColor(const QColor& color)
0410 {
0411     d->guideColorBt->setColor(color);
0412 }
0413 
0414 int EditorToolSettings::guideSize() const
0415 {
0416     return d->guideSize->value();
0417 }
0418 
0419 void EditorToolSettings::setGuideSize(int size)
0420 {
0421     d->guideSize->setValue(size);
0422 }
0423 
0424 void EditorToolSettings::setButtons(Buttons buttonMask)
0425 {
0426     d->okBtn->setVisible(buttonMask & Ok);
0427     d->cancelBtn->setVisible(buttonMask & Cancel);
0428     d->defaultBtn->setVisible(buttonMask & Default);
0429 
0430     d->loadBtn->setVisible(buttonMask & Load);
0431     d->saveAsBtn->setVisible(buttonMask & SaveAs);
0432     d->tryBtn->setVisible(buttonMask & Try);
0433 }
0434 
0435 void EditorToolSettings::setTools(Tools toolMask)
0436 {
0437     d->histogramBox->setVisible(toolMask & Histogram);
0438     d->guideBox->setVisible(toolMask & ColorGuide);
0439 }
0440 
0441 void EditorToolSettings::setHistogramType(HistogramBoxType type)
0442 {
0443     d->histogramBox->setHistogramType(type);
0444 }
0445 
0446 void EditorToolSettings::setTool(EditorTool* const tool)
0447 {
0448     d->tool = tool;
0449     d->toolName->setText(d->tool->toolName());
0450     d->toolIcon->setPixmap(d->tool->toolIcon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)));
0451 }
0452 
0453 void EditorToolSettings::slotAboutPlugin()
0454 {
0455     if (d->tool)
0456     {
0457         if (d->tool->plugin())
0458         {
0459             QPointer<DPluginAboutDlg> dlg = new DPluginAboutDlg(d->tool->plugin());
0460             dlg->exec();
0461             delete dlg;
0462         }
0463     }
0464 }
0465 
0466 void EditorToolSettings::slotHelpPlugin()
0467 {
0468     if (d->tool)
0469     {
0470         if (d->tool->plugin())
0471         {
0472             openOnlineDocumentation(d->tool->plugin()->handbookSection(),
0473                                         d->tool->plugin()->handbookChapter(),
0474                                         d->tool->plugin()->handbookReference());
0475         }
0476     }
0477 }
0478 
0479 } // namespace Digikam
0480 
0481 #include "moc_editortoolsettings.cpp"