File indexing completed on 2025-03-09 03:59:01
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-08-03 0007 * Description : setup Image Editor interface. 0008 * 0009 * SPDX-FileCopyrightText: 2004-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "setupeditoriface.h" 0016 0017 // Qt includes 0018 0019 #include <QCheckBox> 0020 #include <QColor> 0021 #include <QGroupBox> 0022 #include <QLabel> 0023 #include <QVBoxLayout> 0024 #include <QPainter> 0025 #include <QApplication> 0026 #include <QStyle> 0027 #include <QStandardPaths> 0028 0029 // KDE includes 0030 0031 #include <kconfiggroup.h> 0032 #include <ksharedconfig.h> 0033 #include <klocalizedstring.h> 0034 0035 // Local includes 0036 0037 #include "dlayoutbox.h" 0038 #include "dnuminput.h" 0039 #include "dimg.h" 0040 #include "histogramwidget.h" 0041 #include "exposurecontainer.h" 0042 #include "fullscreensettings.h" 0043 #include "dxmlguiwindow.h" 0044 #include "dcolorselector.h" 0045 0046 namespace Digikam 0047 { 0048 0049 class Q_DECL_HIDDEN SetupEditorIface::Private 0050 { 0051 public: 0052 0053 explicit Private() 0054 : themebackgroundColor(nullptr), 0055 expoIndicatorMode (nullptr), 0056 restoreSettings (nullptr), 0057 expoPreview (nullptr), 0058 colorBox (nullptr), 0059 backgroundColor (nullptr), 0060 underExposureColor (nullptr), 0061 overExposureColor (nullptr), 0062 expoPreviewHisto (nullptr), 0063 fullScreenSettings (nullptr), 0064 underExposurePcents (nullptr), 0065 overExposurePcents (nullptr) 0066 { 0067 } 0068 0069 static const QString configGroupName; 0070 static const QString configUseThemeBackgroundColorEntry; 0071 static const QString configBackgroundColorEntry; 0072 static const QString configUnderExposureColorEntry; 0073 static const QString configOverExposureColorEntry; 0074 static const QString configUnderExposurePercentsEntry; 0075 static const QString configOverExposurePercentsEntry; 0076 static const QString configExpoIndicatorModeEntry; 0077 static const QString configRestoreSettingsEntry; 0078 0079 QCheckBox* themebackgroundColor; 0080 QCheckBox* expoIndicatorMode; 0081 QCheckBox* restoreSettings; 0082 0083 QLabel* expoPreview; 0084 0085 DHBox* colorBox; 0086 DColorSelector* backgroundColor; 0087 DColorSelector* underExposureColor; 0088 DColorSelector* overExposureColor; 0089 0090 HistogramWidget* expoPreviewHisto; 0091 0092 FullScreenSettings* fullScreenSettings; 0093 0094 DImg preview; 0095 0096 DDoubleNumInput* underExposurePcents; 0097 DDoubleNumInput* overExposurePcents; 0098 }; 0099 0100 const QString SetupEditorIface::Private::configGroupName(QLatin1String("ImageViewer Settings")); 0101 const QString SetupEditorIface::Private::configUseThemeBackgroundColorEntry(QLatin1String("UseThemeBackgroundColor")); 0102 const QString SetupEditorIface::Private::configBackgroundColorEntry(QLatin1String("BackgroundColor")); 0103 const QString SetupEditorIface::Private::configUnderExposureColorEntry(QLatin1String("UnderExposureColor")); 0104 const QString SetupEditorIface::Private::configOverExposureColorEntry(QLatin1String("OverExposureColor")); 0105 const QString SetupEditorIface::Private::configUnderExposurePercentsEntry(QLatin1String("UnderExposurePercentsEntry")); 0106 const QString SetupEditorIface::Private::configOverExposurePercentsEntry(QLatin1String("OverExposurePercentsEntry")); 0107 const QString SetupEditorIface::Private::configExpoIndicatorModeEntry(QLatin1String("ExpoIndicatorMode")); 0108 const QString SetupEditorIface::Private::configRestoreSettingsEntry(QLatin1String("RestoreToolSettings")); 0109 0110 // -------------------------------------------------------- 0111 0112 SetupEditorIface::SetupEditorIface(QWidget* const parent) 0113 : QScrollArea(parent), 0114 d (new Private) 0115 { 0116 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0117 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0118 QWidget* const panel = new QWidget(viewport()); 0119 setWidget(panel); 0120 setWidgetResizable(true); 0121 0122 QVBoxLayout* const layout = new QVBoxLayout(panel); 0123 0124 // -------------------------------------------------------- 0125 0126 QGroupBox* const interfaceOptionsGroup = new QGroupBox(i18n("Interface Options"), panel); 0127 QVBoxLayout* const gLayout1 = new QVBoxLayout(interfaceOptionsGroup); 0128 0129 d->themebackgroundColor = new QCheckBox(i18n("&Use theme background color"), 0130 interfaceOptionsGroup); 0131 0132 d->themebackgroundColor->setWhatsThis(i18n("Enable this option to use the background theme " 0133 "color in the image editor area.")); 0134 0135 d->colorBox = new DHBox(interfaceOptionsGroup); 0136 QLabel* const backgroundColorlabel = new QLabel(i18n("&Background color:"), d->colorBox); 0137 d->backgroundColor = new DColorSelector(d->colorBox); 0138 backgroundColorlabel->setBuddy(d->backgroundColor); 0139 d->backgroundColor->setWhatsThis(i18n("Customize the background color to use " 0140 "in the image editor area.")); 0141 0142 gLayout1->addWidget(d->themebackgroundColor); 0143 gLayout1->addWidget(d->colorBox); 0144 gLayout1->setContentsMargins(spacing, spacing, spacing, spacing); 0145 gLayout1->setSpacing(spacing); 0146 0147 // -------------------------------------------------------- 0148 0149 d->fullScreenSettings = new FullScreenSettings(FS_EDITOR, panel); 0150 0151 // -------------------------------------------------------- 0152 0153 QGroupBox* const exposureOptionsGroup = new QGroupBox(i18n("Exposure Indicators"), panel); 0154 QGridLayout* const gLayout2 = new QGridLayout(exposureOptionsGroup); 0155 0156 QLabel* const underExpoColorlabel = new QLabel(i18n("&Under-exposure color: "), exposureOptionsGroup); 0157 d->underExposureColor = new DColorSelector(exposureOptionsGroup); 0158 underExpoColorlabel->setBuddy(d->underExposureColor); 0159 d->underExposureColor->setWhatsThis(i18n("Customize color used in image editor to identify " 0160 "under-exposed pixels.")); 0161 0162 QLabel* const underExpoPcentlabel = new QLabel(i18n("Under-exposure percents: "), exposureOptionsGroup); 0163 d->underExposurePcents = new DDoubleNumInput(exposureOptionsGroup); 0164 d->underExposurePcents->setDecimals(1); 0165 d->underExposurePcents->setRange(0.1, 5.0, 0.1); 0166 d->underExposurePcents->setDefaultValue(1.0); 0167 underExpoPcentlabel->setBuddy(d->underExposurePcents); 0168 d->underExposurePcents->setWhatsThis(i18n("Adjust the percents of the bottom of image histogram " 0169 "which will be used to check under exposed pixels.")); 0170 0171 QLabel* const overExpoColorlabel = new QLabel(i18n("&Over-exposure color: "), exposureOptionsGroup); 0172 d->overExposureColor = new DColorSelector(exposureOptionsGroup); 0173 overExpoColorlabel->setBuddy(d->overExposureColor); 0174 d->overExposureColor->setWhatsThis(i18n("Customize color used in image editor to identify " 0175 "over-exposed pixels.")); 0176 0177 QLabel* const overExpoPcentlabel = new QLabel(i18n("Over-exposure percents: "), exposureOptionsGroup); 0178 d->overExposurePcents = new DDoubleNumInput(exposureOptionsGroup); 0179 d->overExposurePcents->setDecimals(1); 0180 d->overExposurePcents->setRange(0.1, 5.0, 0.1); 0181 d->overExposurePcents->setDefaultValue(1.0); 0182 overExpoPcentlabel->setBuddy(d->underExposurePcents); 0183 d->overExposurePcents->setWhatsThis(i18n("Adjust the percents of the top of image histogram " 0184 "which will be used to check over exposed pixels.")); 0185 0186 d->expoIndicatorMode = new QCheckBox(i18n("Indicate exposure as pure color"), exposureOptionsGroup); 0187 d->expoIndicatorMode->setWhatsThis(i18n("If this option is enabled, over- and under-exposure indicators will be displayed " 0188 "only when pure white and pure black color matches, as all color components match " 0189 "the condition in the same time. " 0190 "Otherwise, indicators are turned on when one of the color components matches the condition.")); 0191 0192 QLabel* const exampleLabel = new QLabel(i18n("Example:"), exposureOptionsGroup); 0193 d->expoPreview = new QLabel(exposureOptionsGroup); 0194 d->expoPreviewHisto = new HistogramWidget(256, 128, exposureOptionsGroup, false, false); 0195 QImage image(QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0196 QLatin1String("digikam/data/sample-aix.png"))); 0197 d->preview = DImg(image); 0198 0199 if (!d->preview.isNull()) 0200 { 0201 d->expoPreviewHisto->updateData(d->preview); 0202 } 0203 0204 d->expoPreviewHisto->setChannelType(ColorChannels); 0205 d->expoPreview->setFrameStyle(QFrame::Box | QFrame::Plain); 0206 0207 gLayout2->addWidget(underExpoColorlabel, 0, 0, 1, 2); 0208 gLayout2->addWidget(d->underExposureColor, 0, 2, 1, 1); 0209 gLayout2->addWidget(underExpoPcentlabel, 1, 0, 1, 2); 0210 gLayout2->addWidget(d->underExposurePcents, 1, 2, 1, 1); 0211 gLayout2->addWidget(overExpoColorlabel, 2, 0, 1, 2); 0212 gLayout2->addWidget(d->overExposureColor, 2, 2, 1, 1); 0213 gLayout2->addWidget(overExpoPcentlabel, 3, 0, 1, 2); 0214 gLayout2->addWidget(d->overExposurePcents, 3, 2, 1, 1); 0215 gLayout2->addWidget(d->expoIndicatorMode, 4, 0, 1, 2); 0216 gLayout2->addWidget(exampleLabel, 5, 0, 1, 2); 0217 gLayout2->addWidget(d->expoPreview, 6, 0, 1, 1); 0218 gLayout2->addWidget(d->expoPreviewHisto, 6, 2, 1, 1); 0219 gLayout2->setColumnStretch(1, 10); 0220 gLayout2->setSpacing(spacing); 0221 gLayout2->setContentsMargins(spacing, spacing, spacing, spacing); 0222 0223 // -------------------------------------------------------- 0224 0225 QGroupBox* const restoreSettingsGroup = new QGroupBox(i18n("Tool Options"), panel); 0226 QVBoxLayout* const gLayout3 = new QVBoxLayout(restoreSettingsGroup); 0227 0228 d->restoreSettings = new QCheckBox(i18n("&Restore the settings of the Image Editor tools"), 0229 restoreSettingsGroup); 0230 d->restoreSettings->setWhatsThis(i18n("Enable this option to restore the settings of the Image " 0231 "Editor tools from the last session. Otherwise, the " 0232 "default settings will be used.")); 0233 0234 gLayout3->addWidget(d->restoreSettings); 0235 gLayout3->setContentsMargins(spacing, spacing, spacing, spacing); 0236 gLayout3->setSpacing(spacing); 0237 0238 // -------------------------------------------------------- 0239 0240 layout->addWidget(interfaceOptionsGroup); 0241 layout->addWidget(d->fullScreenSettings); 0242 layout->addWidget(exposureOptionsGroup); 0243 layout->addWidget(restoreSettingsGroup); 0244 layout->addStretch(); 0245 layout->setContentsMargins(spacing, spacing, spacing, spacing); 0246 layout->setSpacing(spacing); 0247 0248 // -------------------------------------------------------- 0249 0250 connect(d->themebackgroundColor, SIGNAL(toggled(bool)), 0251 this, SLOT(slotThemeBackgroundColor(bool))); 0252 0253 connect(d->expoIndicatorMode, SIGNAL(toggled(bool)), 0254 this, SLOT(slotExpoSettingsChanged())); 0255 0256 connect(d->underExposureColor, SIGNAL(signalColorSelected(QColor)), 0257 this, SLOT(slotExpoSettingsChanged())); 0258 0259 connect(d->overExposureColor, SIGNAL(signalColorSelected(QColor)), 0260 this, SLOT(slotExpoSettingsChanged())); 0261 0262 connect(d->underExposurePcents, SIGNAL(valueChanged(double)), 0263 this, SLOT(slotExpoSettingsChanged())); 0264 0265 connect(d->underExposurePcents, SIGNAL(valueChanged(double)), 0266 this, SLOT(slotShowUnderExpoHistogramGuide(double))); 0267 0268 connect(d->overExposurePcents, SIGNAL(valueChanged(double)), 0269 this, SLOT(slotExpoSettingsChanged())); 0270 0271 connect(d->overExposurePcents, SIGNAL(valueChanged(double)), 0272 this, SLOT(slotShowOverExpoHistogramGuide(double))); 0273 0274 readSettings(); 0275 0276 // -------------------------------------------------------- 0277 0278 slotExpoSettingsChanged(); 0279 } 0280 0281 SetupEditorIface::~SetupEditorIface() 0282 { 0283 delete d; 0284 } 0285 0286 void SetupEditorIface::slotThemeBackgroundColor(bool e) 0287 { 0288 d->colorBox->setEnabled(!e); 0289 } 0290 0291 void SetupEditorIface::slotExpoSettingsChanged() 0292 { 0293 ExposureSettingsContainer prm; 0294 prm.underExposureIndicator = true; 0295 prm.overExposureIndicator = true; 0296 prm.exposureIndicatorMode = d->expoIndicatorMode->isChecked(); 0297 prm.underExposurePercent = d->underExposurePcents->value(); 0298 prm.overExposurePercent = d->overExposurePcents->value(); 0299 prm.underExposureColor = d->underExposureColor->color(); 0300 prm.overExposureColor = d->overExposureColor->color(); 0301 0302 QPixmap pix = d->preview.convertToPixmap(); 0303 QPainter p(&pix); 0304 QImage pureColorMask = d->preview.pureColorMask(&prm); 0305 QPixmap pixMask = QPixmap::fromImage(pureColorMask); 0306 p.drawPixmap(0, 0, pixMask, 0, 0, pixMask.width(), pixMask.height()); 0307 0308 d->expoPreview->setPixmap(pix); 0309 } 0310 0311 void SetupEditorIface::slotShowOverExpoHistogramGuide(double v) 0312 { 0313 int max = lround(255.0 - (255.0 * v / 100.0)); 0314 DColor color(max, max, max, max, false); 0315 d->expoPreviewHisto->setHistogramGuideByColor(color); 0316 } 0317 0318 void SetupEditorIface::slotShowUnderExpoHistogramGuide(double v) 0319 { 0320 int min = lround(0.0 + (255.0 * v / 100.0)); 0321 DColor color(min, min, min, min, false); 0322 d->expoPreviewHisto->setHistogramGuideByColor(color); 0323 } 0324 0325 void SetupEditorIface::readSettings() 0326 { 0327 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0328 KConfigGroup group = config->group(d->configGroupName); 0329 QColor Black(Qt::black); 0330 QColor White(Qt::white); 0331 d->themebackgroundColor->setChecked(group.readEntry(d->configUseThemeBackgroundColorEntry, true)); 0332 d->backgroundColor->setColor(group.readEntry(d->configBackgroundColorEntry, Black)); 0333 d->underExposureColor->setColor(group.readEntry(d->configUnderExposureColorEntry, White)); 0334 d->overExposureColor->setColor(group.readEntry(d->configOverExposureColorEntry, Black)); 0335 d->expoIndicatorMode->setChecked(group.readEntry(d->configExpoIndicatorModeEntry, true)); 0336 d->underExposurePcents->setValue(group.readEntry(d->configUnderExposurePercentsEntry, 1.0)); 0337 d->overExposurePcents->setValue(group.readEntry(d->configOverExposurePercentsEntry, 1.0)); 0338 d->restoreSettings->setChecked(group.readEntry(d->configRestoreSettingsEntry, true)); 0339 d->fullScreenSettings->readSettings(group); 0340 } 0341 0342 void SetupEditorIface::applySettings() 0343 { 0344 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0345 KConfigGroup group = config->group(d->configGroupName); 0346 group.writeEntry(d->configUseThemeBackgroundColorEntry, d->themebackgroundColor->isChecked()); 0347 group.writeEntry(d->configBackgroundColorEntry, d->backgroundColor->color()); 0348 group.writeEntry(d->configUnderExposureColorEntry, d->underExposureColor->color()); 0349 group.writeEntry(d->configOverExposureColorEntry, d->overExposureColor->color()); 0350 group.writeEntry(d->configExpoIndicatorModeEntry, d->expoIndicatorMode->isChecked()); 0351 group.writeEntry(d->configUnderExposurePercentsEntry, d->underExposurePcents->value()); 0352 group.writeEntry(d->configOverExposurePercentsEntry, d->overExposurePcents->value()); 0353 group.writeEntry(d->configRestoreSettingsEntry, d->restoreSettings->isChecked()); 0354 0355 d->fullScreenSettings->saveSettings(group); 0356 0357 group.sync(); 0358 } 0359 0360 } // namespace Digikam 0361 0362 #include "moc_setupeditoriface.cpp"