diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 6cb90a444..987852891 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -2522,8 +2522,22 @@ void EditorPanel::updateExternalEditorWidget(int selectedIndex, const std::vecto // 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 gioIcon = Gio::Icon::create(editors[i].icon_name); + if (!editors[i].icon_serialized.empty()) { + Glib::RefPtr gioIcon; + GError *e = nullptr; + GVariant *icon_variant = g_variant_parse( + nullptr, editors[i].icon_serialized.c_str(), nullptr, nullptr, &e); + + if (e) { + std::cerr + << "Error loading external editor icon from \"" + << editors[i].icon_serialized << "\": " << e->message + << std::endl; + gioIcon = Glib::RefPtr(); + } else { + gioIcon = Gio::Icon::deserialize(Glib::VariantBase(icon_variant)); + } + send_to_external->insertEntry(i, gioIcon, name); } else { send_to_external->insertEntry(i, "palette-brush.png", name); diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index b64cdcf9f..61bf8dc3a 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include + #include "externaleditorpreferences.h" #include "multilangmgr.h" #include "rtimage.h" @@ -85,11 +87,11 @@ ExternalEditorPreferences::getEditors() const for (auto rowIter = children.begin(); rowIter != children.end(); rowIter++) { const Gio::Icon *const icon = rowIter->get_value(model_columns.icon).get(); - const auto &icon_name = icon == nullptr ? "" : icon->to_string(); + const auto &icon_serialized = icon == nullptr ? "" : icon->serialize().print(); editors.push_back(ExternalEditorPreferences::EditorInfo( rowIter->get_value(model_columns.name), rowIter->get_value(model_columns.command), - icon_name, + icon_serialized, rowIter->get_value(model_columns.other_data) )); } @@ -104,8 +106,28 @@ void ExternalEditorPreferences::setEditors( for (const ExternalEditorPreferences::EditorInfo & editor : editors) { auto row = *list_model->append(); + Glib::RefPtr icon; + + // Get icon. + if (editor.icon_serialized.empty()) { + icon = Glib::RefPtr(); + } else { + GError *e = nullptr; + GVariant *icon_variant = g_variant_parse( + nullptr, editor.icon_serialized.c_str(), nullptr, nullptr, &e); + if (e) { + std::cerr + << "Error loading external editor icon from \"" + << editor.icon_serialized << "\": " << e->message + << std::endl; + icon = Glib::RefPtr(); + } else { + icon = Gio::Icon::deserialize(Glib::VariantBase(icon_variant)); + } + } + row[model_columns.name] = editor.name; - row[model_columns.icon] = editor.icon_name.empty() ? Glib::RefPtr() : Gio::Icon::create(editor.icon_name); + row[model_columns.icon] = icon; row[model_columns.command] = editor.command; row[model_columns.other_data] = editor.other_data; } @@ -247,8 +269,8 @@ void ExternalEditorPreferences::updateToolbarSensitivity() } ExternalEditorPreferences::EditorInfo::EditorInfo( - Glib::ustring name, Glib::ustring command, Glib::ustring icon_name, void *other_data -) : name(name), icon_name(icon_name), command(command), other_data(other_data) + Glib::ustring name, Glib::ustring command, Glib::ustring icon_serialized, void *other_data +) : name(name), icon_serialized(icon_serialized), command(command), other_data(other_data) { } diff --git a/rtgui/externaleditorpreferences.h b/rtgui/externaleditorpreferences.h index dbd0f1648..5761d8b63 100644 --- a/rtgui/externaleditorpreferences.h +++ b/rtgui/externaleditorpreferences.h @@ -41,7 +41,7 @@ public: explicit EditorInfo( Glib::ustring name = Glib::ustring(), Glib::ustring command = Glib::ustring(), - Glib::ustring icon_name = Glib::ustring(), + Glib::ustring icon_serialized = Glib::ustring(), void *other_data = nullptr ); /** @@ -49,9 +49,9 @@ public: */ Glib::ustring name; /** - * The string representation of the icon. See Gio::Icon::to_string(). + * The string representation of the icon. See Gio::Icon::serialize(). */ - Glib::ustring icon_name; + Glib::ustring icon_serialized; /** * The commandline for running the program. See * Gio::AppInfo::get_commandline() diff --git a/rtgui/options.cc b/rtgui/options.cc index 6a944faa6..53cedea95 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -859,7 +859,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_group("External Editor")) { if (keyFile.has_key("External Editor", "Names") || keyFile.has_key("External Editor", "Commands") - || keyFile.has_key("External Editor", "IconNames")) { + || keyFile.has_key("External Editor", "IconsSerialized")) { // Multiple external editors. const auto & names = @@ -872,21 +872,21 @@ void Options::readFromFile(Glib::ustring fname) std::vector() : static_cast>( keyFile.get_string_list("External Editor", "Commands")); - const auto & icon_names = - !keyFile.has_key("External Editor", "IconNames") ? + const auto & icons_serialized = + !keyFile.has_key("External Editor", "IconsSerialized") ? std::vector() : static_cast>( - keyFile.get_string_list("External Editor", "IconNames")); + keyFile.get_string_list("External Editor", "IconsSerialized")); externalEditors = std::vector(std::max(std::max( - names.size(), commands.size()), icon_names.size())); + names.size(), commands.size()), icons_serialized.size())); for (unsigned i = 0; i < names.size(); i++) { externalEditors[i].name = names[i]; } for (unsigned i = 0; i < commands.size(); i++) { externalEditors[i].command = commands[i]; } - for (unsigned i = 0; i < icon_names.size(); i++) { - externalEditors[i].icon_name = icon_names[i]; + for (unsigned i = 0; i < icons_serialized.size(); i++) { + externalEditors[i].icon_serialized = icons_serialized[i]; } if (keyFile.has_key("External Editor", "EditorIndex")) { @@ -903,6 +903,9 @@ void Options::readFromFile(Glib::ustring fname) editorToSendTo = keyFile.get_integer("External Editor", "EditorKind"); #ifdef WIN32 + auto getIconSerialized = [](const Glib::ustring &executable) { + return Glib::ustring::compose("('themed', <['%1,0', '%1,0-symbolic']>)", executable); + }; Glib::ustring gimpDir = ""; if (keyFile.has_key("External Editor", "GimpDir")) { gimpDir = keyFile.get_string("External Editor", "GimpDir"); @@ -912,7 +915,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); } else { for (auto ver = 12; ver >= 0; --ver) { executable = Glib::build_filename(gimpDir, "bin", Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"), ver)); @@ -920,7 +923,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 1) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("GIMP", "\"" + executable + "\"", getIconSerialized(executable))); break; } } @@ -935,7 +938,7 @@ void Options::readFromFile(Glib::ustring fname) if (editorToSendTo == 2) { externalEditorIndex = externalEditors.size(); } - externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", executable + ",0")); + externalEditors.push_back(ExternalEditor("Photoshop", "\"" + executable + "\"", getIconSerialized(executable))); } if (keyFile.has_key("External Editor", "CustomEditor")) { @@ -2296,17 +2299,17 @@ void Options::saveToFile(Glib::ustring fname) { std::vector names; std::vector commands; - std::vector icon_names; + std::vector icons_serialized; for (const auto & editor : externalEditors) { names.push_back(editor.name); commands.push_back(editor.command); - icon_names.push_back(editor.icon_name); + icons_serialized.push_back(editor.icon_serialized); } keyFile.set_string_list("External Editor", "Names", names); keyFile.set_string_list("External Editor", "Commands", commands); - keyFile.set_string_list("External Editor", "IconNames", icon_names); + keyFile.set_string_list("External Editor", "IconsSerialized", icons_serialized); keyFile.set_integer("External Editor", "EditorIndex", externalEditorIndex); } @@ -2978,12 +2981,12 @@ Glib::ustring Options::getICCProfileCopyright() ExternalEditor::ExternalEditor() {} ExternalEditor::ExternalEditor( - const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name -): name(name), command(command), icon_name(icon_name) {} + const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized +): name(name), command(command), icon_serialized(icon_serialized) {} bool ExternalEditor::operator==(const ExternalEditor &other) const { - return this->name == other.name && this->command == other.command && this->icon_name == other.icon_name; + return this->name == other.name && this->command == other.command && this->icon_serialized == other.icon_serialized; } bool ExternalEditor::operator!=(const ExternalEditor &other) const diff --git a/rtgui/options.h b/rtgui/options.h index 38d3f3d76..d6b546d40 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -54,10 +54,10 @@ struct ExternalEditor { ExternalEditor(); - ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_name); + ExternalEditor(const Glib::ustring &name, const Glib::ustring &command, const Glib::ustring &icon_serialized); Glib::ustring name; Glib::ustring command; - Glib::ustring icon_name; + Glib::ustring icon_serialized; bool operator==(const ExternalEditor & other) const; bool operator!=(const ExternalEditor & other) const; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 786262896..a8f5c64a3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1793,7 +1793,7 @@ void Preferences::storePreferences() 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)); + editors[i].name, editors[i].command, editors[i].icon_serialized)); 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. @@ -2100,7 +2100,7 @@ void Preferences::fillPreferences() std::vector editorInfos; for (const auto &editor : moptions.externalEditors) { editorInfos.push_back(ExternalEditorPreferences::EditorInfo( - editor.name, editor.command, editor.icon_name)); + editor.name, editor.command, editor.icon_serialized)); } if (moptions.externalEditorIndex >= 0) { // Mark the current editor so we can track it. diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 9a38c1885..98e61b897 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -294,7 +294,12 @@ Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fi Glib::RefPtr RTImage::createPixbufFromGIcon(const Glib::RefPtr &icon, int size) { // TODO: Listen for theme changes and update icon, remove from cache. - return Gtk::IconTheme::get_default()->lookup_icon(icon, size, Gtk::ICON_LOOKUP_FORCE_SIZE).load_icon(); + Gtk::IconInfo iconInfo = Gtk::IconTheme::get_default()->lookup_icon(icon, size, Gtk::ICON_LOOKUP_FORCE_SIZE); + try { + return iconInfo.load_icon(); + } catch (Glib::Exception &e) { + return Glib::RefPtr(); + } } Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::ustring& fileName)