refactor wxGTK mnemonics conversion functions in a separate file to be able to reuse them from wxMenu too
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49869 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
16
Makefile.in
16
Makefile.in
@@ -4524,6 +4524,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS = \
|
|||||||
monodll_listbox.o \
|
monodll_listbox.o \
|
||||||
monodll_mdi.o \
|
monodll_mdi.o \
|
||||||
monodll_menu.o \
|
monodll_menu.o \
|
||||||
|
monodll_mnemonics.o \
|
||||||
monodll_msgdlg.o \
|
monodll_msgdlg.o \
|
||||||
monodll_notebook.o \
|
monodll_notebook.o \
|
||||||
monodll_radiobox.o \
|
monodll_radiobox.o \
|
||||||
@@ -6403,6 +6404,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_1 = \
|
|||||||
monolib_listbox.o \
|
monolib_listbox.o \
|
||||||
monolib_mdi.o \
|
monolib_mdi.o \
|
||||||
monolib_menu.o \
|
monolib_menu.o \
|
||||||
|
monolib_mnemonics.o \
|
||||||
monolib_msgdlg.o \
|
monolib_msgdlg.o \
|
||||||
monolib_notebook.o \
|
monolib_notebook.o \
|
||||||
monolib_radiobox.o \
|
monolib_radiobox.o \
|
||||||
@@ -8559,6 +8561,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_2 = \
|
|||||||
coredll_listbox.o \
|
coredll_listbox.o \
|
||||||
coredll_mdi.o \
|
coredll_mdi.o \
|
||||||
coredll_menu.o \
|
coredll_menu.o \
|
||||||
|
coredll_mnemonics.o \
|
||||||
coredll_msgdlg.o \
|
coredll_msgdlg.o \
|
||||||
coredll_notebook.o \
|
coredll_notebook.o \
|
||||||
coredll_radiobox.o \
|
coredll_radiobox.o \
|
||||||
@@ -10053,6 +10056,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_3 = \
|
|||||||
corelib_listbox.o \
|
corelib_listbox.o \
|
||||||
corelib_mdi.o \
|
corelib_mdi.o \
|
||||||
corelib_menu.o \
|
corelib_menu.o \
|
||||||
|
corelib_mnemonics.o \
|
||||||
corelib_msgdlg.o \
|
corelib_msgdlg.o \
|
||||||
corelib_notebook.o \
|
corelib_notebook.o \
|
||||||
corelib_radiobox.o \
|
corelib_radiobox.o \
|
||||||
@@ -13735,6 +13739,9 @@ monodll_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(MONODLL_ODEP)
|
|||||||
monodll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONODLL_ODEP)
|
monodll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONODLL_ODEP)
|
||||||
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
||||||
|
|
||||||
|
monodll_mnemonics.o: $(srcdir)/src/gtk/mnemonics.cpp $(MONODLL_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/mnemonics.cpp
|
||||||
|
|
||||||
monodll_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(MONODLL_ODEP)
|
monodll_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(MONODLL_ODEP)
|
||||||
$(CCC) -c -o $@ $(MONODLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
$(CCC) -c -o $@ $(MONODLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
||||||
|
|
||||||
@@ -18187,6 +18194,9 @@ monolib_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(MONOLIB_ODEP)
|
|||||||
monolib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONOLIB_ODEP)
|
monolib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONOLIB_ODEP)
|
||||||
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
||||||
|
|
||||||
|
monolib_mnemonics.o: $(srcdir)/src/gtk/mnemonics.cpp $(MONOLIB_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/mnemonics.cpp
|
||||||
|
|
||||||
monolib_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(MONOLIB_ODEP)
|
monolib_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(MONOLIB_ODEP)
|
||||||
$(CCC) -c -o $@ $(MONOLIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
$(CCC) -c -o $@ $(MONOLIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
||||||
|
|
||||||
@@ -23965,6 +23975,9 @@ coredll_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(COREDLL_ODEP)
|
|||||||
coredll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(COREDLL_ODEP)
|
coredll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(COREDLL_ODEP)
|
||||||
$(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
$(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
||||||
|
|
||||||
|
coredll_mnemonics.o: $(srcdir)/src/gtk/mnemonics.cpp $(COREDLL_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/mnemonics.cpp
|
||||||
|
|
||||||
coredll_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(COREDLL_ODEP)
|
coredll_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(COREDLL_ODEP)
|
||||||
$(CCC) -c -o $@ $(COREDLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
$(CCC) -c -o $@ $(COREDLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
||||||
|
|
||||||
@@ -27034,6 +27047,9 @@ corelib_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(CORELIB_ODEP)
|
|||||||
corelib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(CORELIB_ODEP)
|
corelib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(CORELIB_ODEP)
|
||||||
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/gnome/gvfs.cpp
|
||||||
|
|
||||||
|
corelib_mnemonics.o: $(srcdir)/src/gtk/mnemonics.cpp $(CORELIB_ODEP)
|
||||||
|
$(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/mnemonics.cpp
|
||||||
|
|
||||||
corelib_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(CORELIB_ODEP)
|
corelib_treeentry_gtk.o: $(srcdir)/src/gtk/treeentry_gtk.c $(CORELIB_ODEP)
|
||||||
$(CCC) -c -o $@ $(CORELIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
$(CCC) -c -o $@ $(CORELIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
|
||||||
|
|
||||||
|
@@ -1056,6 +1056,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
|||||||
src/gtk/listbox.cpp
|
src/gtk/listbox.cpp
|
||||||
src/gtk/mdi.cpp
|
src/gtk/mdi.cpp
|
||||||
src/gtk/menu.cpp
|
src/gtk/menu.cpp
|
||||||
|
src/gtk/mnemonics.cpp
|
||||||
src/gtk/msgdlg.cpp
|
src/gtk/msgdlg.cpp
|
||||||
src/gtk/notebook.cpp
|
src/gtk/notebook.cpp
|
||||||
src/gtk/radiobox.cpp
|
src/gtk/radiobox.cpp
|
||||||
|
39
include/wx/gtk/private/mnemonics.h
Normal file
39
include/wx/gtk/private/mnemonics.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: gtk/private/mnemonics.h
|
||||||
|
// Purpose: helper functions for dealing with GTK+ mnemonics
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2007-11-12
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _GTK_PRIVATE_MNEMONICS_H_
|
||||||
|
#define _GTK_PRIVATE_MNEMONICS_H_
|
||||||
|
|
||||||
|
#if wxUSE_CONTROLS || wxUSE_MENUS
|
||||||
|
|
||||||
|
#include "wx/string.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// functions to convert between wxWidgets and GTK+ string containing mnemonics
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// remove all mnemonics from a string
|
||||||
|
wxString wxGTKRemoveMnemonics(const wxString& label);
|
||||||
|
|
||||||
|
// convert a wx string with '&' to GTK+ string with '_'s
|
||||||
|
wxString wxConvertMnemonicsToGTK(const wxString& label);
|
||||||
|
|
||||||
|
// convert a wx string with '&' to indicate mnemonics as well as HTML entities
|
||||||
|
// to a GTK+ string with "&" used instead of '&', i.e. suitable for use
|
||||||
|
// with GTK+ functions using markup strings
|
||||||
|
wxString wxConvertMnemonicsToGTKMarkup(const wxString& label);
|
||||||
|
|
||||||
|
// convert GTK+ string with '_'s to wx string with '&'s
|
||||||
|
wxString wxConvertMnemonicsFromGTK(const wxString& label);
|
||||||
|
|
||||||
|
#endif // wxUSE_CONTROLS || wxUSE_MENUS
|
||||||
|
|
||||||
|
#endif // _GTK_PRIVATE_MNEMONICS_H_
|
||||||
|
|
@@ -67,6 +67,8 @@ private:
|
|||||||
bool m_eol;
|
bool m_eol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // wxUSE_STATTEXT
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
wxMARKUP_ENTITY_AMP,
|
wxMARKUP_ENTITY_AMP,
|
||||||
@@ -92,6 +94,4 @@ enum
|
|||||||
//
|
//
|
||||||
extern const wxChar *wxMarkupEntities[wxMARKUP_ELEMENT_MAX][wxMARKUP_ENTITY_MAX];
|
extern const wxChar *wxMarkupEntities[wxMARKUP_ELEMENT_MAX][wxMARKUP_ENTITY_MAX];
|
||||||
|
|
||||||
#endif // wxUSE_STATTEXT
|
|
||||||
|
|
||||||
#endif // _WX_PRIVATE_STATTEXT_H_
|
#endif // _WX_PRIVATE_STATTEXT_H_
|
||||||
|
@@ -37,8 +37,6 @@
|
|||||||
#include "wx/containr.h"
|
#include "wx/containr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_STATTEXT
|
|
||||||
|
|
||||||
const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] =
|
const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] =
|
||||||
{
|
{
|
||||||
// the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string
|
// the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string
|
||||||
@@ -47,6 +45,7 @@ const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] =
|
|||||||
{ wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") }
|
{ wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if wxUSE_STATTEXT
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTextWrapper
|
// wxTextWrapper
|
||||||
|
@@ -22,8 +22,7 @@
|
|||||||
#include "wx/fontutil.h"
|
#include "wx/fontutil.h"
|
||||||
#include "wx/gtk/private.h"
|
#include "wx/gtk/private.h"
|
||||||
|
|
||||||
#include "wx/private/stattext.h"
|
#include "wx/gtk/private/mnemonics.h"
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// wxControl implementation
|
// wxControl implementation
|
||||||
@@ -151,121 +150,22 @@ void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
|
|||||||
// worker function implementing GTK*Mnemonics() functions
|
// worker function implementing GTK*Mnemonics() functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum MnemonicsFlag
|
|
||||||
{
|
|
||||||
MNEMONICS_REMOVE,
|
|
||||||
MNEMONICS_CONVERT,
|
|
||||||
MNEMONICS_CONVERT_MARKUP
|
|
||||||
};
|
|
||||||
|
|
||||||
static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
|
|
||||||
{
|
|
||||||
wxString labelGTK;
|
|
||||||
labelGTK.reserve(label.length());
|
|
||||||
for ( wxString::const_iterator i = label.begin(); i != label.end(); ++i )
|
|
||||||
{
|
|
||||||
wxChar ch = *i;
|
|
||||||
|
|
||||||
switch ( ch )
|
|
||||||
{
|
|
||||||
case wxT('&'):
|
|
||||||
if ( i + 1 == label.end() )
|
|
||||||
{
|
|
||||||
// "&" at the end of string is an error
|
|
||||||
wxLogDebug(wxT("Invalid label \"%s\"."), label);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( flag == MNEMONICS_CONVERT_MARKUP )
|
|
||||||
{
|
|
||||||
bool isMnemonic = true;
|
|
||||||
size_t distanceFromEnd = label.end() - i;
|
|
||||||
|
|
||||||
// is this ampersand introducing a mnemonic or rather an entity?
|
|
||||||
for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++)
|
|
||||||
{
|
|
||||||
const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j];
|
|
||||||
size_t entityLen = wxStrlen(entity);
|
|
||||||
|
|
||||||
if (distanceFromEnd >= entityLen &&
|
|
||||||
wxString(i, i + entityLen) == entity)
|
|
||||||
{
|
|
||||||
labelGTK << entity;
|
|
||||||
i += entityLen - 1; // the -1 is because main for()
|
|
||||||
// loop already increments i
|
|
||||||
isMnemonic = false;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isMnemonic)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch = *(++i); // skip '&' itself
|
|
||||||
switch ( ch )
|
|
||||||
{
|
|
||||||
case wxT('&'):
|
|
||||||
// special case: "&&" is not a mnemonic at all but just
|
|
||||||
// an escaped "&"
|
|
||||||
if ( flag == MNEMONICS_CONVERT_MARKUP )
|
|
||||||
labelGTK += wxT("&");
|
|
||||||
else
|
|
||||||
labelGTK += wxT('&');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxT('_'):
|
|
||||||
if ( flag != MNEMONICS_REMOVE )
|
|
||||||
{
|
|
||||||
// '_' can't be a GTK mnemonic apparently so
|
|
||||||
// replace it with something similar
|
|
||||||
labelGTK += wxT("_-");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//else: fall through
|
|
||||||
|
|
||||||
default:
|
|
||||||
if ( flag != MNEMONICS_REMOVE )
|
|
||||||
labelGTK += wxT('_');
|
|
||||||
labelGTK += ch;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wxT('_'):
|
|
||||||
if ( flag != MNEMONICS_REMOVE )
|
|
||||||
{
|
|
||||||
// escape any existing underlines in the string so that
|
|
||||||
// they don't become mnemonics accidentally
|
|
||||||
labelGTK += wxT("__");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//else: fall through
|
|
||||||
|
|
||||||
default:
|
|
||||||
labelGTK += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return labelGTK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxString wxControl::GTKRemoveMnemonics(const wxString& label)
|
wxString wxControl::GTKRemoveMnemonics(const wxString& label)
|
||||||
{
|
{
|
||||||
return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
|
return wxGTKRemoveMnemonics(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxString wxControl::GTKConvertMnemonics(const wxString& label)
|
wxString wxControl::GTKConvertMnemonics(const wxString& label)
|
||||||
{
|
{
|
||||||
return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
|
return wxConvertMnemonicsToGTK(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
|
wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
|
||||||
{
|
{
|
||||||
return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP);
|
return wxConvertMnemonicsToGTKMarkup(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "wx/accel.h"
|
#include "wx/accel.h"
|
||||||
#include "wx/stockitem.h"
|
#include "wx/stockitem.h"
|
||||||
#include "wx/gtk/private.h"
|
#include "wx/gtk/private.h"
|
||||||
|
#include "wx/gtk/private/mnemonics.h"
|
||||||
|
|
||||||
// FIXME: is this right? somehow I don't think so (VZ)
|
// FIXME: is this right? somehow I don't think so (VZ)
|
||||||
|
|
||||||
@@ -47,79 +48,6 @@ static const int wxGTK_TITLE_ID = -3;
|
|||||||
static wxString GetGtkHotKey( const wxMenuItem& item );
|
static wxString GetGtkHotKey( const wxMenuItem& item );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// idle system
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static wxString wxReplaceUnderscore( const wxString& title )
|
|
||||||
{
|
|
||||||
// GTK 1.2 wants to have "_" instead of "&" for accelerators
|
|
||||||
wxString str;
|
|
||||||
|
|
||||||
for ( wxString::const_iterator pc = title.begin(); pc != title.end(); ++pc )
|
|
||||||
{
|
|
||||||
if ((*pc == wxT('&')) && (pc+1 != title.end()) && (*(pc+1) == wxT('&')))
|
|
||||||
{
|
|
||||||
// "&" is doubled to indicate "&" instead of accelerator
|
|
||||||
++pc;
|
|
||||||
str << wxT('&');
|
|
||||||
}
|
|
||||||
else if (*pc == wxT('&'))
|
|
||||||
{
|
|
||||||
str << wxT('_');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( *pc == wxT('_') )
|
|
||||||
{
|
|
||||||
// underscores must be doubled to prevent them from being
|
|
||||||
// interpreted as accelerator character prefix by GTK
|
|
||||||
str << *pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
str << *pc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wxPrintf( wxT("before %s after %s\n"), title.c_str(), str.c_str() );
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wxString wxConvertFromGTKToWXLabel(const wxString& gtkLabel)
|
|
||||||
{
|
|
||||||
wxString label;
|
|
||||||
for ( const wxChar *pc = gtkLabel.c_str(); *pc; pc++ )
|
|
||||||
{
|
|
||||||
// '_' is the escape character for GTK+.
|
|
||||||
|
|
||||||
if ( *pc == wxT('_') && *(pc+1) == wxT('_'))
|
|
||||||
{
|
|
||||||
// An underscore was escaped.
|
|
||||||
label += wxT('_');
|
|
||||||
pc++;
|
|
||||||
}
|
|
||||||
else if ( *pc == wxT('_') )
|
|
||||||
{
|
|
||||||
// Convert GTK+ hotkey symbol to wxWidgets/Windows standard
|
|
||||||
label += wxT('&');
|
|
||||||
}
|
|
||||||
else if ( *pc == wxT('&') )
|
|
||||||
{
|
|
||||||
// Double the ampersand to escape it as far as wxWidgets is concerned
|
|
||||||
label += wxT("&&");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// don't remove ampersands '&' since if we have them in the menu title
|
|
||||||
// it means that they were doubled to indicate "&" instead of accelerator
|
|
||||||
label += *pc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// activate message from GTK
|
// activate message from GTK
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -367,7 +295,7 @@ bool wxMenuBar::Append( wxMenu *menu, const wxString &title )
|
|||||||
|
|
||||||
bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title, int pos)
|
bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title, int pos)
|
||||||
{
|
{
|
||||||
wxString str( wxReplaceUnderscore( title ) );
|
const wxString str(wxConvertMnemonicsToGTK(title));
|
||||||
|
|
||||||
// This doesn't have much effect right now.
|
// This doesn't have much effect right now.
|
||||||
menu->SetTitle( str );
|
menu->SetTitle( str );
|
||||||
@@ -443,7 +371,7 @@ wxMenu *wxMenuBar::Remove(size_t pos)
|
|||||||
|
|
||||||
static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
|
static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
|
||||||
{
|
{
|
||||||
if (wxMenuItem::GetLabelText(wxConvertFromGTKToWXLabel(menu->GetTitle())) == wxMenuItem::GetLabelText(menuString))
|
if (wxMenuItem::GetLabelText(wxConvertMnemonicsFromGTK(menu->GetTitle())) == wxMenuItem::GetLabelText(menuString))
|
||||||
{
|
{
|
||||||
int res = menu->FindItem( itemString );
|
int res = menu->FindItem( itemString );
|
||||||
if (res != wxNOT_FOUND)
|
if (res != wxNOT_FOUND)
|
||||||
@@ -536,7 +464,7 @@ wxString wxMenuBar::GetMenuLabel( size_t pos ) const
|
|||||||
|
|
||||||
wxMenu* menu = node->GetData();
|
wxMenu* menu = node->GetData();
|
||||||
|
|
||||||
return wxConvertFromGTKToWXLabel(menu->GetTitle());
|
return wxConvertMnemonicsFromGTK(menu->GetTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label )
|
void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label )
|
||||||
@@ -547,7 +475,7 @@ void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label )
|
|||||||
|
|
||||||
wxMenu* menu = node->GetData();
|
wxMenu* menu = node->GetData();
|
||||||
|
|
||||||
const wxString str( wxReplaceUnderscore( label ) );
|
const wxString str(wxConvertMnemonicsToGTK(label));
|
||||||
|
|
||||||
menu->SetTitle( str );
|
menu->SetTitle( str );
|
||||||
|
|
||||||
@@ -785,9 +713,9 @@ wxString wxMenuItemBase::GetLabelText(const wxString& text)
|
|||||||
|
|
||||||
wxString wxMenuItem::GetItemLabel() const
|
wxString wxMenuItem::GetItemLabel() const
|
||||||
{
|
{
|
||||||
wxString label = wxConvertFromGTKToWXLabel(m_text);
|
wxString label = wxConvertMnemonicsFromGTK(m_text);
|
||||||
if (!m_hotKey.IsEmpty())
|
if (!m_hotKey.IsEmpty())
|
||||||
label = label + wxT("\t") + m_hotKey;
|
label << "\t" << m_hotKey;
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
189
src/gtk/mnemonics.cpp
Normal file
189
src/gtk/mnemonics.cpp
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: src/gtk/mnemonics.cpp
|
||||||
|
// Purpose: implementation of GTK mnemonics conversion functions
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2007-11-12
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// for compilers that support precompilation, includes "wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/private/stattext.h" // for wxMarkupEntities
|
||||||
|
|
||||||
|
#include "wx/gtk/private/mnemonics.h"
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// internal helper: apply the operation indicated by flag
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum MnemonicsFlag
|
||||||
|
{
|
||||||
|
MNEMONICS_REMOVE,
|
||||||
|
MNEMONICS_CONVERT,
|
||||||
|
MNEMONICS_CONVERT_MARKUP
|
||||||
|
};
|
||||||
|
|
||||||
|
static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
|
||||||
|
{
|
||||||
|
wxString labelGTK;
|
||||||
|
labelGTK.reserve(label.length());
|
||||||
|
for ( wxString::const_iterator i = label.begin(); i != label.end(); ++i )
|
||||||
|
{
|
||||||
|
wxChar ch = *i;
|
||||||
|
|
||||||
|
switch ( ch )
|
||||||
|
{
|
||||||
|
case wxT('&'):
|
||||||
|
if ( i + 1 == label.end() )
|
||||||
|
{
|
||||||
|
// "&" at the end of string is an error
|
||||||
|
wxLogDebug(wxT("Invalid label \"%s\"."), label);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flag == MNEMONICS_CONVERT_MARKUP )
|
||||||
|
{
|
||||||
|
bool isMnemonic = true;
|
||||||
|
size_t distanceFromEnd = label.end() - i;
|
||||||
|
|
||||||
|
// is this ampersand introducing a mnemonic or rather an entity?
|
||||||
|
for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++)
|
||||||
|
{
|
||||||
|
const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j];
|
||||||
|
size_t entityLen = wxStrlen(entity);
|
||||||
|
|
||||||
|
if (distanceFromEnd >= entityLen &&
|
||||||
|
wxString(i, i + entityLen) == entity)
|
||||||
|
{
|
||||||
|
labelGTK << entity;
|
||||||
|
i += entityLen - 1; // the -1 is because main for()
|
||||||
|
// loop already increments i
|
||||||
|
isMnemonic = false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMnemonic)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = *(++i); // skip '&' itself
|
||||||
|
switch ( ch )
|
||||||
|
{
|
||||||
|
case wxT('&'):
|
||||||
|
// special case: "&&" is not a mnemonic at all but just
|
||||||
|
// an escaped "&"
|
||||||
|
if ( flag == MNEMONICS_CONVERT_MARKUP )
|
||||||
|
labelGTK += wxT("&");
|
||||||
|
else
|
||||||
|
labelGTK += wxT('&');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxT('_'):
|
||||||
|
if ( flag != MNEMONICS_REMOVE )
|
||||||
|
{
|
||||||
|
// '_' can't be a GTK mnemonic apparently so
|
||||||
|
// replace it with something similar
|
||||||
|
labelGTK += wxT("_-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//else: fall through
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ( flag != MNEMONICS_REMOVE )
|
||||||
|
labelGTK += wxT('_');
|
||||||
|
labelGTK += ch;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxT('_'):
|
||||||
|
if ( flag != MNEMONICS_REMOVE )
|
||||||
|
{
|
||||||
|
// escape any existing underlines in the string so that
|
||||||
|
// they don't become mnemonics accidentally
|
||||||
|
labelGTK += wxT("__");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//else: fall through
|
||||||
|
|
||||||
|
default:
|
||||||
|
labelGTK += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return labelGTK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// public functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxString wxGTKRemoveMnemonics(const wxString& label)
|
||||||
|
{
|
||||||
|
return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxConvertMnemonicsToGTK(const wxString& label)
|
||||||
|
{
|
||||||
|
return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxConvertMnemonicsToGTKMarkup(const wxString& label)
|
||||||
|
{
|
||||||
|
return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxConvertMnemonicsFromGTK(const wxString& gtkLabel)
|
||||||
|
{
|
||||||
|
wxString label;
|
||||||
|
for ( const wxChar *pc = gtkLabel.c_str(); *pc; pc++ )
|
||||||
|
{
|
||||||
|
// '_' is the escape character for GTK+.
|
||||||
|
|
||||||
|
if ( *pc == wxT('_') && *(pc+1) == wxT('_'))
|
||||||
|
{
|
||||||
|
// An underscore was escaped.
|
||||||
|
label += wxT('_');
|
||||||
|
pc++;
|
||||||
|
}
|
||||||
|
else if ( *pc == wxT('_') )
|
||||||
|
{
|
||||||
|
// Convert GTK+ hotkey symbol to wxWidgets/Windows standard
|
||||||
|
label += wxT('&');
|
||||||
|
}
|
||||||
|
else if ( *pc == wxT('&') )
|
||||||
|
{
|
||||||
|
// Double the ampersand to escape it as far as wxWidgets is concerned
|
||||||
|
label += wxT("&&");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// don't remove ampersands '&' since if we have them in the menu title
|
||||||
|
// it means that they were doubled to indicate "&" instead of accelerator
|
||||||
|
label += *pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user