diff --git a/core/dplugins/bqm/colors/bcgcorrectionplugin.cpp b/core/dplugins/bqm/colors/bcgcorrectionplugin.cpp index bba96265ca..3a35fc9bbb 100644 --- a/core/dplugins/bqm/colors/bcgcorrectionplugin.cpp +++ b/core/dplugins/bqm/colors/bcgcorrectionplugin.cpp @@ -1,94 +1,94 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 * Description : a BQM plugin to adjust BCG * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "bcgcorrectionplugin.h" // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "bcgcorrection.h" namespace Digikam { BCGCorrectionPlugin::BCGCorrectionPlugin(QObject* const parent) : DPluginBqm(parent) { } BCGCorrectionPlugin::~BCGCorrectionPlugin() { } QString BCGCorrectionPlugin::name() const { return i18n("BCG Correction"); } QString BCGCorrectionPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon BCGCorrectionPlugin::icon() const { return QIcon::fromTheme(QLatin1String("contrast")); } QString BCGCorrectionPlugin::description() const { - return i18n("A tool to fix Brightness/Contrast/Gamma"); + return i18n("A tool to fix Brightness / Contrast / Gamma"); } QString BCGCorrectionPlugin::details() const { - return i18n("

This Batch Queue Manager tool can adjust Brightness/Contrast/Gamma from images.

"); + return i18n("

This Batch Queue Manager tool can adjust Brightness / Contrast / Gamma from images.

"); } QList BCGCorrectionPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), QLatin1String("(C) 2010-2019")) ; } void BCGCorrectionPlugin::setup(QObject* const parent) { BCGCorrection* const tool = new BCGCorrection(parent); tool->setPlugin(this); addTool(tool); } } // namespace Digikam diff --git a/core/dplugins/bqm/colors/hslcorrectionplugin.cpp b/core/dplugins/bqm/colors/hslcorrectionplugin.cpp index f0c7e9b193..d38a800de1 100644 --- a/core/dplugins/bqm/colors/hslcorrectionplugin.cpp +++ b/core/dplugins/bqm/colors/hslcorrectionplugin.cpp @@ -1,94 +1,94 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 * Description : a BQM plugin to adjust HSL * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "hslcorrectionplugin.h" // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "hslcorrection.h" namespace Digikam { HSLCorrectionPlugin::HSLCorrectionPlugin(QObject* const parent) : DPluginBqm(parent) { } HSLCorrectionPlugin::~HSLCorrectionPlugin() { } QString HSLCorrectionPlugin::name() const { return i18n("HSL Correction"); } QString HSLCorrectionPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon HSLCorrectionPlugin::icon() const { return QIcon::fromTheme(QLatin1String("adjusthsl")); } QString HSLCorrectionPlugin::description() const { - return i18n("A tool to fix Hue/Saturation/Lightness"); + return i18n("A tool to fix Hue / Saturation / Lightness"); } QString HSLCorrectionPlugin::details() const { - return i18n("

This Batch Queue Manager tool can adjust Hue/Saturation/Lightness from images.

"); + return i18n("

This Batch Queue Manager tool can adjust Hue / Saturation / Lightness from images.

"); } QList HSLCorrectionPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), QLatin1String("(C) 2010-2019")) ; } void HSLCorrectionPlugin::setup(QObject* const parent) { HSLCorrection* const tool = new HSLCorrection(parent); tool->setPlugin(this); addTool(tool); } } // namespace Digikam diff --git a/core/dplugins/bqm/colors/iccconvertplugin.cpp b/core/dplugins/bqm/colors/iccconvertplugin.cpp index 89c988b0ce..54b9e2720b 100644 --- a/core/dplugins/bqm/colors/iccconvertplugin.cpp +++ b/core/dplugins/bqm/colors/iccconvertplugin.cpp @@ -1,94 +1,94 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 * Description : a BQM plugin to convert to color space * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "iccconvertplugin.h" // Qt includes #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "iccconvert.h" namespace Digikam { IccConvertPlugin::IccConvertPlugin(QObject* const parent) : DPluginBqm(parent) { } IccConvertPlugin::~IccConvertPlugin() { } QString IccConvertPlugin::name() const { - return i18n("ICC Convert"); + return i18n("Color Profile Conversion"); } QString IccConvertPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon IccConvertPlugin::icon() const { return QIcon::fromTheme(QLatin1String("preferences-desktop-display-color")); } QString IccConvertPlugin::description() const { - return i18n("A tool to convert image to a color space"); + return i18n("A tool to convert images to a color space"); } QString IccConvertPlugin::details() const { return i18n("

This Batch Queue Manager tool can convert images to a different color space.

"); } QList IccConvertPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), QLatin1String("(C) 2010-2019")) ; } void IccConvertPlugin::setup(QObject* const parent) { IccConvert* const tool = new IccConvert(parent); tool->setPlugin(this); addTool(tool); } } // namespace Digikam diff --git a/core/dplugins/editor/colors/CMakeLists.txt b/core/dplugins/editor/colors/CMakeLists.txt index 7cd69a1153..47645466b3 100644 --- a/core/dplugins/editor/colors/CMakeLists.txt +++ b/core/dplugins/editor/colors/CMakeLists.txt @@ -1,45 +1,69 @@ # # Copyright (c) 2015-2019 by Gilles Caulier, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif (POLICY CMP0063) include_directories($ $ $ $ $ $ $ ) DIGIKAM_ADD_EDITOR_PLUGIN(BcgTool ${CMAKE_CURRENT_SOURCE_DIR}/bcgtoolplugin.cpp ${CMAKE_CURRENT_SOURCE_DIR}/bcgtool.cpp ) DIGIKAM_ADD_EDITOR_PLUGIN(AdjustCurvesTool ${CMAKE_CURRENT_SOURCE_DIR}/adjustcurvestoolplugin.cpp ${CMAKE_CURRENT_SOURCE_DIR}/adjustcurvestool.cpp ) DIGIKAM_ADD_EDITOR_PLUGIN(AdjustLevelsTool ${CMAKE_CURRENT_SOURCE_DIR}/adjustlevelstoolplugin.cpp ${CMAKE_CURRENT_SOURCE_DIR}/adjustlevelstool.cpp ) DIGIKAM_ADD_EDITOR_PLUGIN(AutoCorrectionTool ${CMAKE_CURRENT_SOURCE_DIR}/autocorrectiontoolplugin.cpp ${CMAKE_CURRENT_SOURCE_DIR}/autocorrectiontool.cpp ) DIGIKAM_ADD_EDITOR_PLUGIN(BWSepiaTool ${CMAKE_CURRENT_SOURCE_DIR}/bwsepiatoolplugin.cpp ${CMAKE_CURRENT_SOURCE_DIR}/bwsepiatool.cpp ) +DIGIKAM_ADD_EDITOR_PLUGIN(CBTool + ${CMAKE_CURRENT_SOURCE_DIR}/cbtoolplugin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cbtool.cpp +) + +DIGIKAM_ADD_EDITOR_PLUGIN(ChannelMixerTool + ${CMAKE_CURRENT_SOURCE_DIR}/channelmixertoolplugin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/channelmixertool.cpp +) + +DIGIKAM_ADD_EDITOR_PLUGIN(FilmTool + ${CMAKE_CURRENT_SOURCE_DIR}/filmtoolplugin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/filmtool.cpp +) + +DIGIKAM_ADD_EDITOR_PLUGIN(HSLTool + ${CMAKE_CURRENT_SOURCE_DIR}/hsltoolplugin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/hsltool.cpp +) + +DIGIKAM_ADD_EDITOR_PLUGIN(ProfileConversionTool + ${CMAKE_CURRENT_SOURCE_DIR}/profileconversiontoolplugin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/profileconversiontool.cpp +) diff --git a/core/dplugins/editor/colors/bcgtoolplugin.cpp b/core/dplugins/editor/colors/bcgtoolplugin.cpp index 5920cd71cc..655303f295 100644 --- a/core/dplugins/editor/colors/bcgtoolplugin.cpp +++ b/core/dplugins/editor/colors/bcgtoolplugin.cpp @@ -1,113 +1,113 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 * Description : image editor plugin to fix BCG. * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "bcgtoolplugin.h" // Qt includes #include // KDE includes #include // Local includes #include "editorwindow.h" #include "bcgtool.h" namespace Digikam { BCGToolPlugin::BCGToolPlugin(QObject* const parent) : DPluginEditor(parent) { } BCGToolPlugin::~BCGToolPlugin() { } QString BCGToolPlugin::name() const { return i18n("BCG Correction"); } QString BCGToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } QIcon BCGToolPlugin::icon() const { return QIcon::fromTheme(QLatin1String("contrast")); } QString BCGToolPlugin::description() const { - return i18n("A tool to fix Brightness/Contrast/Gamma"); + return i18n("A tool to fix Brightness / Contrast / Gamma"); } QString BCGToolPlugin::details() const { - return i18n("

This Image Editor tool can adjust Brightness/Contrast/Gamma from image.

"); + return i18n("

This Image Editor tool can adjust Brightness / Contrast / Gamma from image.

"); } QList BCGToolPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Renchi Raju"), QLatin1String("renchi dot raju at gmail dot com"), QLatin1String("(C) 2004")) << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), QLatin1String("(C) 2005-2019")) ; } void BCGToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); ac->setIcon(icon()); ac->setText(i18nc("@action", "Brightness/Contrast/Gamma...")); ac->setObjectName(QLatin1String("editorwindow_color_bcg")); ac->setActionCategory(DPluginAction::EditorColor); connect(ac, SIGNAL(triggered(bool)), this, SLOT(slotBCGTool())); addAction(ac); } void BCGToolPlugin::slotBCGTool() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { BCGTool* const tool = new BCGTool(editor); tool->setPlugin(this); editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/cbtool.cpp b/core/dplugins/editor/colors/cbtool.cpp index a5d251f72a..bc6d6922e1 100644 --- a/core/dplugins/editor/colors/cbtool.cpp +++ b/core/dplugins/editor/colors/cbtool.cpp @@ -1,174 +1,172 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-07-11 * Description : digiKam image editor Color Balance tool. * * Copyright (C) 2004-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "cbtool.h" // Qt includes #include #include // KDE includes #include #include // Local includes #include "cbsettings.h" #include "cbfilter.h" #include "dimg.h" #include "editortoolsettings.h" #include "histogrambox.h" #include "histogramwidget.h" #include "imageiface.h" #include "imageregionwidget.h" namespace Digikam { class Q_DECL_HIDDEN CBTool::Private { public: explicit Private() : cbSettings(0), previewWidget(0), gboxSettings(0) { } static const QString configGroupName; static const QString configHistogramChannelEntry; static const QString configHistogramScaleEntry; CBSettings* cbSettings; ImageRegionWidget* previewWidget; EditorToolSettings* gboxSettings; }; const QString CBTool::Private::configGroupName(QLatin1String("colorbalance Tool")); const QString CBTool::Private::configHistogramChannelEntry(QLatin1String("Histogram Channel")); const QString CBTool::Private::configHistogramScaleEntry(QLatin1String("Histogram Scale")); // -------------------------------------------------------- CBTool::CBTool(QObject* const parent) : EditorToolThreaded(parent), d(new Private) { setObjectName(QLatin1String("colorbalance")); - setToolName(i18n("Color Balance")); - setToolIcon(QIcon::fromTheme(QLatin1String("adjustrgb"))); setInitPreview(true); d->previewWidget = new ImageRegionWidget; setToolView(d->previewWidget); setPreviewModeMask(PreviewToolBar::AllPreviewModes); // ------------------------------------------------------------- d->gboxSettings = new EditorToolSettings(0); d->gboxSettings->setTools(EditorToolSettings::Histogram); d->gboxSettings->setHistogramType(LRGBC); d->gboxSettings->setButtons(EditorToolSettings::Default| EditorToolSettings::Ok| EditorToolSettings::Cancel); d->cbSettings = new CBSettings(d->gboxSettings->plainPage()); setToolSettings(d->gboxSettings); // ------------------------------------------------------------- connect(d->cbSettings, SIGNAL(signalSettingsChanged()), this, SLOT(slotTimer())); } CBTool::~CBTool() { delete d; } void CBTool::readSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry, (int)LuminosityChannel)); d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry, (int)LogScaleHistogram)); d->cbSettings->readSettings(group); } void CBTool::writeSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); group.writeEntry(d->configHistogramChannelEntry, (int)d->gboxSettings->histogramBox()->channel()); group.writeEntry(d->configHistogramScaleEntry, (int)d->gboxSettings->histogramBox()->scale()); d->cbSettings->writeSettings(group); group.sync(); } void CBTool::slotResetSettings() { d->cbSettings->resetToDefault(); slotPreview(); } void CBTool::preparePreview() { CBContainer settings = d->cbSettings->settings(); d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation(); DImg preview = d->previewWidget->getOriginalRegionImage(true); setFilter(new CBFilter(&preview, this, settings)); } void CBTool::setPreviewImage() { DImg preview = filter()->getTargetImage(); d->previewWidget->setPreviewImage(preview); // Update histogram. d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false); } void CBTool::prepareFinal() { CBContainer settings = d->cbSettings->settings(); ImageIface iface; setFilter(new CBFilter(iface.original(), this, settings)); } void CBTool::setFinalImage() { ImageIface iface; iface.setOriginal(i18n("Color Balance"), filter()->filterAction(), filter()->getTargetImage()); } } // namespace Digikam diff --git a/core/dplugins/editor/colors/cbtoolplugin.cpp b/core/dplugins/editor/colors/cbtoolplugin.cpp index c51795a666..8d95840883 100644 --- a/core/dplugins/editor/colors/cbtoolplugin.cpp +++ b/core/dplugins/editor/colors/cbtoolplugin.cpp @@ -1,112 +1,112 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors automatically + * Description : image editor plugin to fix colors balance * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#include "autocorrectiontoolplugin.h" +#include "cbtoolplugin.h" // Qt includes #include // KDE includes #include // Local includes #include "editorwindow.h" -#include "autocorrectiontool.h" +#include "cbtool.h" namespace Digikam { -AutoCorrectionToolPlugin::AutoCorrectionToolPlugin(QObject* const parent) +CBToolPlugin::CBToolPlugin(QObject* const parent) : DPluginEditor(parent) { } -AutoCorrectionToolPlugin::~AutoCorrectionToolPlugin() +CBToolPlugin::~CBToolPlugin() { } -QString AutoCorrectionToolPlugin::name() const +QString CBToolPlugin::name() const { - return i18n("Auto Correction"); + return i18n("Color Balance"); } -QString AutoCorrectionToolPlugin::iid() const +QString CBToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } -QIcon AutoCorrectionToolPlugin::icon() const +QIcon CBToolPlugin::icon() const { - return QIcon::fromTheme(QLatin1String("autocorrection")); + return QIcon::fromTheme(QLatin1String("adjustrgb")); } -QString AutoCorrectionToolPlugin::description() const +QString CBToolPlugin::description() const { - return i18n("A tool to fix colors automatically"); + return i18n("A tool to adjust color balance"); } -QString AutoCorrectionToolPlugin::details() const +QString CBToolPlugin::details() const { - return i18n("

This Image Editor tool can adjust colors automatically from image.

"); + return i18n("

This Image Editor tool can adjust color balance from image.

"); } -QList AutoCorrectionToolPlugin::authors() const +QList CBToolPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), - QLatin1String("(C) 2005-2019")) + QLatin1String("(C) 2004-2019")) ; } -void AutoCorrectionToolPlugin::setup(QObject* const parent) +void CBToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); ac->setIcon(icon()); - ac->setText(i18nc("@action", "Auto-Correction...")); - ac->setObjectName(QLatin1String("editorwindow_color_autocorrection")); - // NOTE: Photoshop 7 use CTRL+SHIFT+B - ac->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_B); + ac->setText(i18nc("@action", "Color Balance...")); + ac->setObjectName(QLatin1String("editorwindow_color_rgb")); + // NOTE: Photoshop 7 use CTRL+B. + ac->setShortcut(Qt::CTRL+Qt::Key_B); ac->setActionCategory(DPluginAction::EditorColor); connect(ac, SIGNAL(triggered(bool)), - this, SLOT(slotAutoCorrection())); + this, SLOT(slotColorBalance())); addAction(ac); } -void AutoCorrectionToolPlugin::slotAutoCorrection() +void CBToolPlugin::slotColorBalance() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { - AutoCorrectionTool* const tool = new AutoCorrectionTool(editor); + CBTool* const tool = new CBTool(editor); tool->setPlugin(this); editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/cbtoolplugin.h b/core/dplugins/editor/colors/cbtoolplugin.h index edd4864914..beecb2160f 100644 --- a/core/dplugins/editor/colors/cbtoolplugin.h +++ b/core/dplugins/editor/colors/cbtoolplugin.h @@ -1,62 +1,62 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors automatically + * Description : image editor plugin to fix colors balance * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#ifndef DIGIKAM_AUTOCORRECTIONTOOL_PLUGIN_H -#define DIGIKAM_AUTOCORRECTIONTOOL_PLUGIN_H +#ifndef DIGIKAM_CBTOOL_PLUGIN_H +#define DIGIKAM_CBTOOL_PLUGIN_H // Local includes #include "dplugineditor.h" -#define DPLUGIN_IID "org.kde.digikam.plugin.editor.AutoCorrectionTool" +#define DPLUGIN_IID "org.kde.digikam.plugin.editor.CBTool" namespace Digikam { -class AutoCorrectionToolPlugin : public DPluginEditor +class CBToolPlugin : public DPluginEditor { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginEditor) public: - explicit AutoCorrectionToolPlugin(QObject* const parent = 0); - ~AutoCorrectionToolPlugin(); + explicit CBToolPlugin(QObject* const parent = 0); + ~CBToolPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; void setup(QObject* const); private Q_SLOTS: - void slotAutoCorrection(); + void slotColorBalance(); }; } // namespace Digikam -#endif // DIGIKAM_AUTOCORRECTIONTOOL_PLUGIN_H +#endif // DIGIKAM_CBTOOL_PLUGIN_H diff --git a/core/dplugins/editor/colors/channelmixertool.cpp b/core/dplugins/editor/colors/channelmixertool.cpp index 484be138e5..b051577789 100644 --- a/core/dplugins/editor/colors/channelmixertool.cpp +++ b/core/dplugins/editor/colors/channelmixertool.cpp @@ -1,228 +1,226 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-02-26 * Description : image channels mixer. * * Copyright (C) 2005-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "channelmixertool.h" // C++ includes #include #include #include #include #include // Qt includes #include #include // KDE includes #include #include // Local includes #include "colorgradientwidget.h" #include "dimg.h" #include "mixerfilter.h" #include "mixersettings.h" #include "editortoolsettings.h" #include "histogrambox.h" #include "histogramwidget.h" #include "imagehistogram.h" #include "imageiface.h" #include "imageregionwidget.h" #include "dnuminput.h" namespace Digikam { class Q_DECL_HIDDEN ChannelMixerTool::Private { public: explicit Private() : settingsView(0), previewWidget(0), gboxSettings(0) { } static const QString configGroupName; static const QString configHistogramChannelEntry; static const QString configHistogramScaleEntry; MixerSettings* settingsView; ImageRegionWidget* previewWidget; EditorToolSettings* gboxSettings; }; const QString ChannelMixerTool::Private::configGroupName(QLatin1String("channelmixer Tool")); const QString ChannelMixerTool::Private::configHistogramChannelEntry(QLatin1String("Histogram Channel")); const QString ChannelMixerTool::Private::configHistogramScaleEntry(QLatin1String("Histogram Scale")); // -------------------------------------------------------- ChannelMixerTool::ChannelMixerTool(QObject* const parent) : EditorToolThreaded(parent), d(new Private) { setObjectName(QLatin1String("channelmixer")); - setToolName(i18n("Channel Mixer")); - setToolIcon(QIcon::fromTheme(QLatin1String("channelmixer"))); // ------------------------------------------------------------- d->previewWidget = new ImageRegionWidget; setToolView(d->previewWidget); setPreviewModeMask(PreviewToolBar::AllPreviewModes); // ------------------------------------------------------------- d->gboxSettings = new EditorToolSettings(0); d->gboxSettings->setButtons(EditorToolSettings::Default| EditorToolSettings::Load| EditorToolSettings::SaveAs| EditorToolSettings::Ok| EditorToolSettings::Cancel); d->gboxSettings->setTools(EditorToolSettings::Histogram); d->gboxSettings->setHistogramType(LRGBC); // ------------------------------------------------------------- QVBoxLayout* vbox = new QVBoxLayout(d->gboxSettings->plainPage()); d->settingsView = new MixerSettings(d->gboxSettings->plainPage()); vbox->addWidget(d->settingsView); vbox->addStretch(10); vbox->setContentsMargins(QMargins()); vbox->setSpacing(0); setToolSettings(d->gboxSettings); // ------------------------------------------------------------- connect(d->settingsView, SIGNAL(signalSettingsChanged()), this, SLOT(slotTimer())); connect(d->settingsView, SIGNAL(signalOutChannelChanged()), this, SLOT(slotOutChannelChanged())); } ChannelMixerTool::~ChannelMixerTool() { delete d; } void ChannelMixerTool::slotOutChannelChanged() { if (d->settingsView->settings().bMonochrome) { d->gboxSettings->histogramBox()->setGradientColors(QColor("black"), QColor("white")); } // d->settingsView->setCurrentChannel(d->gboxSettings->histogramBox()->channel()); } void ChannelMixerTool::preparePreview() { MixerContainer settings = d->settingsView->settings(); d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation(); DImg preview = d->previewWidget->getOriginalRegionImage(true); setFilter(new MixerFilter(&preview, this, settings)); } void ChannelMixerTool::setPreviewImage() { DImg preview = filter()->getTargetImage(); d->previewWidget->setPreviewImage(preview); // Update histogram. d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false); } void ChannelMixerTool::prepareFinal() { MixerContainer settings = d->settingsView->settings(); ImageIface iface; setFilter(new MixerFilter(iface.original(), this, settings)); } void ChannelMixerTool::setFinalImage() { ImageIface iface; iface.setOriginal(i18n("Channel Mixer"), filter()->filterAction(), filter()->getTargetImage()); } void ChannelMixerTool::readSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); d->settingsView->readSettings(group); // we need to call these methods here, otherwise the histogram will not be updated correctly d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry, (int)RedChannel)); d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry, (int)LogScaleHistogram)); slotPreview(); } void ChannelMixerTool::writeSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); d->settingsView->writeSettings(group); group.writeEntry(d->configHistogramChannelEntry, (int)d->gboxSettings->histogramBox()->channel()); group.writeEntry(d->configHistogramScaleEntry, (int)d->gboxSettings->histogramBox()->scale()); config->sync(); } void ChannelMixerTool::slotResetSettings() { d->settingsView->resetToDefault(); } void ChannelMixerTool::slotLoadSettings() { d->settingsView->loadSettings(); d->gboxSettings->histogramBox()->setChannel((ChannelType)d->settingsView->currentChannel()); } void ChannelMixerTool::slotSaveAsSettings() { d->settingsView->saveAsSettings(); } } // namespace Digikam diff --git a/core/dplugins/editor/colors/channelmixertoolplugin.cpp b/core/dplugins/editor/colors/channelmixertoolplugin.cpp index 8d95840883..f8ace3b80e 100644 --- a/core/dplugins/editor/colors/channelmixertoolplugin.cpp +++ b/core/dplugins/editor/colors/channelmixertoolplugin.cpp @@ -1,112 +1,111 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors balance + * Description : image editor plugin to mix color channels * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#include "cbtoolplugin.h" +#include "channelmixertoolplugin.h" // Qt includes #include // KDE includes #include // Local includes #include "editorwindow.h" -#include "cbtool.h" +#include "channelmixertool.h" namespace Digikam { -CBToolPlugin::CBToolPlugin(QObject* const parent) +ChannelMixerToolPlugin::ChannelMixerToolPlugin(QObject* const parent) : DPluginEditor(parent) { } -CBToolPlugin::~CBToolPlugin() +ChannelMixerToolPlugin::~ChannelMixerToolPlugin() { } -QString CBToolPlugin::name() const +QString ChannelMixerToolPlugin::name() const { - return i18n("Color Balance"); + return i18n("Channel Mixer"); } -QString CBToolPlugin::iid() const +QString ChannelMixerToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } -QIcon CBToolPlugin::icon() const +QIcon ChannelMixerToolPlugin::icon() const { - return QIcon::fromTheme(QLatin1String("adjustrgb")); + return QIcon::fromTheme(QLatin1String("channelmixer")); } -QString CBToolPlugin::description() const +QString ChannelMixerToolPlugin::description() const { - return i18n("A tool to adjust color balance"); + return i18n("A tool to mix color channel"); } -QString CBToolPlugin::details() const +QString ChannelMixerToolPlugin::details() const { - return i18n("

This Image Editor tool can adjust color balance from image.

"); + return i18n("

This Image Editor tool can mix color channels from image.

"); } -QList CBToolPlugin::authors() const +QList ChannelMixerToolPlugin::authors() const { return QList() << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), - QLatin1String("(C) 2004-2019")) + QLatin1String("(C) 2005-2019")) ; } -void CBToolPlugin::setup(QObject* const parent) +void ChannelMixerToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); ac->setIcon(icon()); - ac->setText(i18nc("@action", "Color Balance...")); - ac->setObjectName(QLatin1String("editorwindow_color_rgb")); - // NOTE: Photoshop 7 use CTRL+B. - ac->setShortcut(Qt::CTRL+Qt::Key_B); + ac->setText(i18nc("@action", "Channel Mixer...")); + ac->setObjectName(QLatin1String("editorwindow_color_channelmixer")); + ac->setShortcut(Qt::CTRL+Qt::Key_H); ac->setActionCategory(DPluginAction::EditorColor); connect(ac, SIGNAL(triggered(bool)), - this, SLOT(slotColorBalance())); + this, SLOT(slotChannelMixer())); addAction(ac); } -void CBToolPlugin::slotColorBalance() +void ChannelMixerToolPlugin::slotChannelMixer() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { - CBTool* const tool = new CBTool(editor); + ChannelMixerTool* const tool = new ChannelMixerTool(editor); tool->setPlugin(this); editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/channelmixertoolplugin.h b/core/dplugins/editor/colors/channelmixertoolplugin.h index beecb2160f..7525665e04 100644 --- a/core/dplugins/editor/colors/channelmixertoolplugin.h +++ b/core/dplugins/editor/colors/channelmixertoolplugin.h @@ -1,62 +1,62 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors balance + * Description : image editor plugin to mix color channels * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#ifndef DIGIKAM_CBTOOL_PLUGIN_H -#define DIGIKAM_CBTOOL_PLUGIN_H +#ifndef DIGIKAM_CHANNELMIXERTOOL_PLUGIN_H +#define DIGIKAM_CHANNELMIXERTOOL_PLUGIN_H // Local includes #include "dplugineditor.h" -#define DPLUGIN_IID "org.kde.digikam.plugin.editor.CBTool" +#define DPLUGIN_IID "org.kde.digikam.plugin.editor.ChannelMixerTool" namespace Digikam { -class CBToolPlugin : public DPluginEditor +class ChannelMixerToolPlugin : public DPluginEditor { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginEditor) public: - explicit CBToolPlugin(QObject* const parent = 0); - ~CBToolPlugin(); + explicit ChannelMixerToolPlugin(QObject* const parent = 0); + ~ChannelMixerToolPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; void setup(QObject* const); private Q_SLOTS: - void slotColorBalance(); + void slotChannelMixer(); }; } // namespace Digikam -#endif // DIGIKAM_CBTOOL_PLUGIN_H +#endif // DIGIKAM_CHANNELMIXERTOOL_PLUGIN_H diff --git a/core/dplugins/editor/colors/filmtoolplugin.cpp b/core/dplugins/editor/colors/filmtoolplugin.cpp index 8d95840883..09c292a3b2 100644 --- a/core/dplugins/editor/colors/filmtoolplugin.cpp +++ b/core/dplugins/editor/colors/filmtoolplugin.cpp @@ -1,112 +1,111 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors balance + * Description : image editor plugin to emulate film color * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#include "cbtoolplugin.h" +#include "filmtoolplugin.h" // Qt includes #include // KDE includes #include // Local includes #include "editorwindow.h" -#include "cbtool.h" +#include "filmtool.h" namespace Digikam { -CBToolPlugin::CBToolPlugin(QObject* const parent) +FilmToolPlugin::FilmToolPlugin(QObject* const parent) : DPluginEditor(parent) { } -CBToolPlugin::~CBToolPlugin() +FilmToolPlugin::~FilmToolPlugin() { } -QString CBToolPlugin::name() const +QString FilmToolPlugin::name() const { - return i18n("Color Balance"); + return i18n("Color Negative Film"); } -QString CBToolPlugin::iid() const +QString FilmToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } -QIcon CBToolPlugin::icon() const +QIcon FilmToolPlugin::icon() const { - return QIcon::fromTheme(QLatin1String("adjustrgb")); + return QIcon::fromTheme(QLatin1String("colorneg")); } -QString CBToolPlugin::description() const +QString FilmToolPlugin::description() const { - return i18n("A tool to adjust color balance"); + return i18n("A tool to emulate color negative film"); } -QString CBToolPlugin::details() const +QString FilmToolPlugin::details() const { - return i18n("

This Image Editor tool can adjust color balance from image.

"); + return i18n("

This Image Editor tool can emulate color negative film from image.

"); } -QList CBToolPlugin::authors() const +QList FilmToolPlugin::authors() const { return QList() - << DPluginAuthor(QLatin1String("Gilles Caulier"), - QLatin1String("caulier dot gilles at gmail dot com"), - QLatin1String("(C) 2004-2019")) + << DPluginAuthor(QLatin1String("Matthias Welwarsky"), + QLatin1String("matthias at welwarsky dot de"), + QLatin1String("(C) 2012")) ; } -void CBToolPlugin::setup(QObject* const parent) +void FilmToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); ac->setIcon(icon()); - ac->setText(i18nc("@action", "Color Balance...")); - ac->setObjectName(QLatin1String("editorwindow_color_rgb")); - // NOTE: Photoshop 7 use CTRL+B. - ac->setShortcut(Qt::CTRL+Qt::Key_B); + ac->setText(i18nc("@action", "Color Negative...")); + ac->setObjectName(QLatin1String("editorwindow_color_film")); + ac->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_I); ac->setActionCategory(DPluginAction::EditorColor); connect(ac, SIGNAL(triggered(bool)), - this, SLOT(slotColorBalance())); + this, SLOT(slotFilmTool())); addAction(ac); } -void CBToolPlugin::slotColorBalance() +void FilmToolPlugin::slotFilmTool() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { - CBTool* const tool = new CBTool(editor); + FilmTool* const tool = new FilmTool(editor); tool->setPlugin(this); editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/filmtoolplugin.h b/core/dplugins/editor/colors/filmtoolplugin.h index beecb2160f..d54af7a675 100644 --- a/core/dplugins/editor/colors/filmtoolplugin.h +++ b/core/dplugins/editor/colors/filmtoolplugin.h @@ -1,62 +1,62 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to fix colors balance + * Description : image editor plugin to emulate film color * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#ifndef DIGIKAM_CBTOOL_PLUGIN_H -#define DIGIKAM_CBTOOL_PLUGIN_H +#ifndef DIGIKAM_FILMTOOL_PLUGIN_H +#define DIGIKAM_FILMTOOL_PLUGIN_H // Local includes #include "dplugineditor.h" -#define DPLUGIN_IID "org.kde.digikam.plugin.editor.CBTool" +#define DPLUGIN_IID "org.kde.digikam.plugin.editor.FilmTool" namespace Digikam { -class CBToolPlugin : public DPluginEditor +class FilmToolPlugin : public DPluginEditor { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginEditor) public: - explicit CBToolPlugin(QObject* const parent = 0); - ~CBToolPlugin(); + explicit FilmToolPlugin(QObject* const parent = 0); + ~FilmToolPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; void setup(QObject* const); private Q_SLOTS: - void slotColorBalance(); + void slotFilmTool(); }; } // namespace Digikam -#endif // DIGIKAM_CBTOOL_PLUGIN_H +#endif // DIGIKAM_FILMTOOL_PLUGIN_H diff --git a/core/dplugins/editor/colors/hsltool.cpp b/core/dplugins/editor/colors/hsltool.cpp index b1e94a5e6b..b228d366fd 100644 --- a/core/dplugins/editor/colors/hsltool.cpp +++ b/core/dplugins/editor/colors/hsltool.cpp @@ -1,177 +1,175 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2004-07-16 * Description : digiKam image editor to adjust Hue, Saturation, * and Lightness of picture. * * Copyright (C) 2004-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "hsltool.h" // Qt includes #include #include #include // KDE includes #include #include // Local includes #include "dimg.h" #include "hslsettings.h" #include "editortoolsettings.h" #include "histogrambox.h" #include "histogramwidget.h" #include "imageiface.h" #include "imageregionwidget.h" namespace Digikam { class Q_DECL_HIDDEN HSLTool::Private { public: explicit Private() : hslSettings(0), previewWidget(0), gboxSettings(0) { } static const QString configGroupName; static const QString configHistogramChannelEntry; static const QString configHistogramScaleEntry; HSLSettings* hslSettings; ImageRegionWidget* previewWidget; EditorToolSettings* gboxSettings; }; const QString HSLTool::Private::configGroupName(QLatin1String("hsladjust Tool")); const QString HSLTool::Private::configHistogramChannelEntry(QLatin1String("Histogram Channel")); const QString HSLTool::Private::configHistogramScaleEntry(QLatin1String("Histogram Scale")); // -------------------------------------------------------- HSLTool::HSLTool(QObject* const parent) : EditorToolThreaded(parent), d(new Private) { setObjectName(QLatin1String("adjusthsl")); - setToolName(i18n("Hue / Saturation / Lightness")); - setToolIcon(QIcon::fromTheme(QLatin1String("adjusthsl"))); setToolHelp(QLatin1String("hsladjusttool.anchor")); setInitPreview(true); d->previewWidget = new ImageRegionWidget; setToolView(d->previewWidget); setPreviewModeMask(PreviewToolBar::AllPreviewModes); // ------------------------------------------------------------- d->gboxSettings = new EditorToolSettings(0); d->gboxSettings->setTools(EditorToolSettings::Histogram); d->gboxSettings->setHistogramType(LRGBC); d->gboxSettings->setButtons(EditorToolSettings::Default| EditorToolSettings::Ok| EditorToolSettings::Cancel); // ------------------------------------------------------------- d->hslSettings = new HSLSettings(d->gboxSettings->plainPage()); setToolSettings(d->gboxSettings); // ------------------------------------------------------------- connect(d->hslSettings, SIGNAL(signalSettingsChanged()), this, SLOT(slotTimer())); } HSLTool::~HSLTool() { delete d; } void HSLTool::readSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry, (int)LuminosityChannel)); d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry, (int)LogScaleHistogram)); d->hslSettings->readSettings(group); } void HSLTool::writeSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); group.writeEntry(d->configHistogramChannelEntry, (int)d->gboxSettings->histogramBox()->channel()); group.writeEntry(d->configHistogramScaleEntry, (int)d->gboxSettings->histogramBox()->scale()); d->hslSettings->writeSettings(group); config->sync(); } void HSLTool::slotResetSettings() { d->hslSettings->resetToDefault(); slotPreview(); } void HSLTool::preparePreview() { HSLContainer settings = d->hslSettings->settings(); d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation(); DImg preview = d->previewWidget->getOriginalRegionImage(true); setFilter(new HSLFilter(&preview, this, settings)); } void HSLTool::setPreviewImage() { DImg preview = filter()->getTargetImage(); d->previewWidget->setPreviewImage(preview); // Update histogram. d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false); } void HSLTool::prepareFinal() { HSLContainer settings = d->hslSettings->settings(); ImageIface iface; setFilter(new HSLFilter(iface.original(), this, settings)); } void HSLTool::setFinalImage() { ImageIface iface; iface.setOriginal(i18n("HSL Adjustments"), filter()->filterAction(), filter()->getTargetImage()); } } // namespace Digikam diff --git a/core/dplugins/editor/colors/hsltoolplugin.cpp b/core/dplugins/editor/colors/hsltoolplugin.cpp index 09c292a3b2..243f83c399 100644 --- a/core/dplugins/editor/colors/hsltoolplugin.cpp +++ b/core/dplugins/editor/colors/hsltoolplugin.cpp @@ -1,111 +1,112 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to emulate film color + * Description : image editor plugin to adjust HSL * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#include "filmtoolplugin.h" +#include "hsltoolplugin.h" // Qt includes #include // KDE includes #include // Local includes #include "editorwindow.h" -#include "filmtool.h" +#include "hsltool.h" namespace Digikam { -FilmToolPlugin::FilmToolPlugin(QObject* const parent) +HSLToolPlugin::HSLToolPlugin(QObject* const parent) : DPluginEditor(parent) { } -FilmToolPlugin::~FilmToolPlugin() +HSLToolPlugin::~HSLToolPlugin() { } -QString FilmToolPlugin::name() const +QString HSLToolPlugin::name() const { - return i18n("Color Negative Film"); + return i18n("HSL Correction"); } -QString FilmToolPlugin::iid() const +QString HSLToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } -QIcon FilmToolPlugin::icon() const +QIcon HSLToolPlugin::icon() const { - return QIcon::fromTheme(QLatin1String("colorneg")); + return QIcon::fromTheme(QLatin1String("adjusthsl")); } -QString FilmToolPlugin::description() const +QString HSLToolPlugin::description() const { - return i18n("A tool to emulate color negative film"); + return i18n("A tool to fix Hue / Saturation / Lightness"); } -QString FilmToolPlugin::details() const +QString HSLToolPlugin::details() const { - return i18n("

This Image Editor tool can emulate color negative film from image.

"); + return i18n("

This Image Editor tool can adjust Hue / Saturation / Lightness from image.

"); } -QList FilmToolPlugin::authors() const +QList HSLToolPlugin::authors() const { return QList() - << DPluginAuthor(QLatin1String("Matthias Welwarsky"), - QLatin1String("matthias at welwarsky dot de"), - QLatin1String("(C) 2012")) + << DPluginAuthor(QLatin1String("Gilles Caulier"), + QLatin1String("caulier dot gilles at gmail dot com"), + QLatin1String("(C) 2004-2019")) ; } - -void FilmToolPlugin::setup(QObject* const parent) + +void HSLToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); ac->setIcon(icon()); - ac->setText(i18nc("@action", "Color Negative...")); - ac->setObjectName(QLatin1String("editorwindow_color_film")); - ac->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_I); + ac->setText(i18nc("@action", "Hue/Saturation/Lightness...")); + ac->setObjectName(QLatin1String("editorwindow_color_hsl")); + // NOTE: Photoshop 7 use CTRL+U. + ac->setShortcut(Qt::CTRL+Qt::Key_U); ac->setActionCategory(DPluginAction::EditorColor); connect(ac, SIGNAL(triggered(bool)), - this, SLOT(slotFilmTool())); + this, SLOT(slotHSL())); addAction(ac); } -void FilmToolPlugin::slotFilmTool() +void HSLToolPlugin::slotHSL() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { - FilmTool* const tool = new FilmTool(editor); + HSLTool* const tool = new HSLTool(editor); tool->setPlugin(this); editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/hsltoolplugin.h b/core/dplugins/editor/colors/hsltoolplugin.h index d54af7a675..8a5415b796 100644 --- a/core/dplugins/editor/colors/hsltoolplugin.h +++ b/core/dplugins/editor/colors/hsltoolplugin.h @@ -1,62 +1,62 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to emulate film color + * Description : image editor plugin to adjust HSL * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#ifndef DIGIKAM_FILMTOOL_PLUGIN_H -#define DIGIKAM_FILMTOOL_PLUGIN_H +#ifndef DIGIKAM_HSLTOOL_PLUGIN_H +#define DIGIKAM_HSLTOOL_PLUGIN_H // Local includes #include "dplugineditor.h" -#define DPLUGIN_IID "org.kde.digikam.plugin.editor.FilmTool" +#define DPLUGIN_IID "org.kde.digikam.plugin.editor.HSLTool" namespace Digikam { -class FilmToolPlugin : public DPluginEditor +class HSLToolPlugin : public DPluginEditor { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginEditor) public: - explicit FilmToolPlugin(QObject* const parent = 0); - ~FilmToolPlugin(); + explicit HSLToolPlugin(QObject* const parent = 0); + ~HSLToolPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; void setup(QObject* const); private Q_SLOTS: - void slotFilmTool(); + void slotHSL(); }; } // namespace Digikam -#endif // DIGIKAM_FILMTOOL_PLUGIN_H +#endif // DIGIKAM_HSLTOOL_PLUGIN_H diff --git a/core/dplugins/editor/colors/profileconversiontool.cpp b/core/dplugins/editor/colors/profileconversiontool.cpp index 6961eb1e06..251733ace1 100644 --- a/core/dplugins/editor/colors/profileconversiontool.cpp +++ b/core/dplugins/editor/colors/profileconversiontool.cpp @@ -1,271 +1,269 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-09-19 * Description : a tool for color space conversion * * Copyright (C) 2009-2012 by Marcel Wiesweg * Copyright (C) 2009-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "profileconversiontool.h" // Qt includes #include #include #include #include // KDE includes #include #include // Local includes #include "editortoolsettings.h" #include "iccprofileinfodlg.h" #include "iccprofilesettings.h" #include "iccsettings.h" #include "iccsettingscontainer.h" #include "icctransform.h" #include "icctransformfilter.h" #include "histogramwidget.h" #include "imageiface.h" #include "imageregionwidget.h" #include "dmetadata.h" namespace Digikam { class Q_DECL_HIDDEN ProfileConversionTool::Private { public: explicit Private() : profilesBox(0), previewWidget(0), gboxSettings(0) { } static const QString configGroupName; static const QString configProfileEntry; IccProfilesSettings* profilesBox; ImageRegionWidget* previewWidget; EditorToolSettings* gboxSettings; IccProfile currentProfile; IccTransform transform; public: static IccTransform getTransform(const IccProfile& in, const IccProfile& out); }; const QString ProfileConversionTool::Private::configGroupName(QLatin1String("Profile Conversion Tool")); const QString ProfileConversionTool::Private::configProfileEntry(QLatin1String("Profile")); IccTransform ProfileConversionTool::Private::getTransform(const IccProfile& in, const IccProfile& out) { ICCSettingsContainer settings = IccSettings::instance()->settings(); IccTransform transform; transform.setIntent(settings.renderingIntent); transform.setUseBlackPointCompensation(settings.useBPC); transform.setInputProfile(in); transform.setOutputProfile(out); return transform; } // ---------------------------------------------------------------------------- ProfileConversionTool::ProfileConversionTool(QObject* const parent) : EditorToolThreaded(parent), d(new Private) { setObjectName(QLatin1String("profile conversion")); - setToolName(i18n("Color Profile Conversion")); - setToolIcon(QIcon::fromTheme(QLatin1String("preferences-desktop-display-color"))); //TODO setToolHelp(QLatin1String("colormanagement.anchor")); // ------------------------------------------------------------- ImageIface iface; d->currentProfile = iface.originalIccProfile(); d->gboxSettings = new EditorToolSettings(0); d->gboxSettings->setButtons(EditorToolSettings::Ok| EditorToolSettings::Cancel); d->gboxSettings->setTools(EditorToolSettings::Histogram); d->gboxSettings->setHistogramType(LRGBAC); // ------------------------------------------------------------- QGridLayout* grid = new QGridLayout(d->gboxSettings->plainPage()); QLabel* currentProfileTitle = new QLabel; QLabel* currentProfileDesc = new QLabel; QPushButton* currentProfInfo = new QPushButton(i18n("Info...")); d->profilesBox = new IccProfilesSettings; currentProfileTitle->setText(i18n("Current Color Space:")); currentProfileDesc->setText(QString::fromUtf8("%1").arg(d->currentProfile.description())); currentProfileDesc->setWordWrap(true); const int spacing = d->gboxSettings->spacingHint(); grid->addWidget(currentProfileTitle, 0, 0, 1, 5); grid->addWidget(currentProfileDesc, 1, 0, 1, 5); grid->addWidget(currentProfInfo, 2, 0, 1, 1); grid->addWidget(d->profilesBox, 3, 0, 1, 5); grid->setRowStretch(4, 10); grid->setContentsMargins(spacing, spacing, spacing, spacing); grid->setSpacing(spacing); // ------------------------------------------------------------- d->previewWidget = new ImageRegionWidget; setToolSettings(d->gboxSettings); setToolView(d->previewWidget); setPreviewModeMask(PreviewToolBar::AllPreviewModes); // ------------------------------------------------------------- connect(currentProfInfo, SIGNAL(clicked()), this, SLOT(slotCurrentProfInfo())); connect(d->profilesBox, SIGNAL(signalSettingsChanged()), this, SLOT(slotProfileChanged())); } ProfileConversionTool::~ProfileConversionTool() { delete d; } void ProfileConversionTool::slotCurrentProfInfo() { ICCProfileInfoDlg infoDlg(qApp->activeWindow(), QString(), d->currentProfile); infoDlg.exec(); } void ProfileConversionTool::slotProfileChanged() { d->gboxSettings->enableButton(EditorToolSettings::Ok, !d->profilesBox->currentProfile().isNull()); updateTransform(); slotTimer(); } void ProfileConversionTool::updateTransform() { d->transform = d->getTransform(d->currentProfile, d->profilesBox->currentProfile()); } void ProfileConversionTool::readSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); d->profilesBox->setCurrentProfile(IccProfile(group.readPathEntry(d->configProfileEntry, d->currentProfile.filePath()))); d->profilesBox->readSettings(group); } void ProfileConversionTool::writeSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d->configGroupName); group.writePathEntry(d->configProfileEntry, d->profilesBox->currentProfile().filePath()); d->profilesBox->writeSettings(group); config->sync(); } void ProfileConversionTool::slotResetSettings() { d->profilesBox->resetToDefault(); } void ProfileConversionTool::preparePreview() { DImg preview = d->previewWidget->getOriginalRegionImage(true); setFilter(new IccTransformFilter(&preview, this, d->transform)); } void ProfileConversionTool::setPreviewImage() { DImg preview = filter()->getTargetImage(); d->previewWidget->setPreviewImage(preview); // Update histogram. d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), false); } void ProfileConversionTool::prepareFinal() { ImageIface iface; setFilter(new IccTransformFilter(iface.original(), this, d->transform)); } void ProfileConversionTool::setFinalImage() { ImageIface iface; DImg imDest = filter()->getTargetImage(); iface.setOriginal(i18n("Color Profile Conversion"), filter()->filterAction(), imDest); iface.setOriginalIccProfile(imDest.getIccProfile()); DMetadata meta(iface.originalMetadata()); meta.removeExifColorSpace(); iface.setOriginalMetadata(meta.data()); } // Static Methods. QStringList ProfileConversionTool::favoriteProfiles() { Private d; KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(d.configGroupName); return IccProfilesSettings::favoriteProfiles(group); } void ProfileConversionTool::fastConversion(const IccProfile& profile) { ImageIface iface; IccProfile currentProfile = iface.originalIccProfile(); IccTransform transform = Private::getTransform(currentProfile, profile); IccTransformFilter filter(iface.original(), 0, transform); filter.startFilterDirectly(); DImg imDest = filter.getTargetImage(); iface.setOriginal(i18n("Color Profile Conversion"), filter.filterAction(), imDest); iface.setOriginalIccProfile(imDest.getIccProfile()); DMetadata meta(iface.originalMetadata()); meta.removeExifColorSpace(); iface.setOriginalMetadata(meta.data()); } } // namespace Digikam diff --git a/core/dplugins/editor/colors/profileconversiontoolplugin.cpp b/core/dplugins/editor/colors/profileconversiontoolplugin.cpp index 5e957d22d7..4953274e2b 100644 --- a/core/dplugins/editor/colors/profileconversiontoolplugin.cpp +++ b/core/dplugins/editor/colors/profileconversiontoolplugin.cpp @@ -1,112 +1,214 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to adjust HSL + * Description : image editor plugin to convert to color space * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#include "hsltoolplugin.h" +#include "profileconversiontoolplugin.h" // Qt includes #include +#include +#include // KDE includes #include // Local includes #include "editorwindow.h" -#include "hsltool.h" +#include "profileconversiontool.h" +#include "iccprofilescombobox.h" +#include "iccsettings.h" +#include "iccsettingscontainer.h" +#include "icctransform.h" +#include "imageiface.h" namespace Digikam { -HSLToolPlugin::HSLToolPlugin(QObject* const parent) +ProfileConversionToolPlugin::ProfileConversionToolPlugin(QObject* const parent) : DPluginEditor(parent) { } -HSLToolPlugin::~HSLToolPlugin() +ProfileConversionToolPlugin::~ProfileConversionToolPlugin() { } -QString HSLToolPlugin::name() const +QString ProfileConversionToolPlugin::name() const { - return i18n("Hue / Saturation / Lightness"); + return i18n("Color Profile Conversion"); } -QString HSLToolPlugin::iid() const +QString ProfileConversionToolPlugin::iid() const { return QLatin1String(DPLUGIN_IID); } -QIcon HSLToolPlugin::icon() const +QIcon ProfileConversionToolPlugin::icon() const { - return QIcon::fromTheme(QLatin1String("adjusthsl")); + return QIcon::fromTheme(QLatin1String("preferences-desktop-display-color")); } -QString HSLToolPlugin::description() const +QString ProfileConversionToolPlugin::description() const { - return i18n("A tool to fix Hue / Saturation / Lightness"); + return i18n("A tool to convert image to a color space"); } -QString HSLToolPlugin::details() const +QString ProfileConversionToolPlugin::details() const { - return i18n("

This Image Editor tool can adjust Hue / Saturation / Lightness from image.

"); + return i18n("

This Image Editor tool can can convert image to a different color space.

"); } -QList HSLToolPlugin::authors() const +QList ProfileConversionToolPlugin::authors() const { return QList() + << DPluginAuthor(QLatin1String("Marcel Wiesweg"), + QLatin1String("marcel dot wiesweg at gmx dot de"), + QLatin1String("(C) 2009-2012")) << DPluginAuthor(QLatin1String("Gilles Caulier"), QLatin1String("caulier dot gilles at gmail dot com"), - QLatin1String("(C) 2004-2019")) + QLatin1String("(C) 2009-2019")) ; } -void HSLToolPlugin::setup(QObject* const parent) +void ProfileConversionToolPlugin::setup(QObject* const parent) { DPluginAction* const ac = new DPluginAction(parent); - ac->setIcon(icon()); - ac->setText(i18nc("@action", "Hue/Saturation/Lightness...")); - ac->setObjectName(QLatin1String("editorwindow_color_hsl")); - // NOTE: Photoshop 7 use CTRL+U. - ac->setShortcut(Qt::CTRL+Qt::Key_U); - ac->setActionCategory(DPluginAction::EditorColor); + m_profileMenuAction = new IccProfilesMenuAction(icon(), QString(), parent); + + connect(m_profileMenuAction, SIGNAL(triggered(IccProfile)), + this, SLOT(slotConvertToColorSpace(IccProfile))); - connect(ac, SIGNAL(triggered(bool)), - this, SLOT(slotHSL())); + connect(IccSettings::instance(), SIGNAL(settingsChanged()), + this, SLOT(slotUpdateColorSpaceMenu())); + + ac->setMenu(m_profileMenuAction); + ac->setText(i18n("Color Spaces")); + ac->setObjectName(QLatin1String("editorwindow_colormanagement")); + ac->setActionCategory(DPluginAction::EditorColor); addAction(ac); + + DPluginAction* const ac2 = new DPluginAction(parent); + ac2->setIcon(icon()); + ac2->setText(i18nc("@action", "Color Space Converter...")); + ac2->setObjectName(QLatin1String("editorwindow_color_spaceconverter")); + ac2->setActionCategory(DPluginAction::EditorColor); + + connect(ac2, SIGNAL(triggered(bool)), + this, SLOT(slotProfileConversionTool())); + + m_colorSpaceConverter = ac2; + + addAction(ac2); + + slotUpdateColorSpaceMenu(); +} + +void ProfileConversionToolPlugin::slotConvertToColorSpace(const IccProfile& profile) +{ + ImageIface iface; + + if (iface.originalIccProfile().isNull()) + { + QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), + i18n("This image is not color managed.")); + return; + } + + qApp->setOverrideCursor(Qt::WaitCursor); + ProfileConversionTool::fastConversion(profile); + qApp->restoreOverrideCursor(); +} + +void ProfileConversionToolPlugin::slotUpdateColorSpaceMenu() +{ + m_profileMenuAction->clear(); + + if (!IccSettings::instance()->isEnabled()) + { + QAction* const action = new QAction(i18n("Color Management is disabled..."), this); + m_profileMenuAction->addAction(action); + + connect(action, SIGNAL(triggered()), + this, SLOT(slotSetupICC())); + } + else + { + ICCSettingsContainer settings = IccSettings::instance()->settings(); + + QList standardProfiles, favoriteProfiles; + QSet standardProfilePaths, favoriteProfilePaths; + standardProfiles << IccProfile::sRGB() + << IccProfile::adobeRGB() + << IccProfile::wideGamutRGB() + << IccProfile::proPhotoRGB(); + + foreach (IccProfile profile, standardProfiles) // krazy:exclude=foreach + { + m_profileMenuAction->addProfile(profile, profile.description()); + standardProfilePaths << profile.filePath(); + } + + m_profileMenuAction->addSeparator(); + + favoriteProfilePaths = QSet::fromList(ProfileConversionTool::favoriteProfiles()); + favoriteProfilePaths -= standardProfilePaths; + + foreach (const QString& path, favoriteProfilePaths) + { + favoriteProfiles << IccProfile(path); + } + + m_profileMenuAction->addProfiles(favoriteProfiles); + } + + m_profileMenuAction->addSeparator(); + m_profileMenuAction->addAction(m_colorSpaceConverter); + + EditorWindow* const editor = dynamic_cast(m_profileMenuAction->parent()); + + if (editor) + { + m_colorSpaceConverter->setEnabled(editor->actionEnabledState() && + IccSettings::instance()->isEnabled()); + } } -void HSLToolPlugin::slotHSL() +void ProfileConversionToolPlugin::slotProfileConversionTool() { EditorWindow* const editor = dynamic_cast(sender()->parent()); if (editor) { - HSLTool* const tool = new HSLTool(editor); + ProfileConversionTool* const tool = new ProfileConversionTool(this); tool->setPlugin(this); + + connect(tool, SIGNAL(okClicked()), + this, SLOT(slotUpdateColorSpaceMenu())); + editor->loadTool(tool); } } } // namespace Digikam diff --git a/core/dplugins/editor/colors/profileconversiontoolplugin.h b/core/dplugins/editor/colors/profileconversiontoolplugin.h index 8a5415b796..8380428a65 100644 --- a/core/dplugins/editor/colors/profileconversiontoolplugin.h +++ b/core/dplugins/editor/colors/profileconversiontoolplugin.h @@ -1,62 +1,72 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2018-07-30 - * Description : image editor plugin to adjust HSL + * Description : image editor plugin to convert to color space * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ -#ifndef DIGIKAM_HSLTOOL_PLUGIN_H -#define DIGIKAM_HSLTOOL_PLUGIN_H +#ifndef DIGIKAM_PROFILECONVERSIONTOOL_PLUGIN_H +#define DIGIKAM_PROFILECONVERSIONTOOL_PLUGIN_H // Local includes #include "dplugineditor.h" -#define DPLUGIN_IID "org.kde.digikam.plugin.editor.HSLTool" +#define DPLUGIN_IID "org.kde.digikam.plugin.editor.ProfileConversionTool" namespace Digikam { -class HSLToolPlugin : public DPluginEditor +class IccProfile; +class IccProfilesMenuAction; + +class ProfileConversionToolPlugin : public DPluginEditor { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginEditor) public: - explicit HSLToolPlugin(QObject* const parent = 0); - ~HSLToolPlugin(); + explicit ProfileConversionToolPlugin(QObject* const parent = 0); + ~ProfileConversionToolPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; void setup(QObject* const); private Q_SLOTS: - void slotHSL(); + void slotConvertToColorSpace(const IccProfile& profile); + void slotUpdateColorSpaceMenu(); + void slotProfileConversionTool(); + +private: + + IccProfilesMenuAction* m_profileMenuAction; + QAction* m_colorSpaceConverter; }; } // namespace Digikam -#endif // DIGIKAM_HSLTOOL_PLUGIN_H +#endif // DIGIKAM_PROFILECONVERSIONTOOL_PLUGIN_H diff --git a/core/utilities/imageeditor/CMakeLists.txt b/core/utilities/imageeditor/CMakeLists.txt index 0f8929adae..1d5a932cc4 100644 --- a/core/utilities/imageeditor/CMakeLists.txt +++ b/core/utilities/imageeditor/CMakeLists.txt @@ -1,162 +1,157 @@ # # Copyright (c) 2010-2019 by Gilles Caulier, # Copyright (c) 2015 by Veaceslav Munteanu, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif (POLICY CMP0063) include_directories($ $ $ $ $ $ $ $ $ $ $ ) if(KF5KIO_FOUND) include_directories($) endif() if(Gphoto2_FOUND) include_directories(${GPHOTO2_INCLUDE_DIRS}) endif() set(libeditorwidgets_SRCS widgets/imageguidewidget.cpp widgets/imagebrushguidewidget.cpp widgets/imagepreviewitem.cpp widgets/previewtoolbar.cpp widgets/previewlist.cpp widgets/imageregionwidget.cpp widgets/imageregionitem.cpp widgets/rubberitem.cpp widgets/canvas.cpp ) set(libeditordlg_SRCS dialogs/colorcorrectiondlg.cpp dialogs/softproofdialog.cpp dialogs/versioningpromptusersavedlg.cpp ) set(libeditorgui_SRCS main/imagewindow.cpp main/imagewindow_setup.cpp main/imagewindow_config.cpp main/imagewindow_tools.cpp main/imagewindow_import.cpp ) install(FILES main/imageeditorui5.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/digikam) set(libeditorcore_SRCS core/undocache.cpp core/undoaction.cpp core/undomanager.cpp core/editorcore.cpp core/iccpostloadingmanager.cpp ) set(libeditorprintiface_SRCS printiface/printhelper.cpp printiface/printoptionspage.cpp printiface/printconfig.cpp ) ki18n_wrap_ui(libeditorprintiface_SRCS printiface/printoptionspage.ui ) set(libeditorrawimport_SRCS rawimport/rawimport.cpp rawimport/rawpreview.cpp rawimport/rawsettingsbox.cpp ) set(libeditortools_SRCS tools/decorate/inserttextwidget.cpp tools/decorate/inserttexttool.cpp tools/decorate/bordertool.cpp tools/decorate/texturetool.cpp tools/filters/colorfxtool.cpp tools/filters/charcoaltool.cpp tools/filters/embosstool.cpp tools/filters/oilpainttool.cpp tools/filters/blurfxtool.cpp tools/filters/distortionfxtool.cpp tools/filters/raindroptool.cpp tools/filters/filmgraintool.cpp - tools/colors/profileconversiontool.cpp - tools/colors/cbtool.cpp tools/colors/whitebalancetool.cpp - tools/colors/hsltool.cpp - tools/colors/channelmixertool.cpp - tools/colors/filmtool.cpp tools/enhance/restorationtool.cpp tools/enhance/blurtool.cpp tools/enhance/sharpentool.cpp tools/enhance/noisereductiontool.cpp tools/enhance/localcontrasttool.cpp tools/enhance/redeyetool.cpp tools/enhance/antivignettingtool.cpp tools/enhance/lensdistortiontool.cpp tools/enhance/healingclonetool.cpp tools/enhance/hotpixels/weights.cpp tools/enhance/hotpixels/blackframeparser.cpp tools/enhance/hotpixels/blackframelistview.cpp tools/enhance/hotpixels/hotpixelfixer.cpp tools/enhance/hotpixels/hotpixelstool.cpp tools/transform/freerotationtool.cpp tools/transform/sheartool.cpp tools/transform/resizetool.cpp tools/transform/perspectivetool.cpp tools/transform/perspectivewidget.cpp tools/transform/triangle.cpp tools/transform/matrix.cpp tools/transform/imageselectionwidget.cpp tools/transform/ratiocroptool.cpp ) if(Lqr-1_FOUND) set(libeditortools_SRCS ${libeditortools_SRCS} tools/transform/contentawareresizetool.cpp ) endif() if(LensFun_FOUND) set(libeditortools_SRCS ${libeditortools_SRCS} tools/enhance/lensautofixtool.cpp ) include_directories(${LENSFUN_INCLUDE_DIRS}) endif() set(libeditoriface_SRCS editor/editortool.cpp editor/editortooliface.cpp editor/editorstackview.cpp editor/editortoolsettings.cpp editor/editorwindow.cpp editor/imageiface.cpp ) # this lib is used to build digikam core add_library(imageeditor_src OBJECT ${libeditorcore_SRCS} ${libeditordlg_SRCS} ${libeditoriface_SRCS} ${libeditorprintiface_SRCS} ${libeditorrawimport_SRCS} ${libeditorwidgets_SRCS} ${libeditortools_SRCS} ) add_library(imageeditorgui_src OBJECT ${libeditorgui_SRCS}) diff --git a/core/utilities/imageeditor/editor/editorwindow.cpp b/core/utilities/imageeditor/editor/editorwindow.cpp index 9f196cb03d..0a57a314de 100644 --- a/core/utilities/imageeditor/editor/editorwindow.cpp +++ b/core/utilities/imageeditor/editor/editorwindow.cpp @@ -1,3533 +1,3417 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2006-01-20 * Description : core image editor GUI implementation * * Copyright (C) 2006-2019 by Gilles Caulier * Copyright (C) 2009-2011 by Andi Clemens * Copyright (C) 2015 by Mohamed_Anwer * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "editorwindow.h" #include "editorwindow_p.h" // C++ includes #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include #include #ifdef HAVE_KIO # include #endif // Local includes #include "digikam_debug.h" #include "digikam_globals.h" #include "dmessagebox.h" #include "applicationsettings.h" #include "actioncategorizedview.h" #include "canvas.h" #include "categorizeditemmodel.h" #include "colorcorrectiondlg.h" #include "editorcore.h" #include "dlogoaction.h" #include "dmetadata.h" #include "dzoombar.h" #include "drawdecoderwidget.h" #include "editorstackview.h" #include "editortool.h" #include "editortoolsettings.h" #include "editortooliface.h" #include "exposurecontainer.h" #include "dfileoperations.h" #include "filereadwritelock.h" #include "filesaveoptionsbox.h" #include "filesaveoptionsdlg.h" #include "iccpostloadingmanager.h" #include "iccsettings.h" #include "iccsettingscontainer.h" #include "icctransform.h" #include "imagedialog.h" #include "iofilesettings.h" #include "metaenginesettings.h" #include "libsinfodlg.h" #include "loadingcacheinterface.h" #include "printhelper.h" #include "jpegsettings.h" #include "pngsettings.h" #include "savingcontext.h" #include "sidebar.h" #include "slideshowsettings.h" #include "softproofdialog.h" #include "statusprogressbar.h" #include "thememanager.h" #include "thumbnailsize.h" #include "thumbnailloadthread.h" #include "versioningpromptusersavedlg.h" #include "undostate.h" #include "versionmanager.h" +#include "dfiledialog.h" #include "dexpanderbox.h" + #include "inserttexttool.h" #include "bordertool.h" #include "texturetool.h" #include "colorfxtool.h" #include "charcoaltool.h" #include "embosstool.h" #include "oilpainttool.h" #include "blurfxtool.h" #include "distortionfxtool.h" #include "raindroptool.h" #include "filmgraintool.h" #include "invertfilter.h" #include "imageiface.h" -#include "iccprofilescombobox.h" -#include "hsltool.h" -#include "profileconversiontool.h" -#include "cbtool.h" #include "whitebalancetool.h" -#include "channelmixertool.h" -#include "filmtool.h" #include "restorationtool.h" #include "blurtool.h" #include "healingclonetool.h" #include "sharpentool.h" #include "noisereductiontool.h" #include "localcontrasttool.h" #include "redeyetool.h" #include "antivignettingtool.h" #include "lensdistortiontool.h" #include "hotpixelstool.h" #include "perspectivetool.h" #include "freerotationtool.h" #include "sheartool.h" #include "resizetool.h" #include "ratiocroptool.h" -#include "dfiledialog.h" #ifdef HAVE_LIBLQR_1 # include "contentawareresizetool.h" #endif #ifdef HAVE_LENSFUN # include "lensautofixtool.h" #endif namespace Digikam { EditorWindow::EditorWindow(const QString& name) : DXmlGuiWindow(0), d(new Private) { setConfigGroupName(QLatin1String("ImageViewer Settings")); setObjectName(name); setWindowFlags(Qt::Window); setFullScreenOptions(FS_EDITOR); m_nonDestructive = true; m_contextMenu = 0; m_servicesMenu = 0; m_serviceAction = 0; m_canvas = 0; m_openVersionAction = 0; m_saveAction = 0; m_saveAsAction = 0; m_saveCurrentVersionAction = 0; m_saveNewVersionAction = 0; m_saveNewVersionAsAction = 0; m_saveNewVersionInFormatAction = 0; m_resLabel = 0; m_nameLabel = 0; m_exportAction = 0; m_revertAction = 0; m_discardChangesAction = 0; m_fileDeleteAction = 0; m_forwardAction = 0; m_backwardAction = 0; m_firstAction = 0; m_lastAction = 0; m_applyToolAction = 0; m_closeToolAction = 0; m_undoAction = 0; m_redoAction = 0; m_showBarAction = 0; m_splitter = 0; m_vSplitter = 0; m_stackView = 0; m_setExifOrientationTag = true; m_editingOriginalImage = true; m_actionEnabledState = false; m_cancelSlideShow = false; // Settings containers instance. d->exposureSettings = new ExposureSettingsContainer(); d->toolIface = new EditorToolIface(this); m_IOFileSettings = new IOFileSettings(); //d->waitingLoop = new QEventLoop(this); } EditorWindow::~EditorWindow() { delete m_canvas; delete m_IOFileSettings; delete d->toolIface; delete d->exposureSettings; delete d; } EditorStackView* EditorWindow::editorStackView() const { return m_stackView; } ExposureSettingsContainer* EditorWindow::exposureSettings() const { return d->exposureSettings; } void EditorWindow::setupContextMenu() { m_contextMenu = new QMenu(this); addAction2ContextMenu(QLatin1String("editorwindow_fullscreen"), true); addAction2ContextMenu(QLatin1String("options_show_menubar"), true); m_contextMenu->addSeparator(); // -------------------------------------------------------- addAction2ContextMenu(QLatin1String("editorwindow_backward"), true); addAction2ContextMenu(QLatin1String("editorwindow_forward"), true); m_contextMenu->addSeparator(); // -------------------------------------------------------- addAction2ContextMenu(QLatin1String("editorwindow_slideshow"), true); addAction2ContextMenu(QLatin1String("editorwindow_transform_rotateleft"), true); addAction2ContextMenu(QLatin1String("editorwindow_transform_rotateright"), true); addAction2ContextMenu(QLatin1String("editorwindow_transform_crop"), true); m_contextMenu->addSeparator(); // -------------------------------------------------------- addAction2ContextMenu(QLatin1String("editorwindow_delete"), true); } void EditorWindow::setupStandardConnections() { connect(m_stackView, SIGNAL(signalToggleOffFitToWindow()), this, SLOT(slotToggleOffFitToWindow())); // -- Canvas connections ------------------------------------------------ connect(m_canvas, SIGNAL(signalShowNextImage()), this, SLOT(slotForward())); connect(m_canvas, SIGNAL(signalShowPrevImage()), this, SLOT(slotBackward())); connect(m_canvas, SIGNAL(signalRightButtonClicked()), this, SLOT(slotContextMenu())); connect(m_stackView, SIGNAL(signalZoomChanged(bool,bool,double)), this, SLOT(slotZoomChanged(bool,bool,double))); connect(m_canvas, SIGNAL(signalChanged()), this, SLOT(slotChanged())); connect(m_canvas, SIGNAL(signalAddedDropedItems(QDropEvent*)), this, SLOT(slotAddedDropedItems(QDropEvent*))); connect(m_canvas->interface(), SIGNAL(signalUndoStateChanged()), this, SLOT(slotUndoStateChanged())); connect(m_canvas, SIGNAL(signalSelected(bool)), this, SLOT(slotSelected(bool))); connect(m_canvas, SIGNAL(signalPrepareToLoad()), this, SLOT(slotPrepareToLoad())); connect(m_canvas, SIGNAL(signalLoadingStarted(QString)), this, SLOT(slotLoadingStarted(QString))); connect(m_canvas, SIGNAL(signalLoadingFinished(QString,bool)), this, SLOT(slotLoadingFinished(QString,bool))); connect(m_canvas, SIGNAL(signalLoadingProgress(QString,float)), this, SLOT(slotLoadingProgress(QString,float))); connect(m_canvas, SIGNAL(signalSavingStarted(QString)), this, SLOT(slotSavingStarted(QString))); connect(m_canvas, SIGNAL(signalSavingFinished(QString,bool)), this, SLOT(slotSavingFinished(QString,bool))); connect(m_canvas, SIGNAL(signalSavingProgress(QString,float)), this, SLOT(slotSavingProgress(QString,float))); connect(m_canvas, SIGNAL(signalSelectionChanged(QRect)), this, SLOT(slotSelectionChanged(QRect))); connect(m_canvas, SIGNAL(signalSelectionSetText(QRect)), this, SLOT(slotSelectionSetText(QRect))); connect(m_canvas->interface(), SIGNAL(signalFileOriginChanged(QString)), this, SLOT(slotFileOriginChanged(QString))); // -- status bar connections -------------------------------------- connect(m_nameLabel, SIGNAL(signalCancelButtonPressed()), this, SLOT(slotNameLabelCancelButtonPressed())); connect(m_nameLabel, SIGNAL(signalCancelButtonPressed()), d->toolIface, SLOT(slotToolAborted())); // -- Icc settings connections -------------------------------------- connect(IccSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotColorManagementOptionsChanged())); } void EditorWindow::setupStandardActions() { // -- Standard 'File' menu actions --------------------------------------------- KActionCollection* const ac = actionCollection(); m_backwardAction = buildStdAction(StdBackAction, this, SLOT(slotBackward()), this); ac->addAction(QLatin1String("editorwindow_backward"), m_backwardAction); ac->setDefaultShortcuts(m_backwardAction, QList() << Qt::Key_PageUp << Qt::Key_Backspace << Qt::Key_Up << Qt::Key_Left); m_backwardAction->setEnabled(false); m_forwardAction = buildStdAction(StdForwardAction, this, SLOT(slotForward()), this); ac->addAction(QLatin1String("editorwindow_forward"), m_forwardAction); ac->setDefaultShortcuts(m_forwardAction, QList() << Qt::Key_PageDown << Qt::Key_Space << Qt::Key_Down << Qt::Key_Right); m_forwardAction->setEnabled(false); m_firstAction = new QAction(QIcon::fromTheme(QLatin1String("go-first")), i18n("&First"), this); connect(m_firstAction, SIGNAL(triggered()), this, SLOT(slotFirst())); ac->addAction(QLatin1String("editorwindow_first"), m_firstAction); ac->setDefaultShortcuts(m_firstAction, QList() << Qt::CTRL + Qt::Key_Home); m_firstAction->setEnabled(false); m_lastAction = new QAction(QIcon::fromTheme(QLatin1String("go-last")), i18n("&Last"), this); connect(m_lastAction, SIGNAL(triggered()), this, SLOT(slotLast())); ac->addAction(QLatin1String("editorwindow_last"), m_lastAction); ac->setDefaultShortcuts(m_lastAction, QList() << Qt::CTRL + Qt::Key_End); m_lastAction->setEnabled(false); m_openVersionAction = new QAction(QIcon::fromTheme(QLatin1String("view-preview")), i18nc("@action", "Open Original"), this); connect(m_openVersionAction, SIGNAL(triggered()), this, SLOT(slotOpenOriginal())); ac->addAction(QLatin1String("editorwindow_openversion"), m_openVersionAction); ac->setDefaultShortcuts(m_openVersionAction, QList() << Qt::CTRL + Qt::Key_End); m_saveAction = buildStdAction(StdSaveAction, this, SLOT(saveOrSaveAs()), this); ac->addAction(QLatin1String("editorwindow_save"), m_saveAction); m_saveAsAction = buildStdAction(StdSaveAsAction, this, SLOT(saveAs()), this); ac->addAction(QLatin1String("editorwindow_saveas"), m_saveAsAction); m_saveCurrentVersionAction = new QAction(QIcon::fromTheme(QLatin1String("dialog-ok-apply")), i18nc("@action Save changes to current version", "Save Changes"), this); m_saveCurrentVersionAction->setToolTip(i18nc("@info:tooltip", "Save the modifications to the current version of the file")); connect(m_saveCurrentVersionAction, SIGNAL(triggered()), this, SLOT(saveCurrentVersion())); ac->addAction(QLatin1String("editorwindow_savecurrentversion"), m_saveCurrentVersionAction); m_saveNewVersionAction = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("list-add")), i18nc("@action Save changes to a newly created version", "Save As New Version"), this); m_saveNewVersionAction->setToolTip(i18nc("@info:tooltip", "Save the current modifications to a new version of the file")); connect(m_saveNewVersionAction, SIGNAL(triggered()), this, SLOT(saveNewVersion())); ac->addAction(QLatin1String("editorwindow_savenewversion"), m_saveNewVersionAction); QAction* const m_saveNewVersionAsAction = new QAction(QIcon::fromTheme(QLatin1String("document-save-as")), i18nc("@action Save changes to a newly created version, specifying the filename and format", "Save New Version As..."), this); m_saveNewVersionAsAction->setToolTip(i18nc("@info:tooltip", "Save the current modifications to a new version of the file, " "specifying the filename and format")); connect(m_saveNewVersionAsAction, SIGNAL(triggered()), this, SLOT(saveNewVersionAs())); m_saveNewVersionInFormatAction = new QMenu(i18nc("@action Save As New Version...Save in format...", "Save in Format"), this); m_saveNewVersionInFormatAction->setIcon(QIcon::fromTheme(QLatin1String("view-preview"))); d->plugNewVersionInFormatAction(this, m_saveNewVersionInFormatAction, i18nc("@action:inmenu", "JPEG"), QLatin1String("JPG")); d->plugNewVersionInFormatAction(this, m_saveNewVersionInFormatAction, i18nc("@action:inmenu", "TIFF"), QLatin1String("TIFF")); d->plugNewVersionInFormatAction(this, m_saveNewVersionInFormatAction, i18nc("@action:inmenu", "PNG"), QLatin1String("PNG")); d->plugNewVersionInFormatAction(this, m_saveNewVersionInFormatAction, i18nc("@action:inmenu", "PGF"), QLatin1String("PGF")); #ifdef HAVE_JASPER d->plugNewVersionInFormatAction(this, m_saveNewVersionInFormatAction, i18nc("@action:inmenu", "JPEG 2000"), QLatin1String("JP2")); #endif // HAVE_JASPER m_saveNewVersionAction->menu()->addAction(m_saveNewVersionAsAction); m_saveNewVersionAction->menu()->addAction(m_saveNewVersionInFormatAction->menuAction()); // This also triggers saveAs, but in the context of non-destructive we want a slightly different appearance m_exportAction = new QAction(QIcon::fromTheme(QLatin1String("document-export")), i18nc("@action", "Export"), this); m_exportAction->setToolTip(i18nc("@info:tooltip", "Save the file in a folder outside your collection")); connect(m_exportAction, SIGNAL(triggered()), this, SLOT(saveAs())); ac->addAction(QLatin1String("editorwindow_export"), m_exportAction); ac->setDefaultShortcut(m_exportAction, Qt::CTRL + Qt::SHIFT + Qt::Key_E); // NOTE: Gimp shortcut m_revertAction = buildStdAction(StdRevertAction, this, SLOT(slotRevert()), this); ac->addAction(QLatin1String("editorwindow_revert"), m_revertAction); m_discardChangesAction = new QAction(QIcon::fromTheme(QLatin1String("task-reject")), i18nc("@action", "Discard Changes"), this); m_discardChangesAction->setToolTip(i18nc("@info:tooltip", "Discard all current changes to this file")); connect(m_discardChangesAction, SIGNAL(triggered()), this, SLOT(slotDiscardChanges())); ac->addAction(QLatin1String("editorwindow_discardchanges"), m_discardChangesAction); m_openVersionAction->setEnabled(false); m_saveAction->setEnabled(false); m_saveAsAction->setEnabled(false); m_saveCurrentVersionAction->setEnabled(false); m_saveNewVersionAction->setEnabled(false); m_revertAction->setEnabled(false); m_discardChangesAction->setEnabled(false); d->filePrintAction = new QAction(QIcon::fromTheme(QLatin1String("document-print-frame")), i18n("Print Image..."), this); connect(d->filePrintAction, SIGNAL(triggered()), this, SLOT(slotFilePrint())); ac->addAction(QLatin1String("editorwindow_print"), d->filePrintAction); ac->setDefaultShortcut(d->filePrintAction, Qt::CTRL + Qt::Key_P); d->filePrintAction->setEnabled(false); d->openWithAction = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-filetype-association")), i18n("Open With Default Application"), this); d->openWithAction->setWhatsThis(i18n("Open the item with default assigned application.")); connect(d->openWithAction, SIGNAL(triggered()), this, SLOT(slotFileWithDefaultApplication())); ac->addAction(QLatin1String("open_with_default_application"), d->openWithAction); ac->setDefaultShortcut(d->openWithAction, Qt::META + Qt::Key_F4); d->openWithAction->setEnabled(false); m_fileDeleteAction = new QAction(QIcon::fromTheme(QLatin1String("user-trash-full")), i18nc("Non-pluralized", "Move to Trash"), this); connect(m_fileDeleteAction, SIGNAL(triggered()), this, SLOT(slotDeleteCurrentItem())); ac->addAction(QLatin1String("editorwindow_delete"), m_fileDeleteAction); ac->setDefaultShortcut(m_fileDeleteAction, Qt::Key_Delete); m_fileDeleteAction->setEnabled(false); QAction* const closeAction = buildStdAction(StdCloseAction, this, SLOT(close()), this); ac->addAction(QLatin1String("editorwindow_close"), closeAction); // -- Standard 'Edit' menu actions --------------------------------------------- d->copyAction = buildStdAction(StdCopyAction, m_canvas, SLOT(slotCopy()), this); ac->addAction(QLatin1String("editorwindow_copy"), d->copyAction); d->copyAction->setEnabled(false); m_undoAction = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("edit-undo")), i18n("Undo"), this); m_undoAction->setEnabled(false); ac->addAction(QLatin1String("editorwindow_undo"), m_undoAction); ac->setDefaultShortcuts(m_undoAction, QList() << Qt::CTRL + Qt::Key_Z); connect(m_undoAction->menu(), SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowUndoMenu())); // we are using a signal mapper to identify which of a bunch of actions was triggered d->undoSignalMapper = new QSignalMapper(this); // connect mapper to view connect(d->undoSignalMapper, SIGNAL(mapped(int)), m_canvas, SLOT(slotUndo(int))); // connect simple undo action connect(m_undoAction, SIGNAL(triggered()), d->undoSignalMapper, SLOT(map())); d->undoSignalMapper->setMapping(m_undoAction, 1); m_redoAction = new KToolBarPopupAction(QIcon::fromTheme(QLatin1String("edit-redo")), i18n("Redo"), this); m_redoAction->setEnabled(false); ac->addAction(QLatin1String("editorwindow_redo"), m_redoAction); ac->setDefaultShortcuts(m_redoAction, QList() << Qt::CTRL + Qt::SHIFT + Qt::Key_Z); connect(m_redoAction->menu(), SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowRedoMenu())); d->redoSignalMapper = new QSignalMapper(this); connect(d->redoSignalMapper, SIGNAL(mapped(int)), m_canvas, SLOT(slotRedo(int))); connect(m_redoAction, SIGNAL(triggered()), d->redoSignalMapper, SLOT(map())); d->redoSignalMapper->setMapping(m_redoAction, 1); d->selectAllAction = new QAction(i18nc("Create a selection containing the full image", "Select All"), this); connect(d->selectAllAction, SIGNAL(triggered()), m_canvas, SLOT(slotSelectAll())); ac->addAction(QLatin1String("editorwindow_selectAll"), d->selectAllAction); ac->setDefaultShortcut(d->selectAllAction, Qt::CTRL + Qt::Key_A); d->selectNoneAction = new QAction(i18n("Select None"), this); connect(d->selectNoneAction, SIGNAL(triggered()), m_canvas, SLOT(slotSelectNone())); ac->addAction(QLatin1String("editorwindow_selectNone"), d->selectNoneAction); ac->setDefaultShortcut(d->selectNoneAction, Qt::CTRL + Qt::SHIFT + Qt::Key_A); // -- Standard 'View' menu actions --------------------------------------------- d->zoomPlusAction = buildStdAction(StdZoomInAction, this, SLOT(slotIncreaseZoom()), this); ac->addAction(QLatin1String("editorwindow_zoomplus"), d->zoomPlusAction); d->zoomMinusAction = buildStdAction(StdZoomOutAction, this, SLOT(slotDecreaseZoom()), this); ac->addAction(QLatin1String("editorwindow_zoomminus"), d->zoomMinusAction); d->zoomTo100percents = new QAction(QIcon::fromTheme(QLatin1String("zoom-original")), i18n("Zoom to 100%"), this); connect(d->zoomTo100percents, SIGNAL(triggered()), this, SLOT(slotZoomTo100Percents())); ac->addAction(QLatin1String("editorwindow_zoomto100percents"), d->zoomTo100percents); ac->setDefaultShortcut(d->zoomTo100percents, Qt::CTRL + Qt::Key_Period); d->zoomFitToWindowAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-fit-best")), i18n("Fit to &Window"), this); d->zoomFitToWindowAction->setCheckable(true); connect(d->zoomFitToWindowAction, SIGNAL(triggered()), this, SLOT(slotToggleFitToWindow())); ac->addAction(QLatin1String("editorwindow_zoomfit2window"), d->zoomFitToWindowAction); ac->setDefaultShortcut(d->zoomFitToWindowAction, Qt::ALT + Qt::CTRL + Qt::Key_E); d->zoomFitToSelectAction = new QAction(QIcon::fromTheme(QLatin1String("zoom-select-fit")), i18n("Fit to &Selection"), this); connect(d->zoomFitToSelectAction, SIGNAL(triggered()), this, SLOT(slotFitToSelect())); ac->addAction(QLatin1String("editorwindow_zoomfit2select"), d->zoomFitToSelectAction); ac->setDefaultShortcut(d->zoomFitToSelectAction, Qt::ALT + Qt::CTRL + Qt::Key_S); // NOTE: Photoshop 7 use ALT+CTRL+0 d->zoomFitToSelectAction->setEnabled(false); d->zoomFitToSelectAction->setWhatsThis(i18n("This option can be used to zoom the image to the " "current selection area.")); // -- Standard 'Decorate' menu actions --------------------------------------------- d->insertTextAction = new QAction(QIcon::fromTheme(QLatin1String("insert-text")), i18n("Insert Text..."), this); actionCollection()->addAction(QLatin1String("editorwindow_decorate_inserttext"), d->insertTextAction ); actionCollection()->setDefaultShortcut(d->insertTextAction, Qt::SHIFT+Qt::CTRL+Qt::Key_T); connect(d->insertTextAction, SIGNAL(triggered(bool)), this, SLOT(slotInsertText())); d->insertTextAction->setEnabled(false); d->borderAction = new QAction(QIcon::fromTheme(QLatin1String("bordertool")), i18n("Add Border..."), this); actionCollection()->addAction(QLatin1String("editorwindow_decorate_border"), d->borderAction ); connect(d->borderAction, SIGNAL(triggered(bool)), this, SLOT(slotBorder())); d->borderAction->setEnabled(false); d->textureAction = new QAction(QIcon::fromTheme(QLatin1String("texture")), i18n("Apply Texture..."), this); actionCollection()->addAction(QLatin1String("editorwindow_decorate_texture"), d->textureAction ); connect(d->textureAction, SIGNAL(triggered(bool)), this, SLOT(slotTexture())); d->textureAction->setEnabled(false); // -- Standard 'Effects' menu actions --------------------------------------------- d->colorEffectsAction = new QAction(QIcon::fromTheme(QLatin1String("colorfx")), i18n("Color Effects..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_colorfx"), d->colorEffectsAction); connect(d->colorEffectsAction, SIGNAL(triggered(bool)), this, SLOT(slotColorEffects())); d->colorEffectsAction->setEnabled(false); d->charcoalAction = new QAction(QIcon::fromTheme(QLatin1String("charcoaltool")), i18n("Charcoal Drawing..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_charcoal"), d->charcoalAction); connect(d->charcoalAction, SIGNAL(triggered(bool)), this, SLOT(slotCharcoal())); d->charcoalAction->setEnabled(false); d->embossAction = new QAction(QIcon::fromTheme(QLatin1String("embosstool")), i18n("Emboss..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_emboss"), d->embossAction); connect(d->embossAction, SIGNAL(triggered(bool)), this, SLOT(slotEmboss())); d->embossAction->setEnabled(false); d->oilpaintAction = new QAction(QIcon::fromTheme(QLatin1String("oilpaint")), i18n("Oil Paint..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_oilpaint"), d->oilpaintAction); connect(d->oilpaintAction, SIGNAL(triggered(bool)), this ,SLOT(slotOilPaint())); d->oilpaintAction->setEnabled(false); d->blurfxAction = new QAction(QIcon::fromTheme(QLatin1String("blurfx")), i18n("Blur Effects..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_blurfx"), d->blurfxAction); connect(d->blurfxAction, SIGNAL(triggered(bool)), this, SLOT(slotBlurFX())); d->blurfxAction->setEnabled(false); d->distortionfxAction = new QAction(QIcon::fromTheme(QLatin1String("draw-spiral")), i18n("Distortion Effects..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_distortionfx"), d->distortionfxAction ); connect(d->distortionfxAction, SIGNAL(triggered(bool)), this, SLOT(slotDistortionFX())); d->distortionfxAction->setEnabled(false); d->raindropAction = new QAction(QIcon::fromTheme(QLatin1String("raindrop")), i18n("Raindrops..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_raindrop"), d->raindropAction); connect(d->raindropAction, SIGNAL(triggered(bool)), this, SLOT(slotRainDrop())); d->raindropAction->setEnabled(false); d->filmgrainAction = new QAction(QIcon::fromTheme(QLatin1String("filmgrain")), i18n("Add Film Grain..."), this); actionCollection()->addAction(QLatin1String("editorwindow_filter_filmgrain"), d->filmgrainAction); connect(d->filmgrainAction, SIGNAL(triggered(bool)), this, SLOT(slotFilmGrain())); d->filmgrainAction->setEnabled(false); // -- Standard 'Colors' menu actions --------------------------------------------- d->BCGAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_bcg"), this); actionCollection()->addActions(QList() << d->BCGAction); d->BCGAction->setEnabled(false); d->curvesAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_adjustcurves"), this); actionCollection()->addActions(QList() << d->curvesAction); d->curvesAction->setEnabled(false); d->levelsAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_adjustlevels"), this); actionCollection()->addActions(QList() << d->levelsAction); d->levelsAction->setEnabled(false); d->autoCorrectionAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_autocorrection"), this); actionCollection()->addActions(QList() << d->autoCorrectionAction); d->autoCorrectionAction->setEnabled(false); d->BWAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_blackwhite"), this); actionCollection()->addActions(QList() << d->BWAction); d->BWAction->setEnabled(false); + d->CBAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_rgb"), this); + actionCollection()->addActions(QList() << d->CBAction); + d->CBAction->setEnabled(false); + + d->channelMixerAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_channelmixer"), this); + actionCollection()->addActions(QList() << d->channelMixerAction); + d->channelMixerAction->setEnabled(false); + + d->filmAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_film"), this); + actionCollection()->addActions(QList() << d->filmAction); + d->filmAction->setEnabled(false); - // ********************************************************** - - // NOTE: Photoshop 7 use CTRL+U. - d->HSLAction = new QAction(QIcon::fromTheme(QLatin1String("adjusthsl")), i18n("Hue/Saturation/Lightness..."), this); - actionCollection()->addAction(QLatin1String("editorwindow_color_hsl"), d->HSLAction); - actionCollection()->setDefaultShortcut(d->HSLAction, Qt::CTRL+Qt::Key_U); - connect(d->HSLAction, SIGNAL(triggered(bool)), - this, SLOT(slotHSL())); + d->HSLAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_hsl"), this); + actionCollection()->addActions(QList() << d->HSLAction); d->HSLAction->setEnabled(false); - // NOTE: Photoshop 7 use CTRL+B. - d->CBAction = new QAction(QIcon::fromTheme(QLatin1String("adjustrgb")), i18n("Color Balance..."), this); - actionCollection()->addAction(QLatin1String("editorwindow_color_rgb"), d->CBAction); - actionCollection()->setDefaultShortcut(d->CBAction, Qt::CTRL+Qt::Key_B); - connect(d->CBAction, SIGNAL(triggered(bool)), - this, SLOT(slotCB())); - d->CBAction->setEnabled(false); + d->profileMenuAction = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_colormanagement"), this); + actionCollection()->addActions(QList() << d->profileMenuAction); + d->profileMenuAction->setEnabled(false); + + d->colorSpaceConverter = DPluginLoader::instance()->pluginAction(QLatin1String("editorwindow_color_spaceconverter"), this); + d->colorSpaceConverter->setEnabled(false); + + // ********************************************************** // NOTE: Photoshop 7 use CTRL+I. d->invertAction = new QAction(QIcon::fromTheme(QLatin1String("edit-select-invert")), i18n("Invert"), this); actionCollection()->addAction(QLatin1String("editorwindow_color_invert"), d->invertAction); actionCollection()->setDefaultShortcut(d->invertAction, Qt::CTRL+Qt::Key_I); connect(d->invertAction, SIGNAL(triggered(bool)), this, SLOT(slotInvert())); d->invertAction->setEnabled(false); d->convertTo8Bits = new QAction(QIcon::fromTheme(QLatin1String("depth16to8")), i18n("8 bits"), this); actionCollection()->addAction(QLatin1String("editorwindow_convertto8bits"), d->convertTo8Bits); connect(d->convertTo8Bits, SIGNAL(triggered(bool)), this, SLOT(slotConvertTo8Bits())); d->convertTo8Bits->setEnabled(false); d->convertTo16Bits = new QAction(QIcon::fromTheme(QLatin1String("depth8to16")), i18n("16 bits"), this); actionCollection()->addAction(QLatin1String("editorwindow_convertto16bits"), d->convertTo16Bits); connect(d->convertTo16Bits, SIGNAL(triggered(bool)), this, SLOT(slotConvertTo16Bits())); d->convertTo16Bits->setEnabled(false); - d->profileMenuAction = new IccProfilesMenuAction(QIcon::fromTheme(QLatin1String("preferences-desktop-display-color")), i18n("Color Spaces"), this); - actionCollection()->addAction(QLatin1String("editorwindow_colormanagement"), d->profileMenuAction->menuAction()); - connect(d->profileMenuAction, SIGNAL(triggered(IccProfile)), - this, SLOT(slotConvertToColorSpace(IccProfile))); - d->profileMenuAction->setEnabled(false); - - connect(IccSettings::instance(), SIGNAL(settingsChanged()), - this, SLOT(slotUpdateColorSpaceMenu())); - - d->colorSpaceConverter = new QAction(QIcon::fromTheme(QLatin1String("preferences-desktop-display-color")), - i18n("Color Space Converter..."), this); - connect(d->colorSpaceConverter, SIGNAL(triggered()), - this, SLOT(slotProfileConversionTool())); - d->colorSpaceConverter->setEnabled(false); - - slotUpdateColorSpaceMenu(); - d->whitebalanceAction = new QAction(QIcon::fromTheme(QLatin1String("bordertool")), i18n("White Balance..."), this); actionCollection()->addAction(QLatin1String("editorwindow_color_whitebalance"), d->whitebalanceAction); actionCollection()->setDefaultShortcut(d->whitebalanceAction, Qt::CTRL+Qt::SHIFT+Qt::Key_W); connect(d->whitebalanceAction, SIGNAL(triggered(bool)), this, SLOT(slotWhiteBalance())); d->whitebalanceAction->setEnabled(false); - d->channelMixerAction = new QAction(QIcon::fromTheme(QLatin1String("channelmixer")), i18n("Channel Mixer..."), this); - actionCollection()->addAction(QLatin1String("editorwindow_color_channelmixer"), d->channelMixerAction); - actionCollection()->setDefaultShortcut(d->channelMixerAction, Qt::CTRL+Qt::Key_H); - connect(d->channelMixerAction, SIGNAL(triggered(bool)), - this, SLOT(slotChannelMixer())); - d->channelMixerAction->setEnabled(false); - - d->filmAction = new QAction(QIcon::fromTheme(QLatin1String("colorneg")), i18n("Color Negative..."), this); - actionCollection()->addAction(QLatin1String("editorwindow_color_film"), d->filmAction); - actionCollection()->setDefaultShortcut(d->filmAction, Qt::CTRL+Qt::SHIFT+Qt::Key_I); - connect(d->filmAction, SIGNAL(triggered(bool)), - this, SLOT(slotFilm())); - d->filmAction->setEnabled(false); - // -- Standard 'Enhance' menu actions --------------------------------------------- d->restorationAction = new QAction(QIcon::fromTheme(QLatin1String("restoration")), i18n("Restoration..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_restoration"), d->restorationAction); connect(d->restorationAction, SIGNAL(triggered(bool)), this, SLOT(slotRestoration())); d->restorationAction->setEnabled(false); d->sharpenAction = new QAction(QIcon::fromTheme(QLatin1String("sharpenimage")), i18n("Sharpen..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_sharpen"), d->sharpenAction); connect(d->sharpenAction, SIGNAL(triggered(bool)), this, SLOT(slotSharpen())); d->sharpenAction->setEnabled(false); d->blurAction = new QAction(QIcon::fromTheme(QLatin1String("blurimage")), i18n("Blur..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_blur"), d->blurAction); connect(d->blurAction, SIGNAL(triggered(bool)), this, SLOT(slotBlur())); d->blurAction->setEnabled(false); /* d->healCloneAction = new QAction(QIcon::fromTheme(QLatin1String("edit-clone")), i18n("Healing Clone..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_healingclone"), d->healCloneAction); d->healCloneAction->setWhatsThis( i18n( "This filter can be used to clone a part in a photo to erase unwanted region.") ); connect(d->healCloneAction, SIGNAL(triggered(bool)), this, SLOT(slotHealingClone())); d->healCloneAction->setEnabled(false); */ d->noiseReductionAction = new QAction(QIcon::fromTheme(QLatin1String("noisereduction")), i18n("Noise Reduction..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_noisereduction"), d->noiseReductionAction); connect(d->noiseReductionAction, SIGNAL(triggered(bool)), this, SLOT(slotNoiseReduction())); d->noiseReductionAction->setEnabled(false); d->localContrastAction = new QAction(QIcon::fromTheme(QLatin1String("contrast")), i18n("Local Contrast..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_localcontrast"), d->localContrastAction); connect(d->localContrastAction, SIGNAL(triggered(bool)), this, SLOT(slotLocalContrast())); d->localContrastAction->setEnabled(false); d->redeyeAction = new QAction(QIcon::fromTheme(QLatin1String("redeyes")), i18n("Red Eye..."), this); d->redeyeAction->setWhatsThis(i18n("This filter can be used to correct red eyes in a photo. " "Select a region including the eyes to use this option.")); actionCollection()->addAction(QLatin1String("editorwindow_enhance_redeye"), d->redeyeAction); connect(d->redeyeAction, SIGNAL(triggered(bool)), this, SLOT(slotRedEye())); d->redeyeAction->setEnabled(false); d->antivignettingAction = new QAction(QIcon::fromTheme(QLatin1String("antivignetting")), i18n("Vignetting Correction..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_antivignetting"), d->antivignettingAction); connect(d->antivignettingAction, SIGNAL(triggered(bool)), this, SLOT(slotAntiVignetting())); d->antivignettingAction->setEnabled(false); d->lensdistortionAction = new QAction(QIcon::fromTheme(QLatin1String("lensdistortion")), i18n("Distortion..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_lensdistortion"), d->lensdistortionAction); connect(d->lensdistortionAction, SIGNAL(triggered(bool)), this, SLOT(slotLensDistortion())); d->lensdistortionAction->setEnabled(false); d->hotpixelsAction = new QAction(QIcon::fromTheme(QLatin1String("hotpixels")), i18n("Hot Pixels..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_hotpixels"), d->hotpixelsAction); connect(d->hotpixelsAction, SIGNAL(triggered(bool)), this, SLOT(slotHotPixels())); d->hotpixelsAction->setEnabled(false); #ifdef HAVE_LENSFUN d->lensAutoFixAction = new QAction(QIcon::fromTheme(QLatin1String("lensautofix")), i18n("Auto-Correction..."), this); actionCollection()->addAction(QLatin1String("editorwindow_enhance_lensautofix"), d->lensAutoFixAction ); connect(d->lensAutoFixAction, SIGNAL(triggered(bool)), this, SLOT(slotLensAutoFix())); d->lensAutoFixAction->setEnabled(false); #endif // HAVE_LENSFUN HotPixelsTool::registerFilter(); QList actions = DPluginLoader::instance()->pluginsActions(DPluginAction::Generic, this); foreach (DPluginAction* const ac, actions) { ac->setEnabled(false); } // -------------------------------------------------------- createFullScreenAction(QLatin1String("editorwindow_fullscreen")); createSidebarActions(); d->slideShowAction = new QAction(QIcon::fromTheme(QLatin1String("view-presentation")), i18n("Slideshow"), this); connect(d->slideShowAction, SIGNAL(triggered()), this, SLOT(slotToggleSlideShow())); ac->addAction(QLatin1String("editorwindow_slideshow"), d->slideShowAction); ac->setDefaultShortcut(d->slideShowAction, Qt::Key_F9); d->viewUnderExpoAction = new QAction(QIcon::fromTheme(QLatin1String("underexposure")), i18n("Under-Exposure Indicator"), this); d->viewUnderExpoAction->setCheckable(true); d->viewUnderExpoAction->setWhatsThis(i18n("Set this option to display black " "overlaid on the image. This will help you to avoid " "under-exposing the image.")); connect(d->viewUnderExpoAction, SIGNAL(triggered(bool)), this, SLOT(slotSetUnderExposureIndicator(bool))); ac->addAction(QLatin1String("editorwindow_underexposure"), d->viewUnderExpoAction); ac->setDefaultShortcut(d->viewUnderExpoAction, Qt::Key_F10); d->viewOverExpoAction = new QAction(QIcon::fromTheme(QLatin1String("overexposure")), i18n("Over-Exposure Indicator"), this); d->viewOverExpoAction->setCheckable(true); d->viewOverExpoAction->setWhatsThis(i18n("Set this option to display white " "overlaid on the image. This will help you to avoid " "over-exposing the image.")); connect(d->viewOverExpoAction, SIGNAL(triggered(bool)), this, SLOT(slotSetOverExposureIndicator(bool))); ac->addAction(QLatin1String("editorwindow_overexposure"), d->viewOverExpoAction); ac->setDefaultShortcut(d->viewOverExpoAction, Qt::Key_F11); d->viewCMViewAction = new QAction(QIcon::fromTheme(QLatin1String("video-display")), i18n("Color-Managed View"), this); d->viewCMViewAction->setCheckable(true); connect(d->viewCMViewAction, SIGNAL(triggered()), this, SLOT(slotToggleColorManagedView())); ac->addAction(QLatin1String("editorwindow_cmview"), d->viewCMViewAction); ac->setDefaultShortcut(d->viewCMViewAction, Qt::Key_F12); d->softProofOptionsAction = new QAction(QIcon::fromTheme(QLatin1String("printer")), i18n("Soft Proofing Options..."), this); connect(d->softProofOptionsAction, SIGNAL(triggered()), this, SLOT(slotSoftProofingOptions())); ac->addAction(QLatin1String("editorwindow_softproofoptions"), d->softProofOptionsAction); d->viewSoftProofAction = new QAction(QIcon::fromTheme(QLatin1String("document-print-preview")), i18n("Soft Proofing View"), this); d->viewSoftProofAction->setCheckable(true); connect(d->viewSoftProofAction, SIGNAL(triggered()), this, SLOT(slotUpdateSoftProofingState())); ac->addAction(QLatin1String("editorwindow_softproofview"), d->viewSoftProofAction); // -- Standard 'Transform' menu actions --------------------------------------------- d->cropAction = new QAction(QIcon::fromTheme(QLatin1String("transform-crop-and-resize")), i18nc("@action", "Crop to Selection"), this); connect(d->cropAction, SIGNAL(triggered()), m_canvas, SLOT(slotCrop())); d->cropAction->setEnabled(false); d->cropAction->setWhatsThis(i18n("This option can be used to crop the image. " "Select a region of the image to enable this action.")); ac->addAction(QLatin1String("editorwindow_transform_crop"), d->cropAction); ac->setDefaultShortcut(d->cropAction, Qt::CTRL + Qt::Key_X); d->autoCropAction = new QAction(QIcon::fromTheme(QLatin1String("transform-crop")), i18nc("@action", "Auto-Crop"), this); d->autoCropAction->setWhatsThis(i18n("This option can be used to crop automatically the image.")); connect(d->autoCropAction, SIGNAL(triggered()), m_canvas, SLOT(slotAutoCrop())); d->autoCropAction->setEnabled(false); ac->addAction(QLatin1String("editorwindow_transform_autocrop"), d->autoCropAction); ac->setDefaultShortcut(d->autoCropAction, Qt::SHIFT + Qt::CTRL + Qt::Key_X); d->perspectiveAction = new QAction(QIcon::fromTheme(QLatin1String("perspective")), i18n("Perspective Adjustment..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_perspective"), d->perspectiveAction); connect(d->perspectiveAction, SIGNAL(triggered(bool)), this, SLOT(slotPerspective())); d->perspectiveAction->setEnabled(false); d->sheartoolAction = new QAction(QIcon::fromTheme(QLatin1String("transform-shear-left")), i18n("Shear..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_sheartool"), d->sheartoolAction); connect(d->sheartoolAction, SIGNAL(triggered(bool)), this, SLOT(slotShearTool())); d->sheartoolAction->setEnabled(false); d->resizeAction = new QAction(QIcon::fromTheme(QLatin1String("transform-scale")), i18n("&Resize..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_resize"), d->resizeAction); connect(d->resizeAction, SIGNAL(triggered()), this, SLOT(slotResize())); d->resizeAction->setEnabled(false); d->aspectRatioCropAction = new QAction(QIcon::fromTheme(QLatin1String("transform-crop")), i18n("Aspect Ratio Crop..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_ratiocrop"), d->aspectRatioCropAction); connect(d->aspectRatioCropAction, SIGNAL(triggered(bool)), this, SLOT(slotRatioCrop())); d->aspectRatioCropAction->setEnabled(false); #ifdef HAVE_LIBLQR_1 d->contentAwareResizingAction = new QAction(QIcon::fromTheme(QLatin1String("transform-scale")), i18n("Liquid Rescale..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_contentawareresizing"), d->contentAwareResizingAction); connect(d->contentAwareResizingAction, SIGNAL(triggered(bool)), this, SLOT(slotContentAwareResizing())); d->contentAwareResizingAction->setEnabled(false); #endif /* HAVE_LIBLQR_1 */ //----------------------------------------------------------------------------------- d->freerotationAction = new QAction(QIcon::fromTheme(QLatin1String("transform-rotate")), i18n("Free Rotation..."), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_freerotation"), d->freerotationAction ); connect(d->freerotationAction, SIGNAL(triggered(bool)), this, SLOT(slotFreeRotation())); d->freerotationAction->setEnabled(false); QAction* const point1Action = new QAction(i18n("Set Point 1"), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_freerotation_point1"), point1Action); actionCollection()->setDefaultShortcut(point1Action, Qt::CTRL + Qt::SHIFT + Qt::Key_1); connect(point1Action, SIGNAL(triggered(bool)), this, SIGNAL(signalPoint1Action())); QAction* const point2Action = new QAction(i18n("Set Point 2"), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_freerotation_point2"), point2Action); actionCollection()->setDefaultShortcut(point2Action, Qt::CTRL + Qt::SHIFT + Qt::Key_2); connect(point2Action, SIGNAL(triggered(bool)), this, SIGNAL(signalPoint2Action())); QAction* const autoAdjustAction = new QAction(i18n("Auto Adjust"), this); actionCollection()->addAction(QLatin1String("editorwindow_transform_freerotation_autoadjust"), autoAdjustAction); actionCollection()->setDefaultShortcut(autoAdjustAction, Qt::CTRL + Qt::SHIFT + Qt::Key_R); connect(autoAdjustAction, SIGNAL(triggered(bool)), this, SIGNAL(signalAutoAdjustAction())); // -- Standard 'Flip' menu actions --------------------------------------------- d->flipHorizAction = new QAction(QIcon::fromTheme(QLatin1String("object-flip-horizontal")), i18n("Flip Horizontally"), this); connect(d->flipHorizAction, SIGNAL(triggered()), m_canvas, SLOT(slotFlipHoriz())); connect(d->flipHorizAction, SIGNAL(triggered()), this, SLOT(slotFlipHIntoQue())); ac->addAction(QLatin1String("editorwindow_transform_fliphoriz"), d->flipHorizAction); ac->setDefaultShortcut(d->flipHorizAction, Qt::CTRL + Qt::Key_Asterisk); d->flipHorizAction->setEnabled(false); d->flipVertAction = new QAction(QIcon::fromTheme(QLatin1String("object-flip-vertical")), i18n("Flip Vertically"), this); connect(d->flipVertAction, SIGNAL(triggered()), m_canvas, SLOT(slotFlipVert())); connect(d->flipVertAction, SIGNAL(triggered()), this, SLOT(slotFlipVIntoQue())); ac->addAction(QLatin1String("editorwindow_transform_flipvert"), d->flipVertAction); ac->setDefaultShortcut(d->flipVertAction, Qt::CTRL + Qt::Key_Slash); d->flipVertAction->setEnabled(false); // -- Standard 'Rotate' menu actions ---------------------------------------- d->rotateLeftAction = new QAction(QIcon::fromTheme(QLatin1String("object-rotate-left")), i18n("Rotate Left"), this); connect(d->rotateLeftAction, SIGNAL(triggered()), m_canvas, SLOT(slotRotate270())); connect(d->rotateLeftAction, SIGNAL(triggered()), this, SLOT(slotRotateLeftIntoQue())); ac->addAction(QLatin1String("editorwindow_transform_rotateleft"), d->rotateLeftAction); ac->setDefaultShortcut(d->rotateLeftAction, Qt::SHIFT + Qt::CTRL + Qt::Key_Left); d->rotateLeftAction->setEnabled(false); d->rotateRightAction = new QAction(QIcon::fromTheme(QLatin1String("object-rotate-right")), i18n("Rotate Right"), this); connect(d->rotateRightAction, SIGNAL(triggered()), m_canvas, SLOT(slotRotate90())); connect(d->rotateRightAction, SIGNAL(triggered()), this, SLOT(slotRotateRightIntoQue())); ac->addAction(QLatin1String("editorwindow_transform_rotateright"), d->rotateRightAction); ac->setDefaultShortcut(d->rotateRightAction, Qt::SHIFT + Qt::CTRL + Qt::Key_Right); d->rotateRightAction->setEnabled(false); m_showBarAction = thumbBar()->getToggleAction(this); ac->addAction(QLatin1String("editorwindow_showthumbs"), m_showBarAction); ac->setDefaultShortcut(m_showBarAction, Qt::CTRL + Qt::Key_T); // Provides a menu entry that allows showing/hiding the toolbar(s) setStandardToolBarMenuEnabled(true); // Provides a menu entry that allows showing/hiding the statusbar createStandardStatusBarAction(); // Standard 'Configure' menu actions createSettingsActions(); // --------------------------------------------------------------------------------- ThemeManager::instance()->registerThemeActions(this); connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()), this, SLOT(slotThemeChanged())); // -- Keyboard-only actions -------------------------------------------------------- QAction* const altBackwardAction = new QAction(i18n("Previous Image"), this); ac->addAction(QLatin1String("editorwindow_backward_shift_space"), altBackwardAction); ac->setDefaultShortcut(altBackwardAction, Qt::SHIFT + Qt::Key_Space); connect(altBackwardAction, SIGNAL(triggered()), this, SLOT(slotBackward())); // -- Tool control actions --------------------------------------------------------- m_applyToolAction = new QAction(QIcon::fromTheme(QLatin1String("dialog-ok-apply")), i18n("OK"), this); ac->addAction(QLatin1String("editorwindow_applytool"), m_applyToolAction); ac->setDefaultShortcut(m_applyToolAction, Qt::Key_Return); connect(m_applyToolAction, SIGNAL(triggered()), this, SLOT(slotApplyTool())); m_closeToolAction = new QAction(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("Cancel"), this); ac->addAction(QLatin1String("editorwindow_closetool"), m_closeToolAction); ac->setDefaultShortcut(m_closeToolAction, Qt::Key_Escape); connect(m_closeToolAction, SIGNAL(triggered()), this, SLOT(slotCloseTool())); toggleNonDestructiveActions(); toggleToolActions(); } void EditorWindow::setupStatusBar() { m_nameLabel = new StatusProgressBar(statusBar()); m_nameLabel->setAlignment(Qt::AlignCenter); statusBar()->addWidget(m_nameLabel, 100); d->infoLabel = new DAdjustableLabel(statusBar()); d->infoLabel->setAdjustedText(i18n("No selection")); d->infoLabel->setAlignment(Qt::AlignCenter); statusBar()->addWidget(d->infoLabel, 100); d->infoLabel->setToolTip(i18n("Information about current image selection")); m_resLabel = new DAdjustableLabel(statusBar()); m_resLabel->setAlignment(Qt::AlignCenter); statusBar()->addWidget(m_resLabel, 100); m_resLabel->setToolTip(i18n("Information about image size")); d->zoomBar = new DZoomBar(statusBar()); d->zoomBar->setZoomToFitAction(d->zoomFitToWindowAction); d->zoomBar->setZoomTo100Action(d->zoomTo100percents); d->zoomBar->setZoomPlusAction(d->zoomPlusAction); d->zoomBar->setZoomMinusAction(d->zoomMinusAction); d->zoomBar->setBarMode(DZoomBar::PreviewZoomCtrl); statusBar()->addPermanentWidget(d->zoomBar); connect(d->zoomBar, SIGNAL(signalZoomSliderChanged(int)), m_stackView, SLOT(slotZoomSliderChanged(int))); connect(d->zoomBar, SIGNAL(signalZoomValueEdited(double)), m_stackView, SLOT(setZoomFactor(double))); d->previewToolBar = new PreviewToolBar(statusBar()); d->previewToolBar->registerMenuActionGroup(this); d->previewToolBar->setEnabled(false); statusBar()->addPermanentWidget(d->previewToolBar); connect(d->previewToolBar, SIGNAL(signalPreviewModeChanged(int)), this, SIGNAL(signalPreviewModeChanged(int))); QWidget* const buttonsBox = new QWidget(statusBar()); QHBoxLayout* const hlay = new QHBoxLayout(buttonsBox); QButtonGroup* const buttonsGrp = new QButtonGroup(buttonsBox); buttonsGrp->setExclusive(false); d->underExposureIndicator = new QToolButton(buttonsBox); d->underExposureIndicator->setDefaultAction(d->viewUnderExpoAction); d->underExposureIndicator->setFocusPolicy(Qt::NoFocus); d->overExposureIndicator = new QToolButton(buttonsBox); d->overExposureIndicator->setDefaultAction(d->viewOverExpoAction); d->overExposureIndicator->setFocusPolicy(Qt::NoFocus); d->cmViewIndicator = new QToolButton(buttonsBox); d->cmViewIndicator->setDefaultAction(d->viewCMViewAction); d->cmViewIndicator->setFocusPolicy(Qt::NoFocus); buttonsGrp->addButton(d->underExposureIndicator); buttonsGrp->addButton(d->overExposureIndicator); buttonsGrp->addButton(d->cmViewIndicator); hlay->setSpacing(0); hlay->setContentsMargins(QMargins()); hlay->addWidget(d->underExposureIndicator); hlay->addWidget(d->overExposureIndicator); hlay->addWidget(d->cmViewIndicator); statusBar()->addPermanentWidget(buttonsBox); } void EditorWindow::printImage(const QUrl&) { DImg* const image = m_canvas->interface()->getImg(); if (!image || image->isNull()) { return; } PrintHelper printHelp(this); printHelp.print(*image); } void EditorWindow::slotAboutToShowUndoMenu() { m_undoAction->menu()->clear(); QStringList titles = m_canvas->interface()->getUndoHistory(); for (int i = 0; i < titles.size(); ++i) { QAction* const action = m_undoAction->menu()->addAction(titles.at(i), d->undoSignalMapper, SLOT(map())); d->undoSignalMapper->setMapping(action, i + 1); } } void EditorWindow::slotAboutToShowRedoMenu() { m_redoAction->menu()->clear(); QStringList titles = m_canvas->interface()->getRedoHistory(); for (int i = 0; i < titles.size(); ++i) { QAction* const action = m_redoAction->menu()->addAction(titles.at(i), d->redoSignalMapper, SLOT(map())); d->redoSignalMapper->setMapping(action, i + 1); } } void EditorWindow::slotIncreaseZoom() { m_stackView->increaseZoom(); } void EditorWindow::slotDecreaseZoom() { m_stackView->decreaseZoom(); } void EditorWindow::slotToggleFitToWindow() { d->zoomPlusAction->setEnabled(true); d->zoomBar->setEnabled(true); d->zoomMinusAction->setEnabled(true); m_stackView->toggleFitToWindow(); } void EditorWindow::slotFitToSelect() { d->zoomPlusAction->setEnabled(true); d->zoomBar->setEnabled(true); d->zoomMinusAction->setEnabled(true); m_stackView->fitToSelect(); } void EditorWindow::slotZoomTo100Percents() { d->zoomPlusAction->setEnabled(true); d->zoomBar->setEnabled(true); d->zoomMinusAction->setEnabled(true); m_stackView->zoomTo100Percent(); } void EditorWindow::slotZoomChanged(bool isMax, bool isMin, double zoom) { //qCDebug(DIGIKAM_GENERAL_LOG) << "EditorWindow::slotZoomChanged"; d->zoomPlusAction->setEnabled(!isMax); d->zoomMinusAction->setEnabled(!isMin); double zmin = m_stackView->zoomMin(); double zmax = m_stackView->zoomMax(); d->zoomBar->setZoom(zoom, zmin, zmax); } void EditorWindow::slotToggleOffFitToWindow() { d->zoomFitToWindowAction->blockSignals(true); d->zoomFitToWindowAction->setChecked(false); d->zoomFitToWindowAction->blockSignals(false); } void EditorWindow::readStandardSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(configGroupName()); // Restore Canvas layout if (group.hasKey(d->configVerticalSplitterSizesEntry) && m_vSplitter) { QByteArray state; state = group.readEntry(d->configVerticalSplitterStateEntry, state); m_vSplitter->restoreState(QByteArray::fromBase64(state)); } // Restore full screen Mode readFullScreenSettings(group); // Restore Auto zoom action bool autoZoom = group.readEntry(d->configAutoZoomEntry, true); if (autoZoom) { d->zoomFitToWindowAction->trigger(); } slotSetUnderExposureIndicator(group.readEntry(d->configUnderExposureIndicatorEntry, false)); slotSetOverExposureIndicator(group.readEntry(d->configOverExposureIndicatorEntry, false)); d->previewToolBar->readSettings(group); } void EditorWindow::applyStandardSettings() { applyColorManagementSettings(); d->toolIface->updateICCSettings(); applyIOSettings(); // -- GUI Settings ------------------------------------------------------- KConfigGroup group = KSharedConfig::openConfig()->group(configGroupName()); d->legacyUpdateSplitterState(group); m_splitter->restoreState(group); readFullScreenSettings(group); slotThemeChanged(); // -- Exposure Indicators Settings --------------------------------------- d->exposureSettings->underExposureColor = group.readEntry(d->configUnderExposureColorEntry, QColor(Qt::white)); d->exposureSettings->underExposurePercent = group.readEntry(d->configUnderExposurePercentsEntry, 1.0); d->exposureSettings->overExposureColor = group.readEntry(d->configOverExposureColorEntry, QColor(Qt::black)); d->exposureSettings->overExposurePercent = group.readEntry(d->configOverExposurePercentsEntry, 1.0); d->exposureSettings->exposureIndicatorMode = group.readEntry(d->configExpoIndicatorModeEntry, true); d->toolIface->updateExposureSettings(); // -- Metadata Settings -------------------------------------------------- MetaEngineSettingsContainer writeSettings = MetaEngineSettings::instance()->settings(); m_setExifOrientationTag = writeSettings.exifSetOrientation; m_canvas->setExifOrient(writeSettings.exifRotate); } void EditorWindow::applyIOSettings() { // -- JPEG, PNG, TIFF, JPEG2000, PGF files format settings ---------------- KConfigGroup group = KSharedConfig::openConfig()->group(configGroupName()); m_IOFileSettings->JPEGCompression = JPEGSettings::convertCompressionForLibJpeg(group.readEntry(d->configJpegCompressionEntry, 75)); m_IOFileSettings->JPEGSubSampling = group.readEntry(d->configJpegSubSamplingEntry, 1); // Medium subsampling m_IOFileSettings->PNGCompression = PNGSettings::convertCompressionForLibPng(group.readEntry(d->configPngCompressionEntry, 1)); // TIFF compression setting. m_IOFileSettings->TIFFCompression = group.readEntry(d->configTiffCompressionEntry, false); // JPEG2000 quality slider settings : 1 - 100 m_IOFileSettings->JPEG2000Compression = group.readEntry(d->configJpeg2000CompressionEntry, 100); // JPEG2000 LossLess setting. m_IOFileSettings->JPEG2000LossLess = group.readEntry(d->configJpeg2000LossLessEntry, true); // PGF quality slider settings : 1 - 9 m_IOFileSettings->PGFCompression = group.readEntry(d->configPgfCompressionEntry, 3); // PGF LossLess setting. m_IOFileSettings->PGFLossLess = group.readEntry(d->configPgfLossLessEntry, true); // -- RAW images decoding settings ------------------------------------------------------ m_IOFileSettings->useRAWImport = group.readEntry(d->configUseRawImportToolEntry, false); DRawDecoderWidget::readSettings(m_IOFileSettings->rawDecodingSettings.rawPrm, group); // Raw Color Management settings: // If digiKam Color Management is enabled, no need to correct color of decoded RAW image, // else, sRGB color workspace will be used. ICCSettingsContainer settings = IccSettings::instance()->settings(); if (settings.enableCM) { if (settings.defaultUncalibratedBehavior & ICCSettingsContainer::AutomaticColors) { m_IOFileSettings->rawDecodingSettings.rawPrm.outputColorSpace = DRawDecoderSettings::CUSTOMOUTPUTCS; m_IOFileSettings->rawDecodingSettings.rawPrm.outputProfile = settings.workspaceProfile; } else { m_IOFileSettings->rawDecodingSettings.rawPrm.outputColorSpace = DRawDecoderSettings::RAWCOLOR; } } else { m_IOFileSettings->rawDecodingSettings.rawPrm.outputColorSpace = DRawDecoderSettings::SRGB; } } void EditorWindow::applyColorManagementSettings() { ICCSettingsContainer settings = IccSettings::instance()->settings(); d->toolIface->updateICCSettings(); m_canvas->setICCSettings(settings); d->viewCMViewAction->blockSignals(true); d->viewCMViewAction->setEnabled(settings.enableCM); d->viewCMViewAction->setChecked(settings.useManagedView); setColorManagedViewIndicatorToolTip(settings.enableCM, settings.useManagedView); d->viewCMViewAction->blockSignals(false); d->viewSoftProofAction->setEnabled(settings.enableCM && !settings.defaultProofProfile.isEmpty()); d->softProofOptionsAction->setEnabled(settings.enableCM); } void EditorWindow::saveStandardSettings() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(configGroupName()); group.writeEntry(d->configAutoZoomEntry, d->zoomFitToWindowAction->isChecked()); m_splitter->saveState(group); if (m_vSplitter) { group.writeEntry(d->configVerticalSplitterStateEntry, m_vSplitter->saveState().toBase64()); } group.writeEntry("Show Thumbbar", thumbBar()->shouldBeVisible()); group.writeEntry(d->configUnderExposureIndicatorEntry, d->exposureSettings->underExposureIndicator); group.writeEntry(d->configOverExposureIndicatorEntry, d->exposureSettings->overExposureIndicator); d->previewToolBar->writeSettings(group); config->sync(); } /** Method used by Editor Tools. Only tools based on imageregionwidget support zooming. TODO: Fix this behavior when editor tool preview widgets will be factored. */ void EditorWindow::toggleZoomActions(bool val) { d->zoomMinusAction->setEnabled(val); d->zoomPlusAction->setEnabled(val); d->zoomTo100percents->setEnabled(val); d->zoomFitToWindowAction->setEnabled(val); d->zoomBar->setEnabled(val); } void EditorWindow::readSettings() { readStandardSettings(); } void EditorWindow::saveSettings() { saveStandardSettings(); } void EditorWindow::toggleActions(bool val) { toggleStandardActions(val); } +bool EditorWindow::actionEnabledState() const +{ + return m_actionEnabledState; +} + void EditorWindow::toggleStandardActions(bool val) { d->zoomFitToSelectAction->setEnabled(val); toggleZoomActions(val); m_actionEnabledState = val; m_forwardAction->setEnabled(val); m_backwardAction->setEnabled(val); m_firstAction->setEnabled(val); m_lastAction->setEnabled(val); d->rotateLeftAction->setEnabled(val); d->rotateRightAction->setEnabled(val); d->flipHorizAction->setEnabled(val); d->flipVertAction->setEnabled(val); m_fileDeleteAction->setEnabled(val); m_saveAsAction->setEnabled(val); d->openWithAction->setEnabled(val); d->filePrintAction->setEnabled(val); m_exportAction->setEnabled(val); d->selectAllAction->setEnabled(val); d->selectNoneAction->setEnabled(val); d->slideShowAction->setEnabled(val); QList actions = DPluginLoader::instance()->pluginsActions(DPluginAction::Generic, this); foreach (DPluginAction* const ac, actions) { ac->setEnabled(val); } // these actions are special: They are turned off if val is false, // but if val is true, they may be turned on or off. if (val) { // Update actions by retrieving current values slotUndoStateChanged(); } else { m_openVersionAction->setEnabled(false); m_revertAction->setEnabled(false); m_saveAction->setEnabled(false); m_saveCurrentVersionAction->setEnabled(false); m_saveNewVersionAction->setEnabled(false); m_discardChangesAction->setEnabled(false); m_undoAction->setEnabled(false); m_redoAction->setEnabled(false); } // Tools actions d->insertTextAction->setEnabled(val); d->borderAction->setEnabled(val); d->textureAction->setEnabled(val); d->charcoalAction->setEnabled(val); d->colorEffectsAction->setEnabled(val); d->embossAction->setEnabled(val); d->oilpaintAction->setEnabled(val); d->blurfxAction->setEnabled(val); d->distortionfxAction->setEnabled(val); d->raindropAction->setEnabled(val); d->filmgrainAction->setEnabled(val); d->convertTo8Bits->setEnabled(val); d->convertTo16Bits->setEnabled(val); d->invertAction->setEnabled(val); d->BCGAction->setEnabled(val); d->CBAction->setEnabled(val); d->autoCorrectionAction->setEnabled(val); d->BWAction->setEnabled(val); d->HSLAction->setEnabled(val); + d->profileMenuAction->setEnabled(val); d->colorSpaceConverter->setEnabled(val && IccSettings::instance()->isEnabled()); + d->whitebalanceAction->setEnabled(val); d->channelMixerAction->setEnabled(val); d->curvesAction->setEnabled(val); d->levelsAction->setEnabled(val); d->filmAction->setEnabled(val); d->restorationAction->setEnabled(val); d->blurAction->setEnabled(val); //d->healCloneAction->setEnabled(val); d->sharpenAction->setEnabled(val); d->noiseReductionAction->setEnabled(val); d->localContrastAction->setEnabled(val); d->redeyeAction->setEnabled(val); d->lensdistortionAction->setEnabled(val); d->antivignettingAction->setEnabled(val); d->hotpixelsAction->setEnabled(val); d->resizeAction->setEnabled(val); d->autoCropAction->setEnabled(val); d->perspectiveAction->setEnabled(val); d->freerotationAction->setEnabled(val); d->sheartoolAction->setEnabled(val); d->aspectRatioCropAction->setEnabled(val); #ifdef HAVE_LENSFUN d->lensAutoFixAction->setEnabled(val); #endif #ifdef HAVE_LIBLQR_1 d->contentAwareResizingAction->setEnabled(val); #endif } void EditorWindow::toggleNonDestructiveActions() { m_saveAction->setVisible(!m_nonDestructive); m_saveAsAction->setVisible(!m_nonDestructive); m_revertAction->setVisible(!m_nonDestructive); m_openVersionAction->setVisible(m_nonDestructive); m_saveCurrentVersionAction->setVisible(m_nonDestructive); m_saveNewVersionAction->setVisible(m_nonDestructive); m_exportAction->setVisible(m_nonDestructive); m_discardChangesAction->setVisible(m_nonDestructive); } void EditorWindow::toggleToolActions(EditorTool* tool) { if (tool) { m_applyToolAction->setText(tool->toolSettings()->button(EditorToolSettings::Ok)->text()); m_applyToolAction->setIcon(tool->toolSettings()->button(EditorToolSettings::Ok)->icon()); m_applyToolAction->setToolTip(tool->toolSettings()->button(EditorToolSettings::Ok)->toolTip()); m_closeToolAction->setText(tool->toolSettings()->button(EditorToolSettings::Cancel)->text()); m_closeToolAction->setIcon(tool->toolSettings()->button(EditorToolSettings::Cancel)->icon()); m_closeToolAction->setToolTip(tool->toolSettings()->button(EditorToolSettings::Cancel)->toolTip()); } m_applyToolAction->setVisible(tool); m_closeToolAction->setVisible(tool); } void EditorWindow::slotLoadingProgress(const QString&, float progress) { m_nameLabel->setProgressValue((int)(progress * 100.0)); } void EditorWindow::slotSavingProgress(const QString&, float progress) { m_nameLabel->setProgressValue((int)(progress * 100.0)); if (m_savingProgressDialog) { m_savingProgressDialog->setValue((int)(progress * 100.0)); } } void EditorWindow::execSavingProgressDialog() { if (m_savingProgressDialog) { return; } m_savingProgressDialog = new QProgressDialog(this); m_savingProgressDialog->setWindowTitle(i18n("Saving image...")); m_savingProgressDialog->setLabelText(i18n("Please wait for the image to be saved...")); m_savingProgressDialog->setAttribute(Qt::WA_DeleteOnClose); m_savingProgressDialog->setAutoClose(true); m_savingProgressDialog->setMinimumDuration(1000); m_savingProgressDialog->setMaximum(100); // we must enter a fully modal dialog, no QEventLoop is sufficient for KWin to accept longer waiting times m_savingProgressDialog->setModal(true); m_savingProgressDialog->exec(); } bool EditorWindow::promptForOverWrite() { QUrl destination = saveDestinationUrl(); if (destination.isLocalFile()) { QFileInfo fi(m_canvas->currentImageFilePath()); QString warnMsg(i18n("About to overwrite file \"%1\"\nAre you sure?", QDir::toNativeSeparators(fi.fileName()))); return (DMessageBox::showContinueCancel(QMessageBox::Warning, this, i18n("Warning"), warnMsg, QLatin1String("editorWindowSaveOverwrite")) == QMessageBox::Yes); } else { // in this case it will handle the overwrite request return true; } } void EditorWindow::slotUndoStateChanged() { UndoState state = m_canvas->interface()->undoState(); // RAW conversion qualifies as a "non-undoable" action // You can save as new version, but cannot undo or revert m_undoAction->setEnabled(state.hasUndo); m_redoAction->setEnabled(state.hasRedo); m_revertAction->setEnabled(state.hasUndoableChanges); m_saveAction->setEnabled(state.hasChanges); m_saveCurrentVersionAction->setEnabled(state.hasChanges); m_saveNewVersionAction->setEnabled(state.hasChanges); m_discardChangesAction->setEnabled(state.hasUndoableChanges); m_openVersionAction->setEnabled(hasOriginalToRestore()); } bool EditorWindow::hasOriginalToRestore() { return m_canvas->interface()->getResolvedInitialHistory().hasOriginalReferredImage(); } DImageHistory EditorWindow::resolvedImageHistory(const DImageHistory& history) { // simple, database-less version DImageHistory r = history; QList::iterator it; for (it = r.entries().begin(); it != r.entries().end(); ++it) { QList::iterator hit; for (hit = it->referredImages.begin(); hit != it->referredImages.end();) { QFileInfo info(hit->m_filePath + QLatin1Char('/') + hit->m_fileName); if (!info.exists()) { hit = it->referredImages.erase(hit); } else { ++hit; } } } return r; } bool EditorWindow::promptUserSave(const QUrl& url, SaveAskMode mode, bool allowCancel) { if (d->currentWindowModalDialog) { d->currentWindowModalDialog->reject(); } if (m_canvas->interface()->undoState().hasUndoableChanges) { // if window is minimized, show it if (isMinimized()) { KWindowSystem::unminimizeWindow(winId()); } bool shallSave = true; bool shallDiscard = false; bool newVersion = false; if (mode == AskIfNeeded) { if (m_nonDestructive) { if (versionManager()->settings().editorClosingMode == VersionManagerSettings::AutoSave) { shallSave = true; } else { QPointer dialog = new VersioningPromptUserSaveDialog(this); dialog->exec(); if (!dialog) { return false; } shallSave = dialog->shallSave() || dialog->newVersion(); shallDiscard = dialog->shallDiscard(); newVersion = dialog->newVersion(); } } else { QString boxMessage; boxMessage = i18nc("@info", "The image %1 has been modified.
" "Do you want to save it?
", url.fileName()); int result; if (allowCancel) { result = QMessageBox::warning(this, qApp->applicationName(), boxMessage, QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); } else { result = QMessageBox::warning(this, qApp->applicationName(), boxMessage, QMessageBox::Save | QMessageBox::Discard); } shallSave = (result == QMessageBox::Save); shallDiscard = (result == QMessageBox::Discard); } } if (shallSave) { bool saving = false; switch (mode) { case AskIfNeeded: if (m_nonDestructive) { if (newVersion) { saving = saveNewVersion(); } else { // will know on its own if new version is required saving = saveCurrentVersion(); } } else { if (m_canvas->isReadOnly()) { saving = saveAs(); } else if (promptForOverWrite()) { saving = save(); } } break; case OverwriteWithoutAsking: if (m_nonDestructive) { if (newVersion) { saving = saveNewVersion(); } else { // will know on its own if new version is required saving = saveCurrentVersion(); } } else { if (m_canvas->isReadOnly()) { saving = saveAs(); } else { saving = save(); } } break; case AlwaysSaveAs: if (m_nonDestructive) { saving = saveNewVersion(); } else { saving = saveAs(); } break; } // save and saveAs return false if they were canceled and did not enter saving at all // In this case, do not call enterWaitingLoop because quitWaitingloop will not be called. if (saving) { // Waiting for asynchronous image file saving operation running in separate thread. m_savingContext.synchronizingState = SavingContext::SynchronousSaving; enterWaitingLoop(); m_savingContext.synchronizingState = SavingContext::NormalSaving; return m_savingContext.synchronousSavingResult; } else { return false; } } else if (shallDiscard) { // Discard m_saveAction->setEnabled(false); return true; } else { return false; } } return true; } bool EditorWindow::promptUserDelete(const QUrl& url) { if (d->currentWindowModalDialog) { d->currentWindowModalDialog->reject(); } if (m_canvas->interface()->undoState().hasUndoableChanges) { // if window is minimized, show it if (isMinimized()) { KWindowSystem::unminimizeWindow(winId()); } QString boxMessage = i18nc("@info", "The image %1 has been modified.
" "All changes will be lost.", url.fileName()); int result = DMessageBox::showContinueCancel(QMessageBox::Warning, this, QString(), boxMessage); if (result == QMessageBox::Cancel) { return false; } } return true; } bool EditorWindow::waitForSavingToComplete() { // avoid reentrancy - return false means we have reentered the loop already. if (m_savingContext.synchronizingState == SavingContext::SynchronousSaving) { return false; } if (m_savingContext.savingState != SavingContext::SavingStateNone) { // Waiting for asynchronous image file saving operation running in separate thread. m_savingContext.synchronizingState = SavingContext::SynchronousSaving; enterWaitingLoop(); m_savingContext.synchronizingState = SavingContext::NormalSaving; } return true; } void EditorWindow::enterWaitingLoop() { //d->waitingLoop->exec(QEventLoop::ExcludeUserInputEvents); execSavingProgressDialog(); } void EditorWindow::quitWaitingLoop() { //d->waitingLoop->quit(); if (m_savingProgressDialog) { m_savingProgressDialog->close(); } } void EditorWindow::slotSelected(bool val) { // Update menu actions. d->cropAction->setEnabled(val); d->zoomFitToSelectAction->setEnabled(val); d->copyAction->setEnabled(val); QRect sel = m_canvas->getSelectedArea(); // Update histogram into sidebar. emit signalSelectionChanged(sel); // Update status bar if (val) { slotSelectionSetText(sel); } else { setToolInfoMessage(i18n("No selection")); } } void EditorWindow::slotPrepareToLoad() { // Disable actions as appropriate during loading emit signalNoCurrentItem(); unsetCursor(); m_animLogo->stop(); toggleActions(false); slotUpdateItemInfo(); } void EditorWindow::slotLoadingStarted(const QString& /*filename*/) { setCursor(Qt::WaitCursor); toggleActions(false); m_animLogo->start(); m_nameLabel->setProgressBarMode(StatusProgressBar::ProgressBarMode, i18n("Loading:")); } void EditorWindow::slotLoadingFinished(const QString& filename, bool success) { m_nameLabel->setProgressBarMode(StatusProgressBar::TextMode); // Enable actions as appropriate after loading // No need to re-enable image properties sidebar here, it's will be done // automatically by a signal from canvas toggleActions(success); slotUpdateItemInfo(); unsetCursor(); m_animLogo->stop(); if (success) { colorManage(); // Set a history which contains all available files as referredImages DImageHistory resolved = resolvedImageHistory(m_canvas->interface()->getInitialImageHistory()); m_canvas->interface()->setResolvedInitialHistory(resolved); } else { DNotificationPopup::message(DNotificationPopup::Boxed, i18n("Cannot load \"%1\"", filename), m_canvas, m_canvas->mapToGlobal(QPoint(30, 30))); } } void EditorWindow::resetOrigin() { // With versioning, "only" resetting undo history does not work anymore // as we calculate undo state based on the initial history stored in the DImg resetOriginSwitchFile(); } void EditorWindow::resetOriginSwitchFile() { DImageHistory resolved = resolvedImageHistory(m_canvas->interface()->getItemHistory()); m_canvas->interface()->switchToLastSaved(resolved); } void EditorWindow::colorManage() { if (!IccSettings::instance()->isEnabled()) { return; } DImg image = m_canvas->currentImage(); if (image.isNull()) { return; } if (!IccManager::needsPostLoadingManagement(image)) { return; } IccPostLoadingManager manager(image, m_canvas->currentImageFilePath()); if (!manager.hasValidWorkspace()) { QString message = i18n("Cannot open the specified working space profile (\"%1\"). " "No color transformation will be applied. " "Please check the color management " "configuration in digiKam's setup.", IccSettings::instance()->settings().workspaceProfile); QMessageBox::information(this, qApp->applicationName(), message); } // Show dialog and get transform from user choice IccTransform trans = manager.postLoadingManage(this); // apply transform in thread. // Do _not_ test for willHaveEffect() here - there are more side effects when calling this method m_canvas->applyTransform(trans); slotUpdateItemInfo(); } void EditorWindow::slotNameLabelCancelButtonPressed() { // If we saving an image... if (m_savingContext.savingState != SavingContext::SavingStateNone) { m_savingContext.abortingSaving = true; m_canvas->abortSaving(); } // If we preparing SlideShow... m_cancelSlideShow = true; } void EditorWindow::slotFileOriginChanged(const QString&) { // implemented in subclass } bool EditorWindow::saveOrSaveAs() { if (m_canvas->isReadOnly()) { return saveAs(); } return save(); } void EditorWindow::slotSavingStarted(const QString& /*filename*/) { setCursor(Qt::WaitCursor); m_animLogo->start(); // Disable actions as appropriate during saving emit signalNoCurrentItem(); toggleActions(false); m_nameLabel->setProgressBarMode(StatusProgressBar::CancelProgressBarMode, i18n("Saving:")); } void EditorWindow::slotSavingFinished(const QString& filename, bool success) { Q_UNUSED(filename); qCDebug(DIGIKAM_GENERAL_LOG) << filename << success << (m_savingContext.savingState != SavingContext::SavingStateNone); // only handle this if we really wanted to save a file... if (m_savingContext.savingState != SavingContext::SavingStateNone) { m_savingContext.executedOperation = m_savingContext.savingState; m_savingContext.savingState = SavingContext::SavingStateNone; if (!success) { if (!m_savingContext.abortingSaving) { QMessageBox::critical(this, qApp->applicationName(), i18n("Failed to save file\n\"%1\"\nto\n\"%2\".", m_savingContext.destinationURL.fileName(), m_savingContext.destinationURL.toLocalFile())); } finishSaving(false); return; } moveFile(); } else { qCWarning(DIGIKAM_GENERAL_LOG) << "Why was slotSavingFinished called if we did not want to save a file?"; } } void EditorWindow::movingSaveFileFinished(bool successful) { if (!successful) { finishSaving(false); return; } // now that we know the real destination file name, pass it to be recorded in image history m_canvas->interface()->setLastSaved(m_savingContext.destinationURL.toLocalFile()); // remove image from cache since it has changed LoadingCacheInterface::fileChanged(m_savingContext.destinationURL.toLocalFile()); ThumbnailLoadThread::deleteThumbnail(m_savingContext.destinationURL.toLocalFile()); // restore state of disabled actions. saveIsComplete can start any other task // (loading!) which might itself in turn change states finishSaving(true); switch (m_savingContext.executedOperation) { case SavingContext::SavingStateNone: break; case SavingContext::SavingStateSave: saveIsComplete(); break; case SavingContext::SavingStateSaveAs: saveAsIsComplete(); break; case SavingContext::SavingStateVersion: saveVersionIsComplete(); break; } // Take all actions necessary to update information and re-enable sidebar slotChanged(); } void EditorWindow::finishSaving(bool success) { m_savingContext.synchronousSavingResult = success; delete m_savingContext.saveTempFile; m_savingContext.saveTempFile = 0; // Exit of internal Qt event loop to unlock promptUserSave() method. if (m_savingContext.synchronizingState == SavingContext::SynchronousSaving) { quitWaitingLoop(); } // Enable actions as appropriate after saving toggleActions(true); unsetCursor(); m_animLogo->stop(); m_nameLabel->setProgressBarMode(StatusProgressBar::TextMode); /*if (m_savingProgressDialog) { m_savingProgressDialog->close(); }*/ // On error, continue using current image if (!success) { /* Why this? * m_canvas->switchToLastSaved(m_savingContext.srcURL.toLocalFile());*/ } } void EditorWindow::setupTempSaveFile(const QUrl& url) { // if the destination url is on local file system, try to set the temp file // location to the destination folder, otherwise use a local default QString tempDir = url.adjusted(QUrl::RemoveFilename|QUrl::StripTrailingSlash).toLocalFile(); if (!url.isLocalFile() || tempDir.isEmpty()) { tempDir = QDir::tempPath(); } QFileInfo fi(url.toLocalFile()); QString suffix = fi.suffix(); // use magic file extension which tells the digikamalbums ioslave to ignore the file m_savingContext.saveTempFile = new SafeTemporaryFile(tempDir + QLatin1String("/EditorWindow-XXXXXX.digikamtempfile.") + suffix); m_savingContext.saveTempFile->setAutoRemove(false); if (!m_savingContext.saveTempFile->open()) { QMessageBox::critical(this, qApp->applicationName(), i18n("Could not open a temporary file in the folder \"%1\": %2 (%3)", QDir::toNativeSeparators(tempDir), m_savingContext.saveTempFile->errorString(), m_savingContext.saveTempFile->error())); return; } m_savingContext.saveTempFileName = m_savingContext.saveTempFile->fileName(); delete m_savingContext.saveTempFile; m_savingContext.saveTempFile = 0; } void EditorWindow::startingSave(const QUrl& url) { qCDebug(DIGIKAM_GENERAL_LOG) << "startSaving url = " << url; // avoid any reentrancy. Should be impossible anyway since actions will be disabled. if (m_savingContext.savingState != SavingContext::SavingStateNone) { return; } m_savingContext = SavingContext(); if (!checkPermissions(url)) { return; } setupTempSaveFile(url); m_savingContext.srcURL = url; m_savingContext.destinationURL = m_savingContext.srcURL; m_savingContext.destinationExisted = true; m_savingContext.originalFormat = m_canvas->currentImageFileFormat(); m_savingContext.format = m_savingContext.originalFormat; m_savingContext.abortingSaving = false; m_savingContext.savingState = SavingContext::SavingStateSave; m_savingContext.executedOperation = SavingContext::SavingStateNone; m_canvas->interface()->saveAs(m_savingContext.saveTempFileName, m_IOFileSettings, m_setExifOrientationTag && m_canvas->exifRotated(), m_savingContext.format, m_savingContext.destinationURL.toLocalFile()); } bool EditorWindow::showFileSaveDialog(const QUrl& initialUrl, QUrl& newURL) { QString all; QStringList list = supportedImageMimeTypes(QIODevice::WriteOnly, all); DFileDialog* const imageFileSaveDialog = new DFileDialog(this); imageFileSaveDialog->setWindowTitle(i18n("New Image File Name")); imageFileSaveDialog->setDirectoryUrl(initialUrl.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash)); imageFileSaveDialog->setAcceptMode(QFileDialog::AcceptSave); imageFileSaveDialog->setFileMode(QFileDialog::AnyFile); imageFileSaveDialog->setNameFilters(list); // restore old settings for the dialog KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(configGroupName()); const QString optionLastExtension = QLatin1String("LastSavedImageExtension"); QString ext = group.readEntry(optionLastExtension, "png"); foreach(const QString& s, list) { if (s.contains(QString::fromLatin1("*.%1").arg(ext))) { imageFileSaveDialog->selectNameFilter(s); break; } } // adjust extension of proposed filename QString fileName = initialUrl.fileName(); if (!fileName.isNull()) { int lastDot = fileName.lastIndexOf(QLatin1Char('.')); QString completeBaseName = (lastDot == -1) ? fileName : fileName.left(lastDot); fileName = completeBaseName + QLatin1Char('.') + ext; } if (!fileName.isNull()) { imageFileSaveDialog->selectFile(fileName); } // Start dialog and check if canceled. int result; if (d->currentWindowModalDialog) { // go application-modal - we will create utter confusion if descending into more than one window-modal dialog imageFileSaveDialog->setModal(true); result = imageFileSaveDialog->exec(); } else { imageFileSaveDialog->setWindowModality(Qt::WindowModal); d->currentWindowModalDialog = imageFileSaveDialog; result = imageFileSaveDialog->exec(); d->currentWindowModalDialog = 0; } if (result != QDialog::Accepted || !imageFileSaveDialog) { qCDebug(DIGIKAM_GENERAL_LOG) << "File Save Dialog rejected"; return false; } QList urls = imageFileSaveDialog->selectedUrls(); if (urls.isEmpty()) { qCDebug(DIGIKAM_GENERAL_LOG) << "no target url"; return false; } newURL = urls.first(); newURL.setPath(QDir::cleanPath(newURL.path())); QFileInfo fi(newURL.fileName()); if (fi.suffix().isEmpty()) { ext = imageFileSaveDialog->selectedNameFilter().section(QLatin1String("*."), 1, 1); ext = ext.left(ext.length() - 1); if (ext.isEmpty()) { ext = QLatin1String("jpg"); } newURL.setPath(newURL.path() + QLatin1Char('.') + ext); } qCDebug(DIGIKAM_GENERAL_LOG) << "Writing file to " << newURL; //-- Show Settings Dialog ---------------------------------------------- const QString configShowImageSettingsDialog = QLatin1String("ShowImageSettingsDialog"); bool showDialog = group.readEntry(configShowImageSettingsDialog, true); FileSaveOptionsBox* const options = new FileSaveOptionsBox(); if (showDialog && options->discoverFormat(newURL.fileName(), DImg::NONE) != DImg::NONE) { FileSaveOptionsDlg* const fileSaveOptionsDialog = new FileSaveOptionsDlg(this, options); options->setImageFileFormat(newURL.fileName()); if (d->currentWindowModalDialog) { // go application-modal - we will create utter confusion if descending into more than one window-modal dialog fileSaveOptionsDialog->setModal(true); result = fileSaveOptionsDialog->exec(); } else { fileSaveOptionsDialog->setWindowModality(Qt::WindowModal); d->currentWindowModalDialog = fileSaveOptionsDialog; result = fileSaveOptionsDialog->exec(); d->currentWindowModalDialog = 0; } if (result != QDialog::Accepted || !fileSaveOptionsDialog) { return false; } } // write settings to config options->applySettings(); // read settings from config to local container applyIOSettings(); // select the format to save the image with m_savingContext.format = selectValidSavingFormat(newURL); if (m_savingContext.format.isNull()) { QMessageBox::critical(this, qApp->applicationName(), i18n("Unable to determine the format to save the target image with.")); return false; } if (!newURL.isValid()) { QMessageBox::critical(this, qApp->applicationName(), i18n("Cannot Save: Found file path %1 is invalid.", newURL.toDisplayString())); qCWarning(DIGIKAM_GENERAL_LOG) << "target URL is not valid !"; return false; } group.writeEntry(optionLastExtension, m_savingContext.format); config->sync(); return true; } QString EditorWindow::selectValidSavingFormat(const QUrl& targetUrl) { qCDebug(DIGIKAM_GENERAL_LOG) << "Trying to find a saving format from targetUrl = " << targetUrl; // build a list of valid types QString all; supportedImageMimeTypes(QIODevice::WriteOnly, all); qCDebug(DIGIKAM_GENERAL_LOG) << "Qt Offered types: " << all; QStringList validTypes = all.split(QLatin1String("*."), QString::SkipEmptyParts); validTypes.replaceInStrings(QLatin1String(" "), QString()); qCDebug(DIGIKAM_GENERAL_LOG) << "Writable formats: " << validTypes; // determine the format to use the format provided in the filename QString suffix; if (targetUrl.isLocalFile()) { // for local files QFileInfo can be used QFileInfo fi(targetUrl.toLocalFile()); suffix = fi.suffix(); qCDebug(DIGIKAM_GENERAL_LOG) << "Possible format from local file: " << suffix; } else { // for remote files string manipulation is needed unfortunately QString fileName = targetUrl.fileName(); const int periodLocation = fileName.lastIndexOf(QLatin1Char('.')); if (periodLocation >= 0) { suffix = fileName.right(fileName.size() - periodLocation - 1); } qCDebug(DIGIKAM_GENERAL_LOG) << "Possible format from remote file: " << suffix; } if (!suffix.isEmpty() && validTypes.contains(suffix, Qt::CaseInsensitive)) { qCDebug(DIGIKAM_GENERAL_LOG) << "Using format from target url " << suffix; return suffix; } // another way to determine the format is to use the original file { QString originalFormat = QString::fromUtf8(QImageReader::imageFormat(m_savingContext.srcURL.toLocalFile())); if (validTypes.contains(originalFormat, Qt::CaseInsensitive)) { qCDebug(DIGIKAM_GENERAL_LOG) << "Using format from original file: " << originalFormat; return originalFormat; } } qCDebug(DIGIKAM_GENERAL_LOG) << "No suitable format found"; return QString(); } bool EditorWindow::startingSaveAs(const QUrl& url) { qCDebug(DIGIKAM_GENERAL_LOG) << "startSavingAs called"; if (m_savingContext.savingState != SavingContext::SavingStateNone) { return false; } m_savingContext = SavingContext(); m_savingContext.srcURL = url; QUrl suggested = m_savingContext.srcURL; // Run dialog ------------------------------------------------------------------- QUrl newURL; if (!showFileSaveDialog(suggested, newURL)) { return false; } // if new and original URL are equal use save() ------------------------------ QUrl currURL(m_savingContext.srcURL); currURL.setPath(QDir::cleanPath(currURL.path())); newURL.setPath(QDir::cleanPath(newURL.path())); if (currURL.matches(newURL, QUrl::None)) { save(); return false; } // Check for overwrite ---------------------------------------------------------- QFileInfo fi(newURL.toLocalFile()); m_savingContext.destinationExisted = fi.exists(); if (m_savingContext.destinationExisted) { if (!checkOverwrite(newURL)) { return false; } // There will be two message boxes if the file is not writable. // This may be controversial, and it may be changed, but it was a deliberate decision. if (!checkPermissions(newURL)) { return false; } } // Now do the actual saving ----------------------------------------------------- setupTempSaveFile(newURL); m_savingContext.destinationURL = newURL; m_savingContext.originalFormat = m_canvas->currentImageFileFormat(); m_savingContext.savingState = SavingContext::SavingStateSaveAs; m_savingContext.executedOperation = SavingContext::SavingStateNone; m_savingContext.abortingSaving = false; // in any case, destructive (Save as) or non (Export), mark as New Version m_canvas->interface()->setHistoryIsBranch(true); m_canvas->interface()->saveAs(m_savingContext.saveTempFileName, m_IOFileSettings, m_setExifOrientationTag && m_canvas->exifRotated(), m_savingContext.format.toLower(), m_savingContext.destinationURL.toLocalFile()); return true; } bool EditorWindow::startingSaveCurrentVersion(const QUrl& url) { return startingSaveVersion(url, false, false, QString()); } bool EditorWindow::startingSaveNewVersion(const QUrl& url) { return startingSaveVersion(url, true, false, QString()); } bool EditorWindow::startingSaveNewVersionAs(const QUrl& url) { return startingSaveVersion(url, true, true, QString()); } bool EditorWindow::startingSaveNewVersionInFormat(const QUrl& url, const QString& format) { return startingSaveVersion(url, true, false, format); } VersionFileOperation EditorWindow::saveVersionFileOperation(const QUrl& url, bool fork) { DImageHistory resolvedHistory = m_canvas->interface()->getResolvedInitialHistory(); DImageHistory history = m_canvas->interface()->getItemHistory(); VersionFileInfo currentName(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile(), url.fileName(), m_canvas->currentImageFileFormat()); return versionManager()->operation(fork ? VersionManager::NewVersionName : VersionManager::CurrentVersionName, currentName, resolvedHistory, history); } VersionFileOperation EditorWindow::saveAsVersionFileOperation(const QUrl& url, const QUrl& saveUrl, const QString& format) { DImageHistory resolvedHistory = m_canvas->interface()->getResolvedInitialHistory(); DImageHistory history = m_canvas->interface()->getItemHistory(); VersionFileInfo currentName(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile(), url.fileName(), m_canvas->currentImageFileFormat()); VersionFileInfo saveLocation(saveUrl.adjusted(QUrl::RemoveFilename).toLocalFile(), saveUrl.fileName(), format); return versionManager()->operationNewVersionAs(currentName, saveLocation, resolvedHistory, history); } VersionFileOperation EditorWindow::saveInFormatVersionFileOperation(const QUrl& url, const QString& format) { DImageHistory resolvedHistory = m_canvas->interface()->getResolvedInitialHistory(); DImageHistory history = m_canvas->interface()->getItemHistory(); VersionFileInfo currentName(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile(), url.fileName(), m_canvas->currentImageFileFormat()); return versionManager()->operationNewVersionInFormat(currentName, format, resolvedHistory, history); } bool EditorWindow::startingSaveVersion(const QUrl& url, bool fork, bool saveAs, const QString& format) { qCDebug(DIGIKAM_GENERAL_LOG) << "Saving image" << url << "non-destructive, new version:" << fork << ", saveAs:" << saveAs << "format:" << format; if (m_savingContext.savingState != SavingContext::SavingStateNone) { return false; } m_savingContext = SavingContext(); m_savingContext.versionFileOperation = saveVersionFileOperation(url, fork); m_canvas->interface()->setHistoryIsBranch(fork); if (saveAs) { QUrl suggested = m_savingContext.versionFileOperation.saveFile.fileUrl(); QUrl selectedUrl; if (!showFileSaveDialog(suggested, selectedUrl)) { return false; } m_savingContext.versionFileOperation = saveAsVersionFileOperation(url, selectedUrl, m_savingContext.format); } else if (!format.isNull()) { m_savingContext.versionFileOperation = saveInFormatVersionFileOperation(url, format); } const QUrl newURL = m_savingContext.versionFileOperation.saveFile.fileUrl(); qCDebug(DIGIKAM_GENERAL_LOG) << "Writing file to " << newURL; if (!newURL.isValid()) { QMessageBox::critical(this, qApp->applicationName(), i18nc("@info", "Cannot save file %1 to " "the suggested version file name %2", url.fileName(), newURL.fileName())); qCWarning(DIGIKAM_GENERAL_LOG) << "target URL is not valid !"; return false; } QFileInfo fi(newURL.toLocalFile()); m_savingContext.destinationExisted = fi.exists(); // Check for overwrite (saveAs only) -------------------------------------------- if (m_savingContext.destinationExisted) { // So, should we refuse to overwrite the original? // It's a frontal crash against non-destructive principles. // It is tempting to refuse, yet I think the user has to decide in the end /*QUrl currURL(m_savingContext.srcURL); currURL.cleanPath(); newURL.cleanPath(); if (currURL.equals(newURL)) { ... return false; }*/ // check for overwrite, unless the operation explicitly tells us to overwrite if (!(m_savingContext.versionFileOperation.tasks & VersionFileOperation::Replace) && !checkOverwrite(newURL)) { return false; } // There will be two message boxes if the file is not writable. // This may be controversial, and it may be changed, but it was a deliberate decision. if (!checkPermissions(newURL)) { return false; } } setupTempSaveFile(newURL); m_savingContext.srcURL = url; m_savingContext.destinationURL = newURL; m_savingContext.originalFormat = m_canvas->currentImageFileFormat(); m_savingContext.format = m_savingContext.versionFileOperation.saveFile.format; m_savingContext.abortingSaving = false; m_savingContext.savingState = SavingContext::SavingStateVersion; m_savingContext.executedOperation = SavingContext::SavingStateNone; m_canvas->interface()->saveAs(m_savingContext.saveTempFileName, m_IOFileSettings, m_setExifOrientationTag && m_canvas->exifRotated(), m_savingContext.format.toLower(), m_savingContext.versionFileOperation); return true; } bool EditorWindow::checkPermissions(const QUrl& url) { //TODO: Check that the permissions can actually be changed // if write permissions are not available. QFileInfo fi(url.toLocalFile()); if (fi.exists() && !fi.isWritable()) { int result = QMessageBox::warning(this, i18n("Overwrite File?"), i18n("You do not have write permissions " "for the file named \"%1\". " "Are you sure you want " "to overwrite it?", url.fileName()), QMessageBox::Save | QMessageBox::Cancel); if (result != QMessageBox::Save) { return false; } } return true; } bool EditorWindow::checkOverwrite(const QUrl& url) { int result = QMessageBox::warning(this, i18n("Overwrite File?"), i18n("A file named \"%1\" already " "exists. Are you sure you want " "to overwrite it?", url.fileName()), QMessageBox::Save | QMessageBox::Cancel); return (result == QMessageBox::Save); } bool EditorWindow::moveLocalFile(const QString& org, const QString& dst) { QString sidecarOrg = DMetadata::sidecarFilePathForFile(org); QString source = m_savingContext.srcURL.toLocalFile(); if (QFileInfo(sidecarOrg).exists()) { QString sidecarDst = DMetadata::sidecarFilePathForFile(dst); if (!DFileOperations::localFileRename(source, sidecarOrg, sidecarDst)) { qCDebug(DIGIKAM_GENERAL_LOG) << "Failed to move sidecar file"; } } if (!DFileOperations::localFileRename(source, org, dst)) { QMessageBox::critical(this, i18n("Error Saving File"), i18n("Failed to overwrite original file")); return false; } return true; } void EditorWindow::moveFile() { // Move local file. if (m_savingContext.executedOperation == SavingContext::SavingStateVersion) { // check if we need to move the current file to an intermediate name if (m_savingContext.versionFileOperation.tasks & VersionFileOperation::MoveToIntermediate) { //qCDebug(DIGIKAM_GENERAL_LOG) << "MoveToIntermediate: Moving " << m_savingContext.srcURL.toLocalFile() << "to" // << m_savingContext.versionFileOperation.intermediateForLoadedFile.filePath() moveLocalFile(m_savingContext.srcURL.toLocalFile(), m_savingContext.versionFileOperation.intermediateForLoadedFile.filePath()); LoadingCacheInterface::fileChanged(m_savingContext.destinationURL.toLocalFile()); ThumbnailLoadThread::deleteThumbnail(m_savingContext.destinationURL.toLocalFile()); } } bool moveSuccessful = moveLocalFile(m_savingContext.saveTempFileName, m_savingContext.destinationURL.toLocalFile()); if (m_savingContext.executedOperation == SavingContext::SavingStateVersion) { if (moveSuccessful && m_savingContext.versionFileOperation.tasks & VersionFileOperation::SaveAndDelete) { QFile file(m_savingContext.versionFileOperation.loadedFile.filePath()); file.remove(); } } movingSaveFileFinished(moveSuccessful); } void EditorWindow::slotDiscardChanges() { m_canvas->interface()->rollbackToOrigin(); } void EditorWindow::slotOpenOriginal() { // no-op in this base class } void EditorWindow::slotColorManagementOptionsChanged() { applyColorManagementSettings(); applyIOSettings(); } void EditorWindow::slotToggleColorManagedView() { if (!IccSettings::instance()->isEnabled()) { return; } bool cmv = !IccSettings::instance()->settings().useManagedView; IccSettings::instance()->setUseManagedView(cmv); } void EditorWindow::setColorManagedViewIndicatorToolTip(bool available, bool cmv) { QString tooltip; if (available) { if (cmv) { tooltip = i18n("Color-Managed View is enabled."); } else { tooltip = i18n("Color-Managed View is disabled."); } } else { tooltip = i18n("Color Management is not configured, so the Color-Managed View is not available."); } d->cmViewIndicator->setToolTip(tooltip); } void EditorWindow::slotSoftProofingOptions() { // Adjusts global settings QPointer dlg = new SoftProofDialog(this); dlg->exec(); d->viewSoftProofAction->setChecked(dlg->shallEnableSoftProofView()); slotUpdateSoftProofingState(); delete dlg; } void EditorWindow::slotUpdateSoftProofingState() { bool on = d->viewSoftProofAction->isChecked(); m_canvas->setSoftProofingEnabled(on); d->toolIface->updateICCSettings(); } void EditorWindow::slotSetUnderExposureIndicator(bool on) { d->exposureSettings->underExposureIndicator = on; d->toolIface->updateExposureSettings(); d->viewUnderExpoAction->setChecked(on); setUnderExposureToolTip(on); } void EditorWindow::setUnderExposureToolTip(bool on) { d->underExposureIndicator->setToolTip( on ? i18n("Under-Exposure indicator is enabled") : i18n("Under-Exposure indicator is disabled")); } void EditorWindow::slotSetOverExposureIndicator(bool on) { d->exposureSettings->overExposureIndicator = on; d->toolIface->updateExposureSettings(); d->viewOverExpoAction->setChecked(on); setOverExposureToolTip(on); } void EditorWindow::setOverExposureToolTip(bool on) { d->overExposureIndicator->setToolTip( on ? i18n("Over-Exposure indicator is enabled") : i18n("Over-Exposure indicator is disabled")); } void EditorWindow::slotToggleSlideShow() { SlideShowSettings settings; settings.readFromConfig(); slideShow(settings); } void EditorWindow::slotSelectionChanged(const QRect& sel) { slotSelectionSetText(sel); emit signalSelectionChanged(sel); } void EditorWindow::slotSelectionSetText(const QRect& sel) { setToolInfoMessage(QString::fromLatin1("(%1, %2) (%3 x %4)").arg(sel.x()).arg(sel.y()).arg(sel.width()).arg(sel.height())); } void EditorWindow::slotComponentsInfo() { LibsInfoDlg* const dlg = new LibsInfoDlg(this); dlg->show(); } void EditorWindow::setToolStartProgress(const QString& toolName) { m_animLogo->start(); m_nameLabel->setProgressValue(0); m_nameLabel->setProgressBarMode(StatusProgressBar::CancelProgressBarMode, QString::fromUtf8("%1:").arg(toolName)); } void EditorWindow::setToolProgress(int progress) { m_nameLabel->setProgressValue(progress); } void EditorWindow::setToolStopProgress() { m_animLogo->stop(); m_nameLabel->setProgressValue(0); m_nameLabel->setProgressBarMode(StatusProgressBar::TextMode); slotUpdateItemInfo(); } void EditorWindow::slotCloseTool() { if (d->toolIface) { d->toolIface->slotCloseTool(); } } void EditorWindow::slotApplyTool() { if (d->toolIface) { d->toolIface->slotApplyTool(); } } void EditorWindow::setPreviewModeMask(int mask) { d->previewToolBar->setPreviewModeMask(mask); } PreviewToolBar::PreviewMode EditorWindow::previewMode() const { return d->previewToolBar->previewMode(); } void EditorWindow::setToolInfoMessage(const QString& txt) { d->infoLabel->setAdjustedText(txt); } VersionManager* EditorWindow::versionManager() const { return &d->defaultVersionManager; } void EditorWindow::setupSelectToolsAction() { // Create action model ActionItemModel* const actionModel = new ActionItemModel(this); actionModel->setMode(ActionItemModel::ToplevelMenuCategory | ActionItemModel::SortCategoriesByInsertionOrder); // Builtin actions QString transformCategory = i18nc("@title Image Transform", "Transform"); actionModel->addAction(d->rotateLeftAction, transformCategory); actionModel->addAction(d->rotateRightAction, transformCategory); actionModel->addAction(d->flipHorizAction, transformCategory); actionModel->addAction(d->flipVertAction, transformCategory); actionModel->addAction(d->cropAction, transformCategory); actionModel->addAction(d->autoCropAction, transformCategory); actionModel->addAction(d->aspectRatioCropAction, transformCategory); actionModel->addAction(d->resizeAction, transformCategory); actionModel->addAction(d->sheartoolAction, transformCategory); actionModel->addAction(d->freerotationAction, transformCategory); actionModel->addAction(d->perspectiveAction, transformCategory); #ifdef HAVE_LIBLQR_1 actionModel->addAction(d->contentAwareResizingAction, transformCategory); #endif QString decorateCategory = i18nc("@title Image Decorate", "Decorate"); actionModel->addAction(d->textureAction, decorateCategory); actionModel->addAction(d->borderAction, decorateCategory); actionModel->addAction(d->insertTextAction, decorateCategory); QString effectsCategory = i18nc("@title Image Effect", "Effects"); actionModel->addAction(d->filmgrainAction, effectsCategory); actionModel->addAction(d->raindropAction, effectsCategory); actionModel->addAction(d->distortionfxAction, effectsCategory); actionModel->addAction(d->blurfxAction, effectsCategory); actionModel->addAction(d->oilpaintAction, effectsCategory); actionModel->addAction(d->embossAction, effectsCategory); actionModel->addAction(d->charcoalAction, effectsCategory); actionModel->addAction(d->colorEffectsAction, effectsCategory); QString colorsCategory = i18nc("@title Image Colors", "Colors"); actionModel->addAction(d->convertTo8Bits, colorsCategory); actionModel->addAction(d->convertTo16Bits, colorsCategory); actionModel->addAction(d->invertAction, colorsCategory); actionModel->addAction(d->BCGAction, colorsCategory); actionModel->addAction(d->CBAction, colorsCategory); actionModel->addAction(d->autoCorrectionAction, colorsCategory); actionModel->addAction(d->BWAction, colorsCategory); actionModel->addAction(d->HSLAction, colorsCategory); actionModel->addAction(d->whitebalanceAction, colorsCategory); actionModel->addAction(d->channelMixerAction, colorsCategory); actionModel->addAction(d->curvesAction, colorsCategory); actionModel->addAction(d->levelsAction, colorsCategory); actionModel->addAction(d->filmAction, colorsCategory); actionModel->addAction(d->colorSpaceConverter, colorsCategory); QString enhanceCategory = i18nc("@title Image Enhance", "Enhance"); actionModel->addAction(d->restorationAction, enhanceCategory); actionModel->addAction(d->blurAction, enhanceCategory); //actionModel->addAction(d->healCloneAction, enhanceCategory); actionModel->addAction(d->sharpenAction, enhanceCategory); actionModel->addAction(d->noiseReductionAction, enhanceCategory); actionModel->addAction(d->localContrastAction, enhanceCategory); actionModel->addAction(d->redeyeAction, enhanceCategory); actionModel->addAction(d->lensdistortionAction, enhanceCategory); actionModel->addAction(d->antivignettingAction, enhanceCategory); actionModel->addAction(d->hotpixelsAction, enhanceCategory); #ifdef HAVE_LENSFUN actionModel->addAction(d->lensAutoFixAction, enhanceCategory); #endif QString postCategory = i18nc("@title Post Processing Tools", "Post-Processing"); foreach (DPluginAction* const ac, DPluginLoader::instance()->pluginsActions(DPluginAction::GenericTool, this)) { actionModel->addAction(ac, postCategory); } foreach (DPluginAction* const ac, DPluginLoader::instance()->pluginsActions(DPluginAction::GenericMetadata, this)) { actionModel->addAction(ac, postCategory); } QString exportCategory = i18nc("@title Export Tools", "Export"); foreach (DPluginAction* const ac, DPluginLoader::instance()->pluginsActions(DPluginAction::GenericExport, this)) { actionModel->addAction(ac, exportCategory); } QString importCategory = i18nc("@title Import Tools", "Import"); foreach (DPluginAction* const ac, DPluginLoader::instance()->pluginsActions(DPluginAction::GenericImport, this)) { actionModel->addAction(ac, importCategory); } // setup categorized view DCategorizedSortFilterProxyModel* const filterModel = actionModel->createFilterModel(); ActionCategorizedView* const selectToolsActionView = new ActionCategorizedView; selectToolsActionView->setupIconMode(); selectToolsActionView->setModel(filterModel); selectToolsActionView->adjustGridSize(); connect(selectToolsActionView, SIGNAL(clicked(QModelIndex)), actionModel, SLOT(trigger(QModelIndex))); EditorToolIface::editorToolIface()->setToolsIconView(selectToolsActionView); } void EditorWindow::slotThemeChanged() { KSharedConfig::Ptr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(configGroupName()); if (!group.readEntry(d->configUseThemeBackgroundColorEntry, true)) { m_bgColor = group.readEntry(d->configBackgroundColorEntry, QColor(Qt::black)); } else { m_bgColor = palette().color(QPalette::Base); } m_canvas->setBackgroundBrush(QBrush(m_bgColor)); d->toolIface->themeChanged(); } void EditorWindow::addAction2ContextMenu(const QString& actionName, bool addDisabled) { if (!m_contextMenu) { return; } QAction* const action = actionCollection()->action(actionName); if (action && (action->isEnabled() || addDisabled)) { m_contextMenu->addAction(action); } } void EditorWindow::showSideBars(bool visible) { if (visible) { rightSideBar()->restore(QList() << thumbBar(), d->fullscreenSizeBackup); } else { // See bug #166472, a simple backup()/restore() will hide non-sidebar splitter child widgets // in horizontal mode thumbbar wont be member of the splitter, it is just ignored then rightSideBar()->backup(QList() << thumbBar(), &d->fullscreenSizeBackup); } } void EditorWindow::slotToggleRightSideBar() { rightSideBar()->isExpanded() ? rightSideBar()->shrink() : rightSideBar()->expand(); } void EditorWindow::slotPreviousRightSideBarTab() { rightSideBar()->activePreviousTab(); } void EditorWindow::slotNextRightSideBarTab() { rightSideBar()->activeNextTab(); } void EditorWindow::showThumbBar(bool visible) { visible ? thumbBar()->restoreVisibility() : thumbBar()->hide(); } bool EditorWindow::thumbbarVisibility() const { return thumbBar()->isVisible(); } void EditorWindow::customizedFullScreenMode(bool set) { set ? m_canvas->setBackgroundBrush(QBrush(Qt::black)) : m_canvas->setBackgroundBrush(QBrush(m_bgColor)); showStatusBarAction()->setEnabled(!set); toolBarMenuAction()->setEnabled(!set); showMenuBarAction()->setEnabled(!set); m_showBarAction->setEnabled(!set); } void EditorWindow::addServicesMenuForUrl(const QUrl& url) { KService::List offers = DFileOperations::servicesForOpenWith(QList() << url); qCDebug(DIGIKAM_GENERAL_LOG) << offers.count() << " services found to open " << url; if (m_servicesMenu) { delete m_servicesMenu; m_servicesMenu = 0; } if (m_serviceAction) { delete m_serviceAction; m_serviceAction = 0; } if (!offers.isEmpty()) { m_servicesMenu = new QMenu(this); QAction* const serviceAction = m_servicesMenu->menuAction(); serviceAction->setText(i18n("Open With")); foreach(const KService::Ptr& service, offers) { QString name = service->name().replace(QLatin1Char('&'), QLatin1String("&&")); QAction* const action = m_servicesMenu->addAction(name); action->setIcon(QIcon::fromTheme(service->icon())); action->setData(service->name()); d->servicesMap[name] = service; } #ifdef HAVE_KIO m_servicesMenu->addSeparator(); m_servicesMenu->addAction(i18n("Other...")); m_contextMenu->addAction(serviceAction); connect(m_servicesMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotOpenWith(QAction*))); } else { m_serviceAction = new QAction(i18n("Open With..."), this); m_contextMenu->addAction(m_serviceAction); connect(m_servicesMenu, SIGNAL(triggered()), this, SLOT(slotOpenWith())); #endif // HAVE_KIO } } void EditorWindow::openWith(const QUrl& url, QAction* action) { KService::Ptr service; QString name = action ? action->data().toString() : QString(); #ifdef HAVE_KIO if (name.isEmpty()) { QPointer dlg = new KOpenWithDialog(QList() << url); if (dlg->exec() != KOpenWithDialog::Accepted) { delete dlg; return; } service = dlg->service(); if (!service) { // User entered a custom command if (!dlg->text().isEmpty()) { DFileOperations::runFiles(dlg->text(), QList() << url); } delete dlg; return; } delete dlg; } else #endif // HAVE_KIO { service = d->servicesMap[name]; } DFileOperations::runFiles(service.data(), QList() << url); } void EditorWindow::loadTool(EditorTool* const tool) { EditorToolIface::editorToolIface()->loadTool(tool); connect(tool, SIGNAL(okClicked()), this, SLOT(slotToolDone())); connect(tool, SIGNAL(cancelClicked()), this, SLOT(slotToolDone())); } void EditorWindow::slotToolDone() { EditorToolIface::editorToolIface()->unLoadTool(); } void EditorWindow::slotInsertText() { loadTool(new InsertTextTool(this)); } void EditorWindow::slotBorder() { loadTool(new BorderTool(this)); } void EditorWindow::slotTexture() { loadTool(new TextureTool(this)); } void EditorWindow::slotColorEffects() { loadTool(new ColorFxTool(this)); } void EditorWindow::slotCharcoal() { loadTool(new CharcoalTool(this)); } void EditorWindow::slotEmboss() { loadTool(new EmbossTool(this)); } void EditorWindow::slotOilPaint() { loadTool(new OilPaintTool(this)); } void EditorWindow::slotBlurFX() { loadTool(new BlurFXTool(this)); } void EditorWindow::slotDistortionFX() { loadTool(new DistortionFXTool(this)); } void EditorWindow::slotRainDrop() { loadTool(new RainDropTool(this)); } void EditorWindow::slotFilmGrain() { loadTool(new FilmGrainTool(this)); } void EditorWindow::slotInvert() { qApp->setOverrideCursor(Qt::WaitCursor); ImageIface iface; InvertFilter invert(iface.original(), 0L); invert.startFilterDirectly(); iface.setOriginal(i18n("Invert"), invert.filterAction(), invert.getTargetImage()); qApp->restoreOverrideCursor(); } void EditorWindow::slotConvertTo8Bits() { ImageIface iface; if (!iface.originalSixteenBit()) { QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), i18n("This image is already using a depth of 8 bits / color / pixel.")); return; } else { if (DMessageBox::showContinueCancel(QMessageBox::Warning, qApp->activeWindow(), qApp->applicationName(), i18n("Performing this operation will reduce image color quality. " "Do you want to continue?"), QLatin1String("ToolColor16To8Bits")) == QMessageBox::Cancel) { return; } } qApp->setOverrideCursor(Qt::WaitCursor); iface.convertOriginalColorDepth(32); qApp->restoreOverrideCursor(); } void EditorWindow::slotConvertTo16Bits() { ImageIface iface; if (iface.originalSixteenBit()) { QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), i18n("This image is already using a depth of 16 bits / color / pixel.")); return; } qApp->setOverrideCursor(Qt::WaitCursor); iface.convertOriginalColorDepth(64); qApp->restoreOverrideCursor(); } -void EditorWindow::slotConvertToColorSpace(const IccProfile& profile) -{ - ImageIface iface; - - if (iface.originalIccProfile().isNull()) - { - QMessageBox::critical(qApp->activeWindow(), qApp->applicationName(), - i18n("This image is not color managed.")); - return; - } - - qApp->setOverrideCursor(Qt::WaitCursor); - ProfileConversionTool::fastConversion(profile); - qApp->restoreOverrideCursor(); -} - -void EditorWindow::slotUpdateColorSpaceMenu() -{ - d->profileMenuAction->clear(); - - if (!IccSettings::instance()->isEnabled()) - { - QAction* const action = new QAction(i18n("Color Management is disabled..."), this); - d->profileMenuAction->addAction(action); - - connect(action, SIGNAL(triggered()), - this, SLOT(slotSetupICC())); - } - else - { - ICCSettingsContainer settings = IccSettings::instance()->settings(); - - QList standardProfiles, favoriteProfiles; - QSet standardProfilePaths, favoriteProfilePaths; - standardProfiles << IccProfile::sRGB() - << IccProfile::adobeRGB() - << IccProfile::wideGamutRGB() - << IccProfile::proPhotoRGB(); - - foreach(IccProfile profile, standardProfiles) // krazy:exclude=foreach - { - d->profileMenuAction->addProfile(profile, profile.description()); - standardProfilePaths << profile.filePath(); - } - - d->profileMenuAction->addSeparator(); - - favoriteProfilePaths = QSet::fromList(ProfileConversionTool::favoriteProfiles()); - favoriteProfilePaths -= standardProfilePaths; - - foreach(const QString& path, favoriteProfilePaths) - { - favoriteProfiles << IccProfile(path); - } - - d->profileMenuAction->addProfiles(favoriteProfiles); - } - - d->profileMenuAction->addSeparator(); - d->profileMenuAction->addAction(d->colorSpaceConverter); - d->colorSpaceConverter->setEnabled(m_actionEnabledState && IccSettings::instance()->isEnabled()); -} - -void EditorWindow::slotProfileConversionTool() -{ - ProfileConversionTool* const tool = new ProfileConversionTool(this); - - connect(tool, SIGNAL(okClicked()), - this, SLOT(slotUpdateColorSpaceMenu())); - - loadTool(tool); -} - -void EditorWindow::slotHSL() -{ - loadTool(new HSLTool(this)); -} - void EditorWindow::slotWhiteBalance() { loadTool(new WhiteBalanceTool(this)); } -void EditorWindow::slotChannelMixer() -{ - loadTool(new ChannelMixerTool(this)); -} - -void EditorWindow::slotFilm() -{ - loadTool(new FilmTool(this)); -} - -void EditorWindow::slotCB() -{ - loadTool(new CBTool(this)); -} - void EditorWindow::slotHotPixels() { loadTool(new HotPixelsTool(this)); } void EditorWindow::slotLensDistortion() { loadTool(new LensDistortionTool(this)); } void EditorWindow::slotRestoration() { loadTool(new RestorationTool(this)); } void EditorWindow::slotBlur() { loadTool(new BlurTool(this)); } void EditorWindow::slotHealingClone() { loadTool(new HealingCloneTool(this)); } void EditorWindow::slotSharpen() { loadTool(new SharpenTool(this)); } void EditorWindow::slotNoiseReduction() { loadTool(new NoiseReductionTool(this)); } void EditorWindow::slotLocalContrast() { loadTool(new LocalContrastTool(this)); } void EditorWindow::slotRedEye() { loadTool(new RedEyeTool(this)); } void EditorWindow::slotLensAutoFix() { #ifdef HAVE_LENSFUN loadTool(new LensAutoFixTool(this)); #endif } void EditorWindow::slotAntiVignetting() { loadTool(new AntiVignettingTool(this)); } void EditorWindow::slotPerspective() { loadTool(new PerspectiveTool(this)); } void EditorWindow::slotShearTool() { loadTool(new ShearTool(this)); } void EditorWindow::slotResize() { loadTool(new ResizeTool(this)); } void EditorWindow::slotRatioCrop() { loadTool(new RatioCropTool(this)); } void EditorWindow::slotContentAwareResizing() { #ifdef HAVE_LIBLQR_1 loadTool(new ContentAwareResizeTool(this)); #endif } void EditorWindow::slotFreeRotation() { FreeRotationTool* const tool = new FreeRotationTool(this); connect(this, SIGNAL(signalPoint1Action()), tool, SLOT(slotAutoAdjustP1Clicked())); connect(this, SIGNAL(signalPoint2Action()), tool, SLOT(slotAutoAdjustP2Clicked())); connect(this, SIGNAL(signalAutoAdjustAction()), tool, SLOT(slotAutoAdjustClicked())); loadTool(tool); } void EditorWindow::slotRotateLeftIntoQue() { m_transformQue.append(TransformType::RotateLeft); } void EditorWindow::slotRotateRightIntoQue() { m_transformQue.append(TransformType::RotateRight); } void EditorWindow::slotFlipHIntoQue() { m_transformQue.append(TransformType::FlipHorizontal); } void EditorWindow::slotFlipVIntoQue() { m_transformQue.append(TransformType::FlipVertical); } void EditorWindow::registerPluginsActions() { DXmlGuiWindow::registerPluginsActions(); DPluginLoader* const dpl = DPluginLoader::instance(); dpl->registerEditorPlugins(this); QList actions = dpl->pluginsActions(DPluginAction::Editor, this); foreach (DPluginAction* const ac, actions) { actionCollection()->addActions(QList() << ac); } } } // namespace Digikam diff --git a/core/utilities/imageeditor/editor/editorwindow.h b/core/utilities/imageeditor/editor/editorwindow.h index b52f69ff87..ee67c089e5 100644 --- a/core/utilities/imageeditor/editor/editorwindow.h +++ b/core/utilities/imageeditor/editor/editorwindow.h @@ -1,441 +1,435 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2006-01-20 * Description : core image editor GUI implementation * * Copyright (C) 2006-2019 by Gilles Caulier * Copyright (C) 2009-2011 by Andi Clemens * Copyright (C) 2015 by Mohamed_Anwer * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_IMAGE_EDITOR_WINDOW_H #define DIGIKAM_IMAGE_EDITOR_WINDOW_H // C++ includes #include // Qt includes #include #include #include #include #include #include // Local includes #include "digikam_export.h" #include "digikam_config.h" #include "thumbbardock.h" #include "previewtoolbar.h" #include "savingcontext.h" #include "dxmlguiwindow.h" class QSplitter; class QMenu; class QAction; class KSelectAction; class KToolBarPopupAction; namespace Digikam { class DAdjustableLabel; class DCategorizedView; class Canvas; class DImageHistory; class EditorTool; class EditorStackView; class ExposureSettingsContainer; class IOFileSettings; class ICCSettingsContainer; class Sidebar; class SidebarSplitter; class SlideShowSettings; class StatusProgressBar; class VersionManager; class VersionFileOperation; class IccProfile; class DIGIKAM_EXPORT EditorWindow : public DXmlGuiWindow { Q_OBJECT public: enum TransformType { RotateLeft, RotateRight, FlipHorizontal, FlipVertical }; explicit EditorWindow(const QString& name); ~EditorWindow(); const static QString CONFIG_GROUP_NAME; void registerPluginsActions(); void loadTool(EditorTool* const tool); - + bool actionEnabledState() const; + public Q_SLOTS: virtual void slotSetup() = 0; virtual void slotSetupICC() = 0; Q_SIGNALS: void signalSelectionChanged(const QRect&); void signalNoCurrentItem(); void signalPreviewModeChanged(int); void signalToolApplied(); void signalPoint1Action(); void signalPoint2Action(); void signalAutoAdjustAction(); protected: bool m_nonDestructive; bool m_setExifOrientationTag; bool m_editingOriginalImage; bool m_actionEnabledState; bool m_cancelSlideShow; DAdjustableLabel* m_resLabel; QColor m_bgColor; SidebarSplitter* m_splitter; QSplitter* m_vSplitter; QAction* m_openVersionAction; QAction* m_saveAction; QAction* m_saveAsAction; KToolBarPopupAction* m_saveNewVersionAction; QAction* m_saveCurrentVersionAction; QAction* m_saveNewVersionAsAction; QMenu* m_saveNewVersionInFormatAction; QAction* m_exportAction; QAction* m_revertAction; QAction* m_discardChangesAction; QAction* m_fileDeleteAction; QAction* m_forwardAction; QAction* m_backwardAction; QAction* m_lastAction; QAction* m_firstAction; QAction* m_applyToolAction; QAction* m_closeToolAction; QAction* m_showBarAction; KToolBarPopupAction* m_undoAction; KToolBarPopupAction* m_redoAction; QMenu* m_contextMenu; QMenu* m_servicesMenu; QAction* m_serviceAction; EditorStackView* m_stackView; Canvas* m_canvas; StatusProgressBar* m_nameLabel; IOFileSettings* m_IOFileSettings; QPointer m_savingProgressDialog; SavingContext m_savingContext; QString m_formatForRAWVersioning; QString m_formatForSubversions; //using QVector to store transforms QVector m_transformQue; protected: enum SaveAskMode { AskIfNeeded, OverwriteWithoutAsking, AlwaysSaveAs, SaveVersionWithoutAsking = OverwriteWithoutAsking, AlwaysNewVersion = AlwaysSaveAs }; protected: void saveStandardSettings(); void readStandardSettings(); void applyStandardSettings(); void applyIOSettings(); void applyColorManagementSettings(); void setupStandardConnections(); void setupStandardActions(); void setupStatusBar(); void setupContextMenu(); void setupSelectToolsAction(); void toggleStandardActions(bool val); void toggleZoomActions(bool val); void toggleNonDestructiveActions(); void toggleToolActions(EditorTool* tool = 0); void printImage(const QUrl& url); bool promptForOverWrite(); bool promptUserDelete(const QUrl& url); bool promptUserSave(const QUrl& url, SaveAskMode mode = AskIfNeeded, bool allowCancel = true); bool waitForSavingToComplete(); void startingSave(const QUrl& url); bool startingSaveAs(const QUrl& url); bool startingSaveCurrentVersion(const QUrl& url); bool startingSaveNewVersion(const QUrl& url); bool startingSaveNewVersionAs(const QUrl& url); bool startingSaveNewVersionInFormat(const QUrl& url, const QString& format); bool checkPermissions(const QUrl& url); bool checkOverwrite(const QUrl& url); bool moveLocalFile(const QString& src, const QString& dest); void movingSaveFileFinished(bool successful); void colorManage(); void execSavingProgressDialog(); void resetOrigin(); void resetOriginSwitchFile(); void addServicesMenuForUrl(const QUrl& url); void openWith(const QUrl& url, QAction* action); EditorStackView* editorStackView() const; ExposureSettingsContainer* exposureSettings() const; VersionFileOperation saveVersionFileOperation(const QUrl& url, bool fork); VersionFileOperation saveAsVersionFileOperation(const QUrl& url, const QUrl& saveLocation, const QString& format); VersionFileOperation saveInFormatVersionFileOperation(const QUrl& url, const QString& format); virtual bool hasOriginalToRestore(); virtual DImageHistory resolvedImageHistory(const DImageHistory& history); virtual void moveFile(); virtual void finishSaving(bool success); virtual void readSettings(); virtual void saveSettings(); virtual void toggleActions(bool val); virtual ThumbBarDock* thumbBar() const = 0; virtual Sidebar* rightSideBar() const = 0; virtual void slideShow(SlideShowSettings& settings) = 0; virtual void setupConnections() = 0; virtual void setupActions() = 0; virtual void setupUserArea() = 0; virtual void addServicesMenu() = 0; virtual VersionManager* versionManager() const; /** * Hook method that subclasses must implement to return the destination url * of the image to save. This may also be a remote url. * * This method will only be called while saving. * * @return destination for the file that is currently being saved. */ virtual QUrl saveDestinationUrl() = 0; virtual void saveIsComplete() = 0; virtual void saveAsIsComplete() = 0; virtual void saveVersionIsComplete() = 0; protected Q_SLOTS: void slotAboutToShowUndoMenu(); void slotAboutToShowRedoMenu(); void slotSelected(bool); void slotLoadingProgress(const QString& filePath, float progress); void slotSavingProgress(const QString& filePath, float progress); void slotNameLabelCancelButtonPressed(); virtual void slotPrepareToLoad(); virtual void slotLoadingStarted(const QString& filename); virtual void slotLoadingFinished(const QString& filename, bool success); virtual void slotSavingStarted(const QString& filename); virtual void slotFileOriginChanged(const QString& filePath); virtual void slotComponentsInfo(); virtual void slotDiscardChanges(); virtual void slotOpenOriginal(); virtual bool saveOrSaveAs(); virtual bool saveAs() = 0; virtual bool save() = 0; virtual bool saveNewVersion() = 0; virtual bool saveCurrentVersion() = 0; virtual bool saveNewVersionAs() = 0; virtual bool saveNewVersionInFormat(const QString&) = 0; virtual void slotFilePrint() = 0; virtual void slotFileWithDefaultApplication() = 0; virtual void slotDeleteCurrentItem() = 0; virtual void slotBackward() = 0; virtual void slotForward() = 0; virtual void slotFirst() = 0; virtual void slotLast() = 0; virtual void slotUpdateItemInfo() = 0; virtual void slotChanged() = 0; virtual void slotContextMenu() = 0; virtual void slotRevert() = 0; virtual void slotAddedDropedItems(QDropEvent* e) = 0; virtual void slotOpenWith(QAction* action=0) = 0; private Q_SLOTS: void slotSetUnderExposureIndicator(bool); void slotSetOverExposureIndicator(bool); void slotColorManagementOptionsChanged(); void slotToggleColorManagedView(); void slotSoftProofingOptions(); void slotUpdateSoftProofingState(); void slotSavingFinished(const QString& filename, bool success); void slotToggleSlideShow(); void slotZoomTo100Percents(); void slotZoomChanged(bool isMax, bool isMin, double zoom); void slotSelectionChanged(const QRect& sel); void slotSelectionSetText(const QRect& sel); void slotToggleFitToWindow(); void slotToggleOffFitToWindow(); void slotFitToSelect(); void slotIncreaseZoom(); void slotDecreaseZoom(); void slotCloseTool(); void slotApplyTool(); void slotUndoStateChanged(); void slotThemeChanged(); void slotToggleRightSideBar(); void slotPreviousRightSideBarTab(); void slotNextRightSideBarTab(); void slotToolDone(); void slotInsertText(); void slotBorder(); void slotTexture(); void slotColorEffects(); void slotCharcoal(); void slotEmboss(); void slotOilPaint(); void slotBlurFX(); void slotDistortionFX(); void slotRainDrop(); void slotFilmGrain(); - void slotCB(); - void slotHSL(); void slotInvert(); void slotWhiteBalance(); void slotConvertTo8Bits(); void slotConvertTo16Bits(); - void slotConvertToColorSpace(const IccProfile&); - void slotProfileConversionTool(); - void slotChannelMixer(); - void slotFilm(); - void slotUpdateColorSpaceMenu(); void slotRestoration(); void slotBlur(); void slotHealingClone(); void slotSharpen(); void slotNoiseReduction(); void slotLocalContrast(); void slotRedEye(); void slotLensAutoFix(); void slotAntiVignetting(); void slotLensDistortion(); void slotHotPixels(); void slotPerspective(); void slotFreeRotation(); void slotShearTool(); void slotContentAwareResizing(); void slotResize(); void slotRatioCrop(); void slotRotateLeftIntoQue(); void slotRotateRightIntoQue(); void slotFlipHIntoQue(); void slotFlipVIntoQue(); private: void enterWaitingLoop(); void quitWaitingLoop(); void showSideBars(bool visible); void showThumbBar(bool visible); void customizedFullScreenMode(bool set); bool thumbbarVisibility() const; void setColorManagedViewIndicatorToolTip(bool available, bool cmv); void setUnderExposureToolTip(bool uei); void setOverExposureToolTip(bool oei); void setToolStartProgress(const QString& toolName); void setToolProgress(int progress); void setToolStopProgress(); void setToolInfoMessage(const QString& txt); bool startingSaveVersion(const QUrl& url, bool subversion, bool saveAs, const QString& format); void setPreviewModeMask(int mask); PreviewToolBar::PreviewMode previewMode() const; bool showFileSaveDialog(const QUrl& initialUrl, QUrl& newURL); /** * Sets up a temp file to save image contents to and updates the saving * context to use this file * * @param url file to save the image to */ void setupTempSaveFile(const QUrl& url); /** * Sets the format to use in the saving context. Therefore multiple sources * are used starting with the extension found in the save dialog. * * @param filter filter selected in the dialog * @param targetUrl target url selected for the file to save * @return The valid extension which could be found, or a null string */ QString selectValidSavingFormat(const QUrl& targetUrl); void addAction2ContextMenu(const QString& actionName, bool addDisabled = false); private: class Private; Private* const d; friend class EditorToolIface; }; } // namespace Digikam #endif // DIGIKAM_IMAGE_EDITOR_WINDOW_H diff --git a/core/utilities/imageeditor/editor/editorwindow_p.h b/core/utilities/imageeditor/editor/editorwindow_p.h index 4efa779cee..260ace0134 100644 --- a/core/utilities/imageeditor/editor/editorwindow_p.h +++ b/core/utilities/imageeditor/editor/editorwindow_p.h @@ -1,384 +1,384 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2006-01-20 * Description : core image editor GUI implementation private data. * * Copyright (C) 2006-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_IMAGE_EDITOR_WINDOW_PRIVATE_H #define DIGIKAM_IMAGE_EDITOR_WINDOW_PRIVATE_H // Qt includes #include #include #include #include // KDE includes #include #include // Local includes #include "digikam_debug.h" #include "digikam_globals.h" #include "editorwindow.h" #include "versionmanager.h" #include "dnotificationpopup.h" class QAction; class QDialog; class QEventLoop; class QLabel; class QToolButton; class QWidgetAction; namespace Digikam { class ActionCategorizedView; class DZoomBar; class EditorToolIface; class ExposureSettingsContainer; class ICCSettingsContainer; class PreviewToolBar; class DAdjustableLabel; class IccProfilesMenuAction; class Q_DECL_HIDDEN EditorWindow::Private { public: Private() : cmViewIndicator(0), underExposureIndicator(0), overExposureIndicator(0), infoLabel(0), copyAction(0), cropAction(0), autoCropAction(0), filePrintAction(0), flipHorizAction(0), flipVertAction(0), rotateLeftAction(0), rotateRightAction(0), selectAllAction(0), selectNoneAction(0), slideShowAction(0), softProofOptionsAction(0), zoomFitToSelectAction(0), zoomMinusAction(0), zoomPlusAction(0), zoomTo100percents(0), openWithAction(0), textureAction(0), borderAction(0), insertTextAction(0), filmgrainAction(0), raindropAction(0), distortionfxAction(0), blurfxAction(0), oilpaintAction(0), embossAction(0), charcoalAction(0), colorEffectsAction(0), BCGAction(0), HSLAction(0), CBAction(0), autoCorrectionAction(0), invertAction(0), BWAction(0), convertTo8Bits(0), convertTo16Bits(0), whitebalanceAction(0), channelMixerAction(0), curvesAction(0), levelsAction(0), filmAction(0), profileMenuAction(0), colorSpaceConverter(0), hotpixelsAction(0), lensdistortionAction(0), antivignettingAction(0), lensAutoFixAction(0), redeyeAction(0), restorationAction(0), blurAction(0), healCloneAction(0), sharpenAction(0), noiseReductionAction(0), localContrastAction(0), inPaintingAction(0), aspectRatioCropAction(0), resizeAction(0), contentAwareResizingAction(0), sheartoolAction(0), freerotationAction(0), perspectiveAction(0), undoSignalMapper(0), redoSignalMapper(0), formatMenuActionMapper(0), waitingLoop(0), currentWindowModalDialog(0), zoomFitToWindowAction(0), viewCMViewAction(0), viewSoftProofAction(0), viewUnderExpoAction(0), viewOverExpoAction(0), selectToolsActionView(0), ICCSettings(0), zoomBar(0), previewToolBar(0), exposureSettings(0), toolIface(0) { } ~Private() { } void legacyUpdateSplitterState(KConfigGroup& group); void plugNewVersionInFormatAction(EditorWindow* const q, QMenu* const menuAction, const QString& text, const QString& format); public: static const QString configAutoZoomEntry; static const QString configBackgroundColorEntry; static const QString configJpeg2000CompressionEntry; static const QString configJpeg2000LossLessEntry; static const QString configJpegCompressionEntry; static const QString configJpegSubSamplingEntry; static const QString configPgfCompressionEntry; static const QString configPgfLossLessEntry; static const QString configPngCompressionEntry; static const QString configSplitterStateEntry; static const QString configTiffCompressionEntry; static const QString configUnderExposureColorEntry; static const QString configUnderExposureIndicatorEntry; static const QString configUnderExposurePercentsEntry; static const QString configOverExposureColorEntry; static const QString configOverExposureIndicatorEntry; static const QString configOverExposurePercentsEntry; static const QString configExpoIndicatorModeEntry; static const QString configUseRawImportToolEntry; static const QString configUseThemeBackgroundColorEntry; static const QString configVerticalSplitterSizesEntry; static const QString configVerticalSplitterStateEntry; QToolButton* cmViewIndicator; QToolButton* underExposureIndicator; QToolButton* overExposureIndicator; DAdjustableLabel* infoLabel; QAction* copyAction; QAction* cropAction; QAction* autoCropAction; QAction* filePrintAction; QAction* flipHorizAction; QAction* flipVertAction; QAction* rotateLeftAction; QAction* rotateRightAction; QAction* selectAllAction; QAction* selectNoneAction; QAction* slideShowAction; QAction* softProofOptionsAction; QAction* zoomFitToSelectAction; QAction* zoomMinusAction; QAction* zoomPlusAction; QAction* zoomTo100percents; QAction* openWithAction; // Tools Actions QAction* textureAction; QAction* borderAction; QAction* insertTextAction; QAction* filmgrainAction; QAction* raindropAction; QAction* distortionfxAction; QAction* blurfxAction; QAction* oilpaintAction; QAction* embossAction; QAction* charcoalAction; QAction* colorEffectsAction; QAction* BCGAction; QAction* HSLAction; QAction* CBAction; QAction* autoCorrectionAction; QAction* invertAction; QAction* BWAction; QAction* convertTo8Bits; QAction* convertTo16Bits; QAction* whitebalanceAction; QAction* channelMixerAction; QAction* curvesAction; QAction* levelsAction; QAction* filmAction; - IccProfilesMenuAction* profileMenuAction; + QAction* profileMenuAction; QAction* colorSpaceConverter; QAction* hotpixelsAction; QAction* lensdistortionAction; QAction* antivignettingAction; QAction* lensAutoFixAction; QAction* redeyeAction; QAction* restorationAction; QAction* blurAction; QAction* healCloneAction; QAction* sharpenAction; QAction* noiseReductionAction; QAction* localContrastAction; QAction* inPaintingAction; QAction* aspectRatioCropAction; QAction* resizeAction; QAction* contentAwareResizingAction; QAction* sheartoolAction; QAction* freerotationAction; QAction* perspectiveAction; QSignalMapper* undoSignalMapper; QSignalMapper* redoSignalMapper; QSignalMapper* formatMenuActionMapper; QEventLoop* waitingLoop; QDialog* currentWindowModalDialog; QAction* zoomFitToWindowAction; QAction* viewCMViewAction; QAction* viewSoftProofAction; QAction* viewUnderExpoAction; QAction* viewOverExpoAction; ActionCategorizedView* selectToolsActionView; ICCSettingsContainer* ICCSettings; DZoomBar* zoomBar; PreviewToolBar* previewToolBar; ExposureSettingsContainer* exposureSettings; EditorToolIface* toolIface; VersionManager defaultVersionManager; QList fullscreenSizeBackup; QMap servicesMap; }; const QString EditorWindow::Private::configAutoZoomEntry(QLatin1String("AutoZoom")); const QString EditorWindow::Private::configBackgroundColorEntry(QLatin1String("BackgroundColor")); const QString EditorWindow::Private::configJpeg2000CompressionEntry(QLatin1String("JPEG2000Compression")); const QString EditorWindow::Private::configJpeg2000LossLessEntry(QLatin1String("JPEG2000LossLess")); const QString EditorWindow::Private::configJpegCompressionEntry(QLatin1String("JPEGCompression")); const QString EditorWindow::Private::configJpegSubSamplingEntry(QLatin1String("JPEGSubSampling")); const QString EditorWindow::Private::configPgfCompressionEntry(QLatin1String("PGFCompression")); const QString EditorWindow::Private::configPgfLossLessEntry(QLatin1String("PGFLossLess")); const QString EditorWindow::Private::configPngCompressionEntry(QLatin1String("PNGCompression")); const QString EditorWindow::Private::configSplitterStateEntry(QLatin1String("SplitterState")); const QString EditorWindow::Private::configTiffCompressionEntry(QLatin1String("TIFFCompression")); const QString EditorWindow::Private::configUnderExposureColorEntry(QLatin1String("UnderExposureColor")); const QString EditorWindow::Private::configUnderExposureIndicatorEntry(QLatin1String("UnderExposureIndicator")); const QString EditorWindow::Private::configUnderExposurePercentsEntry(QLatin1String("UnderExposurePercentsEntry")); const QString EditorWindow::Private::configOverExposureColorEntry(QLatin1String("OverExposureColor")); const QString EditorWindow::Private::configOverExposureIndicatorEntry(QLatin1String("OverExposureIndicator")); const QString EditorWindow::Private::configOverExposurePercentsEntry(QLatin1String("OverExposurePercentsEntry")); const QString EditorWindow::Private::configExpoIndicatorModeEntry(QLatin1String("ExpoIndicatorMode")); const QString EditorWindow::Private::configUseRawImportToolEntry(QLatin1String("UseRawImportTool")); const QString EditorWindow::Private::configUseThemeBackgroundColorEntry(QLatin1String("UseThemeBackgroundColor")); const QString EditorWindow::Private::configVerticalSplitterSizesEntry(QLatin1String("Vertical Splitter Sizes")); const QString EditorWindow::Private::configVerticalSplitterStateEntry(QLatin1String("Vertical Splitter State")); void EditorWindow::Private::legacyUpdateSplitterState(KConfigGroup& group) { // Check if the thumbnail size in the config file is splitter based (the // old method), and convert to dock based if needed. if (group.hasKey(configSplitterStateEntry)) { // Read splitter state from config file QByteArray state; state = QByteArray::fromBase64(group.readEntry(configSplitterStateEntry, state)); // Do a cheap check: a splitter state with 3 windows is always 34 bytes. if (state.count() == 34) { // Read the state in streamwise fashion. QDataStream stream(state); // The first 8 bytes are resp. the magic number and the version // (which should be 0, otherwise it's not saved with an older // digiKam version). Then follows the list of window sizes. qint32 marker; qint32 version = -1; QList sizesList; stream >> marker; stream >> version; if (version == 0) { stream >> sizesList; if (sizesList.count() == 3) { qCDebug(DIGIKAM_GENERAL_LOG) << "Found splitter based config, converting to dockbar"; // Remove the first entry (the thumbbar) and write the rest // back. Then it should be fine. sizesList.removeFirst(); QByteArray newData; QDataStream newStream(&newData, QIODevice::WriteOnly); newStream << marker; newStream << version; newStream << sizesList; char s[24]; int numBytes = stream.readRawData(s, 24); newStream.writeRawData(s, numBytes); group.writeEntry(configSplitterStateEntry, newData.toBase64()); } } } } } void EditorWindow::Private::plugNewVersionInFormatAction(EditorWindow* const q, QMenu* const menuAction, const QString& text, const QString& format) { if (!formatMenuActionMapper) { formatMenuActionMapper = new QSignalMapper(q); connect(formatMenuActionMapper, SIGNAL(mapped(QString)), q, SLOT(saveNewVersionInFormat(QString))); } QAction* const action = new QAction(text, q); connect(action, SIGNAL(triggered()), formatMenuActionMapper, SLOT(map())); formatMenuActionMapper->setMapping(action, format); menuAction->addAction(action); } } // namespace Digikam #endif // DIGIKAM_IMAGE_EDITOR_WINDOW_PRIVATE_H