]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/mnemonics.cpp
64 bit clean implementation
[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/private/stattext.h" // for wxMarkupEntities
28
29#include "wx/gtk/private/mnemonics.h"
30
31// ============================================================================
32// implementation
33// ============================================================================
34
35// ----------------------------------------------------------------------------
36// internal helper: apply the operation indicated by flag
37// ----------------------------------------------------------------------------
38
39enum MnemonicsFlag
40{
41 MNEMONICS_REMOVE,
42 MNEMONICS_CONVERT,
43 MNEMONICS_CONVERT_MARKUP
44};
45
46static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
47{
48 wxString labelGTK;
49 labelGTK.reserve(label.length());
50 for ( wxString::const_iterator i = label.begin(); i != label.end(); ++i )
51 {
52 wxChar ch = *i;
53
54 switch ( ch )
55 {
56 case wxT('&'):
57 if ( i + 1 == label.end() )
58 {
59 // "&" at the end of string is an error
60 wxLogDebug(wxT("Invalid label \"%s\"."), label);
61 break;
62 }
63
64 if ( flag == MNEMONICS_CONVERT_MARKUP )
65 {
66 bool isMnemonic = true;
67 size_t distanceFromEnd = label.end() - i;
68
69 // is this ampersand introducing a mnemonic or rather an entity?
70 for (size_t j=0; j < wxMARKUP_ENTITY_MAX; j++)
71 {
72 const wxChar *entity = wxMarkupEntities[wxMARKUP_ELEMENT_NAME][j];
73 size_t entityLen = wxStrlen(entity);
74
75 if (distanceFromEnd >= entityLen &&
76 wxString(i, i + entityLen) == entity)
77 {
78 labelGTK << entity;
79 i += entityLen - 1; // the -1 is because main for()
80 // loop already increments i
81 isMnemonic = false;
82
83 break;
84 }
85 }
86
87 if (!isMnemonic)
88 continue;
89 }
90
91 ch = *(++i); // skip '&' itself
92 switch ( ch )
93 {
94 case wxT('&'):
95 // special case: "&&" is not a mnemonic at all but just
96 // an escaped "&"
97 if ( flag == MNEMONICS_CONVERT_MARKUP )
98 labelGTK += wxT("&amp;");
99 else
100 labelGTK += wxT('&');
101 break;
102
103 case wxT('_'):
104 if ( flag != MNEMONICS_REMOVE )
105 {
106 // '_' can't be a GTK mnemonic apparently so
107 // replace it with something similar
108 labelGTK += wxT("_-");
109 break;
110 }
111 //else: fall through
112
113 default:
114 if ( flag != MNEMONICS_REMOVE )
115 labelGTK += wxT('_');
116 labelGTK += ch;
117 }
118 break;
119
120 case wxT('_'):
121 if ( flag != MNEMONICS_REMOVE )
122 {
123 // escape any existing underlines in the string so that
124 // they don't become mnemonics accidentally
125 labelGTK += wxT("__");
126 break;
127 }
128 //else: fall through
129
130 default:
131 labelGTK += ch;
132 }
133 }
134
135 return labelGTK;
136}
137
138// ----------------------------------------------------------------------------
139// public functions
140// ----------------------------------------------------------------------------
141
142wxString wxGTKRemoveMnemonics(const wxString& label)
143{
144 return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
145}
146
147wxString wxConvertMnemonicsToGTK(const wxString& label)
148{
149 return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
150}
151
152wxString wxConvertMnemonicsToGTKMarkup(const wxString& label)
153{
154 return GTKProcessMnemonics(label, MNEMONICS_CONVERT_MARKUP);
155}
156
157wxString wxConvertMnemonicsFromGTK(const wxString& gtkLabel)
158{
159 wxString label;
160 for ( const wxChar *pc = gtkLabel.c_str(); *pc; pc++ )
161 {
162 // '_' is the escape character for GTK+.
163
164 if ( *pc == wxT('_') && *(pc+1) == wxT('_'))
165 {
166 // An underscore was escaped.
167 label += wxT('_');
168 pc++;
169 }
170 else if ( *pc == wxT('_') )
171 {
172 // Convert GTK+ hotkey symbol to wxWidgets/Windows standard
173 label += wxT('&');
174 }
175 else if ( *pc == wxT('&') )
176 {
177 // Double the ampersand to escape it as far as wxWidgets is concerned
178 label += wxT("&&");
179 }
180 else
181 {
182 // don't remove ampersands '&' since if we have them in the menu title
183 // it means that they were doubled to indicate "&" instead of accelerator
184 label += *pc;
185 }
186 }
187
188 return label;
189}
190