Found via `codespell -q 3 -I ../rawtherapy-whitelist.txt -S ./rtdata/languages -L hist,fo,reall,bloc,alph`
1017 lines
34 KiB
C++
1017 lines
34 KiB
C++
/*
|
|
* This file is part of RawTherapee.
|
|
*
|
|
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
|
*
|
|
* RawTherapee 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* RawTherapee 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "multilangmgr.h"
|
|
#include "toolpanelcoord.h"
|
|
#include "options.h"
|
|
#include "../rtengine/imagesource.h"
|
|
#include "../rtengine/dfmanager.h"
|
|
#include "../rtengine/ffmanager.h"
|
|
#include "../rtengine/improcfun.h"
|
|
#include "../rtengine/procevents.h"
|
|
#include "../rtengine/refreshmap.h"
|
|
|
|
using namespace rtengine::procparams;
|
|
|
|
ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr)
|
|
{
|
|
|
|
favoritePanel = Gtk::manage (new ToolVBox ());
|
|
exposurePanel = Gtk::manage (new ToolVBox ());
|
|
detailsPanel = Gtk::manage (new ToolVBox ());
|
|
colorPanel = Gtk::manage (new ToolVBox ());
|
|
transformPanel = Gtk::manage (new ToolVBox ());
|
|
rawPanel = Gtk::manage (new ToolVBox ());
|
|
advancedPanel = Gtk::manage (new ToolVBox ());
|
|
|
|
coarse = Gtk::manage (new CoarsePanel ());
|
|
toneCurve = Gtk::manage (new ToneCurve ());
|
|
shadowshighlights = Gtk::manage (new ShadowsHighlights ());
|
|
impulsedenoise = Gtk::manage (new ImpulseDenoise ());
|
|
defringe = Gtk::manage (new Defringe ());
|
|
dirpyrdenoise = Gtk::manage (new DirPyrDenoise ());
|
|
epd = Gtk::manage (new EdgePreservingDecompositionUI ());
|
|
sharpening = Gtk::manage (new Sharpening ());
|
|
localContrast = Gtk::manage(new LocalContrast());
|
|
sharpenEdge = Gtk::manage (new SharpenEdge ());
|
|
sharpenMicro = Gtk::manage (new SharpenMicro ());
|
|
lcurve = Gtk::manage (new LCurve ());
|
|
rgbcurves = Gtk::manage (new RGBCurves ());
|
|
colortoning = Gtk::manage (new ColorToning ());
|
|
lensgeom = Gtk::manage (new LensGeometry ());
|
|
lensProf = Gtk::manage (new LensProfilePanel ());
|
|
distortion = Gtk::manage (new Distortion ());
|
|
rotate = Gtk::manage (new Rotate ());
|
|
vibrance = Gtk::manage (new Vibrance ());
|
|
colorappearance = Gtk::manage (new ColorAppearance ());
|
|
whitebalance = Gtk::manage (new WhiteBalance ());
|
|
vignetting = Gtk::manage (new Vignetting ());
|
|
retinex = Gtk::manage (new Retinex ());
|
|
gradient = Gtk::manage (new Gradient ());
|
|
pcvignette = Gtk::manage (new PCVignette ());
|
|
perspective = Gtk::manage (new PerspCorrection ());
|
|
cacorrection = Gtk::manage (new CACorrection ());
|
|
chmixer = Gtk::manage (new ChMixer ());
|
|
blackwhite = Gtk::manage (new BlackWhite ());
|
|
resize = Gtk::manage (new Resize ());
|
|
prsharpening = Gtk::manage (new PrSharpening());
|
|
crop = Gtk::manage (new Crop ());
|
|
icm = Gtk::manage (new ICMPanel ());
|
|
metadata = Gtk::manage(new MetaDataPanel());
|
|
wavelet = Gtk::manage (new Wavelet ());
|
|
dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ());
|
|
hsvequalizer = Gtk::manage (new HSVEqualizer ());
|
|
filmSimulation = Gtk::manage (new FilmSimulation ());
|
|
softlight = Gtk::manage(new SoftLight());
|
|
dehaze = Gtk::manage(new Dehaze());
|
|
sensorbayer = Gtk::manage (new SensorBayer ());
|
|
sensorxtrans = Gtk::manage (new SensorXTrans ());
|
|
bayerprocess = Gtk::manage (new BayerProcess ());
|
|
xtransprocess = Gtk::manage (new XTransProcess ());
|
|
bayerpreprocess = Gtk::manage (new BayerPreProcess ());
|
|
preprocess = Gtk::manage (new PreProcess ());
|
|
darkframe = Gtk::manage (new DarkFrame ());
|
|
flatfield = Gtk::manage (new FlatField ());
|
|
rawcacorrection = Gtk::manage (new RAWCACorr ());
|
|
rawexposure = Gtk::manage (new RAWExposure ());
|
|
bayerrawexposure = Gtk::manage (new BayerRAWExposure ());
|
|
xtransrawexposure = Gtk::manage (new XTransRAWExposure ());
|
|
fattal = Gtk::manage (new FattalToneMapping ());
|
|
|
|
// So Demosaic, Line noise filter, Green Equilibration, Ca-Correction (garder le nom de section identique!) and Black-Level will be moved in a "Bayer sensor" tool,
|
|
// and a separate Demosaic and Black Level tool will be created in an "X-Trans sensor" tool
|
|
|
|
// X-Trans demozaic methods: "3-pass (best), 1-pass (medium), fast"
|
|
// Mettre jour les profils fournis pour inclure les nouvelles section Raw, notamment pour "Default High ISO"
|
|
// Valeurs par dfaut:
|
|
// Best -> low ISO
|
|
// Medium -> High ISO
|
|
favorites.resize(options.favorites.size(), nullptr);
|
|
|
|
addfavoritePanel (colorPanel, whitebalance);
|
|
addfavoritePanel (exposurePanel, toneCurve);
|
|
addfavoritePanel (colorPanel, vibrance);
|
|
addfavoritePanel (colorPanel, chmixer);
|
|
addfavoritePanel (colorPanel, blackwhite);
|
|
addfavoritePanel (exposurePanel, shadowshighlights);
|
|
addfavoritePanel (detailsPanel, sharpening);
|
|
addfavoritePanel (detailsPanel, localContrast);
|
|
addfavoritePanel (detailsPanel, sharpenEdge);
|
|
addfavoritePanel (detailsPanel, sharpenMicro);
|
|
addfavoritePanel (colorPanel, hsvequalizer);
|
|
addfavoritePanel (colorPanel, filmSimulation);
|
|
addfavoritePanel (colorPanel, softlight);
|
|
addfavoritePanel (colorPanel, rgbcurves);
|
|
addfavoritePanel (colorPanel, colortoning);
|
|
addfavoritePanel (exposurePanel, epd);
|
|
addfavoritePanel (exposurePanel, fattal);
|
|
addfavoritePanel (advancedPanel, retinex);
|
|
addfavoritePanel (exposurePanel, pcvignette);
|
|
addfavoritePanel (exposurePanel, gradient);
|
|
addfavoritePanel (exposurePanel, lcurve);
|
|
addfavoritePanel (advancedPanel, colorappearance);
|
|
addfavoritePanel (detailsPanel, impulsedenoise);
|
|
addfavoritePanel (detailsPanel, dirpyrdenoise);
|
|
addfavoritePanel (detailsPanel, defringe);
|
|
addfavoritePanel (detailsPanel, dirpyrequalizer);
|
|
addfavoritePanel (detailsPanel, dehaze);
|
|
addfavoritePanel (advancedPanel, wavelet);
|
|
addfavoritePanel (transformPanel, crop);
|
|
addfavoritePanel (transformPanel, resize);
|
|
addPanel (resize->getPackBox(), prsharpening, 2);
|
|
addfavoritePanel (transformPanel, lensgeom);
|
|
addfavoritePanel (lensgeom->getPackBox(), rotate, 2);
|
|
addfavoritePanel (lensgeom->getPackBox(), perspective, 2);
|
|
addfavoritePanel (lensgeom->getPackBox(), lensProf, 2);
|
|
addfavoritePanel (lensgeom->getPackBox(), distortion, 2);
|
|
addfavoritePanel (lensgeom->getPackBox(), cacorrection, 2);
|
|
addfavoritePanel (lensgeom->getPackBox(), vignetting, 2);
|
|
addfavoritePanel (colorPanel, icm);
|
|
addfavoritePanel (rawPanel, sensorbayer);
|
|
addfavoritePanel (sensorbayer->getPackBox(), bayerprocess, 2);
|
|
addfavoritePanel (sensorbayer->getPackBox(), bayerrawexposure, 2);
|
|
addfavoritePanel (sensorbayer->getPackBox(), bayerpreprocess, 2);
|
|
addfavoritePanel (sensorbayer->getPackBox(), rawcacorrection, 2);
|
|
addfavoritePanel (rawPanel, sensorxtrans);
|
|
addfavoritePanel (sensorxtrans->getPackBox(), xtransprocess, 2);
|
|
addfavoritePanel (sensorxtrans->getPackBox(), xtransrawexposure, 2);
|
|
addfavoritePanel (rawPanel, rawexposure);
|
|
addfavoritePanel (rawPanel, preprocess);
|
|
addfavoritePanel (rawPanel, darkframe);
|
|
addfavoritePanel (rawPanel, flatfield);
|
|
|
|
int favoriteCount = 0;
|
|
for(auto it = favorites.begin(); it != favorites.end(); ++it) {
|
|
if (*it) {
|
|
addPanel(favoritePanel, *it);
|
|
++favoriteCount;
|
|
}
|
|
}
|
|
|
|
toolPanels.push_back (coarse);
|
|
toolPanels.push_back(metadata);
|
|
|
|
toolPanelNotebook = new Gtk::Notebook ();
|
|
toolPanelNotebook->set_name ("ToolPanelNotebook");
|
|
|
|
exposurePanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
detailsPanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
colorPanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
transformPanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
rawPanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
advancedPanelSW = Gtk::manage (new MyScrolledWindow ());
|
|
updateVScrollbars (options.hideTPVScrollbar);
|
|
|
|
// load panel endings
|
|
for (int i = 0; i < 7; i++) {
|
|
vbPanelEnd[i] = Gtk::manage (new Gtk::VBox ());
|
|
imgPanelEnd[i] = Gtk::manage (new RTImage ("ornament1.png"));
|
|
imgPanelEnd[i]->show ();
|
|
vbPanelEnd[i]->pack_start (*imgPanelEnd[i], Gtk::PACK_SHRINK);
|
|
vbPanelEnd[i]->show_all();
|
|
}
|
|
|
|
if(favoriteCount > 0) {
|
|
favoritePanelSW = Gtk::manage(new MyScrolledWindow());
|
|
favoritePanelSW->add(*favoritePanel);
|
|
favoritePanel->pack_start(*Gtk::manage(new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
favoritePanel->pack_start(*vbPanelEnd[0], Gtk::PACK_SHRINK, 4);
|
|
}
|
|
|
|
exposurePanelSW->add (*exposurePanel);
|
|
exposurePanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
exposurePanel->pack_start (*vbPanelEnd[1], Gtk::PACK_SHRINK, 4);
|
|
|
|
detailsPanelSW->add (*detailsPanel);
|
|
detailsPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
detailsPanel->pack_start (*vbPanelEnd[2], Gtk::PACK_SHRINK, 4);
|
|
|
|
colorPanelSW->add (*colorPanel);
|
|
colorPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
colorPanel->pack_start (*vbPanelEnd[3], Gtk::PACK_SHRINK, 4);
|
|
|
|
advancedPanelSW->add (*advancedPanel);
|
|
advancedPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
advancedPanel->pack_start (*vbPanelEnd[6], Gtk::PACK_SHRINK, 0);
|
|
|
|
transformPanelSW->add (*transformPanel);
|
|
transformPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
transformPanel->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 4);
|
|
|
|
rawPanelSW->add (*rawPanel);
|
|
rawPanel->pack_start (*Gtk::manage (new Gtk::HSeparator), Gtk::PACK_SHRINK, 0);
|
|
rawPanel->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0);
|
|
|
|
toiF = Gtk::manage (new TextOrIcon ("star.png", M ("MAIN_TAB_FAVORITES"), M ("MAIN_TAB_FAVORITES_TOOLTIP")));
|
|
toiE = Gtk::manage (new TextOrIcon ("exposure.png", M ("MAIN_TAB_EXPOSURE"), M ("MAIN_TAB_EXPOSURE_TOOLTIP")));
|
|
toiD = Gtk::manage (new TextOrIcon ("detail.png", M ("MAIN_TAB_DETAIL"), M ("MAIN_TAB_DETAIL_TOOLTIP")));
|
|
toiC = Gtk::manage (new TextOrIcon ("color-circles.png", M ("MAIN_TAB_COLOR"), M ("MAIN_TAB_COLOR_TOOLTIP")));
|
|
toiW = Gtk::manage (new TextOrIcon ("atom.png", M ("MAIN_TAB_ADVANCED"), M ("MAIN_TAB_ADVANCED_TOOLTIP")));
|
|
toiT = Gtk::manage (new TextOrIcon ("transform.png", M ("MAIN_TAB_TRANSFORM"), M ("MAIN_TAB_TRANSFORM_TOOLTIP")));
|
|
toiR = Gtk::manage (new TextOrIcon ("bayer.png", M ("MAIN_TAB_RAW"), M ("MAIN_TAB_RAW_TOOLTIP")));
|
|
toiM = Gtk::manage (new TextOrIcon ("metadata.png", M ("MAIN_TAB_METADATA"), M ("MAIN_TAB_METADATA_TOOLTIP")));
|
|
|
|
if (favoritePanelSW) {
|
|
toolPanelNotebook->append_page (*favoritePanelSW, *toiF);
|
|
}
|
|
toolPanelNotebook->append_page (*exposurePanelSW, *toiE);
|
|
toolPanelNotebook->append_page (*detailsPanelSW, *toiD);
|
|
toolPanelNotebook->append_page (*colorPanelSW, *toiC);
|
|
toolPanelNotebook->append_page (*advancedPanelSW, *toiW);
|
|
toolPanelNotebook->append_page (*transformPanelSW, *toiT);
|
|
toolPanelNotebook->append_page (*rawPanelSW, *toiR);
|
|
toolPanelNotebook->append_page (*metadata, *toiM);
|
|
|
|
toolPanelNotebook->set_current_page (0);
|
|
|
|
toolPanelNotebook->set_scrollable ();
|
|
toolPanelNotebook->show_all ();
|
|
|
|
for (auto toolPanel : toolPanels) {
|
|
toolPanel->setListener (this);
|
|
}
|
|
|
|
whitebalance->setWBProvider (this);
|
|
whitebalance->setSpotWBListener (this);
|
|
darkframe->setDFProvider (this);
|
|
flatfield->setFFProvider (this);
|
|
lensgeom->setLensGeomListener (this);
|
|
rotate->setLensGeomListener (this);
|
|
distortion->setLensGeomListener (this);
|
|
crop->setCropPanelListener (this);
|
|
icm->setICMPanelListener (this);
|
|
|
|
toolBar = new ToolBar ();
|
|
toolBar->setToolBarListener (this);
|
|
}
|
|
|
|
void ToolPanelCoordinator::addPanel (Gtk::Box* where, FoldableToolPanel* panel, int level)
|
|
{
|
|
|
|
panel->setParent (where);
|
|
panel->setLevel (level);
|
|
|
|
expList.push_back (panel->getExpander());
|
|
where->pack_start (*panel->getExpander(), false, false);
|
|
toolPanels.push_back (panel);
|
|
}
|
|
|
|
void ToolPanelCoordinator::addfavoritePanel (Gtk::Box* where, FoldableToolPanel* panel, int level)
|
|
{
|
|
auto name = panel->getToolName();
|
|
auto it = std::find(options.favorites.begin(), options.favorites.end(), name);
|
|
if (it != options.favorites.end()) {
|
|
int index = std::distance(options.favorites.begin(), it);
|
|
favorites[index] = panel;
|
|
} else {
|
|
addPanel(where, panel, level);
|
|
}
|
|
}
|
|
|
|
ToolPanelCoordinator::~ToolPanelCoordinator ()
|
|
{
|
|
idle_register.destroy();
|
|
|
|
closeImage ();
|
|
|
|
delete toolPanelNotebook;
|
|
delete toolBar;
|
|
}
|
|
|
|
void ToolPanelCoordinator::imageTypeChanged (bool isRaw, bool isBayer, bool isXtrans, bool isMono)
|
|
{
|
|
if (isRaw) {
|
|
if (isBayer) {
|
|
idle_register.add(
|
|
[this]() -> bool
|
|
{
|
|
rawPanelSW->set_sensitive(true);
|
|
sensorxtrans->FoldableToolPanel::hide();
|
|
sensorbayer->FoldableToolPanel::show();
|
|
preprocess->FoldableToolPanel::show();
|
|
flatfield->FoldableToolPanel::show();
|
|
retinex->FoldableToolPanel::setGrayedOut(false);
|
|
|
|
return false;
|
|
}
|
|
);
|
|
}
|
|
else if (isXtrans) {
|
|
idle_register.add(
|
|
[this]() -> bool
|
|
{
|
|
rawPanelSW->set_sensitive(true);
|
|
sensorxtrans->FoldableToolPanel::show();
|
|
sensorbayer->FoldableToolPanel::hide();
|
|
preprocess->FoldableToolPanel::show();
|
|
flatfield->FoldableToolPanel::show();
|
|
retinex->FoldableToolPanel::setGrayedOut(false);
|
|
|
|
return false;
|
|
}
|
|
);
|
|
}
|
|
else if (isMono) {
|
|
idle_register.add(
|
|
[this]() -> bool
|
|
{
|
|
rawPanelSW->set_sensitive(true);
|
|
sensorbayer->FoldableToolPanel::hide();
|
|
sensorxtrans->FoldableToolPanel::hide();
|
|
preprocess->FoldableToolPanel::hide();
|
|
flatfield->FoldableToolPanel::show();
|
|
retinex->FoldableToolPanel::setGrayedOut(false);
|
|
|
|
return false;
|
|
}
|
|
);
|
|
} else {
|
|
idle_register.add(
|
|
[this]() -> bool
|
|
{
|
|
rawPanelSW->set_sensitive(true);
|
|
sensorbayer->FoldableToolPanel::hide();
|
|
sensorxtrans->FoldableToolPanel::hide();
|
|
preprocess->FoldableToolPanel::hide();
|
|
flatfield->FoldableToolPanel::hide();
|
|
retinex->FoldableToolPanel::setGrayedOut(false);
|
|
|
|
return false;
|
|
}
|
|
);
|
|
}
|
|
} else {
|
|
idle_register.add(
|
|
[this]() -> bool
|
|
{
|
|
rawPanelSW->set_sensitive(false);
|
|
retinex->FoldableToolPanel::setGrayedOut(true);
|
|
|
|
return false;
|
|
}
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void ToolPanelCoordinator::panelChanged(const rtengine::ProcEvent& event, const Glib::ustring& descr)
|
|
{
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
int changeFlags = rtengine::RefreshMapper::getInstance()->getAction(event);
|
|
|
|
ProcParams* params = ipc->beginUpdateParams ();
|
|
|
|
for (auto toolPanel : toolPanels) {
|
|
toolPanel->write (params);
|
|
}
|
|
|
|
// Compensate rotation on flip
|
|
if (event == rtengine::EvCTHFlip || event == rtengine::EvCTVFlip) {
|
|
if (fabs (params->rotate.degree) > 0.001) {
|
|
params->rotate.degree *= -1;
|
|
changeFlags |= rtengine::RefreshMapper::getInstance()->getAction(rtengine::EvROTDegree);
|
|
rotate->read (params);
|
|
}
|
|
}
|
|
|
|
int tr = TR_NONE;
|
|
|
|
if (params->coarse.rotate == 90) {
|
|
tr = TR_R90;
|
|
} else if (params->coarse.rotate == 180) {
|
|
tr = TR_R180;
|
|
} else if (params->coarse.rotate == 270) {
|
|
tr = TR_R270;
|
|
}
|
|
|
|
// Update "on preview" geometry
|
|
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged || event == rtengine::EvHistoryBrowsed || event == rtengine::EvCTRotate) {
|
|
// updating the "on preview" geometry
|
|
int fw, fh;
|
|
ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr);
|
|
gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh);
|
|
}
|
|
|
|
// some transformations make the crop change for convenience
|
|
if (event == rtengine::EvCTHFlip) {
|
|
crop->hFlipCrop ();
|
|
crop->write (params);
|
|
} else if (event == rtengine::EvCTVFlip) {
|
|
crop->vFlipCrop ();
|
|
crop->write (params);
|
|
} else if (event == rtengine::EvCTRotate) {
|
|
crop->rotateCrop (params->coarse.rotate, params->coarse.hflip, params->coarse.vflip);
|
|
crop->write (params);
|
|
resize->update (params->crop.enabled, params->crop.w, params->crop.h, ipc->getFullWidth(), ipc->getFullHeight());
|
|
resize->write (params);
|
|
} else if (event == rtengine::EvCrop) {
|
|
resize->update (params->crop.enabled, params->crop.w, params->crop.h);
|
|
resize->write (params);
|
|
}
|
|
|
|
ipc->endUpdateParams (changeFlags); // starts the IPC processing
|
|
|
|
hasChanged = true;
|
|
|
|
for (auto paramcListener : paramcListeners) {
|
|
paramcListener->procParamsChanged (params, event, descr);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::profileChange(
|
|
const PartialProfile* nparams,
|
|
const rtengine::ProcEvent& event,
|
|
const Glib::ustring& descr,
|
|
const ParamsEdited* paramsEdited,
|
|
bool fromLastSave
|
|
)
|
|
{
|
|
int fw, fh, tr;
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
ProcParams *params = ipc->beginUpdateParams ();
|
|
ProcParams *mergedParams = new ProcParams();
|
|
|
|
// Copy the current params as default values for the fusion
|
|
*mergedParams = *params;
|
|
|
|
// Reset IPTC values when switching procparams from the History
|
|
if (event == rtengine::EvHistoryBrowsed) {
|
|
mergedParams->iptc.clear();
|
|
mergedParams->exif.clear();
|
|
}
|
|
|
|
// And apply the partial profile nparams to mergedParams
|
|
nparams->applyTo (mergedParams, fromLastSave);
|
|
|
|
// Derive the effective changes, if it's a profile change, to prevent slow RAW rerendering if not necessary
|
|
bool filterRawRefresh = false;
|
|
|
|
if (event != rtengine::EvPhotoLoaded) {
|
|
ParamsEdited pe (true);
|
|
std::vector<rtengine::procparams::ProcParams> lParams (2);
|
|
lParams[0] = *params;
|
|
lParams[1] = *mergedParams;
|
|
pe.initFrom (lParams);
|
|
|
|
filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged() && pe.retinex.isUnchanged();
|
|
}
|
|
|
|
*params = *mergedParams;
|
|
delete mergedParams;
|
|
|
|
tr = TR_NONE;
|
|
|
|
if (params->coarse.rotate == 90) {
|
|
tr = TR_R90;
|
|
} else if (params->coarse.rotate == 180) {
|
|
tr = TR_R180;
|
|
} else if (params->coarse.rotate == 270) {
|
|
tr = TR_R270;
|
|
}
|
|
|
|
// trimming overflowing cropped area
|
|
ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr);
|
|
crop->trim (params, fw, fh);
|
|
|
|
// updating the GUI with updated values
|
|
for (auto toolPanel : toolPanels) {
|
|
toolPanel->read (params);
|
|
|
|
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged) {
|
|
toolPanel->autoOpenCurve();
|
|
}
|
|
}
|
|
|
|
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged || event == rtengine::EvHistoryBrowsed || event == rtengine::EvCTRotate) {
|
|
// updating the "on preview" geometry
|
|
gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh);
|
|
}
|
|
|
|
// start the IPC processing
|
|
if (filterRawRefresh) {
|
|
ipc->endUpdateParams ( rtengine::RefreshMapper::getInstance()->getAction(event) & ALLNORAW );
|
|
} else {
|
|
ipc->endUpdateParams (event);
|
|
}
|
|
|
|
hasChanged = event != rtengine::EvProfileChangeNotification;
|
|
|
|
for (auto paramcListener : paramcListeners) {
|
|
paramcListener->procParamsChanged (params, event, descr);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::setDefaults(const ProcParams* defparams)
|
|
{
|
|
if (defparams) {
|
|
for (auto toolPanel : toolPanels) {
|
|
toolPanel->setDefaults(defparams);
|
|
}
|
|
}
|
|
}
|
|
|
|
CropGUIListener* ToolPanelCoordinator::getCropGUIListener ()
|
|
{
|
|
|
|
return crop;
|
|
}
|
|
|
|
void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool raw)
|
|
{
|
|
|
|
ipc = ipc_;
|
|
toneCurve->disableListener ();
|
|
toneCurve->enableAll ();
|
|
toneCurve->enableListener ();
|
|
|
|
if (ipc) {
|
|
const rtengine::FramesMetaData* pMetaData = ipc->getInitialImage()->getMetaData();
|
|
metadata->setImageData(pMetaData);
|
|
|
|
ipc->setAutoExpListener (toneCurve);
|
|
ipc->setAutoCamListener (colorappearance);
|
|
ipc->setAutoBWListener (blackwhite);
|
|
ipc->setFrameCountListener (bayerprocess);
|
|
ipc->setFlatFieldAutoClipListener (flatfield);
|
|
ipc->setBayerAutoContrastListener (bayerprocess);
|
|
ipc->setXtransAutoContrastListener (xtransprocess);
|
|
ipc->setAutoWBListener (whitebalance);
|
|
ipc->setAutoColorTonListener (colortoning);
|
|
ipc->setAutoChromaListener (dirpyrdenoise);
|
|
ipc->setWaveletListener (wavelet);
|
|
ipc->setRetinexListener (retinex);
|
|
ipc->setSizeListener (crop);
|
|
ipc->setSizeListener (resize);
|
|
ipc->setImageTypeListener (this);
|
|
flatfield->setShortcutPath (Glib::path_get_dirname (ipc->getInitialImage()->getFileName()));
|
|
|
|
icm->setRawMeta (raw, (const rtengine::FramesData*)pMetaData);
|
|
lensProf->setRawMeta (raw, pMetaData);
|
|
}
|
|
|
|
|
|
toneCurve->setRaw (raw);
|
|
hasChanged = true;
|
|
}
|
|
|
|
|
|
void ToolPanelCoordinator::closeImage ()
|
|
{
|
|
|
|
if (ipc) {
|
|
ipc->stopProcessing ();
|
|
ipc = nullptr;
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::closeAllTools()
|
|
{
|
|
|
|
for (size_t i = 0; i < options.tpOpen.size(); i++)
|
|
if (i < expList.size()) {
|
|
expList.at (i)->set_expanded (false);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::openAllTools()
|
|
{
|
|
|
|
for (size_t i = 0; i < options.tpOpen.size(); i++)
|
|
if (i < expList.size()) {
|
|
expList.at (i)->set_expanded (true);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::updateToolState()
|
|
{
|
|
|
|
for (size_t i = 0; i < options.tpOpen.size(); i++)
|
|
if (i < expList.size()) {
|
|
expList.at (i)->set_expanded (options.tpOpen.at (i));
|
|
}
|
|
|
|
if (options.tpOpen.size() > expList.size()) {
|
|
size_t sizeWavelet = options.tpOpen.size() - expList.size();
|
|
std::vector<int> temp;
|
|
|
|
for (size_t i = 0; i < sizeWavelet; i++) {
|
|
temp.push_back (options.tpOpen.at (i + expList.size()));
|
|
}
|
|
|
|
wavelet->updateToolState (temp);
|
|
retinex->updateToolState (temp);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::readOptions ()
|
|
{
|
|
|
|
crop->readOptions ();
|
|
}
|
|
|
|
void ToolPanelCoordinator::writeOptions ()
|
|
{
|
|
|
|
crop->writeOptions ();
|
|
|
|
if (options.autoSaveTpOpen) {
|
|
writeToolExpandedStatus (options.tpOpen);
|
|
}
|
|
}
|
|
|
|
|
|
void ToolPanelCoordinator::writeToolExpandedStatus (std::vector<int> &tpOpen)
|
|
{
|
|
tpOpen.clear ();
|
|
|
|
for (size_t i = 0; i < expList.size(); i++) {
|
|
tpOpen.push_back (expList.at (i)->get_expanded ());
|
|
}
|
|
|
|
wavelet->writeOptions (tpOpen);
|
|
retinex->writeOptions (tpOpen);
|
|
}
|
|
|
|
|
|
void ToolPanelCoordinator::spotWBselected(int x, int y, Thumbnail* thm)
|
|
{
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
// toolBar->setTool (TOOL_HAND);
|
|
int rect = whitebalance->getSize ();
|
|
int ww = ipc->getFullWidth();
|
|
int hh = ipc->getFullHeight();
|
|
|
|
if (x - rect > 0 && y - rect > 0 && x + rect < ww && y + rect < hh) {
|
|
double temp;
|
|
double green;
|
|
ipc->getSpotWB (x, y, rect, temp, green);
|
|
whitebalance->setWB (temp, green);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::sharpMaskSelected(bool sharpMask)
|
|
{
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
ipc->beginUpdateParams ();
|
|
ipc->setSharpMask(sharpMask);
|
|
ipc->endUpdateParams (rtengine::EvShrEnabled);
|
|
}
|
|
|
|
int ToolPanelCoordinator::getSpotWBRectSize() const
|
|
{
|
|
return whitebalance->getSize();
|
|
}
|
|
|
|
void ToolPanelCoordinator::cropSelectionReady()
|
|
{
|
|
toolBar->setTool (TMHand);
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::rotateSelectionReady(double rotate_deg, Thumbnail* thm)
|
|
{
|
|
toolBar->setTool (TMHand);
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
if (rotate_deg != 0.0) {
|
|
rotate->straighten (rotate_deg);
|
|
}
|
|
}
|
|
|
|
ToolBar* ToolPanelCoordinator::getToolBar() const
|
|
{
|
|
return toolBar;
|
|
}
|
|
|
|
CropGUIListener* ToolPanelCoordinator::startCropEditing(Thumbnail* thm)
|
|
{
|
|
return crop;
|
|
}
|
|
|
|
void ToolPanelCoordinator::autoCropRequested ()
|
|
{
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
int x1, y1, x2, y2, w, h;
|
|
ipc->getAutoCrop (crop->getRatio(), x1, y1, w, h);
|
|
x2 = x1 + w - 1;
|
|
y2 = y1 + h - 1;
|
|
crop->cropInit (x1, y1, w, h);
|
|
crop->cropResized (x1, y1, x2, y2);
|
|
crop->cropManipReady ();
|
|
}
|
|
|
|
rtengine::RawImage* ToolPanelCoordinator::getDF()
|
|
{
|
|
if (!ipc) {
|
|
return nullptr;
|
|
}
|
|
|
|
const rtengine::FramesMetaData *imd = ipc->getInitialImage()->getMetaData();
|
|
|
|
if (imd) {
|
|
int iso = imd->getISOSpeed();
|
|
double shutter = imd->getShutterSpeed();
|
|
std::string maker ( imd->getMake() );
|
|
std::string model ( imd->getModel() );
|
|
time_t timestamp = imd->getDateTimeAsTS();
|
|
|
|
return rtengine::dfm.searchDarkFrame ( maker, model, iso, shutter, timestamp);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
rtengine::RawImage* ToolPanelCoordinator::getFF()
|
|
{
|
|
if (!ipc) {
|
|
return nullptr;
|
|
}
|
|
|
|
const rtengine::FramesMetaData *imd = ipc->getInitialImage()->getMetaData();
|
|
|
|
if (imd) {
|
|
// int iso = imd->getISOSpeed(); temporarily removed because unused
|
|
// double shutter = imd->getShutterSpeed(); temporarily removed because unused
|
|
double aperture = imd->getFNumber();
|
|
double focallength = imd->getFocalLen();
|
|
std::string maker ( imd->getMake() );
|
|
std::string model ( imd->getModel() );
|
|
std::string lens ( imd->getLens() );
|
|
time_t timestamp = imd->getDateTimeAsTS();
|
|
|
|
return rtengine::ffm.searchFlatField ( maker, model, lens, focallength, aperture, timestamp);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Glib::ustring ToolPanelCoordinator::GetCurrentImageFilePath()
|
|
{
|
|
if (!ipc) {
|
|
return "";
|
|
}
|
|
|
|
return ipc->getInitialImage()->getFileName();
|
|
}
|
|
|
|
void ToolPanelCoordinator::straightenRequested ()
|
|
{
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
toolBar->setTool (TMStraighten);
|
|
}
|
|
|
|
double ToolPanelCoordinator::autoDistorRequested ()
|
|
{
|
|
if (!ipc) {
|
|
return 0.0;
|
|
}
|
|
|
|
return rtengine::ImProcFunctions::getAutoDistor (ipc->getInitialImage()->getFileName(), 400);
|
|
}
|
|
|
|
void ToolPanelCoordinator::spotWBRequested (int size)
|
|
{
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
toolBar->setTool (TMSpotWB);
|
|
}
|
|
|
|
void ToolPanelCoordinator::cropSelectRequested ()
|
|
{
|
|
|
|
if (!ipc) {
|
|
return;
|
|
}
|
|
|
|
toolBar->setTool (TMCropSelect);
|
|
}
|
|
|
|
void ToolPanelCoordinator::saveInputICCReference(const Glib::ustring& fname, bool apply_wb)
|
|
{
|
|
if (ipc) {
|
|
ipc->saveInputICCReference (fname, apply_wb);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::updateCurveBackgroundHistogram(
|
|
const LUTu& histToneCurve,
|
|
const LUTu& histLCurve,
|
|
const LUTu& histCCurve,
|
|
const LUTu& histLCAM,
|
|
const LUTu& histCCAM,
|
|
const LUTu& histRed,
|
|
const LUTu& histGreen,
|
|
const LUTu& histBlue,
|
|
const LUTu& histLuma,
|
|
const LUTu& histLRETI
|
|
)
|
|
{
|
|
colorappearance->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
|
toneCurve->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve,histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
|
lcurve->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
|
rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
|
retinex->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
|
}
|
|
|
|
void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection)
|
|
{
|
|
|
|
for (auto toolPanel : toolPanels) {
|
|
if (toolPanel->getParent() != nullptr) {
|
|
ToolPanel* currentTP = toolPanel;
|
|
|
|
if (currentTP->getParent() == parent) {
|
|
// Section in the same tab, we unfold it if it's not the one that has been clicked
|
|
if (currentTP != openedSection) {
|
|
currentTP->setExpanded (false);
|
|
} else {
|
|
if (!currentTP->getExpanded()) {
|
|
currentTP->setExpanded (true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ToolPanelCoordinator::handleShortcutKey (GdkEventKey* event)
|
|
{
|
|
|
|
//bool ctrl = event->state & GDK_CONTROL_MASK; temporarily removed because unused
|
|
//bool shift = event->state & GDK_SHIFT_MASK; temporarily removed because unused
|
|
bool alt = event->state & GDK_MOD1_MASK;
|
|
|
|
if (alt) {
|
|
switch (event->keyval) {
|
|
case GDK_KEY_u:
|
|
if (favoritePanelSW) {
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*favoritePanelSW));
|
|
}
|
|
return true;
|
|
|
|
case GDK_KEY_e:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*exposurePanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_d:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*detailsPanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_c:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*colorPanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_t:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*transformPanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_r:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*rawPanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_w:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*advancedPanelSW));
|
|
return true;
|
|
|
|
case GDK_KEY_m:
|
|
toolPanelNotebook->set_current_page (toolPanelNotebook->page_num (*metadata));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ToolPanelCoordinator::updateVScrollbars (bool hide)
|
|
{
|
|
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
|
|
Gtk::PolicyType policy = hide ? Gtk::POLICY_NEVER : Gtk::POLICY_AUTOMATIC;
|
|
if (favoritePanelSW) {
|
|
favoritePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
}
|
|
exposurePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
detailsPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
colorPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
transformPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
rawPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
advancedPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy);
|
|
|
|
for (auto currExp : expList) {
|
|
currExp->updateVScrollbars (hide);
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::updateTPVScrollbar (bool hide)
|
|
{
|
|
updateVScrollbars (hide);
|
|
}
|
|
|
|
void ToolPanelCoordinator::toolSelected (ToolMode tool)
|
|
{
|
|
GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected
|
|
|
|
auto checkFavorite = [this](FoldableToolPanel* tool) {
|
|
for (auto fav : favorites) {
|
|
if (fav == tool) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
switch (tool) {
|
|
case TMCropSelect: {
|
|
crop->setExpanded(true);
|
|
toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(checkFavorite(crop) ? *favoritePanelSW : *transformPanelSW));
|
|
break;
|
|
}
|
|
|
|
case TMSpotWB: {
|
|
whitebalance->setExpanded(true);
|
|
toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(checkFavorite(whitebalance) ? *favoritePanelSW : *colorPanelSW));
|
|
break;
|
|
}
|
|
|
|
case TMStraighten: {
|
|
rotate->setExpanded(true);
|
|
bool isFavorite = checkFavorite(rotate);
|
|
if (!isFavorite) {
|
|
isFavorite = checkFavorite(lensgeom);
|
|
lensgeom->setExpanded(true);
|
|
}
|
|
toolPanelNotebook->set_current_page(toolPanelNotebook->page_num(isFavorite ? *favoritePanelSW : *transformPanelSW));
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::editModeSwitchedOff ()
|
|
{
|
|
if (editDataProvider) {
|
|
editDataProvider->switchOffEditMode();
|
|
}
|
|
}
|
|
|
|
void ToolPanelCoordinator::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile)
|
|
{
|
|
|
|
flatfield->setShortcutPath (dirname);
|
|
}
|
|
|
|
void ToolPanelCoordinator::setEditProvider (EditDataProvider *provider)
|
|
{
|
|
editDataProvider = provider;
|
|
|
|
for (size_t i = 0; i < toolPanels.size(); i++) {
|
|
toolPanels.at (i)->setEditProvider (provider);
|
|
}
|
|
}
|