fix: proper localization when using GtkFileChooserNative (#30888)
* fix: proper localization when using GtkFileChooserNative * fix: iwyu
This commit is contained in:
parent
a75617bff1
commit
38b810b2e3
4 changed files with 87 additions and 49 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
|
@ -131,24 +132,25 @@ class FileChooserDialog {
|
||||||
: parent_(
|
: parent_(
|
||||||
static_cast<electron::NativeWindowViews*>(settings.parent_window)),
|
static_cast<electron::NativeWindowViews*>(settings.parent_window)),
|
||||||
filters_(settings.filters) {
|
filters_(settings.filters) {
|
||||||
const char* confirm_text = gtk_util::kOkLabel;
|
|
||||||
|
|
||||||
if (!settings.button_label.empty())
|
|
||||||
confirm_text = settings.button_label.c_str();
|
|
||||||
else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
|
||||||
confirm_text = gtk_util::kSaveLabel;
|
|
||||||
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
|
||||||
confirm_text = gtk_util::kOpenLabel;
|
|
||||||
|
|
||||||
InitGtkFileChooserNativeSupport();
|
InitGtkFileChooserNativeSupport();
|
||||||
|
|
||||||
|
auto label = settings.button_label;
|
||||||
|
|
||||||
if (*supports_gtk_file_chooser_native) {
|
if (*supports_gtk_file_chooser_native) {
|
||||||
dialog_ = GTK_FILE_CHOOSER(
|
dialog_ = GTK_FILE_CHOOSER(dl_gtk_file_chooser_native_new(
|
||||||
dl_gtk_file_chooser_native_new(settings.title.c_str(), NULL, action,
|
settings.title.c_str(), NULL, action,
|
||||||
confirm_text, gtk_util::kCancelLabel));
|
label.empty() ? nullptr : label.c_str(), nullptr));
|
||||||
} else {
|
} else {
|
||||||
|
const char* confirm_text = gtk_util::GetOkLabel();
|
||||||
|
if (!label.empty())
|
||||||
|
confirm_text = label.c_str();
|
||||||
|
else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||||
|
confirm_text = gtk_util::GetSaveLabel();
|
||||||
|
else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||||
|
confirm_text = gtk_util::GetOpenLabel();
|
||||||
|
|
||||||
dialog_ = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(
|
dialog_ = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(
|
||||||
settings.title.c_str(), NULL, action, gtk_util::kCancelLabel,
|
settings.title.c_str(), NULL, action, gtk_util::GetCancelLabel(),
|
||||||
GTK_RESPONSE_CANCEL, confirm_text, GTK_RESPONSE_ACCEPT, NULL));
|
GTK_RESPONSE_CANCEL, confirm_text, GTK_RESPONSE_ACCEPT, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,36 +8,71 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/no_destructor.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "third_party/skia/include/core/SkBitmap.h"
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
#include "third_party/skia/include/core/SkUnPreMultiply.h"
|
#include "third_party/skia/include/core/SkUnPreMultiply.h"
|
||||||
|
#include "ui/gtk/gtk_compat.h" // nogncheck
|
||||||
|
|
||||||
namespace gtk_util {
|
namespace gtk_util {
|
||||||
|
|
||||||
// Copied from L40-L55 in
|
// The following utilities are pulled from
|
||||||
// https://cs.chromium.org/chromium/src/chrome/browser/ui/libgtkui/select_file_dialog_impl_gtk.cc
|
// https://source.chromium.org/chromium/chromium/src/+/main:ui/gtk/select_file_dialog_impl_gtk.cc;l=43-74
|
||||||
#if GTK_CHECK_VERSION(3, 90, 0)
|
|
||||||
// GTK stock items have been deprecated. The docs say to switch to using the
|
const char* GettextPackage() {
|
||||||
// strings "_Open", etc. However this breaks i18n. We could supply our own
|
static base::NoDestructor<std::string> gettext_package(
|
||||||
// internationalized strings, but the "_" in these strings is significant: it's
|
"gtk" + base::NumberToString(gtk::GtkVersion().components()[0]) + "0");
|
||||||
// the keyboard shortcut to select these actions. TODO: Provide
|
return gettext_package->c_str();
|
||||||
// internationalized strings when GTK provides support for it.
|
}
|
||||||
const char* const kCancelLabel = "_Cancel";
|
|
||||||
const char* const kNoLabel = "_No";
|
const char* GtkGettext(const char* str) {
|
||||||
const char* const kOkLabel = "_OK";
|
return g_dgettext(GettextPackage(), str);
|
||||||
const char* const kOpenLabel = "_Open";
|
}
|
||||||
const char* const kSaveLabel = "_Save";
|
|
||||||
const char* const kYesLabel = "_Yes";
|
const char* GetCancelLabel() {
|
||||||
#else
|
if (!gtk::GtkCheckVersion(4))
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
return "gtk-cancel"; // In GTK3, this is GTK_STOCK_CANCEL.
|
||||||
const char* const kCancelLabel = GTK_STOCK_CANCEL;
|
static const char* cancel = GtkGettext("_Cancel");
|
||||||
const char* const kNoLabel = GTK_STOCK_NO;
|
return cancel;
|
||||||
const char* const kOkLabel = GTK_STOCK_OK;
|
}
|
||||||
const char* const kOpenLabel = GTK_STOCK_OPEN;
|
|
||||||
const char* const kSaveLabel = GTK_STOCK_SAVE;
|
const char* GetOpenLabel() {
|
||||||
const char* const kYesLabel = GTK_STOCK_YES;
|
if (!gtk::GtkCheckVersion(4))
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
return "gtk-open"; // In GTK3, this is GTK_STOCK_OPEN.
|
||||||
#endif
|
static const char* open = GtkGettext("_Open");
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetSaveLabel() {
|
||||||
|
if (!gtk::GtkCheckVersion(4))
|
||||||
|
return "gtk-save"; // In GTK3, this is GTK_STOCK_SAVE.
|
||||||
|
static const char* save = GtkGettext("_Save");
|
||||||
|
return save;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetOkLabel() {
|
||||||
|
if (!gtk::GtkCheckVersion(4))
|
||||||
|
return "gtk-ok"; // In GTK3, this is GTK_STOCK_OK.
|
||||||
|
static const char* ok = GtkGettext("_Ok");
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetNoLabel() {
|
||||||
|
if (!gtk::GtkCheckVersion(4))
|
||||||
|
return "gtk-no"; // In GTK3, this is GTK_STOCK_NO.
|
||||||
|
static const char* no = GtkGettext("_No");
|
||||||
|
return no;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetYesLabel() {
|
||||||
|
if (!gtk::GtkCheckVersion(4))
|
||||||
|
return "gtk-yes"; // In GTK3, this is GTK_STOCK_YES.
|
||||||
|
static const char* yes = GtkGettext("_Yes");
|
||||||
|
return yes;
|
||||||
|
}
|
||||||
|
|
||||||
GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
|
GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
|
||||||
if (bitmap.isNull())
|
if (bitmap.isNull())
|
||||||
|
|
|
@ -11,14 +11,15 @@ class SkBitmap;
|
||||||
|
|
||||||
namespace gtk_util {
|
namespace gtk_util {
|
||||||
|
|
||||||
/* These are `const char*` rather than the project-preferred `const char[]`
|
const char* GettextPackage();
|
||||||
because they must fit the type of an external dependency */
|
const char* GtkGettext(const char* str);
|
||||||
extern const char* const kCancelLabel;
|
|
||||||
extern const char* const kNoLabel;
|
const char* GetCancelLabel();
|
||||||
extern const char* const kOkLabel;
|
const char* GetOpenLabel();
|
||||||
extern const char* const kOpenLabel;
|
const char* GetSaveLabel();
|
||||||
extern const char* const kSaveLabel;
|
const char* GetOkLabel();
|
||||||
extern const char* const kYesLabel;
|
const char* GetNoLabel();
|
||||||
|
const char* GetYesLabel();
|
||||||
|
|
||||||
// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so
|
// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so
|
||||||
// it is an expensive operation. The returned GdkPixbuf will have a refcount of
|
// it is an expensive operation. The returned GdkPixbuf will have a refcount of
|
||||||
|
|
|
@ -145,13 +145,13 @@ class GtkMessageBox : public NativeWindowObserver {
|
||||||
const char* TranslateToStock(int id, const std::string& text) {
|
const char* TranslateToStock(int id, const std::string& text) {
|
||||||
const std::string lower = base::ToLowerASCII(text);
|
const std::string lower = base::ToLowerASCII(text);
|
||||||
if (lower == "cancel")
|
if (lower == "cancel")
|
||||||
return gtk_util::kCancelLabel;
|
return gtk_util::GetCancelLabel();
|
||||||
if (lower == "no")
|
if (lower == "no")
|
||||||
return gtk_util::kNoLabel;
|
return gtk_util::GetNoLabel();
|
||||||
if (lower == "ok")
|
if (lower == "ok")
|
||||||
return gtk_util::kOkLabel;
|
return gtk_util::GetOkLabel();
|
||||||
if (lower == "yes")
|
if (lower == "yes")
|
||||||
return gtk_util::kYesLabel;
|
return gtk_util::GetYesLabel();
|
||||||
return text.c_str();
|
return text.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue