1
0
Fork 0

(svn r5944) -Merge TGP (r5578, r5579, r5724, r5726): -Feature: filter for textboxes to only

allow certain patterns (like numbers only)
release/0.5
truelight 2006-08-19 09:31:22 +00:00
parent ee0daa0a4f
commit 83d56d6d79
19 changed files with 95 additions and 57 deletions

View File

@ -202,7 +202,7 @@ static void NewAircraftWndProc(Window *w, WindowEvent *e)
if (sel_eng != INVALID_ENGINE) { if (sel_eng != INVALID_ENGINE) {
WP(w,buildtrain_d).rename_engine = sel_eng; WP(w,buildtrain_d).rename_engine = sel_eng;
ShowQueryString(GetCustomEngineName(sel_eng), ShowQueryString(GetCustomEngineName(sel_eng),
STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w->window_class, w->window_number); STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
} }
} break; } break;
} }
@ -437,7 +437,7 @@ static void AircraftDetailsWndProc(Window *w, WindowEvent *e)
case 2: /* rename */ case 2: /* rename */
v = GetVehicle(w->window_number); v = GetVehicle(w->window_number);
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
ShowQueryString(v->string_id, STR_A030_NAME_AIRCRAFT, 31, 150, w->window_class, w->window_number); ShowQueryString(v->string_id, STR_A030_NAME_AIRCRAFT, 31, 150, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 5: /* increase int */ case 5: /* increase int */
mod = _ctrl_pressed? 5 : 10; mod = _ctrl_pressed? 5 : 10;

View File

@ -181,7 +181,7 @@ static void IConsoleWndProc(Window *w, WindowEvent *e)
} }
break; break;
default: default:
if (IsValidAsciiChar(e->keypress.ascii)) { if (IsValidAsciiChar(e->keypress.ascii, CS_ALPHANUMERAL)) {
_iconsole_scroll = ICON_BUFFER; _iconsole_scroll = ICON_BUFFER;
InsertTextBufferChar(&_iconsole_cmdline, e->keypress.ascii); InsertTextBufferChar(&_iconsole_cmdline, e->keypress.ascii);
IConsoleResetHistoryPos(); IConsoleResetHistoryPos();
@ -1056,7 +1056,7 @@ void IConsoleCmdExec(const char *cmdstr)
if (cmdstr[0] == '#') return; // comments if (cmdstr[0] == '#') return; // comments
for (cmdptr = cmdstr; *cmdptr != '\0'; cmdptr++) { for (cmdptr = cmdstr; *cmdptr != '\0'; cmdptr++) {
if (!IsValidAsciiChar(*cmdptr)) { if (!IsValidAsciiChar(*cmdptr, CS_ALPHANUMERAL)) {
IConsoleError("command contains malformed characters, aborting"); IConsoleError("command contains malformed characters, aborting");
IConsolePrintF(_icolour_err, "ERROR: command was: '%s'", cmdstr); IConsolePrintF(_icolour_err, "ERROR: command was: '%s'", cmdstr);
return; return;

5
gui.h
View File

@ -5,6 +5,7 @@
#include "station.h" #include "station.h"
#include "window.h" #include "window.h"
#include "string.h"
/* main_gui.c */ /* main_gui.c */
void SetupColorsAndInitialWindow(void); void SetupColorsAndInitialWindow(void);
@ -106,7 +107,7 @@ void AskForNewGameToStart(void);
void DrawEditBox(Window *w, querystr_d *string, int wid); void DrawEditBox(Window *w, querystr_d *string, int wid);
void HandleEditBox(Window *w, querystr_d *string, int wid); void HandleEditBox(Window *w, querystr_d *string, int wid);
int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we); int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we, CharSetFilter afilter);
bool HandleCaret(Textbuf *tb); bool HandleCaret(Textbuf *tb);
void DeleteTextBufferAll(Textbuf *tb); void DeleteTextBufferAll(Textbuf *tb);
@ -136,7 +137,7 @@ enum {
bool DoZoomInOutWindow(int how, Window *w); bool DoZoomInOutWindow(int how, Window *w);
void ShowBuildIndustryWindow(void); void ShowBuildIndustryWindow(void);
void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, WindowClass window_class, WindowNumber window_number); void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, WindowClass window_class, WindowNumber window_number, CharSetFilter afilter);
void ShowMusicWindow(void); void ShowMusicWindow(void);
/* main_gui.c */ /* main_gui.c */

View File

@ -381,7 +381,7 @@ static void IndustryViewWndProc(Window *w, WindowEvent *e)
ShowQueryString(STR_CONFIG_PATCHES_INT32, ShowQueryString(STR_CONFIG_PATCHES_INT32,
STR_CONFIG_GAME_PRODUCTION, STR_CONFIG_GAME_PRODUCTION,
10, 100, w->window_class, 10, 100, w->window_class,
w->window_number); w->window_number, CS_ALPHANUMERAL);
} }
} }
} break; } break;

View File

@ -329,21 +329,21 @@ void ShowNetworkGiveMoneyWindow(byte player)
{ {
_rename_id = player; _rename_id = player;
_rename_what = 3; _rename_what = 3;
ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, 180, 1, 0); ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, 180, 1, 0, CS_NUMERAL);
} }
void ShowNetworkNeedGamePassword(void) void ShowNetworkNeedGamePassword(void)
{ {
_rename_id = NETWORK_GAME_PASSWORD; _rename_id = NETWORK_GAME_PASSWORD;
_rename_what = 4; _rename_what = 4;
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_GAME_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0); ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_GAME_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0, CS_ALPHANUMERAL);
} }
void ShowNetworkNeedCompanyPassword(void) void ShowNetworkNeedCompanyPassword(void)
{ {
_rename_id = NETWORK_COMPANY_PASSWORD; _rename_id = NETWORK_COMPANY_PASSWORD;
_rename_what = 4; _rename_what = 4;
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0); ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, 20, 180, WC_SELECT_GAME, 0, CS_ALPHANUMERAL);
} }
#endif /* ENABLE_NETWORK */ #endif /* ENABLE_NETWORK */
@ -352,7 +352,7 @@ void ShowRenameSignWindow(const SignStruct *ss)
{ {
_rename_id = ss->index; _rename_id = ss->index;
_rename_what = 0; _rename_what = 0;
ShowQueryString(ss->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, 1, 0); ShowQueryString(ss->str, STR_280B_EDIT_SIGN_TEXT, 30, 180, 1, 0, CS_ALPHANUMERAL);
} }
void ShowRenameWaypointWindow(const Waypoint *wp) void ShowRenameWaypointWindow(const Waypoint *wp)
@ -369,7 +369,7 @@ void ShowRenameWaypointWindow(const Waypoint *wp)
_rename_id = id; _rename_id = id;
_rename_what = 1; _rename_what = 1;
SetDParam(0, id); SetDParam(0, id);
ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, 1, 0); ShowQueryString(STR_WAYPOINT_RAW, STR_EDIT_WAYPOINT_NAME, 30, 180, 1, 0, CS_ALPHANUMERAL);
} }
static void SelectSignTool(void) static void SelectSignTool(void)

View File

@ -897,7 +897,7 @@ void UpdateTextBufferSize(Textbuf *tb)
tb->caretxoffs = tb->width; tb->caretxoffs = tb->width;
} }
int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we) int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we, CharSetFilter afilter)
{ {
we->keypress.cont = false; we->keypress.cont = false;
@ -921,11 +921,11 @@ int HandleEditBoxKey(Window *w, querystr_d *string, int wid, WindowEvent *we)
InvalidateWidget(w, wid); InvalidateWidget(w, wid);
break; break;
default: default:
if (IsValidAsciiChar(we->keypress.ascii)) { if (IsValidAsciiChar(we->keypress.ascii, afilter)) {
if (InsertTextBufferChar(&string->text, we->keypress.ascii)) if (InsertTextBufferChar(&string->text, we->keypress.ascii))
InvalidateWidget(w, wid); InvalidateWidget(w, wid);
} else { // key wasn't caught } else { // key wasn't caught. Continue only if standard entry specified
we->keypress.cont = true; we->keypress.cont = (afilter == CS_ALPHANUMERAL);
} }
} }
@ -1015,7 +1015,7 @@ press_ok:;
} break; } break;
case WE_KEYPRESS: { case WE_KEYPRESS: {
switch (HandleEditBoxKey(w, &WP(w, querystr_d), 5, e)) { switch (HandleEditBoxKey(w, &WP(w, querystr_d), 5, e, WP(w, querystr_d).afilter)) {
case 1: // Return case 1: // Return
goto press_ok; goto press_ok;
case 2: // Escape case 2: // Escape
@ -1060,7 +1060,7 @@ static const WindowDesc _query_string_desc = {
static char _edit_str_buf[64]; static char _edit_str_buf[64];
static char _orig_str_buf[lengthof(_edit_str_buf)]; static char _orig_str_buf[lengthof(_edit_str_buf)];
void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, WindowClass window_class, WindowNumber window_number) void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, WindowClass window_class, WindowNumber window_number, CharSetFilter afilter)
{ {
Window *w; Window *w;
uint realmaxlen = maxlen & ~0x1000; uint realmaxlen = maxlen & ~0x1000;
@ -1090,6 +1090,7 @@ void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth,
WP(w, querystr_d).text.maxlength = realmaxlen; WP(w, querystr_d).text.maxlength = realmaxlen;
WP(w, querystr_d).text.maxwidth = maxwidth; WP(w, querystr_d).text.maxwidth = maxwidth;
WP(w, querystr_d).text.buf = _edit_str_buf; WP(w, querystr_d).text.buf = _edit_str_buf;
WP(w, querystr_d).afilter = afilter;
UpdateTextBufferSize(&WP(w, querystr_d).text); UpdateTextBufferSize(&WP(w, querystr_d).text);
} }
@ -1358,7 +1359,7 @@ static void SaveLoadDlgWndProc(Window *w, WindowEvent *e)
} }
if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) { if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) /* Press Enter */ if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e, CS_ALPHANUMERAL) == 1) /* Press Enter */
HandleButtonClick(w, 12); HandleButtonClick(w, 12);
} }
break; break;

View File

@ -24,6 +24,7 @@
#include "variables.h" #include "variables.h"
#include "network_server.h" #include "network_server.h"
#include "network_udp.h" #include "network_udp.h"
#include "string.h"
#define BGC 5 #define BGC 5
#define BTC 15 #define BTC 15
@ -430,7 +431,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
31 | 0x1000, // maximum number of characters OR 31 | 0x1000, // maximum number of characters OR
250, // characters up to this width pixels, whichever is satisfied first 250, // characters up to this width pixels, whichever is satisfied first
w->window_class, w->window_class,
w->window_number); w->window_number, CS_ALPHANUMERAL);
} break; } break;
case 13: /* Start server */ case 13: /* Start server */
ShowNetworkStartServerWindow(); ShowNetworkStartServerWindow();
@ -480,7 +481,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
break; break;
} }
if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e, CS_ALPHANUMERAL) == 1) break; // enter pressed
// The name is only allowed when it starts with a letter! // The name is only allowed when it starts with a letter!
if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') { if (_edit_str_buf[0] != '\0' && _edit_str_buf[0] != ' ') {
@ -651,7 +652,7 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
case 4: /* Set password button */ case 4: /* Set password button */
ShowQueryString(BindCString(_network_server_password), ShowQueryString(BindCString(_network_server_password),
STR_NETWORK_SET_PASSWORD, 20, 250, w->window_class, w->window_number); STR_NETWORK_SET_PASSWORD, 20, 250, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 5: { /* Select map */ case 5: { /* Select map */
@ -723,7 +724,7 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
case WE_KEYPRESS: case WE_KEYPRESS:
if (nd->field == 3) { if (nd->field == 3) {
if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e) == 1) break; // enter pressed if (HandleEditBoxKey(w, &WP(w, network_ql_d).q, 3, e, CS_ALPHANUMERAL) == 1) break; // enter pressed
ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name)); ttd_strlcpy(_network_server_name, WP(w, network_ql_d).q.text.buf, sizeof(_network_server_name));
UpdateTextBufferSize(&WP(w, network_ql_d).q.text); UpdateTextBufferSize(&WP(w, network_ql_d).q.text);
@ -1514,7 +1515,7 @@ static void ChatWindowWndProc(Window *w, WindowEvent *e)
break; break;
case WE_KEYPRESS: case WE_KEYPRESS:
switch (HandleEditBoxKey(w, &WP(w, querystr_d), 1, e)) { switch (HandleEditBoxKey(w, &WP(w, querystr_d), 1, e, CS_ALPHANUMERAL)) {
case 1: /* Return */ SendChat(WP(w, querystr_d).text.buf); /* FALLTHROUGH */ case 1: /* Return */ SendChat(WP(w, querystr_d).text.buf); /* FALLTHROUGH */
case 2: /* Escape */ DeleteWindow(w); break; case 2: /* Escape */ DeleteWindow(w); break;
} }

View File

@ -164,7 +164,7 @@ static void TranslateTTDPatchCodes(char *str)
case 0x98: *c = 31; break; case 0x98: *c = 31; break;
default: default:
/* Validate any unhandled character */ /* Validate any unhandled character */
if (!IsValidAsciiChar(*c)) *c = '?'; if (!IsValidAsciiChar(*c, CS_ALPHANUMERAL)) *c = '?';
break; break;
} }
} }

View File

@ -581,14 +581,14 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
const Player *p = GetPlayer(w->window_number); const Player *p = GetPlayer(w->window_number);
WP(w, def_d).byte_1 = 0; WP(w, def_d).byte_1 = 0;
SetDParam(0, p->president_name_2); SetDParam(0, p->president_name_2);
ShowQueryString(p->president_name_1, STR_700B_PRESIDENT_S_NAME, 31, 94, w->window_class, w->window_number); ShowQueryString(p->president_name_1, STR_700B_PRESIDENT_S_NAME, 31, 94, w->window_class, w->window_number, CS_ALPHANUMERAL);
} break; } break;
case 6: {/* change company name */ case 6: {/* change company name */
Player *p = GetPlayer(w->window_number); Player *p = GetPlayer(w->window_number);
WP(w,def_d).byte_1 = 1; WP(w,def_d).byte_1 = 1;
SetDParam(0, p->name_2); SetDParam(0, p->name_2);
ShowQueryString(p->name_1, STR_700A_COMPANY_NAME, 31, 150, w->window_class, w->window_number); ShowQueryString(p->name_1, STR_700A_COMPANY_NAME, 31, 150, w->window_class, w->window_number, CS_ALPHANUMERAL);
} break; } break;
case 7: {/* build hq */ case 7: {/* build hq */
@ -619,7 +619,7 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
if (!IsWindowOfPrototype(w, _other_player_company_widgets)) { if (!IsWindowOfPrototype(w, _other_player_company_widgets)) {
WP(w,def_d).byte_1 = 2; WP(w,def_d).byte_1 = 2;
ShowQueryString(BindCString(_network_player_info[_local_player].password), ShowQueryString(BindCString(_network_player_info[_local_player].password),
STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w->window_class, w->window_number); STR_SET_COMPANY_PASSWORD, sizeof(_network_player_info[_local_player].password), 250, w->window_class, w->window_number, CS_ALPHANUMERAL);
} }
#endif #endif
} break; } break;

View File

@ -241,7 +241,7 @@ static void RoadVehDetailsWndProc(Window *w, WindowEvent *e)
case 2: /* rename */ case 2: /* rename */
v = GetVehicle(w->window_number); v = GetVehicle(w->window_number);
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
ShowQueryString(v->string_id, STR_902C_NAME_ROAD_VEHICLE, 31, 150, w->window_class, w->window_number); ShowQueryString(v->string_id, STR_902C_NAME_ROAD_VEHICLE, 31, 150, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 5: /* increase int */ case 5: /* increase int */
@ -555,7 +555,7 @@ static void NewRoadVehWndProc(Window *w, WindowEvent *e)
if (sel_eng != INVALID_ENGINE) { if (sel_eng != INVALID_ENGINE) {
WP(w,buildtrain_d).rename_engine = sel_eng; WP(w,buildtrain_d).rename_engine = sel_eng;
ShowQueryString(GetCustomEngineName(sel_eng), ShowQueryString(GetCustomEngineName(sel_eng),
STR_9036_RENAME_ROAD_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number); STR_9036_RENAME_ROAD_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
} }
} break; } break;
} }

View File

@ -840,7 +840,7 @@ static void PatchesSelectionWndProc(Window *w, WindowEvent *e)
WP(w,def_d).data_3 = btn; WP(w,def_d).data_3 = btn;
SetDParam(0, value); SetDParam(0, value);
ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, WC_GAME_OPTIONS, 0); ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_CONFIG_PATCHES_QUERY_CAPT, 10, 100, WC_GAME_OPTIONS, 0, CS_NUMERAL);
} }
} }
@ -1138,6 +1138,7 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
int len = 0; int len = 0;
int x = e->click.pt.x; int x = e->click.pt.x;
StringID str = 0; StringID str = 0;
CharSetFilter afilter = CS_ALPHANUMERAL;
switch ( line ) { switch ( line ) {
case 0: // rate case 0: // rate
@ -1154,6 +1155,7 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
str = STR_CONFIG_PATCHES_INT32; str = STR_CONFIG_PATCHES_INT32;
len = 4; len = 4;
edittext = true; edittext = true;
afilter = CS_NUMERAL;
} }
break; break;
case 1: // separator case 1: // separator
@ -1193,6 +1195,7 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
str = STR_CONFIG_PATCHES_INT32; str = STR_CONFIG_PATCHES_INT32;
len = 4; len = 4;
edittext = true; edittext = true;
afilter = CS_NUMERAL;
} }
break; break;
} }
@ -1205,7 +1208,7 @@ static void CustCurrencyWndProc(Window *w, WindowEvent *e)
len + 1, // maximum number of characters OR len + 1, // maximum number of characters OR
250, // characters up to this width pixels, whichever is satisfied first 250, // characters up to this width pixels, whichever is satisfied first
w->window_class, w->window_class,
w->window_number); w->window_number, afilter);
} }
w->flags4 |= 5 << WF_TIMEOUT_SHL; w->flags4 |= 5 << WF_TIMEOUT_SHL;

View File

@ -238,7 +238,7 @@ static void ShipDetailsWndProc(Window *w, WindowEvent *e)
case 2: /* rename */ case 2: /* rename */
v = GetVehicle(w->window_number); v = GetVehicle(w->window_number);
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
ShowQueryString(v->string_id, STR_9831_NAME_SHIP, 31, 150, w->window_class, w->window_number); ShowQueryString(v->string_id, STR_9831_NAME_SHIP, 31, 150, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 5: /* increase int */ case 5: /* increase int */
mod = _ctrl_pressed? 5 : 10; mod = _ctrl_pressed? 5 : 10;
@ -388,7 +388,7 @@ static void NewShipWndProc(Window *w, WindowEvent *e)
if (sel_eng != INVALID_ENGINE) { if (sel_eng != INVALID_ENGINE) {
WP(w,buildtrain_d).rename_engine = sel_eng; WP(w,buildtrain_d).rename_engine = sel_eng;
ShowQueryString(GetCustomEngineName(sel_eng), ShowQueryString(GetCustomEngineName(sel_eng),
STR_9838_RENAME_SHIP_TYPE, 31, 160, w->window_class, w->window_number); STR_9838_RENAME_SHIP_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
} }
} break; } break;
} }

View File

@ -675,7 +675,7 @@ static void StationViewWndProc(Window *w, WindowEvent *e)
case 9: { case 9: {
SetDParam(0, w->window_number); SetDParam(0, w->window_number);
ShowQueryString(STR_STATION, STR_3030_RENAME_STATION_LOADING, 31, 180, w->window_class, w->window_number); ShowQueryString(STR_STATION, STR_3030_RENAME_STATION_LOADING, 31, 180, w->window_class, w->window_number, CS_ALPHANUMERAL);
} break; } break;
case 10: { /* Show a list of scheduled trains to this station */ case 10: { /* Show a list of scheduled trains to this station */

View File

@ -62,10 +62,38 @@ char* CDECL str_fmt(const char* str, ...)
void str_validate(char *str) void str_validate(char *str)
{ {
for (; *str != '\0'; str++) for (; *str != '\0'; str++)
if (!IsValidAsciiChar(*str)) *str = '?'; if (!IsValidAsciiChar(*str, CS_ALPHANUMERAL)) *str = '?';
} }
void strtolower(char *str) void strtolower(char *str)
{ {
for (; *str != '\0'; str++) *str = tolower(*str); for (; *str != '\0'; str++) *str = tolower(*str);
} }
/** Only allow valid ascii-function codes. Filter special codes like BELL and
* so on [we need a special filter here later]
* @param key character to be checked
* @return true or false depending if the character is printable/valid or not */
bool IsValidAsciiChar(byte key, CharSetFilter afilter)
{
// XXX This filter stops certain crashes, but may be too restrictive.
bool firsttest = false;
switch (afilter) {
case CS_ALPHANUMERAL:
firsttest = (key >= ' ' && key < 127);
break;
case CS_NUMERAL://we are quite strict, here
return (key >= 48 && key <= 57);
case CS_ALPHA:
default:
firsttest = ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'));
break;
}
return (firsttest || (key >= 160 &&
key != 0xAA && key != 0xAC && key != 0xAD && key != 0xAF &&
key != 0xB5 && key != 0xB6 && key != 0xB7 && key != 0xB9));
}

View File

@ -32,16 +32,16 @@ void str_validate(char *str);
/** Convert the given string to lowercase */ /** Convert the given string to lowercase */
void strtolower(char *str); void strtolower(char *str);
typedef enum CharSetFilter { //valid char filtering
CS_ALPHANUMERAL, //both numeric and alphabetic
CS_NUMERAL, //only numeric ones.
CS_ALPHA, //only alphabetic values
} CharSetFilter;
/** Only allow valid ascii-function codes. Filter special codes like BELL and /** Only allow valid ascii-function codes. Filter special codes like BELL and
* so on [we need a special filter here later] * so on [we need a special filter here later]
* @param key character to be checked * @param key character to be checked
* @return true or false depending if the character is printable/valid or not */ * @return true or false depending if the character is printable/valid or not */
static inline bool IsValidAsciiChar(byte key) bool IsValidAsciiChar(byte key, CharSetFilter afilter);
{
// XXX This filter stops certain crashes, but may be too restrictive.
return (key >= ' ' && key < 127) || (key >= 160 &&
key != 0xAA && key != 0xAC && key != 0xAD && key != 0xAF &&
key != 0xB5 && key != 0xB6 && key != 0xB7 && key != 0xB9);
}
#endif /* STRING_H */ #endif /* STRING_H */

View File

@ -266,7 +266,7 @@ static void TownViewWndProc(Window *w, WindowEvent *e)
case 8: /* rename */ case 8: /* rename */
SetDParam(0, w->window_number); SetDParam(0, w->window_number);
ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w->window_class, w->window_number); ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 9: /* expand town */ case 9: /* expand town */

View File

@ -277,7 +277,7 @@ static void NewRailVehicleWndProc(Window *w, WindowEvent *e)
if (sel_eng != INVALID_ENGINE) { if (sel_eng != INVALID_ENGINE) {
WP(w,buildtrain_d).rename_engine = sel_eng; WP(w,buildtrain_d).rename_engine = sel_eng;
ShowQueryString(GetCustomEngineName(sel_eng), ShowQueryString(GetCustomEngineName(sel_eng),
STR_886A_RENAME_TRAIN_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number); STR_886A_RENAME_TRAIN_VEHICLE_TYPE, 31, 160, w->window_class, w->window_number, CS_ALPHANUMERAL);
} }
} break; } break;
} }
@ -1269,7 +1269,7 @@ static void TrainDetailsWndProc(Window *w, WindowEvent *e)
case 2: /* name train */ case 2: /* name train */
v = GetVehicle(w->window_number); v = GetVehicle(w->window_number);
SetDParam(0, v->unitnumber); SetDParam(0, v->unitnumber);
ShowQueryString(v->string_id, STR_8865_NAME_TRAIN, 31, 150, w->window_class, w->window_number); ShowQueryString(v->string_id, STR_8865_NAME_TRAIN, 31, 150, w->window_class, w->window_number, CS_ALPHANUMERAL);
break; break;
case 6: /* inc serv interval */ case 6: /* inc serv interval */
mod = _ctrl_pressed? 5 : 10; mod = _ctrl_pressed? 5 : 10;

View File

@ -956,7 +956,7 @@ bool InsertTextBufferClipboard(Textbuf *tb)
data = GlobalLock(cbuf); // clipboard data data = GlobalLock(cbuf); // clipboard data
dataptr = data; dataptr = data;
for (; IsValidAsciiChar(*dataptr) && (tb->length + length) < (tb->maxlength - 1) && for (; IsValidAsciiChar(*dataptr, CS_ALPHANUMERAL) && (tb->length + length) < (tb->maxlength - 1) &&
(tb->maxwidth == 0 || width + tb->width + GetCharacterWidth(FS_NORMAL, (byte)*dataptr) <= tb->maxwidth); dataptr++) { (tb->maxwidth == 0 || width + tb->width + GetCharacterWidth(FS_NORMAL, (byte)*dataptr) <= tb->maxwidth); dataptr++) {
width += GetCharacterWidth(FS_NORMAL, (byte)*dataptr); width += GetCharacterWidth(FS_NORMAL, (byte)*dataptr);
length++; length++;

View File

@ -3,6 +3,8 @@
#ifndef WINDOW_H #ifndef WINDOW_H
#define WINDOW_H #define WINDOW_H
#include "string.h"
typedef union WindowEvent WindowEvent; typedef union WindowEvent WindowEvent;
typedef void WindowProc(Window *w, WindowEvent *e); typedef void WindowProc(Window *w, WindowEvent *e);
@ -244,19 +246,11 @@ typedef struct Textbuf {
uint16 caretxoffs; /* the current position of the caret in pixels */ uint16 caretxoffs; /* the current position of the caret in pixels */
} Textbuf; } Textbuf;
typedef struct querystr_d {
StringID caption;
WindowClass wnd_class;
WindowNumber wnd_num;
Textbuf text;
const char *orig;
} querystr_d;
#define WP(ptr,str) (*(str*)(ptr)->custom) #define WP(ptr,str) (*(str*)(ptr)->custom)
/* You cannot 100% reliably calculate the biggest custom struct as /* You cannot 100% reliably calculate the biggest custom struct as
* the number of pointers in it and alignment will have a huge impact. * the number of pointers in it and alignment will have a huge impact.
* 88 is the largest window-size for 64-bit machines currently */ * 96 is the largest window-size for 64-bit machines currently */
#define WINDOW_CUSTOM_SIZE 88 #define WINDOW_CUSTOM_SIZE 96
typedef struct Scrollbar { typedef struct Scrollbar {
uint16 count, cap, pos; uint16 count, cap, pos;
@ -300,6 +294,16 @@ struct Window {
byte custom[WINDOW_CUSTOM_SIZE]; byte custom[WINDOW_CUSTOM_SIZE];
}; };
typedef struct querystr_d {
StringID caption;
WindowClass wnd_class;
WindowNumber wnd_num;
Textbuf text;
const char *orig;
CharSetFilter afilter;
} querystr_d;
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d));
typedef struct { typedef struct {
byte item_count; /* follow_vehicle */ byte item_count; /* follow_vehicle */
byte sel_index; /* scrollpos_x */ byte sel_index; /* scrollpos_x */