]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/mnemonics.cpp
Use "<Application> Preferences" as generic wxPreferencesEditor dialog title.
[wxWidgets.git] / src / gtk / mnemonics.cpp
CommitLineData
b1f17bf0
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/mnemonics.cpp
3// Purpose: implementation of GTK mnemonics conversion functions
4// Author: Vadim Zeitlin
5// Created: 2007-11-12
6// RCS-ID: $Id$
7// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
0c606d12 26#include "wx/log.h"
b1f17bf0
VZ
27#include "wx/gtk/private/mnemonics.h"
28
0d0fdaac
VZ
29namespace
30{
31
32// ----------------------------------------------------------------------------
33// constants
34// ----------------------------------------------------------------------------
35
36// Names of the standard XML entities.
37const char *const entitiesNames[] =
38{
39 "&amp;", "&lt;", "&gt;", "&apos;", "&quot;"
40};
41
42} // anonymous namespace
43
b1f17bf0
VZ
44// ============================================================================
45// implementation
46// ============================================================================
47
48// ----------------------------------------------------------------------------
49// internal helper: apply the operation indicated by flag
50// ----------------------------------------------------------------------------
51
52enum MnemonicsFlag
53{
54 MNEMONICS_REMOVE,
55 MNEMONICS_CONVERT,
56 MNEMONICS_CONVERT_MARKUP
57};
58
59static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
60{
61 wxString labelGTK;
62 labelGTK.reserve(label.length());
63 for ( wxString::const_iterator i = label.begin(); i != label.end(); ++i )
64 {
65 wxChar ch = *i;
66
67 switch ( ch )
68 {
69 case wxT('&'):
70 if ( i + 1 == label.end() )
71 {
72 // "&" at the end of string is an error
73 wxLogDebug(wxT("Invalid label \"%s\"."), label);
74 break;
75 }
76
77 if ( flag == MNEMONICS_CONVERT_MARKUP )
78 {
79 bool isMnemonic = true;
80 size_t distanceFromEnd = label.end() - i;
81
82 // is this ampersand introducing a mnemonic or rather an entity?
0d0fdaac 83 for (size_t j=0; j < WXSIZEOF(entitiesNames); j++)
b1f17bf0 84 {
0d0fdaac 85 const char *entity = entitiesNames[j];
b1f17bf0
VZ
86 size_t entityLen = wxStrlen(entity);
87
88 if (distanceFromEnd >= entityLen &&
89 wxString(i, i + entityLen) == entity)
90 {
91 labelGTK << entity;
92 i += entityLen - 1; // the -1 is because main for()
93 // loop already increments i
94 isMnemonic = false;
95
96 break;
97 }
98 }
99
100 if (!isMnemonic)
101 continue;
102 }
103
104 ch = *(++i); // skip '&' itself
105 switch ( ch )
106 {
107 case wxT('&'):
108 // special case: "&&" is not a mnemonic at all but just
109 // an escaped "&"
110 if ( flag == MNEMONICS_CONVERT_MARKUP )
111 labelGTK += wxT("&amp;");
112 else
113 labelGTK += wxT('&');
114 break;
115
116 case wxT('_'):
117 if ( flag != MNEMONICS_REMOVE )
118 {
119 // '_' can't be a GTK mnemonic apparently so
120 // replace it with something similar
121 labelGTK += wxT("_-");
122 break;
123 }
124 //else: fall through
125
126 default:
127 if ( flag != MNEMONICS_REMOVE )
128 labelGTK += wxT('_');
129 labelGTK += ch;
130 }
131 break;
132
133 case wxT('_'):
134 if ( flag != MNEMONICS_REMOVE )
135 {
136 // escape any existing underlines in the string so that
137 // they don't become mnemonics accidentally
138 labelGTK += wxT("__");
139 break;
140 }
141 //else: fall through
142
143 default:
144 labelGTK += ch;
145 }
146 }
147
148 return labelGTK;
149}
150
151// ----------------------------------------------------------------------------
152// public functions
153// ----------------------------------------------------------------------------
154
155wxString wxGTKRemoveMnemonics(const wxString& label)
156{
157 return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
158}
159
160wxString wxConvertMnemonicsToGTK(const wxString& label)
161{
162 return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
163}
164
165wxString wxConvertMnemonicsToGTKMarkup(const wxString& label)
166{
167 return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP);
168}
169
170wxString wxConvertMnemonicsFromGTK(const wxString& gtkLabel)
171{
172 wxString label;
173 for ( const wxChar *pc = gtkLabel.c_str(); *pc; pc++ )
174 {
175 // '_' is the escape character for GTK+.
176
177 if ( *pc == wxT('_') && *(pc+1) == wxT('_'))
178 {
179 // An underscore was escaped.
180 label += wxT('_');
181 pc++;
182 }
183 else if ( *pc == wxT('_') )
184 {
185 // Convert GTK+ hotkey symbol to wxWidgets/Windows standard
186 label += wxT('&');
187 }
188 else if ( *pc == wxT('&') )
189 {
190 // Double the ampersand to escape it as far as wxWidgets is concerned
191 label += wxT("&&");
192 }
193 else
194 {
195 // don't remove ampersands '&' since if we have them in the menu title
196 // it means that they were doubled to indicate "&" instead of accelerator
197 label += *pc;
198 }
199 }
200
201 return label;
202}
203