monodll_listbox.o \
monodll_mdi.o \
monodll_menu.o \
+ monodll_mnemonics.o \
monodll_msgdlg.o \
monodll_notebook.o \
monodll_radiobox.o \
monolib_listbox.o \
monolib_mdi.o \
monolib_menu.o \
+ monolib_mnemonics.o \
monolib_msgdlg.o \
monolib_notebook.o \
monolib_radiobox.o \
coredll_listbox.o \
coredll_mdi.o \
coredll_menu.o \
+ coredll_mnemonics.o \
coredll_msgdlg.o \
coredll_notebook.o \
coredll_radiobox.o \
corelib_listbox.o \
corelib_mdi.o \
corelib_menu.o \
+ corelib_mnemonics.o \
corelib_msgdlg.o \
corelib_notebook.o \
corelib_radiobox.o \
monodll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONODLL_ODEP)
$(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)
$(CCC) -c -o $@ $(MONODLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
monolib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(MONOLIB_ODEP)
$(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)
$(CCC) -c -o $@ $(MONOLIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
coredll_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(COREDLL_ODEP)
$(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)
$(CCC) -c -o $@ $(COREDLL_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
corelib_gvfs.o: $(srcdir)/src/gtk/gnome/gvfs.cpp $(CORELIB_ODEP)
$(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)
$(CCC) -c -o $@ $(CORELIB_CFLAGS) $(srcdir)/src/gtk/treeentry_gtk.c
src/gtk/listbox.cpp
src/gtk/mdi.cpp
src/gtk/menu.cpp
+ src/gtk/mnemonics.cpp
src/gtk/msgdlg.cpp
src/gtk/notebook.cpp
src/gtk/radiobox.cpp
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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_
+
bool m_eol;
};
+#endif // wxUSE_STATTEXT
+
enum
{
wxMARKUP_ENTITY_AMP,
//
extern const wxChar *wxMarkupEntities[wxMARKUP_ELEMENT_MAX][wxMARKUP_ENTITY_MAX];
-#endif // wxUSE_STATTEXT
-
#endif // _WX_PRIVATE_STATTEXT_H_
#include "wx/containr.h"
#endif
-#if wxUSE_STATTEXT
-
const wxChar *wxMarkupEntities[][wxMARKUP_ENTITY_MAX] =
{
// the entities handled by SetLabel() when wxST_MARKUP is used and their referenced string
{ wxT("&"), wxT("<"), wxT(">"), wxT("'"), wxT("\"") }
};
+#if wxUSE_STATTEXT
// ----------------------------------------------------------------------------
// wxTextWrapper
#include "wx/fontutil.h"
#include "wx/gtk/private.h"
-#include "wx/private/stattext.h"
-
+#include "wx/gtk/private/mnemonics.h"
// ============================================================================
// wxControl implementation
// 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 */
wxString wxControl::GTKRemoveMnemonics(const wxString& label)
{
- return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
+ return wxGTKRemoveMnemonics(label);
}
/* static */
wxString wxControl::GTKConvertMnemonics(const wxString& label)
{
- return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
+ return wxConvertMnemonicsToGTK(label);
}
/* static */
wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
{
- return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP);
+ return wxConvertMnemonicsToGTKMarkup(label);
}
// ----------------------------------------------------------------------------
#include "wx/accel.h"
#include "wx/stockitem.h"
#include "wx/gtk/private.h"
+#include "wx/gtk/private/mnemonics.h"
// FIXME: is this right? somehow I don't think so (VZ)
static wxString GetGtkHotKey( const wxMenuItem& item );
#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
//-----------------------------------------------------------------------------
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.
menu->SetTitle( str );
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 );
if (res != wxNOT_FOUND)
wxMenu* menu = node->GetData();
- return wxConvertFromGTKToWXLabel(menu->GetTitle());
+ return wxConvertMnemonicsFromGTK(menu->GetTitle());
}
void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label )
wxMenu* menu = node->GetData();
- const wxString str( wxReplaceUnderscore( label ) );
+ const wxString str(wxConvertMnemonicsToGTK(label));
menu->SetTitle( str );
wxString wxMenuItem::GetItemLabel() const
{
- wxString label = wxConvertFromGTKToWXLabel(m_text);
+ wxString label = wxConvertMnemonicsFromGTK(m_text);
if (!m_hotKey.IsEmpty())
- label = label + wxT("\t") + m_hotKey;
+ label << "\t" << m_hotKey;
return label;
}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+