src/misc_gui.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6878 7d1ff2f621c7
child 10210 a2131f7a315d
--- a/src/misc_gui.cpp	Mon Apr 14 20:32:36 2008 +0000
+++ b/src/misc_gui.cpp	Tue Apr 15 00:47:19 2008 +0000
@@ -17,7 +17,7 @@
 #include "textbuf_gui.h"
 #include "viewport_func.h"
 #include "gfx_func.h"
-#include "station.h"
+#include "station_func.h"
 #include "command_func.h"
 #include "player_func.h"
 #include "player_base.h"
@@ -40,6 +40,8 @@
 #include "string_func.h"
 #include "player_gui.h"
 #include "settings_type.h"
+#include "newgrf_cargo.h"
+#include "rail_gui.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -92,29 +94,23 @@
 
 static void Place_LandInfo(TileIndex tile)
 {
-	Player *p;
-	Window *w;
-	Town *t;
-	Money old_money;
-	CommandCost costclear;
-	AcceptedCargo ac;
-	TileDesc td;
-	StringID str;
-
 	DeleteWindowById(WC_LAND_INFO, 0);
 
-	w = AllocateWindowDesc(&_land_info_desc);
+	Window *w = AllocateWindowDesc(&_land_info_desc);
 	WP(w, void_d).data = &_landinfo_data;
 
-	p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : PLAYER_FIRST);
-	t = ClosestTownFromTile(tile, _patches.dist_local_authority);
+	Player *p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : PLAYER_FIRST);
+	Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
-	old_money = p->player_money;
+	Money old_money = p->player_money;
 	p->player_money = INT64_MAX;
-	costclear = DoCommand(tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR);
+	CommandCost costclear = DoCommand(tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR);
 	p->player_money = old_money;
 
 	/* Because build_date is not set yet in every TileDesc, we make sure it is empty */
+	TileDesc td;
+	AcceptedCargo ac;
+
 	td.build_date = 0;
 	GetAcceptedCargo(tile, ac);
 	GetTileDesc(tile, &td);
@@ -126,7 +122,7 @@
 	if (td.owner != OWNER_NONE && td.owner != OWNER_WATER) GetNameOfOwner(td.owner, tile);
 	GetString(_landinfo_data[1], STR_01A7_OWNER, lastof(_landinfo_data[1]));
 
-	str = STR_01A4_COST_TO_CLEAR_N_A;
+	StringID str = STR_01A4_COST_TO_CLEAR_N_A;
 	if (CmdSucceeded(costclear)) {
 		SetDParam(0, costclear.GetCost());
 		str = STR_01A5_COST_TO_CLEAR;
@@ -147,36 +143,33 @@
 	}
 	GetString(_landinfo_data[4], STR_01A8_LOCAL_AUTHORITY, lastof(_landinfo_data[4]));
 
-	{
-		char *p = GetString(_landinfo_data[5], STR_01CE_CARGO_ACCEPTED, lastof(_landinfo_data[5]));
-		bool found = false;
+	char *strp = GetString(_landinfo_data[5], STR_01CE_CARGO_ACCEPTED, lastof(_landinfo_data[5]));
+	bool found = false;
 
-		for (CargoID i = 0; i < NUM_CARGO; ++i) {
-			if (ac[i] > 0) {
-				/* Add a comma between each item. */
-				if (found) {
-					*p++ = ',';
-					*p++ = ' ';
-				}
-				found = true;
+	for (CargoID i = 0; i < NUM_CARGO; ++i) {
+		if (ac[i] > 0) {
+			/* Add a comma between each item. */
+			if (found) {
+				*strp++ = ',';
+				*strp++ = ' ';
+			}
+			found = true;
 
-				/* If the accepted value is less than 8, show it in 1/8:ths */
-				if (ac[i] < 8) {
-					SetDParam(0, ac[i]);
-					SetDParam(1, GetCargo(i)->name);
-					p = GetString(p, STR_01D1_8, lastof(_landinfo_data[5]));
-				} else {
-					p = GetString(p, GetCargo(i)->name, lastof(_landinfo_data[5]));
-				}
+			/* If the accepted value is less than 8, show it in 1/8:ths */
+			if (ac[i] < 8) {
+				SetDParam(0, ac[i]);
+				SetDParam(1, GetCargo(i)->name);
+				strp = GetString(strp, STR_01D1_8, lastof(_landinfo_data[5]));
+			} else {
+				strp = GetString(strp, GetCargo(i)->name, lastof(_landinfo_data[5]));
 			}
 		}
-
-		if (!found) _landinfo_data[5][0] = '\0';
 	}
+	if (!found) _landinfo_data[5][0] = '\0';
 
 	if (td.build_date != 0) {
 		SetDParam(0, td.build_date);
-	GetString(_landinfo_data[6], STR_BUILD_DATE, lastof(_landinfo_data[6]));
+		GetString(_landinfo_data[6], STR_BUILD_DATE, lastof(_landinfo_data[6]));
 	} else {
 		_landinfo_data[6][0] = '\0';
 	}
@@ -265,40 +258,41 @@
 static void AboutWindowProc(Window *w, WindowEvent *e)
 {
 	switch (e->event) {
-	case WE_CREATE: // Set up window counter and start position of scroller
-		WP(w, scroller_d).counter = 5;
-		WP(w, scroller_d).height = w->height - 40;
-		break;
-	case WE_PAINT: {
-		uint i;
-		int y = WP(w, scroller_d).height;
-		DrawWindowWidgets(w);
-
-		/* Show original copyright and revision version */
-		DrawStringCentered(210, 17, STR_00B6_ORIGINAL_COPYRIGHT, TC_FROMSTRING);
-		DrawStringCentered(210, 17 + 10, STR_00B7_VERSION, TC_FROMSTRING);
+		case WE_CREATE: // Set up window counter and start position of scroller
+			WP(w, scroller_d).counter = 5;
+			WP(w, scroller_d).height = w->height - 40;
+			break;
 
-		/* Show all scrolling credits */
-		for (i = 0; i < lengthof(credits); i++) {
-			if (y >= 50 && y < (w->height - 40)) {
-				DoDrawString(credits[i], 10, y, TC_BLACK);
-			}
-			y += 10;
-		}
+		case WE_PAINT: {
+			int y = WP(w, scroller_d).height;
+			DrawWindowWidgets(w);
 
-		/* If the last text has scrolled start anew from the start */
-		if (y < 50) WP(w, scroller_d).height = w->height - 40;
+			/* Show original copyright and revision version */
+			DrawStringCentered(210, 17, STR_00B6_ORIGINAL_COPYRIGHT, TC_FROMSTRING);
+			DrawStringCentered(210, 17 + 10, STR_00B7_VERSION, TC_FROMSTRING);
 
-		DoDrawStringCentered(210, w->height - 25, "Website: http://www.openttd.org", TC_BLACK);
-		DrawStringCentered(210, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, TC_FROMSTRING);
-	} break;
-	case WE_TICK: // Timer to scroll the text and adjust the new top
-		if (--WP(w, scroller_d).counter == 0) {
-			WP(w, scroller_d).counter = 5;
-			WP(w, scroller_d).height--;
-			SetWindowDirty(w);
-		}
-		break;
+			/* Show all scrolling credits */
+			for (uint i = 0; i < lengthof(credits); i++) {
+				if (y >= 50 && y < (w->height - 40)) {
+					DoDrawString(credits[i], 10, y, TC_BLACK);
+				}
+				y += 10;
+			}
+
+			/* If the last text has scrolled start anew from the start */
+			if (y < 50) WP(w, scroller_d).height = w->height - 40;
+
+			DoDrawStringCentered(210, w->height - 25, "Website: http://www.openttd.org", TC_BLACK);
+			DrawStringCentered(210, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, TC_FROMSTRING);
+		} break;
+
+		case WE_TICK: // Timer to scroll the text and adjust the new top
+			if (--WP(w, scroller_d).counter == 0) {
+				WP(w, scroller_d).counter = 5;
+				WP(w, scroller_d).height--;
+				SetWindowDirty(w);
+			}
+			break;
 	}
 }
 
@@ -343,82 +337,85 @@
 static void BuildTreesWndProc(Window *w, WindowEvent *e)
 {
 	switch (e->event) {
-	case WE_PAINT: {
-		int x,y;
-		int i, count;
-
-		DrawWindowWidgets(w);
-
-		WP(w, tree_d).base = i = _tree_base_by_landscape[_opt.landscape];
-		WP(w, tree_d).count = count = _tree_count_by_landscape[_opt.landscape];
-
-		x = 18;
-		y = 54;
-		do {
-			DrawSprite(_tree_sprites[i].sprite, _tree_sprites[i].pal, x, y);
-			x += 35;
-			if (!(++i & 3)) {
-				x -= 35 * 4;
-				y += 47;
-			}
-		} while (--count);
-	} break;
-
-	case WE_CLICK: {
-		int wid = e->we.click.widget;
-
-		switch (wid) {
-		case 0:
+		case WE_CREATE:
 			ResetObjectToPlace();
 			break;
 
-		case 3: case 4: case 5: case 6:
-		case 7: case 8: case 9: case 10:
-		case 11:case 12: case 13: case 14:
-			if (wid - 3 >= WP(w, tree_d).count) break;
+		case WE_PAINT: {
+			DrawWindowWidgets(w);
 
-			if (HandlePlacePushButton(w, wid, SPR_CURSOR_TREE, VHM_RECT, NULL))
-				_tree_to_plant = WP(w, tree_d).base + wid - 3;
-			break;
+			int i = WP(w, tree_d).base = _tree_base_by_landscape[_opt.landscape];
+			int count = WP(w, tree_d).count = _tree_count_by_landscape[_opt.landscape];
 
-		case 15: // tree of random type.
-			if (HandlePlacePushButton(w, 15, SPR_CURSOR_TREE, VHM_RECT, NULL))
-				_tree_to_plant = -1;
+			int x = 18;
+			int y = 54;
+			do {
+				DrawSprite(_tree_sprites[i].sprite, _tree_sprites[i].pal, x, y);
+				x += 35;
+				if (!(++i & 3)) {
+					x -= 35 * 4;
+					y += 47;
+				}
+			} while (--count);
+		} break;
+
+		case WE_CLICK: {
+			int wid = e->we.click.widget;
+
+			switch (wid) {
+				case 0:
+					ResetObjectToPlace();
+					break;
+
+				case 3: case 4: case 5: case 6:
+				case 7: case 8: case 9: case 10:
+				case 11:case 12: case 13: case 14:
+					if (wid - 3 >= WP(w, tree_d).count) break;
+
+					if (HandlePlacePushButton(w, wid, SPR_CURSOR_TREE, VHM_RECT, NULL)) {
+						_tree_to_plant = WP(w, tree_d).base + wid - 3;
+					}
+					break;
+
+				case 15: // tree of random type.
+					if (HandlePlacePushButton(w, 15, SPR_CURSOR_TREE, VHM_RECT, NULL)) {
+						_tree_to_plant = -1;
+					}
+					break;
+
+				case 16: // place trees randomly over the landscape
+					w->LowerWidget(16);
+					w->flags4 |= 5 << WF_TIMEOUT_SHL;
+					SndPlayFx(SND_15_BEEP);
+					PlaceTreesRandomly();
+					MarkWholeScreenDirty();
+					break;
+			}
+		} break;
+
+		case WE_PLACE_OBJ:
+			VpStartPlaceSizing(e->we.place.tile, VPM_X_AND_Y_LIMITED, DDSP_PLANT_TREES);
+			VpSetPlaceSizingLimit(20);
 			break;
 
-		case 16: // place trees randomly over the landscape
-			w->LowerWidget(16);
-			w->flags4 |= 5 << WF_TIMEOUT_SHL;
-			SndPlayFx(SND_15_BEEP);
-			PlaceTreesRandomly();
-			MarkWholeScreenDirty();
-			break;
-		}
-	} break;
-
-	case WE_PLACE_OBJ:
-		VpStartPlaceSizing(e->we.place.tile, VPM_X_AND_Y_LIMITED, DDSP_PLANT_TREES);
-		VpSetPlaceSizingLimit(20);
-		break;
+		case WE_PLACE_DRAG:
+			VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method);
+			return;
 
-	case WE_PLACE_DRAG:
-		VpSelectTilesWithMethod(e->we.place.pt.x, e->we.place.pt.y, e->we.place.select_method);
-		return;
+		case WE_PLACE_MOUSEUP:
+			if (e->we.place.pt.x != -1 && e->we.place.select_proc == DDSP_PLANT_TREES) {
+				DoCommandP(e->we.place.tile, _tree_to_plant, e->we.place.starttile, NULL,
+					CMD_PLANT_TREE | CMD_MSG(STR_2805_CAN_T_PLANT_TREE_HERE));
+			}
+			break;
 
-	case WE_PLACE_MOUSEUP:
-		if (e->we.place.pt.x != -1 && e->we.place.select_proc == DDSP_PLANT_TREES) {
-			DoCommandP(e->we.place.tile, _tree_to_plant, e->we.place.starttile, NULL,
-				CMD_PLANT_TREE | CMD_MSG(STR_2805_CAN_T_PLANT_TREE_HERE));
-		}
-		break;
+		case WE_TIMEOUT:
+			w->RaiseWidget(16);
+			break;
 
-	case WE_TIMEOUT:
-		w->RaiseWidget(16);
-		break;
-
-	case WE_ABORT_PLACE_OBJ:
-		w->RaiseButtons();
-		break;
+		case WE_ABORT_PLACE_OBJ:
+			w->RaiseButtons();
+			break;
 	}
 }
 
@@ -513,83 +510,80 @@
 static void ErrmsgWndProc(Window *w, WindowEvent *e)
 {
 	switch (e->event) {
-	case WE_PAINT:
-		CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
-		DrawWindowWidgets(w);
-		CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
+		case WE_PAINT:
+			CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
+			DrawWindowWidgets(w);
+			CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params));
 
-		/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages.
-		 * If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything
-		 */
-		SwitchToErrorRefStack();
-		RewindTextRefStack();
+			/* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages.
+			* If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything
+			*/
+			SwitchToErrorRefStack();
+			RewindTextRefStack();
 
-		if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) {
-			DrawStringMultiCenter(
-				120,
-				(_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15),
-				_errmsg_message_2,
-				w->width - 2);
-			if (_errmsg_message_1 != INVALID_STRING_ID)
+			if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) {
 				DrawStringMultiCenter(
 					120,
-					30,
-					_errmsg_message_1,
+					(_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15),
+					_errmsg_message_2,
 					w->width - 2);
-		} else {
-			const Player *p = GetPlayer((PlayerID)GetDParamX(_errmsg_decode_params,2));
-			DrawPlayerFace(p->face, p->player_color, 2, 16);
+				if (_errmsg_message_1 != INVALID_STRING_ID) {
+					DrawStringMultiCenter(
+						120,
+						30,
+						_errmsg_message_1,
+						w->width - 2);
+				}
+			} else {
+				const Player *p = GetPlayer((PlayerID)GetDParamX(_errmsg_decode_params,2));
+				DrawPlayerFace(p->face, p->player_color, 2, 16);
 
-			DrawStringMultiCenter(
-				214,
-				(_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45),
-				_errmsg_message_2,
-				w->width - 2);
-			if (_errmsg_message_1 != INVALID_STRING_ID)
 				DrawStringMultiCenter(
 					214,
-					90,
-					_errmsg_message_1,
+					(_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45),
+					_errmsg_message_2,
 					w->width - 2);
-		}
-
-		/* Switch back to the normal text ref. stack for NewGRF texts */
-		SwitchToNormalRefStack();
-		break;
-
-	case WE_MOUSELOOP:
-		if (_right_button_down) DeleteWindow(w);
-		break;
+				if (_errmsg_message_1 != INVALID_STRING_ID) {
+					DrawStringMultiCenter(
+						214,
+						90,
+						_errmsg_message_1,
+						w->width - 2);
+				}
+			}
 
-	case WE_4:
-		if (--_errmsg_duration == 0) DeleteWindow(w);
-		break;
+			/* Switch back to the normal text ref. stack for NewGRF texts */
+			SwitchToNormalRefStack();
+			break;
 
-	case WE_DESTROY:
-		SetRedErrorSquare(0);
-		_switch_mode_errorstr = INVALID_STRING_ID;
-		break;
+		case WE_MOUSELOOP:
+			if (_right_button_down) DeleteWindow(w);
+			break;
 
-	case WE_KEYPRESS:
-		if (e->we.keypress.keycode == WKC_SPACE) {
-			/* Don't continue. */
-			e->we.keypress.cont = false;
-			DeleteWindow(w);
-		}
-		break;
+		case WE_4:
+			if (--_errmsg_duration == 0) DeleteWindow(w);
+			break;
+
+		case WE_DESTROY:
+			SetRedErrorSquare(0);
+			_switch_mode_errorstr = INVALID_STRING_ID;
+			break;
+
+		case WE_KEYPRESS:
+			if (e->we.keypress.keycode == WKC_SPACE) {
+				/* Don't continue. */
+				e->we.keypress.cont = false;
+				DeleteWindow(w);
+			}
+			break;
 	}
 }
 
 void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y)
 {
-	Window *w;
-	const ViewPort *vp;
-	Point pt;
-
 	DeleteWindowById(WC_ERRMSG, 0);
 
-	//assert(msg_2);
-	if (msg_2 == 0) msg_2 = STR_EMPTY;
+	if (msg_2 == STR_NULL) msg_2 = STR_EMPTY;
 
 	_errmsg_message_1 = msg_1;
 	_errmsg_message_2 = msg_2;
@@ -597,9 +591,12 @@
 	_errmsg_duration = _patches.errmsg_duration;
 	if (!_errmsg_duration) return;
 
+	Point pt;
+	const ViewPort *vp;
+	Window *w;
+
 	if (_errmsg_message_1 != STR_013B_OWNED_BY || GetDParamX(_errmsg_decode_params,2) >= 8) {
-
-		if ( (x|y) != 0) {
+		if ((x | y) != 0) {
 			pt = RemapCoords2(x, y);
 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 
@@ -617,7 +614,7 @@
 		}
 		w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
 	} else {
-		if ( (x|y) != 0) {
+		if ((x | y) != 0) {
 			pt = RemapCoords2(x, y);
 			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 			pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
@@ -647,10 +644,9 @@
 
 void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
 {
-	StringID msg;
 	Point pt = RemapCoords(x,y,z);
+	StringID msg = STR_0801_COST;
 
-	msg = STR_0801_COST;
 	if (cost < 0) {
 		cost = -cost;
 		msg = STR_0803_INCOME;
@@ -699,17 +695,15 @@
 static void TooltipsWndProc(Window *w, WindowEvent *e)
 {
 	switch (e->event) {
-		case WE_PAINT: {
-			uint arg;
+		case WE_PAINT:
 			GfxFillRect(0, 0, w->width - 1, w->height - 1, 0);
 			GfxFillRect(1, 1, w->width - 2, w->height - 2, 0x44);
 
-			for (arg = 0; arg < WP(w, tooltips_d).paramcount; arg++) {
+			for (uint arg = 0; arg < WP(w, tooltips_d).paramcount; arg++) {
 				SetDParam(arg, WP(w, tooltips_d).params[arg]);
 			}
 			DrawStringMultiCenter((w->width >> 1), (w->height >> 1) - 5, WP(w, tooltips_d).string_id, w->width - 2);
 			break;
-		}
 
 		case WE_MOUSELOOP:
 			/* We can show tooltips while dragging tools. These are shown as long as
@@ -731,21 +725,16 @@
  * added to a tooltip; currently only supports parameters of {NUM} (integer) */
 void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint64 params[])
 {
-	char buffer[512];
-	Dimension br;
-	Window *w;
-	uint i;
-	int x, y;
-
 	DeleteWindowById(WC_TOOLTIPS, 0);
 
 	/* We only show measurement tooltips with patch setting on */
 	if (str == STR_NULL || (paramcount != 0 && !_patches.measure_tooltip)) return;
 
-	for (i = 0; i != paramcount; i++) SetDParam(i, params[i]);
+	for (uint i = 0; i != paramcount; i++) SetDParam(i, params[i]);
+	char buffer[512];
 	GetString(buffer, str, lastof(buffer));
 
-	br = GetStringBoundingBox(buffer);
+	Dimension br = GetStringBoundingBox(buffer);
 	br.width += 6; br.height += 4; // increase slightly to have some space around the box
 
 	/* Cut tooltip length to 200 pixels max, wrap to new line if longer */
@@ -757,11 +746,11 @@
 	/* Correctly position the tooltip position, watch out for window and cursor size
 	 * Clamp value to below main toolbar and above statusbar. If tooltip would
 	 * go below window, flip it so it is shown above the cursor */
-	y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, 22, _screen.height - 12);
+	int y = Clamp(_cursor.pos.y + _cursor.size.y + _cursor.offs.y + 5, 22, _screen.height - 12);
 	if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5;
-	x = Clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
+	int x = Clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
 
-	w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
+	Window *w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
 
 	WP(w, tooltips_d).string_id = str;
 	assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0]));
@@ -774,13 +763,12 @@
 }
 
 
-static int DrawStationCoverageText(const AcceptedCargo accepts,
-	int str_x, int str_y, StationCoverageType sct)
+static int DrawStationCoverageText(const AcceptedCargo cargo,
+	int str_x, int str_y, StationCoverageType sct, bool supplies)
 {
-	char *b = _userstring;
 	bool first = true;
 
-	b = InlineString(b, STR_000D_ACCEPTS);
+	char *b = InlineString(_userstring, supplies ? STR_SUPPLIES : STR_000D_ACCEPTS);
 
 	for (CargoID i = 0; i < NUM_CARGO; i++) {
 		if (b >= lastof(_userstring) - (1 + 2 * 4)) break; // ',' or ' ' and two calls to Utf8Encode()
@@ -790,7 +778,7 @@
 			case SCT_ALL: break;
 			default: NOT_REACHED();
 		}
-		if (accepts[i] >= 8) {
+		if (cargo[i] >= (supplies ? 1 : 8)) {
 			if (first) {
 				first = false;
 			} else {
@@ -813,13 +801,26 @@
 	return DrawStringMultiLine(str_x, str_y, STR_SPEC_USERSTRING, 144);
 }
 
-int DrawStationCoverageAreaText(int sx, int sy, StationCoverageType sct, int rad)
+/**
+ * Calculates and draws the accepted or supplied cargo around the selected tile(s)
+ * @param sx x position where the string is to be drawn
+ * @param sy y position where the string is to be drawn
+ * @param sct which type of cargo is to be displayed (passengers/non-passengers)
+ * @param rad radius around selected tile(s) to be searched
+ * @param supplies if supplied cargos should be drawn, else accepted cargos
+ * @return Returns the y value below the string that was drawn
+ */
+int DrawStationCoverageAreaText(int sx, int sy, StationCoverageType sct, int rad, bool supplies)
 {
 	TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y);
-	AcceptedCargo accepts;
+	AcceptedCargo cargo;
 	if (tile < MapSize()) {
-		GetAcceptanceAroundTiles(accepts, tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE , rad);
-		return sy + DrawStationCoverageText(accepts, sx, sy, sct);
+		if (supplies) {
+			GetProductionAroundTiles(cargo, tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE , rad);
+		} else {
+			GetAcceptanceAroundTiles(cargo, tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE , rad);
+		}
+		return sy + DrawStationCoverageText(cargo, sx, sy, sct, supplies);
 	}
 
 	return sy;
@@ -863,14 +864,12 @@
 static void DelChar(Textbuf *tb, bool backspace)
 {
 	WChar c;
-	uint width;
-	size_t len;
 	char *s = tb->buf + tb->caretpos;
 
 	if (backspace) s = Utf8PrevChar(s);
 
-	len = Utf8Decode(&c, s);
-	width = GetCharacterWidth(FS_NORMAL, c);
+	size_t len = Utf8Decode(&c, s);
+	uint width = GetCharacterWidth(FS_NORMAL, c);
 
 	tb->width  -= width;
 	if (backspace) {
@@ -949,35 +948,41 @@
 bool MoveTextBufferPos(Textbuf *tb, int navmode)
 {
 	switch (navmode) {
-	case WKC_LEFT:
-		if (tb->caretpos != 0) {
-			WChar c;
-			const char *s = Utf8PrevChar(tb->buf + tb->caretpos);
-			Utf8Decode(&c, s);
-			tb->caretpos    = s - tb->buf; // -= (tb->buf + tb->caretpos - s)
-			tb->caretxoffs -= GetCharacterWidth(FS_NORMAL, c);
+		case WKC_LEFT:
+			if (tb->caretpos != 0) {
+				WChar c;
+				const char *s = Utf8PrevChar(tb->buf + tb->caretpos);
+				Utf8Decode(&c, s);
+				tb->caretpos    = s - tb->buf; // -= (tb->buf + tb->caretpos - s)
+				tb->caretxoffs -= GetCharacterWidth(FS_NORMAL, c);
 
+				return true;
+			}
+			break;
+
+		case WKC_RIGHT:
+			if (tb->caretpos < tb->length) {
+				WChar c;
+
+				tb->caretpos   += Utf8Decode(&c, tb->buf + tb->caretpos);
+				tb->caretxoffs += GetCharacterWidth(FS_NORMAL, c);
+
+				return true;
+			}
+			break;
+
+		case WKC_HOME:
+			tb->caretpos = 0;
+			tb->caretxoffs = 0;
 			return true;
-		}
-		break;
-	case WKC_RIGHT:
-		if (tb->caretpos < tb->length) {
-			WChar c;
 
-			tb->caretpos   += Utf8Decode(&c, tb->buf + tb->caretpos);
-			tb->caretxoffs += GetCharacterWidth(FS_NORMAL, c);
-
+		case WKC_END:
+			tb->caretpos = tb->length;
+			tb->caretxoffs = tb->width;
 			return true;
-		}
-		break;
-	case WKC_HOME:
-		tb->caretpos = 0;
-		tb->caretxoffs = 0;
-		return true;
-	case WKC_END:
-		tb->caretpos = tb->length;
-		tb->caretxoffs = tb->width;
-		return true;
+
+		default:
+			break;
 	}
 
 	return false;
@@ -1029,32 +1034,33 @@
 	e->we.keypress.cont = false;
 
 	switch (e->we.keypress.keycode) {
-	case WKC_ESC: return 2;
-	case WKC_RETURN: case WKC_NUM_ENTER: return 1;
-	case (WKC_CTRL | 'V'):
-		if (InsertTextBufferClipboard(&string->text))
-			w->InvalidateWidget(wid);
-		break;
-	case (WKC_CTRL | 'U'):
-		DeleteTextBufferAll(&string->text);
-		w->InvalidateWidget(wid);
-		break;
-	case WKC_BACKSPACE: case WKC_DELETE:
-		if (DeleteTextBufferChar(&string->text, e->we.keypress.keycode))
+		case WKC_ESC: return 2;
+
+		case WKC_RETURN: case WKC_NUM_ENTER: return 1;
+
+		case (WKC_CTRL | 'V'):
+			if (InsertTextBufferClipboard(&string->text)) w->InvalidateWidget(wid);
+			break;
+
+		case (WKC_CTRL | 'U'):
+			DeleteTextBufferAll(&string->text);
 			w->InvalidateWidget(wid);
-		break;
-	case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
-		if (MoveTextBufferPos(&string->text, e->we.keypress.keycode))
-			w->InvalidateWidget(wid);
-		break;
-	default:
-		if (IsValidChar(e->we.keypress.key, string->afilter)) {
-			if (InsertTextBufferChar(&string->text, e->we.keypress.key)) {
-				w->InvalidateWidget(wid);
+			break;
+
+		case WKC_BACKSPACE: case WKC_DELETE:
+			if (DeleteTextBufferChar(&string->text, e->we.keypress.keycode)) w->InvalidateWidget(wid);
+			break;
+
+		case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
+			if (MoveTextBufferPos(&string->text, e->we.keypress.keycode)) w->InvalidateWidget(wid);
+			break;
+
+		default:
+			if (IsValidChar(e->we.keypress.key, string->afilter)) {
+				if (InsertTextBufferChar(&string->text, e->we.keypress.key)) w->InvalidateWidget(wid);
+			} else { // key wasn't caught. Continue only if standard entry specified
+				e->we.keypress.cont = (string->afilter == CS_ALPHANUMERAL);
 			}
-		} else { // key wasn't caught. Continue only if standard entry specified
-			e->we.keypress.cont = (string->afilter == CS_ALPHANUMERAL);
-		}
 	}
 
 	return 0;
@@ -1079,26 +1085,31 @@
 
 void DrawEditBox(Window *w, querystr_d *string, int wid)
 {
-	DrawPixelInfo dpi, *old_dpi;
-	int delta;
 	const Widget *wi = &w->widget[wid];
-	const Textbuf *tb = &string->text;
+
+	assert((wi->type & WWT_MASK) == WWT_EDITBOX);
 
 	GfxFillRect(wi->left + 1, wi->top + 1, wi->right - 1, wi->bottom - 1, 215);
 
+	DrawPixelInfo dpi;
+	int delta;
+
 	/* Limit the drawing of the string inside the widget boundaries */
 	if (!FillDrawPixelInfo(&dpi,
-	      wi->left + 4,
-	      wi->top + 1,
-	      wi->right - wi->left - 4,
-	      wi->bottom - wi->top - 1)
-	) return;
+			wi->left + 4,
+			wi->top + 1,
+			wi->right - wi->left - 4,
+			wi->bottom - wi->top - 1)) {
+		return;
+	}
 
-	old_dpi = _cur_dpi;
+	DrawPixelInfo *old_dpi = _cur_dpi;
 	_cur_dpi = &dpi;
 
 	/* We will take the current widget length as maximum width, with a small
 	 * space reserved at the end for the caret to show */
+	const Textbuf *tb = &string->text;
+
 	delta = (wi->right - wi->left) - tb->width - 10;
 	if (delta > 0) delta = 0;
 
@@ -1135,6 +1146,10 @@
 
 		case WE_CLICK:
 			switch (e->we.click.widget) {
+				case QUERY_STR_WIDGET_TEXT:
+					ShowOnScreenKeyboard(w, &WP(w, querystr_d), QUERY_STR_WIDGET_TEXT, QUERY_STR_WIDGET_CANCEL, QUERY_STR_WIDGET_OK);
+					break;
+
 				case QUERY_STR_WIDGET_OK:
 		press_ok:;
 					if (qs->orig == NULL || strcmp(qs->text.buf, qs->orig) != 0) {
@@ -1188,7 +1203,7 @@
 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,        STR_018B_CLOSE_WINDOW},
 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   259,     0,    13, STR_012D,        STR_NULL},
 {      WWT_PANEL,   RESIZE_NONE,    14,     0,   259,    14,    29, 0x0,             STR_NULL},
-{      WWT_PANEL,   RESIZE_NONE,    14,     2,   257,    16,    27, 0x0,             STR_NULL},
+{    WWT_EDITBOX,   RESIZE_NONE,    14,     2,   257,    16,    27, 0x0,             STR_NULL},
 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,   129,    30,    41, STR_012E_CANCEL, STR_NULL},
 {    WWT_TEXTBTN,   RESIZE_NONE,    14,   130,   259,    30,    41, STR_012F_OK,     STR_NULL},
 {   WIDGETS_END},
@@ -1202,7 +1217,8 @@
 	QueryStringWndProc
 };
 
-static char _edit_str_buf[64];
+char _edit_str_buf[64];
+char _orig_str_buf[lengthof(_edit_str_buf)];
 
 /** Show a query popup window with a textbox in it.
  * @param str StringID for the text shown in the textbox
@@ -1215,8 +1231,6 @@
  * @param afilter filters out unwanted character input */
 void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, Window *parent, CharSetFilter afilter)
 {
-	static char orig_str_buf[lengthof(_edit_str_buf)];
-	Window *w;
 	uint realmaxlen = maxlen & ~0x1000;
 
 	assert(realmaxlen < lengthof(_edit_str_buf));
@@ -1224,7 +1238,7 @@
 	DeleteWindowById(WC_QUERY_STRING, 0);
 	DeleteWindowById(WC_SAVELOAD, 0);
 
-	w = AllocateWindowDesc(&_query_string_desc);
+	Window *w = AllocateWindowDesc(&_query_string_desc);
 	w->parent = parent;
 
 	GetString(_edit_str_buf, str, lastof(_edit_str_buf));
@@ -1233,8 +1247,8 @@
 	if (maxlen & 0x1000) {
 		WP(w, querystr_d).orig = NULL;
 	} else {
-		strecpy(orig_str_buf, _edit_str_buf, lastof(orig_str_buf));
-		WP(w, querystr_d).orig = orig_str_buf;
+		strecpy(_orig_str_buf, _edit_str_buf, lastof(_orig_str_buf));
+		WP(w, querystr_d).orig = _orig_str_buf;
 	}
 
 	w->LowerWidget(QUERY_STR_WIDGET_TEXT);
@@ -1379,7 +1393,7 @@
 {      WWT_INSET,     RESIZE_RB,    14,     2,   243,    50,   150, 0x0,              STR_400A_LIST_OF_DRIVES_DIRECTORIES},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   245,   256,    60,   151, 0x0,              STR_0190_SCROLL_BAR_SCROLLS_LIST},
 {      WWT_PANEL,    RESIZE_RTB,    14,     0,   256,   152,   167, 0x0,              STR_NULL},
-{      WWT_PANEL,    RESIZE_RTB,    14,     2,   254,   154,   165, 0x0,              STR_400B_CURRENTLY_SELECTED_NAME},
+{    WWT_EDITBOX,    RESIZE_RTB,    14,     2,   254,   154,   165, STR_SAVE_OSKTITLE,STR_400B_CURRENTLY_SELECTED_NAME},
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   127,   168,   179, STR_4003_DELETE,  STR_400C_DELETE_THE_CURRENTLY_SELECTED},
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,   128,   244,   168,   179, STR_4002_SAVE,    STR_400D_SAVE_THE_CURRENT_GAME_USING},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   245,   256,   168,   179, 0x0,              STR_RESIZE_BUTTON},
@@ -1429,14 +1443,12 @@
 {
 	uint sort_start = 0;
 	uint sort_end = 0;
-	uint s_amount;
-	int i;
 
 	/* Directories are always above the files (FIOS_TYPE_DIR)
 	 * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
 	 * Only sort savegames/scenarios, not directories
 	 */
-	for (i = 0; i < _fios_num; i++) {
+	for (int i = 0; i < _fios_num; i++) {
 		switch (_fios_list[i].type) {
 			case FIOS_TYPE_DIR:    sort_start++; break;
 			case FIOS_TYPE_PARENT: sort_start++; break;
@@ -1444,14 +1456,15 @@
 		}
 	}
 
-	s_amount = _fios_num - sort_start - sort_end;
-	if (s_amount > 0)
+	uint s_amount = _fios_num - sort_start - sort_end;
+	if (s_amount > 0) {
 		qsort(_fios_list + sort_start, s_amount, sizeof(FiosItem), compare_FiosItems);
+	}
 }
 
 static void GenerateFileName()
 {
-	/* Check if we are not a specatator who wants to generate a name..
+	/* Check if we are not a spectator who wants to generate a name..
 	    Let's use the name of player #0 for now. */
 	const Player *p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : PLAYER_FIRST);
 
@@ -1468,192 +1481,201 @@
 	static FiosItem o_dir;
 
 	switch (e->event) {
-	case WE_CREATE: // Set up OPENTTD button
-		w->vscroll.cap = 10;
-		w->resize.step_width = 2;
-		w->resize.step_height = 10;
-
-		o_dir.type = FIOS_TYPE_DIRECT;
-		switch (_saveload_mode) {
-			case SLD_SAVE_GAME:
-			case SLD_LOAD_GAME:
-				FioGetDirectory(o_dir.name, lengthof(o_dir.name), SAVE_DIR);
-				break;
-
-			case SLD_SAVE_SCENARIO:
-			case SLD_LOAD_SCENARIO:
-				FioGetDirectory(o_dir.name, lengthof(o_dir.name), SCENARIO_DIR);
-				break;
-
-			case SLD_LOAD_HEIGHTMAP:
-				FioGetDirectory(o_dir.name, lengthof(o_dir.name), HEIGHTMAP_DIR);
-				break;
-
-			default:
-				ttd_strlcpy(o_dir.name, _personal_dir, lengthof(o_dir.name));
-		}
-		break;
-
-	case WE_PAINT: {
-		int pos;
-		int y;
+		case WE_CREATE: // Set up OPENTTD button
+			w->vscroll.cap = 10;
+			w->resize.step_width = 2;
+			w->resize.step_height = 10;
 
-		SetVScrollCount(w, _fios_num);
-		DrawWindowWidgets(w);
-		DrawFiosTexts(w->width);
-
-		if (_savegame_sort_dirty) {
-			_savegame_sort_dirty = false;
-			MakeSortedSaveGameList();
-		}
-
-		GfxFillRect(w->widget[7].left + 1, w->widget[7].top + 1, w->widget[7].right, w->widget[7].bottom, 0xD7);
-		DrawSortButtonState(w, _savegame_sort_order & SORT_BY_NAME ? 2 : 3, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
-
-		y = w->widget[7].top + 1;
-		for (pos = w->vscroll.pos; pos < _fios_num; pos++) {
-			const FiosItem *item = _fios_list + pos;
+			o_dir.type = FIOS_TYPE_DIRECT;
+			switch (_saveload_mode) {
+				case SLD_SAVE_GAME:
+				case SLD_LOAD_GAME:
+					FioGetDirectory(o_dir.name, lengthof(o_dir.name), SAVE_DIR);
+					break;
 
-			DoDrawStringTruncated(item->title, 4, y, _fios_colors[item->type], w->width - 18);
-			y += 10;
-			if (y >= w->vscroll.cap * 10 + w->widget[7].top + 1) break;
-		}
+				case SLD_SAVE_SCENARIO:
+				case SLD_LOAD_SCENARIO:
+					FioGetDirectory(o_dir.name, lengthof(o_dir.name), SCENARIO_DIR);
+					break;
 
-		if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
-			DrawEditBox(w, &WP(w, querystr_d), 10);
-		}
-		break;
-	}
+				case SLD_LOAD_HEIGHTMAP:
+					FioGetDirectory(o_dir.name, lengthof(o_dir.name), HEIGHTMAP_DIR);
+					break;
 
-	case WE_CLICK:
-		switch (e->we.click.widget) {
-		case 2: // Sort save names by name
-			_savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
-				SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
-			_savegame_sort_dirty = true;
-			SetWindowDirty(w);
+				default:
+					ttd_strlcpy(o_dir.name, _personal_dir, lengthof(o_dir.name));
+			}
 			break;
 
-		case 3: // Sort save names by date
-			_savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
-				SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
-			_savegame_sort_dirty = true;
-			SetWindowDirty(w);
-			break;
-
-		case 6: // OpenTTD 'button', jumps to OpenTTD directory
-			FiosBrowseTo(&o_dir);
-			SetWindowDirty(w);
-			BuildFileList();
-			break;
-
-		case 7: { // Click the listbox
-			int y = (e->we.click.pt.y - w->widget[e->we.click.widget].top - 1) / 10;
-			char *name;
-			const FiosItem *file;
-
-			if (y < 0 || (y += w->vscroll.pos) >= w->vscroll.count) return;
-
-			file = _fios_list + y;
+		case WE_PAINT: {
+			int pos;
+			int y;
 
-			name = FiosBrowseTo(file);
-			if (name != NULL) {
-				if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
-					_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD;
-
-					SetFiosType(file->type);
-					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
-					ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+			SetVScrollCount(w, _fios_num);
+			DrawWindowWidgets(w);
+			DrawFiosTexts(w->width);
 
-					DeleteWindow(w);
-				} else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
-					SetFiosType(file->type);
-					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
-					ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+			if (_savegame_sort_dirty) {
+				_savegame_sort_dirty = false;
+				MakeSortedSaveGameList();
+			}
 
-					DeleteWindow(w);
-					ShowHeightmapLoad();
-				} else {
-					/* SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox */
-					ttd_strlcpy(WP(w, querystr_d).text.buf, file->title, WP(w, querystr_d).text.maxlength);
-					UpdateTextBufferSize(&WP(w, querystr_d).text);
-					w->InvalidateWidget(10);
-				}
-			} else {
-				/* Changed directory, need repaint. */
-				SetWindowDirty(w);
-				BuildFileList();
+			GfxFillRect(w->widget[7].left + 1, w->widget[7].top + 1, w->widget[7].right, w->widget[7].bottom, 0xD7);
+			DrawSortButtonState(w, _savegame_sort_order & SORT_BY_NAME ? 2 : 3, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
+
+			y = w->widget[7].top + 1;
+			for (pos = w->vscroll.pos; pos < _fios_num; pos++) {
+				const FiosItem *item = _fios_list + pos;
+
+				DoDrawStringTruncated(item->title, 4, y, _fios_colors[item->type], w->width - 18);
+				y += 10;
+				if (y >= w->vscroll.cap * 10 + w->widget[7].top + 1) break;
+			}
+
+			if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+				DrawEditBox(w, &WP(w, querystr_d), 10);
 			}
 			break;
 		}
 
-		case 11: case 12: // Delete, Save game
-			break;
-		}
-		break;
-	case WE_MOUSELOOP:
-		if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
-			HandleEditBox(w, &WP(w, querystr_d), 10);
-		}
-		break;
-	case WE_KEYPRESS:
-		if (e->we.keypress.keycode == WKC_ESC) {
-			DeleteWindow(w);
-			return;
-		}
+		case WE_CLICK:
+			switch (e->we.click.widget) {
+				case 2: // Sort save names by name
+					_savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
+						SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
+					_savegame_sort_dirty = true;
+					SetWindowDirty(w);
+					break;
 
-		if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
-			if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) // Press Enter
-					w->HandleButtonClick(12);
-		}
-		break;
-	case WE_TIMEOUT:
-		/* This test protects against using widgets 11 and 12 which are only available
-		 * in those two saveload mode  */
-		if (!(_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO)) break;
+				case 3: // Sort save names by date
+					_savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
+						SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
+					_savegame_sort_dirty = true;
+					SetWindowDirty(w);
+					break;
 
-		if (w->IsWidgetLowered(11)) { // Delete button clicked
-			if (!FiosDelete(WP(w, querystr_d).text.buf)) {
-				ShowErrorMessage(INVALID_STRING_ID, STR_4008_UNABLE_TO_DELETE_FILE, 0, 0);
-			} else {
-				BuildFileList();
-				/* Reset file name to current date on successful delete */
-				if (_saveload_mode == SLD_SAVE_GAME) GenerateFileName();
+				case 6: // OpenTTD 'button', jumps to OpenTTD directory
+					FiosBrowseTo(&o_dir);
+					SetWindowDirty(w);
+					BuildFileList();
+					break;
+
+				case 7: { // Click the listbox
+					int y = (e->we.click.pt.y - w->widget[e->we.click.widget].top - 1) / 10;
+					char *name;
+					const FiosItem *file;
+
+					if (y < 0 || (y += w->vscroll.pos) >= w->vscroll.count) return;
+
+					file = _fios_list + y;
+
+					name = FiosBrowseTo(file);
+					if (name != NULL) {
+						if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
+							_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD;
+
+							SetFiosType(file->type);
+							ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+							ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+
+							DeleteWindow(w);
+						} else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
+							SetFiosType(file->type);
+							ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
+							ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
+
+							DeleteWindow(w);
+							ShowHeightmapLoad();
+						} else {
+							/* SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox */
+							ttd_strlcpy(WP(w, querystr_d).text.buf, file->title, WP(w, querystr_d).text.maxlength);
+							UpdateTextBufferSize(&WP(w, querystr_d).text);
+							w->InvalidateWidget(10);
+						}
+					} else {
+						/* Changed directory, need repaint. */
+						SetWindowDirty(w);
+						BuildFileList();
+					}
+					break;
+				}
+
+				case 10: // edit box
+					ShowOnScreenKeyboard(w, &WP(w, querystr_d), e->we.click.widget, 0, 0);
+					break;
+
+				case 11: case 12: // Delete, Save game
+					break;
+			}
+			break;
+
+		case WE_MOUSELOOP:
+			if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+				HandleEditBox(w, &WP(w, querystr_d), 10);
+			}
+			break;
+
+		case WE_KEYPRESS:
+			if (e->we.keypress.keycode == WKC_ESC) {
+				DeleteWindow(w);
+				return;
 			}
 
-			UpdateTextBufferSize(&WP(w, querystr_d).text);
-			SetWindowDirty(w);
-		} else if (w->IsWidgetLowered(12)) { // Save button clicked
-			_switch_mode = SM_SAVE;
-			FiosMakeSavegameName(_file_to_saveload.name, WP(w, querystr_d).text.buf, sizeof(_file_to_saveload.name));
+			if ((_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) &&
+					HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) { // Press Enter
+				w->HandleButtonClick(12);
+			}
+			break;
 
-			/* In the editor set up the vehicle engines correctly (date might have changed) */
-			if (_game_mode == GM_EDITOR) StartupEngines();
-		}
-		break;
-	case WE_DESTROY:
-		/* pause is only used in single-player, non-editor mode, non menu mode */
-		if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
-			if (_pause_game >= 0) DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
-		}
-		FiosFreeSavegameList();
-		ClrBit(_no_scroll, SCROLL_SAVE);
-		break;
-	case WE_RESIZE: {
-		/* Widget 2 and 3 have to go with halve speed, make it so obiwan */
-		uint diff = e->we.sizing.diff.x / 2;
-		w->widget[2].right += diff;
-		w->widget[3].left  += diff;
-		w->widget[3].right += e->we.sizing.diff.x;
+		case WE_TIMEOUT:
+			/* This test protects against using widgets 11 and 12 which are only available
+			* in those two saveload mode  */
+			if (!(_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO)) break;
 
-		/* Same for widget 11 and 12 in save-dialog */
-		if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
-			w->widget[11].right += diff;
-			w->widget[12].left  += diff;
-			w->widget[12].right += e->we.sizing.diff.x;
-		}
+			if (w->IsWidgetLowered(11)) { // Delete button clicked
+				if (!FiosDelete(WP(w, querystr_d).text.buf)) {
+					ShowErrorMessage(INVALID_STRING_ID, STR_4008_UNABLE_TO_DELETE_FILE, 0, 0);
+				} else {
+					BuildFileList();
+					/* Reset file name to current date on successful delete */
+					if (_saveload_mode == SLD_SAVE_GAME) GenerateFileName();
+				}
 
-		w->vscroll.cap += e->we.sizing.diff.y / 10;
+				UpdateTextBufferSize(&WP(w, querystr_d).text);
+				SetWindowDirty(w);
+			} else if (w->IsWidgetLowered(12)) { // Save button clicked
+				_switch_mode = SM_SAVE;
+				FiosMakeSavegameName(_file_to_saveload.name, WP(w, querystr_d).text.buf, sizeof(_file_to_saveload.name));
+
+				/* In the editor set up the vehicle engines correctly (date might have changed) */
+				if (_game_mode == GM_EDITOR) StartupEngines();
+			}
+			break;
+
+		case WE_DESTROY:
+			/* pause is only used in single-player, non-editor mode, non menu mode */
+			if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
+				if (_pause_game >= 0) DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
+			}
+			FiosFreeSavegameList();
+			ClrBit(_no_scroll, SCROLL_SAVE);
+			break;
+
+		case WE_RESIZE: {
+			/* Widget 2 and 3 have to go with halve speed, make it so obiwan */
+			uint diff = e->we.sizing.diff.x / 2;
+			w->widget[2].right += diff;
+			w->widget[3].left  += diff;
+			w->widget[3].right += e->we.sizing.diff.x;
+
+			/* Same for widget 11 and 12 in save-dialog */
+			if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
+				w->widget[11].right += diff;
+				w->widget[12].left  += diff;
+				w->widget[12].right += e->we.sizing.diff.x;
+			}
+
+			w->vscroll.cap += e->we.sizing.diff.y / 10;
 		} break;
 	}
 }
@@ -1695,10 +1717,8 @@
 		STR_LOAD_HEIGHTMAP,
 	};
 
-	Window *w;
 	const WindowDesc *sld = &_save_dialog_desc;
 
-
 	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
 	DeleteWindowById(WC_QUERY_STRING, 0);
 	DeleteWindowById(WC_SAVELOAD, 0);
@@ -1716,7 +1736,8 @@
 	}
 
 	assert((uint)mode < lengthof(saveload_captions));
-	w = AllocateWindowDesc(sld);
+
+	Window *w = AllocateWindowDesc(sld);
 	w->widget[1].data = saveload_captions[mode];
 	w->LowerWidget(7);
 
@@ -1768,10 +1789,17 @@
 	}
 }
 
+/**
+ * The 'amount' to cheat with.
+ * This variable is semantically a constant value, but because the cheat
+ * code requires to be able to write to the variable it is not constified.
+ */
+static int32 _money_cheat_amount = 10000000;
+
 static int32 ClickMoneyCheat(int32 p1, int32 p2)
 {
-		DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT);
-		return true;
+	DoCommandP(0, (uint32)(p2 * _money_cheat_amount), 0, NULL, CMD_MONEY_CHEAT);
+	return _money_cheat_amount;
 }
 
 /**
@@ -1822,43 +1850,30 @@
 	SetDate(ConvertYMDToDate(_cur_year + p2, ymd.month, ymd.day));
 	EnginesMonthlyLoop();
 	SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0));
+	ResetSignalVariant();
 	return _cur_year;
 }
 
 typedef int32 CheckButtonClick(int32, int32);
 
-enum ce_flags_long
-{
-	CE_NONE = 0,
-	CE_CLICK = 1 << 0,
-	CE_END = 1 << 1,
-};
-
-/** Define basic enum properties */
-template <> struct EnumPropsT<ce_flags_long> : MakeEnumPropsT<ce_flags_long, byte, CE_NONE, CE_END, CE_END> {};
-typedef TinyEnumT<ce_flags_long> ce_flags;
-
-
 struct CheatEntry {
 	VarType type;          ///< type of selector
-	ce_flags flags;        ///< selector flags
 	StringID str;          ///< string with descriptive text
 	void *variable;        ///< pointer to the variable
 	bool *been_used;       ///< has this cheat been used before?
 	CheckButtonClick *proc;///< procedure
-	int16 min, max;        ///< range for spinbox setting
 };
 
 static const CheatEntry _cheats_ui[] = {
-	{SLE_BOOL, {CE_CLICK}, STR_CHEAT_MONEY,          &_cheats.money.value,           &_cheats.money.been_used,           &ClickMoneyCheat,         0,  0},
-	{SLE_UINT8, {CE_NONE}, STR_CHEAT_CHANGE_PLAYER,  &_local_player,                 &_cheats.switch_player.been_used,   &ClickChangePlayerCheat,  0, 11},
-	{SLE_BOOL,  {CE_NONE}, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, NULL,                     0,  0},
-	{SLE_BOOL,  {CE_NONE}, STR_CHEAT_CROSSINGTUNNELS,&_cheats.crossing_tunnels.value,&_cheats.crossing_tunnels.been_used,NULL,                     0,  0},
-	{SLE_BOOL,  {CE_NONE}, STR_CHEAT_BUILD_IN_PAUSE, &_cheats.build_in_pause.value,  &_cheats.build_in_pause.been_used,  NULL,                     0,  0},
-	{SLE_BOOL,  {CE_NONE}, STR_CHEAT_NO_JETCRASH,    &_cheats.no_jetcrash.value,     &_cheats.no_jetcrash.been_used,     NULL,                     0,  0},
-	{SLE_BOOL,  {CE_NONE}, STR_CHEAT_SETUP_PROD,     &_cheats.setup_prod.value,      &_cheats.setup_prod.been_used,      NULL,                     0,  0},
-	{SLE_UINT8, {CE_NONE}, STR_CHEAT_SWITCH_CLIMATE, &_opt.landscape,                &_cheats.switch_climate.been_used,  &ClickChangeClimateCheat,-1,  4},
-	{SLE_INT32, {CE_NONE}, STR_CHEAT_CHANGE_DATE,    &_cur_year,                     &_cheats.change_date.been_used,     &ClickChangeDateCheat,   -1,  1},
+	{SLE_INT32, STR_CHEAT_MONEY,           &_money_cheat_amount,            &_cheats.money.been_used,            &ClickMoneyCheat        },
+	{SLE_UINT8, STR_CHEAT_CHANGE_PLAYER,   &_local_player,                  &_cheats.switch_player.been_used,    &ClickChangePlayerCheat },
+	{SLE_BOOL,  STR_CHEAT_EXTRA_DYNAMITE,  &_cheats.magic_bulldozer.value,  &_cheats.magic_bulldozer.been_used,  NULL                    },
+	{SLE_BOOL,  STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, NULL                    },
+	{SLE_BOOL,  STR_CHEAT_BUILD_IN_PAUSE,  &_cheats.build_in_pause.value,   &_cheats.build_in_pause.been_used,   NULL                    },
+	{SLE_BOOL,  STR_CHEAT_NO_JETCRASH,     &_cheats.no_jetcrash.value,      &_cheats.no_jetcrash.been_used,      NULL                    },
+	{SLE_BOOL,  STR_CHEAT_SETUP_PROD,      &_cheats.setup_prod.value,       &_cheats.setup_prod.been_used,       NULL                    },
+	{SLE_UINT8, STR_CHEAT_SWITCH_CLIMATE,  &_opt.landscape,                 &_cheats.switch_climate.been_used,   &ClickChangeClimateCheat},
+	{SLE_INT32, STR_CHEAT_CHANGE_DATE,     &_cur_year,                      &_cheats.change_date.been_used,      &ClickChangeDateCheat   },
 };
 
 
@@ -1873,123 +1888,97 @@
 static void CheatsWndProc(Window *w, WindowEvent *e)
 {
 	switch (e->event) {
-	case WE_PAINT: {
-		int clk = WP(w, def_d).data_1;
-		int x, y;
-		int i;
-
-		DrawWindowWidgets(w);
-
-		DrawStringMultiCenter(200, 25, STR_CHEATS_WARNING, w->width - 50);
-
-		x = 0;
-		y = 45;
-
-		for (i = 0; i != lengthof(_cheats_ui); i++) {
-			const CheatEntry *ce = &_cheats_ui[i];
+		case WE_PAINT: {
+			int clk = WP(w, def_d).data_1;
 
-			DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, x + 5, y + 2);
-
-			switch (ce->type) {
-			case SLE_BOOL: {
-				bool on = (*(bool*)ce->variable);
+			DrawWindowWidgets(w);
+			DrawStringMultiCenter(200, 25, STR_CHEATS_WARNING, w->width - 50);
 
-				if (ce->flags & CE_CLICK) {
-					DrawFrameRect(x + 20, y + 1, x + 30 + 9, y + 9, 0, (clk - (i * 2) == 1) ? FR_LOWERED : FR_NONE);
-					if (i == 0) { // XXX - hack/hack for first element which is increase money. Told ya it's a mess
-						SetDParam(0, 10000000);
-					} else {
-						SetDParam(0, false);
-					}
-				} else {
-					DrawFrameRect(x + 20, y + 1, x + 30 + 9, y + 9, on ? 6 : 4, on ? FR_LOWERED : FR_NONE);
-					SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF);
+			for (int i = 0, x = 0, y = 45; i != lengthof(_cheats_ui); i++) {
+				const CheatEntry *ce = &_cheats_ui[i];
+
+				DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, x + 5, y + 2);
+
+				switch (ce->type) {
+					case SLE_BOOL: {
+						bool on = (*(bool*)ce->variable);
+
+						DrawFrameRect(x + 20, y + 1, x + 30 + 9, y + 9, on ? 6 : 4, on ? FR_LOWERED : FR_NONE);
+						SetDParam(0, on ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF);
+					} break;
+
+					default: {
+						int32 val = (int32)ReadValue(ce->variable, ce->type);
+						char buf[512];
+
+						/* Draw [<][>] boxes for settings of an integer-type */
+						DrawArrowButtons(x + 20, y, 3, clk - (i * 2), true, true);
+
+						switch (ce->str) {
+							/* Display date for change date cheat */
+							case STR_CHEAT_CHANGE_DATE: SetDParam(0, _date); break;
+
+							/* Draw colored flag for change player cheat */
+							case STR_CHEAT_CHANGE_PLAYER:
+								SetDParam(0, val);
+								GetString(buf, STR_CHEAT_CHANGE_PLAYER, lastof(buf));
+								DrawPlayerIcon(_current_player, 60 + GetStringBoundingBox(buf).width, y + 2);
+								break;
+
+							/* Set correct string for switch climate cheat */
+							case STR_CHEAT_SWITCH_CLIMATE: val += STR_TEMPERATE_LANDSCAPE;
+
+							/* Fallthrough */
+							default: SetDParam(0, val);
+						}
+					} break;
 				}
-			} break;
-			default: {
-				int32 val = (int32)ReadValue(ce->variable, ce->type);
-				char buf[512];
-
-				/* Draw [<][>] boxes for settings of an integer-type */
-				DrawArrowButtons(x + 20, y, 3, clk - (i * 2), true, true);
 
-				switch (ce->str) {
-				/* Display date for change date cheat */
-				case STR_CHEAT_CHANGE_DATE: SetDParam(0, _date); break;
-				/* Draw colored flag for change player cheat */
-				case STR_CHEAT_CHANGE_PLAYER:
-					SetDParam(0, val);
-					GetString(buf, STR_CHEAT_CHANGE_PLAYER, lastof(buf));
-					DrawPlayerIcon(_current_player, 60 + GetStringBoundingBox(buf).width, y + 2);
-					break;
-				/* Set correct string for switch climate cheat */
-				case STR_CHEAT_SWITCH_CLIMATE: val += STR_TEMPERATE_LANDSCAPE;
-				/* Fallthrough */
-				default: SetDParam(0, val);
-				}
-			} break;
+				DrawString(50, y + 1, ce->str, TC_FROMSTRING);
+
+				y += 12;
 			}
-
-			DrawString(50, y + 1, ce->str, TC_FROMSTRING);
-
-			y += 12;
+			break;
 		}
-		break;
-	}
 
-	case WE_CLICK: {
-			const CheatEntry *ce;
+		case WE_CLICK: {
 			uint btn = (e->we.click.pt.y - 46) / 12;
-			int32 value, oldvalue;
 			uint x = e->we.click.pt.x;
 
-			/* not clicking a button? */
+			/* Not clicking a button? */
 			if (!IsInsideMM(x, 20, 40) || btn >= lengthof(_cheats_ui)) break;
 
-			ce = &_cheats_ui[btn];
-			oldvalue = value = (int32)ReadValue(ce->variable, ce->type);
+			const CheatEntry *ce = &_cheats_ui[btn];
+			int value = (int32)ReadValue(ce->variable, ce->type);
+			int oldvalue = value;
 
 			*ce->been_used = true;
 
 			switch (ce->type) {
-			case SLE_BOOL:
-				if (ce->flags & CE_CLICK) WP(w, def_d).data_1 = btn * 2 + 1;
-				value ^= 1;
-				if (ce->proc != NULL) ce->proc(value, 0);
-				break;
-			default: {
-				/* Add a dynamic step-size to the scroller. In a maximum of
-				 * 50-steps you should be able to get from min to max */
-				uint16 step = ((ce->max - ce->min) / 20);
-				if (step == 0) step = 1;
+				case SLE_BOOL:
+					value ^= 1;
+					if (ce->proc != NULL) ce->proc(value, 0);
+					break;
 
-				/* Increase or decrease the value and clamp it to extremes */
-				value += (x >= 30) ? step : -step;
-				value = Clamp(value, ce->min, ce->max);
+				default:
+					/* Take whatever the function returns */
+					value = ce->proc(value + ((x >= 30) ? 1 : -1), (x >= 30) ? 1 : -1);
 
-				/* take whatever the function returns */
-				value = ce->proc(value, (x >= 30) ? 1 : -1);
-
-				if (value != oldvalue) {
-					WP(w, def_d).data_1 = btn * 2 + 1 + ((x >= 30) ? 1 : 0);
-				}
-			} break;
+					if (value != oldvalue) WP(w, def_d).data_1 = btn * 2 + 1 + ((x >= 30) ? 1 : 0);
+					break;
 			}
 
-			if (value != oldvalue) {
-				WriteValue(ce->variable, ce->type, (int64)value);
-				SetWindowDirty(w);
-			}
+			if (value != oldvalue) WriteValue(ce->variable, ce->type, (int64)value);
 
 			w->flags4 |= 5 << WF_TIMEOUT_SHL;
 
 			SetWindowDirty(w);
-		}
-		break;
-	case WE_TIMEOUT:
-		WP(w, def_d).data_1 = 0;
-		SetWindowDirty(w);
-		break;
+		} break;
+
+		case WE_TIMEOUT:
+			WP(w, def_d).data_1 = 0;
+			SetWindowDirty(w);
+			break;
 	}
 }