rawTherapee/rtgui/profilepanel.cc
2019-10-23 07:53:09 +02:00

879 lines
28 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 <https://www.gnu.org/licenses/>.
*/
#include "profilepanel.h"
#include "clipboard.h"
#include "multilangmgr.h"
#include "options.h"
#include "profilestorecombobox.h"
#include "rtimage.h"
#include "../rtengine/procparams.h"
using namespace rtengine;
using namespace rtengine::procparams;
PartialPasteDlg* ProfilePanel::partialProfileDlg = nullptr;
Gtk::Window* ProfilePanel::parent;
void ProfilePanel::init (Gtk::Window* parentWindow)
{
parent = parentWindow;
}
void ProfilePanel::cleanup ()
{
delete partialProfileDlg;
}
ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastSavedPSE(nullptr), customPSE(nullptr)
{
tpc = nullptr;
profileFillModeOnImage = new RTImage("profile-filled.png");
profileFillModeOffImage = new RTImage("profile-partial.png");
fillMode = Gtk::manage (new Gtk::ToggleButton());
fillMode->set_active(options.filledProfile);
fillMode->add( options.filledProfile ? *profileFillModeOnImage : *profileFillModeOffImage );
fillMode->signal_toggled().connect ( sigc::mem_fun(*this, &ProfilePanel::profileFillModeToggled) );
fillMode->set_tooltip_text(M("PROFILEPANEL_MODE_TIP"));
//GTK318
#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
fillMode->set_margin_right(2);
#endif
//GTK318
setExpandAlignProperties(fillMode, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
// Create the Combobox
profiles = Gtk::manage (new ProfileStoreComboBox ());
setExpandAlignProperties(profiles, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
load = Gtk::manage (new Gtk::Button ());
load->add (*Gtk::manage (new RTImage ("folder-open.png")));
load->get_style_context()->add_class("Left");
load->set_margin_left(2);
setExpandAlignProperties(load, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
save = Gtk::manage (new Gtk::Button ());
save->add (*Gtk::manage (new RTImage ("save.png")));
save->get_style_context()->add_class("MiddleH");
setExpandAlignProperties(save, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
copy = Gtk::manage (new Gtk::Button ());
copy->add (*Gtk::manage (new RTImage ("copy.png")));
copy->get_style_context()->add_class("MiddleH");
setExpandAlignProperties(copy, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
paste = Gtk::manage (new Gtk::Button ());
paste->add (*Gtk::manage (new RTImage ("paste.png")));
paste->get_style_context()->add_class("Right");
setExpandAlignProperties(paste, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
attach_next_to (*fillMode, Gtk::POS_RIGHT, 1, 1);
attach_next_to (*profiles, Gtk::POS_RIGHT, 1, 1);
attach_next_to (*load, Gtk::POS_RIGHT, 1, 1);
attach_next_to (*save, Gtk::POS_RIGHT, 1, 1);
attach_next_to (*copy, Gtk::POS_RIGHT, 1, 1);
attach_next_to (*paste, Gtk::POS_RIGHT, 1, 1);
setExpandAlignProperties(this, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER);
show ();
load->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::load_clicked) );
save->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::save_clicked) );
copy->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::copy_clicked) );
paste->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::paste_clicked) );
custom = nullptr;
lastsaved = nullptr;
dontupdate = false;
ProfileStore::getInstance()->addListener(this);
changeconn = profiles->signal_changed().connect( sigc::mem_fun(*this, &ProfilePanel::selection_changed) );
load->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPLOAD"));
save->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPSAVE"));
copy->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPCOPY"));
paste->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPPASTE"));
show_all_children ();
}
ProfilePanel::~ProfilePanel ()
{
ProfileStore::getInstance()->removeListener(this);
if (custom) {
custom->deleteInstance();
delete custom;
}
if (lastsaved) {
lastsaved->deleteInstance();
delete lastsaved;
}
delete profileFillModeOnImage;
delete profileFillModeOffImage;
delete lastSavedPSE;
delete customPSE;
}
bool ProfilePanel::isCustomSelected()
{
return profiles->getCurrentLabel() == Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")");
}
bool ProfilePanel::isLastSavedSelected()
{
return profiles->getCurrentLabel() == Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")");
}
Gtk::TreeIter ProfilePanel::getCustomRow()
{
Gtk::TreeIter row;
if (custom) {
row = profiles->getRowFromLabel(Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")"));
}
return row;
}
Gtk::TreeIter ProfilePanel::getLastSavedRow()
{
Gtk::TreeIter row;
if (lastsaved) {
row = profiles->getRowFromLabel(Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")"));
}
return row;
}
Gtk::TreeIter ProfilePanel::addCustomRow()
{
if(customPSE) {
profiles->deleteRow(customPSE);
delete customPSE;
customPSE = nullptr;
}
customPSE = new ProfileStoreEntry(Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")"), PSET_FILE, 0, 0);
Gtk::TreeIter newEntry = profiles->addRow(customPSE);
return newEntry;
}
Gtk::TreeIter ProfilePanel::addLastSavedRow()
{
if(lastSavedPSE) {
profiles->deleteRow(lastSavedPSE);
delete lastSavedPSE;
lastSavedPSE = nullptr;
}
lastSavedPSE = new ProfileStoreEntry(Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")"), PSET_FILE, 0, 0);
Gtk::TreeIter newEntry = profiles->addRow(lastSavedPSE);
return newEntry;
}
void ProfilePanel::storeCurrentValue ()
{
// TODO: Find a way to get and restore the current selection; the following line can't work anymore
storedValue = profiles->getFullPathFromActiveRow();
if (!isCustomSelected() && !isLastSavedSelected()) {
// storing the current entry's procparams, if not "Custom" or "LastSaved"
// for now, the storedPProfile has default internal values
const ProfileStoreEntry *entry = profiles->getSelectedEntry();
const PartialProfile *currProfile;
if (entry && (currProfile = ProfileStore::getInstance()->getProfile(entry)) != nullptr) {
// now storedPProfile has the current entry's values
storedPProfile = new PartialProfile(currProfile->pparams, currProfile->pedited, true);
} else {
storedPProfile = new PartialProfile(true);
}
}
}
/* Get the ProfileStore's entry list and recreate the combobox entries
* If you want want to update the ProfileStore list itself (rescan the dir tree), use its "parseProfiles" method instead
*/
void ProfilePanel::updateProfileList ()
{
bool ccPrevState = changeconn.block(true);
// rescan file tree
profiles->updateProfileList();
if (custom) {
addCustomRow();
}
if (lastsaved) {
addLastSavedRow();
}
changeconn.block (ccPrevState);
}
void ProfilePanel::restoreValue ()
{
bool ccPrevState = changeconn.block(true);
if (!profiles->setActiveRowFromFullPath(storedValue) && storedPProfile) {
if (custom) {
delete custom;
}
custom = new PartialProfile (storedPProfile->pparams, storedPProfile->pedited, true);
Gtk::TreeIter custRow = getCustomRow();
if (custRow) {
profiles->set_active(custRow);
} else {
profiles->set_active (addCustomRow());
}
}
currRow = profiles->get_active();
changeconn.block (ccPrevState);
storedValue = "";
if (storedPProfile) {
storedPProfile->deleteInstance();
delete storedPProfile;
storedPProfile = nullptr;
}
}
void ProfilePanel::save_clicked (GdkEventButton* event)
{
if (event->button != 1) {
return;
}
// If it's a partial profile, it's more intuitive to first allow the user
// to choose which parameters to save before showing the Save As dialog
// #5491
const auto isPartial = event->state & Gdk::CONTROL_MASK;
if (isPartial) {
if (!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg(Glib::ustring(), parent);
}
partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE"));
const auto response = partialProfileDlg->run();
partialProfileDlg->hide();
if (response != Gtk::RESPONSE_OK) {
return;
}
}
Gtk::FileChooserDialog dialog(getToplevelWindow(this), M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE);
bindCurrentFolder(dialog, options.loadSaveProfilePath);
dialog.set_current_name(lastFilename);
//Add the user's default (or global if multiuser=false) profile path to the Shortcut list
try {
dialog.add_shortcut_folder(options.getPreferredProfilePath());
} catch (Glib::Error&) {}
//Add the image's path to the Shortcut list
try {
dialog.add_shortcut_folder(imagePath);
} catch (Glib::Error&) {}
//Add response buttons to the dialog:
dialog.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL);
dialog.add_button(M("GENERAL_SAVE"), Gtk::RESPONSE_OK);
//Add filters, so that only certain file types can be selected:
auto filter_pp = Gtk::FileFilter::create();
filter_pp->set_name(M("FILECHOOSER_FILTER_PP"));
filter_pp->add_pattern("*" + paramFileExtension);
dialog.add_filter(filter_pp);
auto filter_any = Gtk::FileFilter::create();
filter_any->set_name(M("FILECHOOSER_FILTER_ANY"));
filter_any->add_pattern("*");
dialog.add_filter(filter_any);
bool done = true;
do {
if (dialog.run() == Gtk::RESPONSE_OK) {
std::string fname = dialog.get_filename();
if (("." + getExtension(fname)) != paramFileExtension) {
fname += paramFileExtension;
}
if (!confirmOverwrite(dialog, fname)) {
continue;
}
lastFilename = Glib::path_get_basename(fname);
const PartialProfile* toSave;
if (isCustomSelected()) {
toSave = custom;
} else if (isLastSavedSelected()) {
toSave = lastsaved;
} else {
const auto entry = profiles->getSelectedEntry();
toSave = entry ? ProfileStore::getInstance()->getProfile(entry) : nullptr;
}
if (toSave) {
int retCode;
if (isPartial) {
// Build partial profile
PartialProfile ppTemp(true);
partialProfileDlg->applyPaste(ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited);
// Save partial profile
retCode = ppTemp.pparams->save(fname, "", true, ppTemp.pedited);
// Cleanup
ppTemp.deleteInstance();
} else {
// Save full profile
retCode = toSave->pparams->save(fname);
}
if (!retCode) {
const auto ccPrevState = changeconn.block(true);
ProfileStore::getInstance()->parseProfiles();
changeconn.block(ccPrevState);
} else {
done = false;
writeFailed(dialog, fname);
}
}
}
} while (!done);
}
/*
* Copy the actual full profile to the clipboard
*/
void ProfilePanel::copy_clicked (GdkEventButton* event)
{
if (event->button != 1) {
return;
}
const PartialProfile* toSave;
if (isCustomSelected()) {
toSave = custom;
} else if (isLastSavedSelected()) {
toSave = lastsaved;
} else {
const ProfileStoreEntry* entry = profiles->getSelectedEntry();
toSave = entry ? ProfileStore::getInstance()->getProfile (entry) : nullptr;
}
// toSave has to be a complete procparams
if (toSave) {
if (event->state & Gdk::CONTROL_MASK) {
// opening the partial paste dialog window
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->set_title(M("PROFILEPANEL_COPYPPASTE"));
int i = partialProfileDlg->run();
partialProfileDlg->hide();
if (i != Gtk::RESPONSE_OK) {
return;
}
// saving a partial profile
PartialProfile ppTemp(true);
partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited);
clipboard.setPartialProfile(ppTemp);
ppTemp.deleteInstance();
} else {
clipboard.setProcParams (*toSave->pparams);
}
}
return;
}
/*
* Load a potentially partial profile
*/
void ProfilePanel::load_clicked (GdkEventButton* event)
{
if (event->button != 1) {
return;
}
Gtk::FileChooserDialog dialog (getToplevelWindow (this), M("PROFILEPANEL_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN);
bindCurrentFolder (dialog, options.loadSaveProfilePath);
//Add the user's default (or global if multiuser=false) profile path to the Shortcut list
try {
dialog.add_shortcut_folder(options.getPreferredProfilePath());
} catch (Glib::Error&) {}
//Add the image's path to the Shortcut list
try {
dialog.add_shortcut_folder(imagePath);
} catch (Glib::Error&) {}
//Add response buttons to the dialog:
dialog.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL);
dialog.add_button(M("GENERAL_OPEN"), Gtk::RESPONSE_OK);
//Add filters, so that only certain file types can be selected:
Glib::RefPtr<Gtk::FileFilter> filter_pp = Gtk::FileFilter::create();
filter_pp->set_name(M("FILECHOOSER_FILTER_PP"));
filter_pp->add_pattern("*" + paramFileExtension);
dialog.add_filter(filter_pp);
Glib::RefPtr<Gtk::FileFilter> filter_any = Gtk::FileFilter::create();
filter_any->set_name(M("FILECHOOSER_FILTER_ANY"));
filter_any->add_pattern("*");
dialog.add_filter(filter_any);
int result = dialog.run();
dialog.hide();
if (result == Gtk::RESPONSE_OK) {
Glib::ustring fname = dialog.get_filename();
printf("fname=%s\n", fname.c_str());
if (event->state & Gdk::CONTROL_MASK) {
// opening the partial paste dialog window
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->set_title(M("PROFILEPANEL_LOADPPASTE"));
int i = partialProfileDlg->run();
partialProfileDlg->hide();
if (i != Gtk::RESPONSE_OK) {
return;
}
}
bool customCreated = false;
if (!custom) {
custom = new PartialProfile (true);
customCreated = true;
}
ProcParams pp;
ParamsEdited pe;
int err = pp.load (fname, &pe);
if (!err) {
if (!customCreated && fillMode->get_active()) {
custom->pparams->setDefaults();
// Clearing all LocallabSpotEdited to be compliant with default pparams
custom->pedited->locallab.spots.clear();
}
custom->set(true);
bool prevState = changeconn.block(true);
Gtk::TreeIter newEntry = addCustomRow();
profiles->set_active (newEntry);
currRow = profiles->get_active();
changeconn.block(prevState);
// Now we have procparams initialized to default if fillMode is on
// and paramsedited initialized to default in all cases
if (event->state & Gdk::CONTROL_MASK)
// custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited & partialPaste.pedited )
{
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe);
} else {
// custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited )
pe.combine(*custom->pparams, pp, true);
if (!fillMode->get_active()) {
*custom->pedited = pe;
}
}
changeTo (custom, M("PROFILEPANEL_PFILE"));
} else if (customCreated) {
// we delete custom
custom->deleteInstance();
delete custom;
custom = nullptr;
}
}
return;
}
/*
* Paste a full profile from the clipboard
*/
void ProfilePanel::paste_clicked (GdkEventButton* event)
{
if (event->button != 1) {
return;
}
if (!clipboard.hasProcParams()) {
return;
}
if (event->state & Gdk::CONTROL_MASK) {
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->set_title(M("PROFILEPANEL_PASTEPPASTE"));
int i = partialProfileDlg->run();
partialProfileDlg->hide();
if (i != Gtk::RESPONSE_OK) {
return;
}
}
bool prevState = changeconn.block(true);
if (!custom) {
custom = new PartialProfile (true); // custom pedited is initialized to false
if (isLastSavedSelected()) {
*custom->pparams = *lastsaved->pparams;
// Setting LocallabSpotEdited number coherent with nbspot number in lastsaved->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(false));
} else {
const ProfileStoreEntry* entry = profiles->getSelectedEntry();
if (entry) {
const PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (entry);
*custom->pparams = *partProfile->pparams;
// Setting LocallabSpotEdited number coherent with nbspot number in partProfile->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(false));
}
}
profiles->set_active (addCustomRow());
currRow = profiles->get_active();
} else {
if (fillMode->get_active()) {
custom->pparams->setDefaults();
// Clear all LocallabSpotEdited to be compliant with default pparams
custom->pedited->locallab.spots.clear();
} else if (!isCustomSelected ()) {
if (isLastSavedSelected()) {
*custom->pparams = *lastsaved->pparams;
// Setting LocallabSpotEdited number coherent with nbspot number in lastsaved->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
} else {
const ProfileStoreEntry* entry = profiles->getSelectedEntry();
if (entry) {
const PartialProfile* partProfile = ProfileStore::getInstance()->getProfile (entry);
*custom->pparams = *partProfile->pparams;
// Setting LocallabSpotEdited number coherent with nbspot number in partProfile->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
}
}
}
profiles->set_active(getCustomRow());
currRow = profiles->get_active();
}
custom->pedited->set(true);
changeconn.block(prevState);
// Now we have procparams initialized to default if fillMode is on
// and paramsedited initialized to default in all cases
ProcParams pp = clipboard.getProcParams ();
if (clipboard.hasPEdited()) {
ParamsEdited pe = clipboard.getParamsEdited();
if (event->state & Gdk::CONTROL_MASK)
// custom.pparams = clipboard.pparams filtered by ( clipboard.pedited & partialPaste.pedited )
{
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active() ? custom->pedited : nullptr, &pp, &pe);
} else {
// custom.pparams = clipboard.pparams filtered by ( clipboard.pedited )
pe.combine(*custom->pparams, pp, true);
if (!fillMode->get_active()) {
*custom->pedited = pe;
}
}
} else {
if (event->state & Gdk::CONTROL_MASK)
// custom.pparams = clipboard.pparams filtered by ( partialPaste.pedited )
{
if(!partialProfileDlg) {
partialProfileDlg = new PartialPasteDlg (Glib::ustring (), parent);
}
partialProfileDlg->applyPaste (custom->pparams, nullptr, &pp, nullptr);
// Setting LocallabSpotEdited number coherent with nbspot number in custom->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
} else {
// custom.pparams = clipboard.pparams non filtered
*custom->pparams = pp;
// Setting LocallabSpotEdited number coherent with nbspot number in custom->pparams
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(custom->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
}
}
changeTo (custom, M("HISTORY_FROMCLIPBOARD"));
return;
}
void ProfilePanel::changeTo (const PartialProfile* newpp, Glib::ustring profname)
{
if (!newpp) {
return;
}
if (tpc) {
tpc->profileChange (newpp, EvProfileChanged, profname);
}
}
void ProfilePanel::selection_changed ()
{
if (isCustomSelected()) {
if (!dontupdate) {
changeTo (custom, Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")"));
}
} else if (isLastSavedSelected()) {
changeTo (lastsaved, Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")"));
} else {
const ProfileStoreEntry *pse = profiles->getSelectedEntry();
if (pse->type == PSET_FOLDER) {
// this entry is invalid, restoring the old value
bool ccPrevState = changeconn.block(true);
profiles->set_active(currRow);
changeconn.block(ccPrevState);
dontupdate = false;
return;
} else {
currRow = profiles->get_active();
}
const PartialProfile* s = ProfileStore::getInstance()->getProfile (pse);
if (s) {
if (fillMode->get_active() && s->pedited) {
ParamsEdited pe(true);
// Setting LocallabSpotEdited number coherent with nbspot number in s->pparams
pe.locallab.spots.resize(s->pparams->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
PartialProfile s2(s->pparams, &pe, false);
changeTo (&s2, pse->label + "+");
} else {
changeTo (s, pse->label);
}
}
}
dontupdate = false;
}
void ProfilePanel::procParamsChanged(
const rtengine::procparams::ProcParams* p,
const rtengine::ProcEvent& ev,
const Glib::ustring& descr,
const ParamsEdited* paramsEdited
)
{
// to prevent recursion, filter out the events caused by the profilepanel
if (ev == EvProfileChanged || ev == EvPhotoLoaded) {
return;
}
if (!isCustomSelected()) {
dontupdate = true;
if (!custom) {
custom = new PartialProfile (true);
custom->set(true);
profiles->set_active (addCustomRow());
currRow = profiles->get_active();
} else {
profiles->set_active(getCustomRow());
currRow = profiles->get_active();
}
}
*custom->pparams = *p;
// Setting LocallabSpotEdited number coherent with nbspot number in p
custom->pedited->locallab.spots.clear();
custom->pedited->locallab.spots.resize(p->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
}
void ProfilePanel::clearParamChanges()
{
}
/** @brief Initialize the Profile panel with a default profile, overridden by the last saved profile if provided
*
* The file tree has already been created on object's construction. We add here the Custom, LastSaved and/or Internal item.
*
* @param profileFullPath full path of the profile; must start by the virtual root (${G} or ${U}, and without suffix
* @param lastSaved pointer to the last saved ProcParam; may be NULL
*/
void ProfilePanel::initProfile (const Glib::ustring& profileFullPath, ProcParams* lastSaved)
{
const ProfileStoreEntry *pse = nullptr;
const PartialProfile *defprofile = nullptr;
bool ccPrevState = changeconn.block(true);
if (custom) {
custom->deleteInstance();
delete custom;
custom = nullptr;
}
if (lastsaved) {
lastsaved->deleteInstance();
delete lastsaved;
lastsaved = nullptr;
}
if (lastSaved) {
ParamsEdited* pe = new ParamsEdited(true);
// Setting LocallabSpotEdited number coherent with lastSaved->locallab.nbspot (initialized at true such as pe)
pe->locallab.spots.resize(lastSaved->locallab.nbspot, new LocallabParamsEdited::LocallabSpotEdited(true));
// copying the provided last saved profile to ProfilePanel::lastsaved
lastsaved = new PartialProfile(lastSaved, pe);
}
// update the content of the combobox; will add 'custom' and 'lastSaved' if necessary
updateProfileList();
Gtk::TreeIter lasSavedEntry;
// adding the Last Saved combobox entry, if needed
if (lastsaved) {
lasSavedEntry = getLastSavedRow();
}
if (!(pse = ProfileStore::getInstance()->findEntryFromFullPath(profileFullPath))) {
// entry not found, pse = the Internal ProfileStoreEntry
pse = ProfileStore::getInstance()->getInternalDefaultPSE();
}
defprofile = ProfileStore::getInstance()->getProfile (pse);
// selecting the "Internal" entry
profiles->setInternalEntry ();
currRow = profiles->get_active();
if (lastsaved) {
if (lasSavedEntry) {
profiles->set_active (lasSavedEntry);
}
currRow = profiles->get_active();
if (tpc) {
tpc->setDefaults (lastsaved->pparams);
tpc->profileChange (lastsaved, EvPhotoLoaded, profiles->getSelectedEntry()->label, nullptr, true);
}
} else {
if (pse) {
profiles->setActiveRowFromEntry(pse);
currRow = profiles->get_active();
}
if (tpc) {
tpc->setDefaults (defprofile->pparams);
tpc->profileChange (defprofile, EvPhotoLoaded, profiles->getSelectedEntry()->label);
}
}
changeconn.block (ccPrevState);
}
void ProfilePanel::setInitialFileName (const Glib::ustring& filename)
{
lastFilename = Glib::path_get_basename(filename) + paramFileExtension;
imagePath = Glib::path_get_dirname(filename);
}
void ProfilePanel::profileFillModeToggled()
{
if (fillMode->get_active()) {
// The button is pressed, we'll use the profileFillModeOnImage
fillMode->set_image(*profileFillModeOnImage);
} else {
// The button is released, we'll use the profileFillModeOffImage
fillMode->set_image(*profileFillModeOffImage);
}
}
void ProfilePanel::writeOptions()
{
options.filledProfile = fillMode->get_active();
}