Change GUI to support multiple external editors
Replace radio selector in external editor section of preferences with external editor preferences widget. Replace send-to-GIMP button with pop-up button for exporting to a selectable application.
This commit is contained in:
@@ -666,12 +666,15 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
||||
queueimg->set_tooltip_markup (M ("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP"));
|
||||
setExpandAlignProperties (queueimg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
|
||||
|
||||
Gtk::Image *sendToEditorButtonImage = Gtk::manage (new RTImage ("palette-brush.png"));
|
||||
sendtogimp = Gtk::manage (new Gtk::Button ());
|
||||
sendtogimp->set_relief(Gtk::RELIEF_NONE);
|
||||
sendtogimp->add (*sendToEditorButtonImage);
|
||||
sendtogimp->set_tooltip_markup (M ("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP"));
|
||||
setExpandAlignProperties (sendtogimp, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
|
||||
send_to_external = Gtk::make_managed<PopUpButton>("", false);
|
||||
send_to_external->set_tooltip_text(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP"));
|
||||
setExpandAlignProperties(send_to_external->buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL);
|
||||
send_to_external->addEntry("palette-brush.png", M("GENERAL_OTHER"));
|
||||
updateExternalEditorWidget(
|
||||
options.externalEditorIndex >= 0 ? options.externalEditorIndex : options.externalEditors.size(),
|
||||
options.externalEditors
|
||||
);
|
||||
send_to_external->show();
|
||||
|
||||
// Status box
|
||||
progressLabel = Gtk::manage (new MyProgressBar (300));
|
||||
@@ -736,7 +739,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
||||
iops->attach_next_to (*vsep1, Gtk::POS_LEFT, 1, 1);
|
||||
|
||||
if (!gimpPlugin) {
|
||||
iops->attach_next_to (*sendtogimp, Gtk::POS_LEFT, 1, 1);
|
||||
iops->attach_next_to(*send_to_external->buttonGroup, Gtk::POS_LEFT, 1, 1);
|
||||
}
|
||||
|
||||
if (!gimpPlugin && !simpleEditor) {
|
||||
@@ -840,7 +843,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
|
||||
tbRightPanel_1->signal_toggled().connect ( sigc::mem_fun (*this, &EditorPanel::tbRightPanel_1_toggled) );
|
||||
saveimgas->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::saveAsPressed) );
|
||||
queueimg->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::queueImgPressed) );
|
||||
sendtogimp->signal_pressed().connect ( sigc::mem_fun (*this, &EditorPanel::sendToGimpPressed) );
|
||||
send_to_external->signal_changed().connect(sigc::mem_fun(*this, &EditorPanel::sendToExternalChanged));
|
||||
send_to_external->signal_pressed().connect(sigc::mem_fun(*this, &EditorPanel::sendToExternalPressed));
|
||||
toggleHistogramProfile->signal_toggled().connect( sigc::mem_fun (*this, &EditorPanel::histogramProfile_toggled) );
|
||||
|
||||
if (navPrev) {
|
||||
@@ -1673,7 +1677,7 @@ bool EditorPanel::handleShortcutKey (GdkEventKey* event)
|
||||
|
||||
case GDK_KEY_e:
|
||||
if (!gimpPlugin) {
|
||||
sendToGimpPressed();
|
||||
sendToExternalPressed();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1791,7 +1795,7 @@ bool EditorPanel::idle_saveImage (ProgressConnector<rtengine::IImagefloat*> *pc,
|
||||
msgd.run ();
|
||||
|
||||
saveimgas->set_sensitive (true);
|
||||
sendtogimp->set_sensitive (true);
|
||||
send_to_external->set_sensitive(true);
|
||||
isProcessing = false;
|
||||
|
||||
}
|
||||
@@ -1819,7 +1823,7 @@ bool EditorPanel::idle_imageSaved (ProgressConnector<int> *pc, rtengine::IImagef
|
||||
}
|
||||
|
||||
saveimgas->set_sensitive (true);
|
||||
sendtogimp->set_sensitive (true);
|
||||
send_to_external->set_sensitive(true);
|
||||
|
||||
parent->setProgressStr ("");
|
||||
parent->setProgress (0.);
|
||||
@@ -1930,7 +1934,7 @@ void EditorPanel::saveAsPressed ()
|
||||
ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ),
|
||||
sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_saveImage ), ld, fnameOut, sf, pparams));
|
||||
saveimgas->set_sensitive (false);
|
||||
sendtogimp->set_sensitive (false);
|
||||
send_to_external->set_sensitive(false);
|
||||
}
|
||||
} else {
|
||||
BatchQueueEntry* bqe = createBatchQueueEntry ();
|
||||
@@ -1961,7 +1965,7 @@ void EditorPanel::queueImgPressed ()
|
||||
parent->addBatchQueueJob (createBatchQueueEntry ());
|
||||
}
|
||||
|
||||
void EditorPanel::sendToGimpPressed ()
|
||||
void EditorPanel::sendToExternal()
|
||||
{
|
||||
if (!ipc || !openThm) {
|
||||
return;
|
||||
@@ -1975,7 +1979,29 @@ void EditorPanel::sendToGimpPressed ()
|
||||
ld->startFunc (sigc::bind (sigc::ptr_fun (&rtengine::processImage), job, err, parent->getProgressListener(), false ),
|
||||
sigc::bind (sigc::mem_fun ( *this, &EditorPanel::idle_sendToGimp ), ld, openThm->getFileName() ));
|
||||
saveimgas->set_sensitive (false);
|
||||
sendtogimp->set_sensitive (false);
|
||||
send_to_external->set_sensitive(false);
|
||||
}
|
||||
|
||||
void EditorPanel::sendToExternalChanged(int)
|
||||
{
|
||||
int index = send_to_external->getSelected();
|
||||
if (index >= 0 && static_cast<unsigned>(index) == options.externalEditors.size()) {
|
||||
index = -1;
|
||||
}
|
||||
options.externalEditorIndex = index;
|
||||
}
|
||||
|
||||
void EditorPanel::sendToExternalPressed()
|
||||
{
|
||||
if (options.externalEditorIndex == -1) {
|
||||
// "Other" external editor. Show app chooser dialog to let user pick.
|
||||
Gtk::AppChooserDialog *dialog = getAppChooserDialog();
|
||||
dialog->show();
|
||||
} else {
|
||||
struct ExternalEditor editor = options.externalEditors.at(options.externalEditorIndex);
|
||||
external_editor_info = Gio::AppInfo::create_from_commandline(editor.command, editor.name, Gio::APP_INFO_CREATE_NONE);
|
||||
sendToExternal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2078,7 +2104,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector<rtengine::IImagefloat*> *p
|
||||
Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
||||
msgd.run ();
|
||||
saveimgas->set_sensitive (true);
|
||||
sendtogimp->set_sensitive (true);
|
||||
send_to_external->set_sensitive(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2093,18 +2119,12 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImagef
|
||||
|
||||
if (!errore) {
|
||||
saveimgas->set_sensitive (true);
|
||||
sendtogimp->set_sensitive (true);
|
||||
send_to_external->set_sensitive(true);
|
||||
parent->setProgressStr ("");
|
||||
parent->setProgress (0.);
|
||||
bool success = false;
|
||||
|
||||
if (options.editorToSendTo == 1) {
|
||||
success = ExtProgStore::openInGimp (filename);
|
||||
} else if (options.editorToSendTo == 2) {
|
||||
success = ExtProgStore::openInPhotoshop (filename);
|
||||
} else if (options.editorToSendTo == 3) {
|
||||
success = ExtProgStore::openInCustomEditor (filename);
|
||||
}
|
||||
success = ExtProgStore::openInExternalEditor(filename, external_editor_info);
|
||||
|
||||
if (!success) {
|
||||
Gtk::MessageDialog msgd (*parent, M ("MAIN_MSG_CANNOTSTARTEDITOR"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
||||
@@ -2117,6 +2137,36 @@ bool EditorPanel::idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImagef
|
||||
return false;
|
||||
}
|
||||
|
||||
Gtk::AppChooserDialog *EditorPanel::getAppChooserDialog()
|
||||
{
|
||||
if (!app_chooser_dialog.get()) {
|
||||
app_chooser_dialog.reset(new Gtk::AppChooserDialog("image/tiff"));
|
||||
app_chooser_dialog->signal_response().connect(
|
||||
sigc::mem_fun(*this, &EditorPanel::onAppChooserDialogResponse)
|
||||
);
|
||||
app_chooser_dialog->set_modal();
|
||||
}
|
||||
|
||||
return app_chooser_dialog.get();
|
||||
}
|
||||
|
||||
void EditorPanel::onAppChooserDialogResponse(int responseId)
|
||||
{
|
||||
switch (responseId) {
|
||||
case Gtk::RESPONSE_OK:
|
||||
getAppChooserDialog()->close();
|
||||
external_editor_info = getAppChooserDialog()->get_app_info();
|
||||
sendToExternal();
|
||||
break;
|
||||
case Gtk::RESPONSE_CANCEL:
|
||||
case Gtk::RESPONSE_CLOSE:
|
||||
getAppChooserDialog()->close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params)
|
||||
{
|
||||
|
||||
@@ -2392,6 +2442,26 @@ void EditorPanel::tbShowHideSidePanels_managestate()
|
||||
ShowHideSidePanelsconn.block (false);
|
||||
}
|
||||
|
||||
void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vector<ExternalEditor> &editors)
|
||||
{
|
||||
// Remove the editors and leave the "Other" entry.
|
||||
while (send_to_external->getEntryCount() > 1) {
|
||||
send_to_external->removeEntry(0);
|
||||
}
|
||||
// Add the editors.
|
||||
for (unsigned i = 0; i < editors.size(); i++) {
|
||||
const auto & name = editors[i].name.empty() ? Glib::ustring(" ") : editors[i].name;
|
||||
if (!editors[i].icon_name.empty()) {
|
||||
Glib::RefPtr<Gio::Icon> gioIcon = Gio::Icon::create(editors[i].icon_name);
|
||||
send_to_external->insertEntry(i, gioIcon, name);
|
||||
} else {
|
||||
send_to_external->insertEntry(i, "palette-brush.png", name);
|
||||
}
|
||||
}
|
||||
send_to_external->setSelected(selectedIndex);
|
||||
send_to_external->show();
|
||||
}
|
||||
|
||||
void EditorPanel::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class EditorPanel;
|
||||
class FilePanel;
|
||||
class MyProgressBar;
|
||||
class Navigator;
|
||||
class PopUpButton;
|
||||
class Thumbnail;
|
||||
class ToolPanelCoordinator;
|
||||
|
||||
@@ -162,7 +163,9 @@ public:
|
||||
void tbBeforeLock_toggled();
|
||||
void saveAsPressed ();
|
||||
void queueImgPressed ();
|
||||
void sendToGimpPressed ();
|
||||
void sendToExternal();
|
||||
void sendToExternalChanged(int);
|
||||
void sendToExternalPressed();
|
||||
void openNextEditorImage ();
|
||||
void openPreviousEditorImage ();
|
||||
void syncFileBrowser ();
|
||||
@@ -182,6 +185,7 @@ public:
|
||||
{
|
||||
return isProcessing;
|
||||
}
|
||||
void updateExternalEditorWidget(int selectedIndex, const std::vector<ExternalEditor> &editors);
|
||||
void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC);
|
||||
void updateTPVScrollbar (bool hide);
|
||||
void updateHistogramPosition (int oldPosition, int newPosition);
|
||||
@@ -201,6 +205,8 @@ private:
|
||||
bool idle_sendToGimp ( ProgressConnector<rtengine::IImagefloat*> *pc, Glib::ustring fname);
|
||||
bool idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImagefloat* img, Glib::ustring filename);
|
||||
void histogramProfile_toggled ();
|
||||
Gtk::AppChooserDialog *getAppChooserDialog();
|
||||
void onAppChooserDialogResponse(int resposneId);
|
||||
|
||||
|
||||
Glib::ustring lastSaveAsFileName;
|
||||
@@ -230,10 +236,12 @@ private:
|
||||
|
||||
Gtk::Button* queueimg;
|
||||
Gtk::Button* saveimgas;
|
||||
Gtk::Button* sendtogimp;
|
||||
PopUpButton* send_to_external;
|
||||
Gtk::Button* navSync;
|
||||
Gtk::Button* navNext;
|
||||
Gtk::Button* navPrev;
|
||||
Glib::RefPtr<Gio::AppInfo> external_editor_info;
|
||||
std::unique_ptr<Gtk::AppChooserDialog> app_chooser_dialog;
|
||||
|
||||
class ColorManagementToolbar;
|
||||
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
|
||||
|
||||
@@ -251,7 +251,7 @@ void PopUpCommon::setButtonHint()
|
||||
auto item = dynamic_cast<MyImageMenuItem*>(widget);
|
||||
|
||||
if (item) {
|
||||
hint += item->getLabel ()->get_text ();
|
||||
hint += escapeHtmlChars(item->getLabel()->get_text());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <sigc++/slot.h>
|
||||
#include "externaleditorpreferences.h"
|
||||
#include "preferences.h"
|
||||
#include "multilangmgr.h"
|
||||
#include "splash.h"
|
||||
@@ -33,6 +34,8 @@
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
//#define EXT_EDITORS_RADIOS // TODO: Remove the corresponding code after testing.
|
||||
|
||||
namespace {
|
||||
void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::string &labelText, int digits, int inc0, int inc1, int maxLength, int range0, int range1, const std::string &toolTip = "") {
|
||||
Gtk::Box* HB = Gtk::manage ( new Gtk::Box () );
|
||||
@@ -1188,6 +1191,7 @@ Gtk::Widget* Preferences::getGeneralPanel()
|
||||
|
||||
Gtk::Frame* fdg = Gtk::manage(new Gtk::Frame(M("PREFERENCES_EXTERNALEDITOR")));
|
||||
setExpandAlignProperties(fdg, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
|
||||
#ifdef EXT_EDITORS_RADIOS
|
||||
Gtk::Grid* externaleditorGrid = Gtk::manage(new Gtk::Grid());
|
||||
externaleditorGrid->set_column_spacing(4);
|
||||
externaleditorGrid->set_row_spacing(4);
|
||||
@@ -1243,8 +1247,17 @@ Gtk::Widget* Preferences::getGeneralPanel()
|
||||
externaleditorGrid->attach_next_to(*edOther, *edGimp, Gtk::POS_BOTTOM, 1, 1);
|
||||
externaleditorGrid->attach_next_to(*editorToSendTo, *edOther, Gtk::POS_RIGHT, 1, 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
externalEditors = Gtk::make_managed<ExternalEditorPreferences>();
|
||||
externalEditors->set_size_request(-1, 200);
|
||||
#ifdef EXT_EDITORS_RADIOS
|
||||
externaleditorGrid->attach_next_to(*externalEditors, *edOther, Gtk::POS_BOTTOM, 2, 1);
|
||||
|
||||
fdg->add(*externaleditorGrid);
|
||||
#else
|
||||
fdg->add(*externalEditors);
|
||||
#endif
|
||||
vbGeneral->attach_next_to (*fdg, *fclip, Gtk::POS_BOTTOM, 2, 1);
|
||||
langAutoDetectConn = ckbLangAutoDetect->signal_toggled().connect(sigc::mem_fun(*this, &Preferences::langAutoDetectToggled));
|
||||
tconn = themeCBT->signal_changed().connect ( sigc::mem_fun (*this, &Preferences::themeChanged) );
|
||||
@@ -1700,6 +1713,7 @@ void Preferences::storePreferences()
|
||||
|
||||
moptions.pseudoHiDPISupport = pseudoHiDPI->get_active();
|
||||
|
||||
#ifdef EXT_EDITORS_RADIOS
|
||||
#ifdef WIN32
|
||||
moptions.gimpDir = gimpDir->get_filename();
|
||||
moptions.psDir = psDir->get_filename();
|
||||
@@ -1726,6 +1740,20 @@ void Preferences::storePreferences()
|
||||
else if (edOther->get_active()) {
|
||||
moptions.editorToSendTo = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::vector<ExternalEditorPreferences::EditorInfo> &editors = externalEditors->getEditors();
|
||||
moptions.externalEditors.resize(editors.size());
|
||||
moptions.externalEditorIndex = -1;
|
||||
for (unsigned i = 0; i < editors.size(); i++) {
|
||||
moptions.externalEditors[i] = (ExternalEditor(
|
||||
editors[i].name, editors[i].command, editors[i].icon_name));
|
||||
if (editors[i].other_data) {
|
||||
// The current editor was marked before the list was edited. We
|
||||
// found the mark, so this is the editor that was active.
|
||||
moptions.externalEditorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
moptions.CPBPath = txtCustProfBuilderPath->get_text();
|
||||
moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number());
|
||||
@@ -1981,6 +2009,7 @@ void Preferences::fillPreferences()
|
||||
hlThresh->set_value(moptions.highlightThreshold);
|
||||
shThresh->set_value(moptions.shadowThreshold);
|
||||
|
||||
#ifdef EXT_EDITORS_RADIOS
|
||||
edGimp->set_active(moptions.editorToSendTo == 1);
|
||||
edOther->set_active(moptions.editorToSendTo == 3);
|
||||
#ifdef WIN32
|
||||
@@ -2009,6 +2038,18 @@ void Preferences::fillPreferences()
|
||||
|
||||
#endif
|
||||
editorToSendTo->set_text(moptions.customEditorProg);
|
||||
#endif
|
||||
|
||||
std::vector<ExternalEditorPreferences::EditorInfo> editorInfos;
|
||||
for (const auto &editor : moptions.externalEditors) {
|
||||
editorInfos.push_back(ExternalEditorPreferences::EditorInfo(
|
||||
editor.name, editor.command, editor.icon_name));
|
||||
}
|
||||
if (moptions.externalEditorIndex >= 0) {
|
||||
// Mark the current editor so we can track it.
|
||||
editorInfos[moptions.externalEditorIndex].other_data = (void *)1;
|
||||
}
|
||||
externalEditors->setEditors(editorInfos);
|
||||
|
||||
txtCustProfBuilderPath->set_text(moptions.CPBPath);
|
||||
custProfBuilderLabelType->set_active(moptions.CPBKeys);
|
||||
@@ -2474,6 +2515,23 @@ void Preferences::workflowUpdate()
|
||||
parent->updateProfiles (moptions.rtSettings.printerProfile, rtengine::RenderingIntent(moptions.rtSettings.printerIntent), moptions.rtSettings.printerBPC);
|
||||
}
|
||||
|
||||
bool changed = moptions.externalEditorIndex != options.externalEditorIndex
|
||||
|| moptions.externalEditors.size() != options.externalEditors.size();
|
||||
if (!changed) {
|
||||
auto &editors = options.externalEditors;
|
||||
auto &meditors = moptions.externalEditors;
|
||||
for (unsigned i = 0; i < editors.size(); i++) {
|
||||
if (editors[i] != meditors[i]) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
// Update the send to external editor widget.
|
||||
parent->updateExternalEditorWidget(moptions.externalEditorIndex, moptions.externalEditors);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Preferences::addExtPressed()
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "options.h"
|
||||
#include "../rtengine/profilestore.h"
|
||||
|
||||
class ExternalEditorPreferences;
|
||||
class RTWindow;
|
||||
class Splash;
|
||||
|
||||
@@ -101,6 +102,7 @@ class Preferences final :
|
||||
Gtk::RadioButton* edGimp;
|
||||
Gtk::RadioButton* edPS;
|
||||
Gtk::RadioButton* edOther;
|
||||
ExternalEditorPreferences *externalEditors;
|
||||
MyFileChooserButton* darkFrameDir;
|
||||
MyFileChooserButton* flatFieldDir;
|
||||
MyFileChooserButton* clutsDir;
|
||||
|
||||
@@ -1030,6 +1030,13 @@ void RTWindow::MoveFileBrowserToEditor()
|
||||
}
|
||||
}
|
||||
|
||||
void RTWindow::updateExternalEditorWidget(int selectedIndex, const std::vector<ExternalEditor> & editors)
|
||||
{
|
||||
if (epanel) {
|
||||
epanel->updateExternalEditorWidget(selectedIndex, editors);
|
||||
}
|
||||
}
|
||||
|
||||
void RTWindow::updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC)
|
||||
{
|
||||
if (epanel) {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
class BatchQueueEntry;
|
||||
class BatchQueuePanel;
|
||||
class EditorPanel;
|
||||
class ExternalEditor;
|
||||
class FilePanel;
|
||||
class PLDBridge;
|
||||
class RTWindow final :
|
||||
@@ -114,6 +115,7 @@ public:
|
||||
void MoveFileBrowserToEditor();
|
||||
void MoveFileBrowserToMain();
|
||||
|
||||
void updateExternalEditorWidget(int selectedIndex, const std::vector<ExternalEditor> &editors);
|
||||
void updateProfiles (const Glib::ustring &printerProfile, rtengine::RenderingIntent printerIntent, bool printerBPC);
|
||||
void updateTPVScrollbar (bool hide);
|
||||
void updateHistogramPosition (int oldPosition, int newPosition);
|
||||
|
||||
Reference in New Issue
Block a user