diff options
-rw-r--r-- | solenv/sanitizers/ui/vcl.suppr | 1 | ||||
-rw-r--r-- | vcl/inc/strings.hrc | 2 | ||||
-rw-r--r-- | vcl/source/control/edit.cxx | 2 | ||||
-rw-r--r-- | vcl/source/edit/vclmedit.cxx | 4 | ||||
-rw-r--r-- | vcl/uiconfig/ui/editmenu.ui | 1 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtkinst.cxx | 81 |
6 files changed, 65 insertions, 26 deletions
diff --git a/solenv/sanitizers/ui/vcl.suppr b/solenv/sanitizers/ui/vcl.suppr index a07c25780a76..52e3b4d86df5 100644 --- a/solenv/sanitizers/ui/vcl.suppr +++ b/solenv/sanitizers/ui/vcl.suppr @@ -7,6 +7,7 @@ vcl/uiconfig/ui/combobox.ui://GtkEntry[@id='entry'] no-labelled-by vcl/uiconfig/ui/combobox.ui://GtkToggleButton[@id='button'] button-no-label vcl/uiconfig/ui/combobox.ui://GtkMenuButton[@id='overlaybutton'] button-no-label vcl/uiconfig/ui/cupspassworddialog.ui://GtkLabel[@id='text'] orphan-label +vcl/uiconfig/ui/editmenu.ui://GtkMenuItem[@id='specialchar'] button-no-label vcl/uiconfig/ui/menutogglebutton3.ui://GtkToggleButton[@id='togglebutton'] button-no-label vcl/uiconfig/ui/menutogglebutton3.ui://GtkButton[@id='menubutton'] button-no-label vcl/uiconfig/ui/menutogglebutton4.ui://GtkToggleButton[@id='togglebutton'] button-no-label diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc index c2e95f20ceac..7f5699aae1d6 100644 --- a/vcl/inc/strings.hrc +++ b/vcl/inc/strings.hrc @@ -125,6 +125,8 @@ #define STR_UNSAVED_DOCUMENTS NC_("STR_UNSAVED_DOCUMENTS", "There are unsaved documents") +#define STR_SPECIAL_CHARACTER_MENU_ENTRY NC_("editmenu|specialchar", "_Special Character...") + #endif // INCLUDED_VCL_INC_STRINGS_HRC /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx index 0db27e8a315a..92c03118727c 100644 --- a/vcl/source/control/edit.cxx +++ b/vcl/source/control/edit.cxx @@ -1978,6 +1978,8 @@ void Edit::Command( const CommandEvent& rCEvt ) pPopup->EnableItem(pPopup->GetItemId(u"copy"), bEnableCopy); pPopup->EnableItem(pPopup->GetItemId(u"delete"), bEnableDelete); pPopup->EnableItem(pPopup->GetItemId(u"paste"), bEnablePaste); + pPopup->SetItemText(pPopup->GetItemId(u"specialchar"), + BuilderUtils::convertMnemonicMarkup(VclResId(STR_SPECIAL_CHARACTER_MENU_ENTRY))); pPopup->EnableItem(pPopup->GetItemId(u"specialchar"), bEnableSpecialChar); pPopup->EnableItem( pPopup->GetItemId(u"undo"), diff --git a/vcl/source/edit/vclmedit.cxx b/vcl/source/edit/vclmedit.cxx index 541d6bfc20c8..d5197358591d 100644 --- a/vcl/source/edit/vclmedit.cxx +++ b/vcl/source/edit/vclmedit.cxx @@ -41,6 +41,8 @@ #include <vcl/weld.hxx> #include <osl/diagnose.h> #include <tools/json_writer.hxx> +#include <strings.hrc> +#include <svdata.hxx> class ImpVclMEdit : public SfxListener { @@ -789,6 +791,8 @@ void TextWindow::Command( const CommandEvent& rCEvt ) pPopup->EnableItem(pPopup->GetItemId(u"copy"), bEnableCopy); pPopup->EnableItem(pPopup->GetItemId(u"delete"), bEnableDelete); pPopup->EnableItem(pPopup->GetItemId(u"paste"), bEnablePaste); + pPopup->SetItemText(pPopup->GetItemId(u"specialchar"), + BuilderUtils::convertMnemonicMarkup(VclResId(STR_SPECIAL_CHARACTER_MENU_ENTRY))); pPopup->EnableItem(pPopup->GetItemId(u"specialchar"), bEnableSpecialChar); pPopup->EnableItem(pPopup->GetItemId(u"undo"), bEnableUndo); pPopup->ShowItem(pPopup->GetItemId(u"specialchar"), !vcl::GetGetSpecialCharsFunction()); diff --git a/vcl/uiconfig/ui/editmenu.ui b/vcl/uiconfig/ui/editmenu.ui index 8c025d4f1a94..e0d55fb8cca0 100644 --- a/vcl/uiconfig/ui/editmenu.ui +++ b/vcl/uiconfig/ui/editmenu.ui @@ -69,7 +69,6 @@ <object class="GtkMenuItem" id="specialchar"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes" context="editmenu|specialchar">_Special Character...</property> <property name="use_underline">True</property> </object> </child> diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 2cfd0d6b203a..141039dfb79c 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -19024,41 +19024,67 @@ void GtkInstanceDrawingArea::im_context_set_cursor_location(const tools::Rectang } #if !GTK_CHECK_VERSION(4, 0, 0) -static gboolean signalEntryInsertSpecialCharKeyPress(GtkEntry* pEntry, GdkEventKey* pEvent, gpointer) + +static void InsertSpecialChar(GtkEntry *pEntry) { - if ((pEvent->keyval == GDK_KEY_S || pEvent->keyval == GDK_KEY_s) && - (pEvent->state & GDK_MODIFIER_MASK) == static_cast<GdkModifierType>(GDK_SHIFT_MASK|GDK_CONTROL_MASK)) + if (auto pImplFncGetSpecialChars = vcl::GetGetSpecialCharsFunction()) { - if (auto pImplFncGetSpecialChars = vcl::GetGetSpecialCharsFunction()) - { - weld::Window* pDialogParent = nullptr; + weld::Window* pDialogParent = nullptr; - GtkWidget* pTopLevel = widget_get_toplevel(GTK_WIDGET(pEntry)); - if (GtkSalFrame* pFrame = pTopLevel ? GtkSalFrame::getFromWindow(pTopLevel) : nullptr) - pDialogParent = pFrame->GetFrameWeld(); + GtkWidget* pTopLevel = widget_get_toplevel(GTK_WIDGET(pEntry)); + if (GtkSalFrame* pFrame = pTopLevel ? GtkSalFrame::getFromWindow(pTopLevel) : nullptr) + pDialogParent = pFrame->GetFrameWeld(); - std::unique_ptr<GtkInstanceWindow> xFrameWeld; - if (!pDialogParent && pTopLevel) - { - xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(pTopLevel), nullptr, false)); - pDialogParent = xFrameWeld.get(); - } + std::unique_ptr<GtkInstanceWindow> xFrameWeld; + if (!pDialogParent && pTopLevel) + { + xFrameWeld.reset(new GtkInstanceWindow(GTK_WINDOW(pTopLevel), nullptr, false)); + pDialogParent = xFrameWeld.get(); + } - OUString aChars = pImplFncGetSpecialChars(pDialogParent, ::get_font(GTK_WIDGET(pEntry))); - if (!aChars.isEmpty()) - { - gtk_editable_delete_selection(GTK_EDITABLE(pEntry)); - gint position = gtk_editable_get_position(GTK_EDITABLE(pEntry)); - OString sText(OUStringToOString(aChars, RTL_TEXTENCODING_UTF8)); - gtk_editable_insert_text(GTK_EDITABLE(pEntry), sText.getStr(), sText.getLength(), - &position); - gtk_editable_set_position(GTK_EDITABLE(pEntry), position); - } + OUString aChars = pImplFncGetSpecialChars(pDialogParent, ::get_font(GTK_WIDGET(pEntry))); + if (!aChars.isEmpty()) + { + gtk_editable_delete_selection(GTK_EDITABLE(pEntry)); + gint position = gtk_editable_get_position(GTK_EDITABLE(pEntry)); + OString sText(OUStringToOString(aChars, RTL_TEXTENCODING_UTF8)); + gtk_editable_insert_text(GTK_EDITABLE(pEntry), sText.getStr(), sText.getLength(), + &position); + gtk_editable_set_position(GTK_EDITABLE(pEntry), position); } + } +} + +static gboolean signalEntryInsertSpecialCharKeyPress(GtkEntry* pEntry, GdkEventKey* pEvent, gpointer) +{ + if ((pEvent->keyval == GDK_KEY_S || pEvent->keyval == GDK_KEY_s) && + (pEvent->state & GDK_MODIFIER_MASK) == static_cast<GdkModifierType>(GDK_SHIFT_MASK|GDK_CONTROL_MASK)) + { + InsertSpecialChar(pEntry); return true; } return false; } + +static void signalActivateEntryInsertSpecialChar(GtkEntry *pEntry) +{ + InsertSpecialChar(pEntry); +} + +static void signalEntryPopulatePopup(GtkEntry* pEntry, GtkWidget* pMenu, gpointer) +{ + if (!GTK_IS_MENU(pMenu)) + return; + + if (!vcl::GetGetSpecialCharsFunction()) + return; + + GtkWidget *item = gtk_menu_item_new_with_mnemonic(MapToGtkAccelerator(VclResId(STR_SPECIAL_CHARACTER_MENU_ENTRY)).getStr()); + gtk_widget_show(item); + g_signal_connect_swapped(item, "activate", G_CALLBACK(signalActivateEntryInsertSpecialChar), pEntry); + gtk_menu_shell_append(GTK_MENU_SHELL(pMenu), item); +} + #endif namespace { @@ -20970,6 +20996,7 @@ private: gulong m_nEntryFocusInSignalId; gulong m_nEntryFocusOutSignalId; gulong m_nEntryKeyPressEventSignalId; + gulong m_nEntryPopulatePopupMenuSignalId; guint m_nAutoCompleteIdleId; gint m_nNonCustomLineHeight; gint m_nPrePopupCursorPos; @@ -22071,6 +22098,7 @@ public: m_nEntryFocusInSignalId = g_signal_connect(m_pEntry, "focus-in-event", G_CALLBACK(signalEntryFocusIn), this); m_nEntryFocusOutSignalId = g_signal_connect(m_pEntry, "focus-out-event", G_CALLBACK(signalEntryFocusOut), this); m_nEntryKeyPressEventSignalId = g_signal_connect(m_pEntry, "key-press-event", G_CALLBACK(signalEntryKeyPress), this); + m_nEntryPopulatePopupMenuSignalId = g_signal_connect(m_pEntry, "populate-popup", G_CALLBACK(signalEntryPopulatePopup), nullptr); m_nKeyPressEventSignalId = 0; } else @@ -22116,6 +22144,7 @@ public: m_nEntryFocusInSignalId = 0; m_nEntryFocusOutSignalId = 0; m_nEntryKeyPressEventSignalId = 0; + m_nEntryPopulatePopupMenuSignalId = 0; m_nKeyPressEventSignalId = g_signal_connect(m_pToggleButton, "key-press-event", G_CALLBACK(signalKeyPress), this); } @@ -22711,6 +22740,7 @@ public: g_signal_handler_disconnect(m_pEntry, m_nEntryFocusInSignalId); g_signal_handler_disconnect(m_pEntry, m_nEntryFocusOutSignalId); g_signal_handler_disconnect(m_pEntry, m_nEntryKeyPressEventSignalId); + g_signal_handler_disconnect(m_pEntry, m_nEntryPopulatePopupMenuSignalId); } else g_signal_handler_disconnect(m_pToggleButton, m_nKeyPressEventSignalId); @@ -23835,6 +23865,7 @@ private: else if (GTK_IS_ENTRY(pWidget)) { g_signal_connect(pWidget, "key-press-event", G_CALLBACK(signalEntryInsertSpecialCharKeyPress), nullptr); + g_signal_connect(pWidget, "populate-popup", G_CALLBACK(signalEntryPopulatePopup), nullptr); } #endif else if (GTK_IS_WINDOW(pWidget)) |