src/build_vehicle_gui.cpp
changeset 5779 a694ce1457bb
parent 5668 36b39f4a9032
child 5780 b16aec7650c2
equal deleted inserted replaced
5778:94301697f913 5779:a694ce1457bb
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #include "stdafx.h"
     3 #include "stdafx.h"
     4 #include "openttd.h"
     4 #include "openttd.h"
       
     5 #include "train.h"
     5 #include "aircraft.h"
     6 #include "aircraft.h"
     6 #include "debug.h"
     7 #include "debug.h"
     7 #include "functions.h"
     8 #include "functions.h"
     8 #include "table/sprites.h"
     9 #include "table/sprites.h"
     9 #include "table/strings.h"
    10 #include "table/strings.h"
    37 	BUILD_VEHICLE_WIDGET_RESIZE,
    38 	BUILD_VEHICLE_WIDGET_RESIZE,
    38 };
    39 };
    39 
    40 
    40 static const Widget _build_vehicle_widgets[] = {
    41 static const Widget _build_vehicle_widgets[] = {
    41 	{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW },
    42 	{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW },
    42 	{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   239,     0,    13, STR_A005_NEW_AIRCRAFT,   STR_018C_WINDOW_TITLE_DRAG_THIS },
    43 	{    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   227,     0,    13, 0x0,                     STR_018C_WINDOW_TITLE_DRAG_THIS },
    43 	{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,    80,    14,    25, STR_SORT_BY,             STR_SORT_ORDER_TIP},
    44 	{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,    80,    14,    25, STR_SORT_BY,             STR_SORT_ORDER_TIP},
    44 	{      WWT_PANEL,   RESIZE_NONE,    14,    81,   227,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},
    45 	{      WWT_PANEL,  RESIZE_RIGHT,    14,    81,   215,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},
    45 	{    WWT_TEXTBTN,   RESIZE_NONE,    14,   228,   239,    14,    25, STR_0225,                STR_SORT_CRITERIA_TIP},
    46 	{    WWT_TEXTBTN,     RESIZE_LR,    14,   216,   227,    14,    25, STR_0225,                STR_SORT_CRITERIA_TIP},
    46 	{     WWT_MATRIX, RESIZE_BOTTOM,    14,     0,   227,    26,   121, 0x401,                   STR_A025_AIRCRAFT_SELECTION_LIST },
    47 	{     WWT_MATRIX,     RESIZE_RB,    14,     0,   215,    26,   121, 0x0,                     STR_NULL },
    47 	{  WWT_SCROLLBAR, RESIZE_BOTTOM,    14,   228,   239,    26,   121, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
    48 	{  WWT_SCROLLBAR,    RESIZE_LRB,    14,   216,   227,    26,   121, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
    48 	{      WWT_PANEL,     RESIZE_TB,    14,     0,   239,   122,   213, 0x0,                     STR_NULL },
    49 	{      WWT_PANEL,    RESIZE_RTB,    14,     0,   227,   122,   213, 0x0,                     STR_NULL },
    49 
    50 
    50 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   214,   225, STR_A006_BUILD_AIRCRAFT, STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT },
    51 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   214,   225, 0x0,                     STR_NULL },
    51 	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,   115,   227,   214,   225, STR_A037_RENAME,         STR_A038_RENAME_AIRCRAFT_TYPE },
    52 	{ WWT_PUSHTXTBTN,    RESIZE_RTB,    14,   115,   215,   214,   225, 0x0,                     STR_NULL },
    52 	{  WWT_RESIZEBOX,     RESIZE_TB,    14,   228,   239,   214,   225, 0x0,                     STR_RESIZE_BUTTON },
    53 	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   216,   227,   214,   225, 0x0,                     STR_RESIZE_BUTTON },
    53 	{   WIDGETS_END},
    54 	{   WIDGETS_END},
    54 };
    55 };
    55 
    56 
       
    57 /* Setup widget strings to fit the different types of vehicles */
       
    58 static void SetupWindowStrings(const Window *w, byte type)
       
    59 {
       
    60 	switch (type) {
       
    61 		case VEH_Train:
       
    62 			w->widget[BUILD_VEHICLE_WIDGET_CAPTION].data    = STR_JUST_STRING;
       
    63 			w->widget[BUILD_VEHICLE_WIDGET_LIST].tooltips   = STR_8843_TRAIN_VEHICLE_SELECTION;
       
    64 			w->widget[BUILD_VEHICLE_WIDGET_BUILD].data      = STR_881F_BUILD_VEHICLE;
       
    65 			w->widget[BUILD_VEHICLE_WIDGET_BUILD].tooltips  = STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN;
       
    66 			w->widget[BUILD_VEHICLE_WIDGET_RENAME].data     = STR_8820_RENAME;
       
    67 			w->widget[BUILD_VEHICLE_WIDGET_RENAME].tooltips = STR_8845_RENAME_TRAIN_VEHICLE_TYPE;
       
    68 			break;
       
    69 		case VEH_Aircraft:
       
    70 			w->widget[BUILD_VEHICLE_WIDGET_CAPTION].data    = STR_A005_NEW_AIRCRAFT;
       
    71 			w->widget[BUILD_VEHICLE_WIDGET_LIST].tooltips   = STR_A025_AIRCRAFT_SELECTION_LIST;
       
    72 			w->widget[BUILD_VEHICLE_WIDGET_BUILD].data      = STR_A006_BUILD_AIRCRAFT;
       
    73 			w->widget[BUILD_VEHICLE_WIDGET_BUILD].tooltips  = STR_A026_BUILD_THE_HIGHLIGHTED_AIRCRAFT;
       
    74 			w->widget[BUILD_VEHICLE_WIDGET_RENAME].data     = STR_A037_RENAME;
       
    75 			w->widget[BUILD_VEHICLE_WIDGET_RENAME].tooltips = STR_A038_RENAME_AIRCRAFT_TYPE;
       
    76 			break;
       
    77 	}
       
    78 }
       
    79 
    56 static bool _internal_sort_order; // descending/ascending
    80 static bool _internal_sort_order; // descending/ascending
    57 static byte _last_sort_criteria = 0;
    81 static byte _last_sort_criteria_train    = 0;
    58 static bool _last_sort_order = false;
    82 static bool _last_sort_order_train       = false;
       
    83 
       
    84 static byte _last_sort_criteria_aircraft = 0;
       
    85 static bool _last_sort_order_aircraft    = false;
    59 
    86 
    60 static int CDECL EngineNumberSorter(const void *a, const void *b)
    87 static int CDECL EngineNumberSorter(const void *a, const void *b)
    61 {
    88 {
    62 	const EngineID va = *(const EngineID*)a;
    89 	const EngineID va = *(const EngineID*)a;
    63 	const EngineID vb = *(const EngineID*)b;
    90 	const EngineID vb = *(const EngineID*)b;
   118 		return EngineNumberSorter(a, b);
   145 		return EngineNumberSorter(a, b);
   119 	}
   146 	}
   120 	return _internal_sort_order ? -r : r;
   147 	return _internal_sort_order ? -r : r;
   121 }
   148 }
   122 
   149 
       
   150 /* Train sorting functions */
       
   151 static int CDECL TrainEngineCostSorter(const void *a, const void *b)
       
   152 {
       
   153 	int va = RailVehInfo(*(const EngineID*)a)->base_cost;
       
   154 	int vb = RailVehInfo(*(const EngineID*)b)->base_cost;
       
   155 	int r = va - vb;
       
   156 
       
   157 	return _internal_sort_order ? -r : r;
       
   158 }
       
   159 
       
   160 static int CDECL TrainEngineSpeedSorter(const void *a, const void *b)
       
   161 {
       
   162 	int va = RailVehInfo(*(const EngineID*)a)->max_speed;
       
   163 	int vb = RailVehInfo(*(const EngineID*)b)->max_speed;
       
   164 	int r = va - vb;
       
   165 
       
   166 	return _internal_sort_order ? -r : r;
       
   167 }
       
   168 
       
   169 static int CDECL TrainEnginePowerSorter(const void *a, const void *b)
       
   170 {
       
   171 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
       
   172 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
       
   173 
       
   174 	int va = rvi_a->power << (rvi_a->flags & RVI_MULTIHEAD ? 1 : 0);
       
   175 	int vb = rvi_b->power << (rvi_b->flags & RVI_MULTIHEAD ? 1 : 0);
       
   176 	int r = va - vb;
       
   177 
       
   178 	return _internal_sort_order ? -r : r;
       
   179 }
       
   180 
       
   181 static int CDECL TrainEngineRunningCostSorter(const void *a, const void *b)
       
   182 {
       
   183 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
       
   184 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
       
   185 
       
   186 	int va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->flags & RVI_MULTIHEAD ? 2 : 1);
       
   187 	int vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->flags & RVI_MULTIHEAD ? 2 : 1);
       
   188 	int r = va - vb;
       
   189 
       
   190 	return _internal_sort_order ? -r : r;
       
   191 }
       
   192 
       
   193 static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
       
   194 {
       
   195 	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
       
   196 	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
       
   197 
       
   198 	/* Here we are using a few tricks to get the right sort.
       
   199 		* We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
       
   200 		* we will actually calculate cunning cost/power (to make it more than 1).
       
   201 		* Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
       
   202 		* Another thing is that both power and running costs should be doubled for multiheaded engines.
       
   203 		* Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */
       
   204 	int va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power);
       
   205 	int vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power);
       
   206 	int r = vb - va;
       
   207 
       
   208 	return _internal_sort_order ? -r : r;
       
   209 }
       
   210 
       
   211 static int CDECL TrainEnginesThenWagonsSorter(const void *a, const void *b)
       
   212 {
       
   213 	EngineID va = *(const EngineID*)a;
       
   214 	EngineID vb = *(const EngineID*)b;
       
   215 	int val_a = ((RailVehInfo(va)->flags & RVI_WAGON) != 0) ? 1 : 0;
       
   216 	int val_b = ((RailVehInfo(vb)->flags & RVI_WAGON) != 0) ? 1 : 0;
       
   217 	int r = val_a - val_b;
       
   218 
       
   219 	/* Use EngineID to sort instead since we want consistent sorting */
       
   220 	if (r == 0) return EngineNumberSorter(a, b);
       
   221 
       
   222 	return _internal_sort_order ? -r : r;
       
   223 }
       
   224 
   123 /* Aircraft sorting functions */
   225 /* Aircraft sorting functions */
   124 
   226 
   125 static int CDECL AircraftEngineCostSorter(const void *a, const void *b)
   227 static int CDECL AircraftEngineCostSorter(const void *a, const void *b)
   126 {
   228 {
   127 	const int va = AircraftVehInfo(*(const EngineID*)a)->base_cost;
   229 	const int va = AircraftVehInfo(*(const EngineID*)a)->base_cost;
   167 		/* Use EngineID to sort instead since we want consistent sorting */
   269 		/* Use EngineID to sort instead since we want consistent sorting */
   168 		return EngineNumberSorter(a, b);
   270 		return EngineNumberSorter(a, b);
   169 	}
   271 	}
   170 	return _internal_sort_order ? -r : r;
   272 	return _internal_sort_order ? -r : r;
   171 }
   273 }
       
   274 
       
   275 static EngList_SortTypeFunction * const _train_sorter[] = {
       
   276 	&EngineNumberSorter,
       
   277 	&TrainEngineCostSorter,
       
   278 	&TrainEngineSpeedSorter,
       
   279 	&TrainEnginePowerSorter,
       
   280 	&EngineIntroDateSorter,
       
   281 	&EngineNameSorter,
       
   282 	&TrainEngineRunningCostSorter,
       
   283 	&TrainEnginePowerVsRunningCostSorter,
       
   284 	&EngineReliabilitySorter,
       
   285 };
       
   286 
       
   287 static const StringID _train_sort_listing[] = {
       
   288 	STR_ENGINE_SORT_ENGINE_ID,
       
   289 	STR_ENGINE_SORT_COST,
       
   290 	STR_SORT_BY_MAX_SPEED,
       
   291 	STR_ENGINE_SORT_POWER,
       
   292 	STR_ENGINE_SORT_INTRO_DATE,
       
   293 	STR_SORT_BY_DROPDOWN_NAME,
       
   294 	STR_ENGINE_SORT_RUNNING_COST,
       
   295 	STR_ENGINE_SORT_POWER_VS_RUNNING_COST,
       
   296 	STR_SORT_BY_RELIABILITY,
       
   297 	INVALID_STRING_ID
       
   298 };
   172 
   299 
   173 static EngList_SortTypeFunction * const _aircraft_sorter[] = {
   300 static EngList_SortTypeFunction * const _aircraft_sorter[] = {
   174 	&EngineNumberSorter,
   301 	&EngineNumberSorter,
   175 	&AircraftEngineCostSorter,
   302 	&AircraftEngineCostSorter,
   176 	&AircraftEngineSpeedSorter,
   303 	&AircraftEngineSpeedSorter,
   192 	STR_ENGINE_SORT_CARGO_CAPACITY,
   319 	STR_ENGINE_SORT_CARGO_CAPACITY,
   193 	INVALID_STRING_ID
   320 	INVALID_STRING_ID
   194 };
   321 };
   195 
   322 
   196 
   323 
   197 /**
   324 /* Draw rail wagon specific details */
   198 * Draw the purchase info details of an aircraft at a given location.
   325 static int DrawVehiclePurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi)
   199  * @param x,y location where to draw the info
   326 {
   200  * @param engine_number the engine of which to draw the info of
   327 	/* Purchase cost */
   201  */
   328 	SetDParam(0, (rvi->base_cost * _price.build_railwagon) >> 8);
   202 void DrawAircraftPurchaseInfo(int x, int y, uint w, EngineID engine_number)
   329 	DrawString(x, y, STR_PURCHASE_INFO_COST, 0);
   203 {
   330 	y += 10;
   204 	const AircraftVehicleInfo *avi = AircraftVehInfo(engine_number);
   331 
   205 	const Engine *e = GetEngine(engine_number);
   332 	/* Wagon weight - (including cargo) */
       
   333 	SetDParam(0, rvi->weight);
       
   334 	SetDParam(1, (_cargoc.weights[rvi->cargo_type] * rvi->capacity >> 4) + rvi->weight);
       
   335 	DrawString(x, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT, 0);
       
   336 	y += 10;
       
   337 
       
   338 	/* Wagon speed limit, displayed if above zero */
       
   339 	if (rvi->max_speed > 0 && _patches.wagon_speed_limits) {
       
   340 		SetDParam(0, rvi->max_speed);
       
   341 		DrawString(x,y, STR_PURCHASE_INFO_SPEED, 0);
       
   342 		y += 10;
       
   343 	}
       
   344 	return y;
       
   345 }
       
   346 
       
   347 /* Draw locomotive specific details */
       
   348 static int DrawVehiclePurchaseInfo(int x, int y, EngineID engine_number, const RailVehicleInfo *rvi, const Engine *e)
       
   349 {
       
   350 	int multihead = (rvi->flags&RVI_MULTIHEAD?1:0);
       
   351 
       
   352 	/* Purchase Cost - Engine weight */
       
   353 	SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
       
   354 	SetDParam(1, rvi->weight << multihead);
       
   355 	DrawString(x,y, STR_PURCHASE_INFO_COST_WEIGHT, 0);
       
   356 	y += 10;
       
   357 
       
   358 	/* Max speed - Engine power */
       
   359 	SetDParam(0, rvi->max_speed);
       
   360 	SetDParam(1, rvi->power << multihead);
       
   361 	DrawString(x,y, STR_PURCHASE_INFO_SPEED_POWER, 0);
       
   362 	y += 10;
       
   363 
       
   364 	/* Max tractive effort - not applicable if old acceleration or maglev */
       
   365 	if (_patches.realistic_acceleration && e->railtype != RAILTYPE_MAGLEV) {
       
   366 		SetDParam(0, ((rvi->weight << multihead) * 10 * rvi->tractive_effort) / 256);
       
   367 		DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, 0);
       
   368 		y += 10;
       
   369 	}
       
   370 
       
   371 	/* Running cost */
       
   372 	SetDParam(0, (rvi->running_cost_base * _price.running_rail[rvi->running_cost_class] >> 8) << multihead);
       
   373 	DrawString(x,y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
       
   374 	y += 10;
       
   375 
       
   376 	/* Powered wagons power - Powered wagons extra weight */
       
   377 	if (rvi->pow_wag_power != 0) {
       
   378 		SetDParam(0, rvi->pow_wag_power);
       
   379 		SetDParam(1, rvi->pow_wag_weight);
       
   380 		DrawString(x,y, STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT, 0);
       
   381 		y += 10;
       
   382 	};
       
   383 
       
   384 	return y;
       
   385 }
       
   386 
       
   387 /* Draw aircraft specific details */
       
   388 static int DrawVehiclePurchaseInfo(int x, int y, EngineID engine_number, const AircraftVehicleInfo *avi)
       
   389 {
   206 	CargoID cargo;
   390 	CargoID cargo;
   207 	YearMonthDay ymd;
       
   208 	ConvertDateToYMD(e->intro_date, &ymd);
       
   209 
   391 
   210 	/* Purchase cost - Max speed */
   392 	/* Purchase cost - Max speed */
   211 	SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
   393 	SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
   212 	SetDParam(1, avi->max_speed * 128 / 10);
   394 	SetDParam(1, avi->max_speed * 128 / 10);
   213 	DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
   395 	DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
   232 	/* Running cost */
   414 	/* Running cost */
   233 	SetDParam(0, avi->running_cost * _price.aircraft_running >> 8);
   415 	SetDParam(0, avi->running_cost * _price.aircraft_running >> 8);
   234 	DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
   416 	DrawString(x, y, STR_PURCHASE_INFO_RUNNINGCOST, 0);
   235 	y += 10;
   417 	y += 10;
   236 
   418 
   237 	/* Design date - Life length */
   419 	return y;
   238 	SetDParam(0, ymd.year);
   420 }
   239 	SetDParam(1, e->lifelength);
   421 
   240 	DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
   422 /**
   241 	y += 10;
   423  * Draw the purchase info details of a vehicle at a given location.
   242 
   424  * @param x,y location where to draw the info
   243 	/* Reliability */
   425  * @param w how wide are the text allowed to be (size of widget/window to Draw in)
   244 	SetDParam(0, e->reliability * 100 >> 16);
   426  * @param engine_number the engine of which to draw the info of
   245 	DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0);
   427  */
   246 	y += 10;
   428 void DrawVehiclePurchaseInfo(int x, int y, uint w, EngineID engine_number)
       
   429 {
       
   430 	const Engine *e = GetEngine(engine_number);
       
   431 	YearMonthDay ymd;
       
   432 	ConvertDateToYMD(e->intro_date, &ymd);
       
   433 
       
   434 	switch (e->type) {
       
   435 		case VEH_Train: {
       
   436 			const RailVehicleInfo *rvi = RailVehInfo(engine_number);
       
   437 
       
   438 			if (rvi->flags & RVI_WAGON) {
       
   439 				y = DrawVehiclePurchaseInfo(x, y, engine_number, rvi);
       
   440 			} else {
       
   441 				y = DrawVehiclePurchaseInfo(x, y, engine_number, rvi, e);
       
   442 			}
       
   443 
       
   444 			/* Cargo type + capacity, or N/A */
       
   445 			if (rvi->capacity == 0) {
       
   446 				SetDParam(0, CT_INVALID);
       
   447 				SetDParam(2, STR_EMPTY);
       
   448 			} else {
       
   449 				int multihead = (rvi->flags & RVI_MULTIHEAD ? 1 : 0);
       
   450 				SetDParam(0, rvi->cargo_type);
       
   451 				SetDParam(1, (rvi->capacity * (CountArticulatedParts(engine_number) + 1)) << multihead);
       
   452 				SetDParam(2, STR_9842_REFITTABLE);
       
   453 			}
       
   454 			DrawString(x,y, STR_PURCHASE_INFO_CAPACITY, 0);
       
   455 			y += 10;
       
   456 		}
       
   457 			break;
       
   458 		case VEH_Aircraft:
       
   459 			y = DrawVehiclePurchaseInfo(x, y, engine_number, AircraftVehInfo(engine_number));
       
   460 			break;
       
   461 		default: NOT_REACHED();
       
   462 	}
       
   463 
       
   464 	/* Draw details, that applies to all types except rail wagons */
       
   465 	if (e->type != VEH_Train || (RailVehInfo(engine_number)->flags & RVI_WAGON == 0)) {
       
   466 		/* Design date - Life length */
       
   467 		SetDParam(0, ymd.year);
       
   468 		SetDParam(1, e->lifelength);
       
   469 		DrawString(x, y, STR_PURCHASE_INFO_DESIGNED_LIFE, 0);
       
   470 		y += 10;
       
   471 
       
   472 		/* Reliability */
       
   473 		SetDParam(0, e->reliability * 100 >> 16);
       
   474 		DrawString(x, y, STR_PURCHASE_INFO_RELIABILITY, 0);
       
   475 		y += 10;
       
   476 	}
   247 
   477 
   248 	/* Additional text from NewGRF */
   478 	/* Additional text from NewGRF */
   249 	y += ShowAdditionalText(x, y, w, engine_number);
   479 	y += ShowAdditionalText(x, y, w, engine_number);
   250 	y += ShowRefitOptionsList(x, y, w, engine_number);
   480 	switch (e->type) {
       
   481 		case VEH_Train: {
       
   482 			const RailVehicleInfo *rvi = RailVehInfo(engine_number);
       
   483 			if (rvi->capacity > 0) y += ShowRefitOptionsList(x, y, w, engine_number);
       
   484 		} break;
       
   485 		case VEH_Aircraft:
       
   486 			y += ShowRefitOptionsList(x, y, w, engine_number);
       
   487 			break;
       
   488 	}
   251 }
   489 }
   252 
   490 
   253 void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
   491 void DrawAircraftImage(const Vehicle *v, int x, int y, VehicleID selection)
   254 {
   492 {
   255 	SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
   493 	SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
   275 		}
   513 		}
   276 		ShowAircraftViewWindow(v);
   514 		ShowAircraftViewWindow(v);
   277 	}
   515 	}
   278 }
   516 }
   279 
   517 
       
   518 /* Figure out what train EngineIDs to put in the list */
       
   519 static void GenerateBuildTrainList(Window *w)
       
   520 {
       
   521 	EngineID eid, sel_id;
       
   522 	int num_engines = 0;
       
   523 	int num_wagons  = 0;
       
   524 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
       
   525 
       
   526 	bv->filter.railtype = (w->window_number == 0) ? RAILTYPE_END : GetRailType(w->window_number);
       
   527 
       
   528 	EngList_RemoveAll(&bv->eng_list);
       
   529 
       
   530 	/* Make list of all available train engines and wagons.
       
   531 		* Also check to see if the previously selected engine is still available,
       
   532 		* and if not, reset selection to INVALID_ENGINE. This could be the case
       
   533 	* when engines become obsolete and are removed */
       
   534 	for (sel_id = INVALID_ENGINE, eid = 0; eid < NUM_TRAIN_ENGINES; eid++) {
       
   535 		const Engine *e = GetEngine(eid);
       
   536 		const RailVehicleInfo *rvi = RailVehInfo(eid);
       
   537 
       
   538 		if (bv->filter.railtype != RAILTYPE_END && !HasPowerOnRail(e->railtype, bv->filter.railtype)) continue;
       
   539 		if (!IsEngineBuildable(eid, VEH_Train, _local_player)) continue;
       
   540 
       
   541 		EngList_Add(&bv->eng_list, eid);
       
   542 		if ((rvi->flags & RVI_WAGON) == 0) {
       
   543 			num_engines++;
       
   544 		} else {
       
   545 			num_wagons++;
       
   546 		}
       
   547 
       
   548 		if (eid == bv->sel_engine) sel_id = eid;
       
   549 	}
       
   550 
       
   551 	bv->sel_engine = sel_id;
       
   552 
       
   553 	// make engines first, and then wagons, sorted by ListPositionOfEngine()
       
   554 	_internal_sort_order = false;
       
   555 	EngList_Sort(&bv->eng_list, TrainEnginesThenWagonsSorter);
       
   556 
       
   557 	// and then sort engines
       
   558 	_internal_sort_order = bv->descending_sort_order;
       
   559 	EngList_SortPartial(&bv->eng_list, _train_sorter[bv->sort_criteria], 0, num_engines);
       
   560 
       
   561 	// and finally sort wagons
       
   562 	EngList_SortPartial(&bv->eng_list, _train_sorter[bv->sort_criteria], num_engines, num_wagons);
       
   563 }
       
   564 
       
   565 /* Figure out what aircraft EngineIDs to put in the list */
   280 static void GenerateBuildAircraftList(Window *w)
   566 static void GenerateBuildAircraftList(Window *w)
   281 {
   567 {
   282 	EngineID eid, sel_id;
   568 	EngineID eid, sel_id;
   283 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   569 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   284 
   570 
   312 	}
   598 	}
   313 
   599 
   314 	bv->sel_engine = sel_id;
   600 	bv->sel_engine = sel_id;
   315 }
   601 }
   316 
   602 
       
   603 /* Generate the list of vehicles */
   317 static void GenerateBuildList(Window *w)
   604 static void GenerateBuildList(Window *w)
   318 {
   605 {
   319 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   606 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   320 
   607 
   321 	switch (bv->vehicle_type) {
   608 	switch (bv->vehicle_type) {
       
   609 		case VEH_Train:
       
   610 			GenerateBuildTrainList(w);
       
   611 			break;
   322 		case VEH_Aircraft:
   612 		case VEH_Aircraft:
   323 			GenerateBuildAircraftList(w);
   613 			GenerateBuildAircraftList(w);
   324 			_internal_sort_order = bv->descending_sort_order;
   614 			_internal_sort_order = bv->descending_sort_order;
   325 			EngList_Sort(&bv->eng_list, _aircraft_sorter[bv->sort_criteria]);
   615 			EngList_Sort(&bv->eng_list, _aircraft_sorter[bv->sort_criteria]);
   326 			break;
   616 			break;
   327 
   617 	}
   328 		default: NOT_REACHED();
   618 }
   329 	}
   619 
   330 }
   620 static void DrawBuildVehicleWindow(Window *w)
   331 
       
   332 static void DrawBuildAircraftWindow(Window *w)
       
   333 {
   621 {
   334 	const buildvehicle_d *bv = &WP(w, buildvehicle_d);
   622 	const buildvehicle_d *bv = &WP(w, buildvehicle_d);
   335 
   623 
   336 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
   624 	SetWindowWidgetDisabledState(w, BUILD_VEHICLE_WIDGET_BUILD, w->window_number == 0);
   337 
   625 
   338 	SetVScrollCount(w, EngList_Count(&bv->eng_list));
   626 	SetVScrollCount(w, EngList_Count(&bv->eng_list));
       
   627 	SetDParam(0, bv->filter.railtype + STR_881C_NEW_RAIL_VEHICLES); // This should only affect rail vehicles
   339 	DrawWindowWidgets(w);
   628 	DrawWindowWidgets(w);
   340 
   629 
   341 	{
   630 	{
   342 		int x = 2;
   631 		int x = 2;
   343 		int y = 27;
   632 		int y = 27;
   344 		EngineID selected_id = bv->sel_engine;
   633 		EngineID selected_id = bv->sel_engine;
   345 		EngineID eid = w->vscroll.pos;
   634 		uint16 position = w->vscroll.pos;
   346 		uint16 max = min(w->vscroll.pos + w->vscroll.cap, EngList_Count(&bv->eng_list));
   635 		uint16 max = min(w->vscroll.pos + w->vscroll.cap, EngList_Count(&bv->eng_list));
   347 
   636 
   348 		for (; eid < max; eid++) {
   637 		switch (bv->vehicle_type) {
   349 			const EngineID engine = bv->eng_list[eid];
   638 			case VEH_Train:
   350 
   639 				for (; position < max; position++, y += 14) {
   351 			DrawString(x + 62, y + 7, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10);
   640 					const EngineID engine = bv->eng_list[position];
   352 			DrawAircraftEngine(x + 29, y + 10, engine, GetEnginePalette(engine, _local_player));
   641 
   353 			y += 24;
   642 					DrawString(x + 59, y + 2, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10);
       
   643 					DrawTrainEngine(x + 29, y + 6, engine, GetEnginePalette(engine, _local_player));
       
   644 				}
       
   645 				break;
       
   646 			case VEH_Aircraft:
       
   647 				for (; position < max; position++, y += 24) {
       
   648 					const EngineID engine = bv->eng_list[position];
       
   649 
       
   650 					DrawString(x + 62, y + 7, GetCustomEngineName(engine), engine == selected_id ? 0xC : 0x10);
       
   651 					DrawAircraftEngine(x + 29, y + 10, engine, GetEnginePalette(engine, _local_player));
       
   652 				}
       
   653 				break;
   354 		}
   654 		}
   355 
   655 
   356 		if (selected_id != INVALID_ENGINE) {
   656 		if (selected_id != INVALID_ENGINE) {
   357 			const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL];
   657 			const Widget *wi = &w->widget[BUILD_VEHICLE_WIDGET_PANEL];
   358 			DrawAircraftPurchaseInfo(x, wi->top + 1, wi->right - wi->left - 2, selected_id);
   658 			DrawVehiclePurchaseInfo(x, wi->top + 1, wi->right - wi->left - 2, selected_id);
   359 		}
   659 		}
   360 	}
   660 	}
   361 	DrawString(85, 15, _aircraft_sort_listing[bv->sort_criteria], 0x10);
   661 	{
   362 	DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
   662 		StringID str = STR_NULL;
   363 }
   663 		switch (bv->vehicle_type) {
   364 
   664 			case VEH_Train:    str = _train_sort_listing[bv->sort_criteria];    break;
   365 static void BuildAircraftClickEvent(Window *w, WindowEvent *e)
   665 			case VEH_Aircraft: str = _aircraft_sort_listing[bv->sort_criteria]; break;
       
   666 		}
       
   667 
       
   668 		DrawString(85, 15, str, 0x10);
       
   669 		DoDrawString(bv->descending_sort_order ? DOWNARROW : UPARROW, 69, 15, 0x10);
       
   670 	}
       
   671 }
       
   672 
       
   673 static void BuildVehicleClickEvent(Window *w, WindowEvent *e)
   366 {
   674 {
   367 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   675 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   368 
   676 
   369 	switch (e->we.click.widget) {
   677 	switch (e->we.click.widget) {
   370 		case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING:
   678 		case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING:
   371 			bv->descending_sort_order ^= true;
   679 			bv->descending_sort_order ^= true;
   372 			_last_sort_order = bv->descending_sort_order;
   680 			switch (bv->vehicle_type) {
       
   681 				case VEH_Train:    _last_sort_order_train    = bv->descending_sort_order; break;
       
   682 				case VEH_Aircraft: _last_sort_order_aircraft = bv->descending_sort_order; break;
       
   683 			}
   373 			GenerateBuildList(w);
   684 			GenerateBuildList(w);
   374 			SetWindowDirty(w);
   685 			SetWindowDirty(w);
   375 			break;
   686 			break;
   376 
   687 
   377 		case BUILD_VEHICLE_WIDGET_LIST: {
   688 		case BUILD_VEHICLE_WIDGET_LIST: {
   378 			uint i = (e->we.click.pt.y - 26) / 24 + w->vscroll.pos;
   689 			uint i = (e->we.click.pt.y - 26) / GetVehicleListHeight(bv->vehicle_type) + w->vscroll.pos;
   379 			uint num_items = EngList_Count(&bv->eng_list);
   690 			uint num_items = EngList_Count(&bv->eng_list);
   380 			bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE;
   691 			bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE;
   381 			SetWindowDirty(w);
   692 			SetWindowDirty(w);
   382 			break;
   693 			break;
   383 		}
   694 		}
   384 
   695 
   385 		case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN:/* Select sorting criteria dropdown menu */
   696 		case BUILD_VEHICLE_WIDGET_SORT_TEXT: case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN: // Select sorting criteria dropdown menu
   386 			ShowDropDownMenu(w, _aircraft_sort_listing, bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
   697 			switch (bv->vehicle_type) {
       
   698 				case VEH_Train:
       
   699 					ShowDropDownMenu(w, _train_sort_listing, bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
       
   700 					break;
       
   701 				case VEH_Aircraft:
       
   702 					ShowDropDownMenu(w, _aircraft_sort_listing, bv->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
       
   703 					break;
       
   704 			}
   387 			return;
   705 			return;
   388 
   706 
   389 		case BUILD_VEHICLE_WIDGET_BUILD: {
   707 		case BUILD_VEHICLE_WIDGET_BUILD: {
   390 			EngineID sel_eng = bv->sel_engine;
   708 			EngineID sel_eng = bv->sel_engine;
   391 			if (sel_eng != INVALID_ENGINE) {
   709 			if (sel_eng != INVALID_ENGINE) {
   392 				DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
   710 				switch (bv->vehicle_type) {
       
   711 					case VEH_Train:
       
   712 						DoCommandP(w->window_number, sel_eng, 0, (RailVehInfo(sel_eng)->flags & RVI_WAGON) ? CcBuildWagon : CcBuildLoco,
       
   713 								   CMD_BUILD_RAIL_VEHICLE | CMD_MSG(STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE));
       
   714 						break;
       
   715 					case VEH_Aircraft:
       
   716 						DoCommandP(w->window_number, sel_eng, 0, CcBuildAircraft, CMD_BUILD_AIRCRAFT | CMD_MSG(STR_A008_CAN_T_BUILD_AIRCRAFT));
       
   717 						break;
       
   718 				}
   393 			}
   719 			}
   394 			break;
   720 			break;
   395 		}
   721 		}
   396 
   722 
   397 		case BUILD_VEHICLE_WIDGET_RENAME: {
   723 		case BUILD_VEHICLE_WIDGET_RENAME: {
   398 			EngineID sel_eng = bv->sel_engine;
   724 			EngineID sel_eng = bv->sel_engine;
   399 			if (sel_eng != INVALID_ENGINE) {
   725 			if (sel_eng != INVALID_ENGINE) {
       
   726 				StringID str = STR_NULL;
       
   727 
   400 				bv->rename_engine = sel_eng;
   728 				bv->rename_engine = sel_eng;
   401 				ShowQueryString(GetCustomEngineName(sel_eng), STR_A039_RENAME_AIRCRAFT_TYPE, 31, 160, w, CS_ALPHANUMERAL);
   729 				switch (bv->vehicle_type) {
       
   730 					case VEH_Train:    str = STR_886A_RENAME_TRAIN_VEHICLE_TYPE; break;
       
   731 					case VEH_Aircraft: str = STR_A039_RENAME_AIRCRAFT_TYPE;      break;
       
   732 				}
       
   733 				ShowQueryString(GetCustomEngineName(sel_eng), str, 31, 160, w, CS_ALPHANUMERAL);
   402 			}
   734 			}
   403 			break;
   735 			break;
   404 		}
   736 		}
   405 	}
   737 	}
   406 }
   738 }
   407 
   739 
   408 static void NewAircraftWndProc(Window *w, WindowEvent *e)
   740 static void NewVehicleWndProc(Window *w, WindowEvent *e)
   409 {
   741 {
   410 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   742 	buildvehicle_d *bv = &WP(w, buildvehicle_d);
   411 
   743 
   412 	switch (e->event) {
   744 	switch (e->event) {
   413 		case WE_INVALIDATE_DATA:
   745 		case WE_INVALIDATE_DATA:
   417 		case WE_DESTROY:
   749 		case WE_DESTROY:
   418 			EngList_Destroy(&bv->eng_list);
   750 			EngList_Destroy(&bv->eng_list);
   419 			break;
   751 			break;
   420 
   752 
   421 		case WE_PAINT:
   753 		case WE_PAINT:
   422 			DrawBuildAircraftWindow(w);
   754 			DrawBuildVehicleWindow(w);
   423 			break;
   755 			break;
   424 
   756 
   425 		case WE_CLICK:
   757 		case WE_CLICK:
   426 			BuildAircraftClickEvent(w, e);
   758 			BuildVehicleClickEvent(w, e);
   427 			break;
   759 			break;
   428 
   760 
   429 		case WE_ON_EDIT_TEXT: {
   761 		case WE_ON_EDIT_TEXT: {
   430 			if (e->we.edittext.str[0] != '\0') {
   762 			if (e->we.edittext.str[0] != '\0') {
       
   763 				StringID str = STR_NULL;
   431 				_cmd_text = e->we.edittext.str;
   764 				_cmd_text = e->we.edittext.str;
   432 				DoCommandP(0, bv->rename_engine, 0, NULL, CMD_RENAME_ENGINE | CMD_MSG(STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE));
   765 				switch (bv->vehicle_type) {
       
   766 					case VEH_Train:    str = STR_886B_CAN_T_RENAME_TRAIN_VEHICLE; break;
       
   767 					case VEH_Aircraft: str = STR_A03A_CAN_T_RENAME_AIRCRAFT_TYPE; break;
       
   768 				}
       
   769 				DoCommandP(0, bv->rename_engine, 0, NULL, CMD_RENAME_ENGINE | CMD_MSG(str));
   433 			}
   770 			}
   434 			break;
   771 			break;
   435 		}
   772 		}
   436 
   773 
   437 		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   774 		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
   438 			if (bv->sort_criteria != e->we.dropdown.index) {
   775 			if (bv->sort_criteria != e->we.dropdown.index) {
   439 				bv->sort_criteria = _last_sort_criteria = e->we.dropdown.index;
   776 				bv->sort_criteria = e->we.dropdown.index;
       
   777 				switch (bv->vehicle_type) {
       
   778 					case VEH_Train:    _last_sort_criteria_train    = bv->sort_criteria; break;
       
   779 					case VEH_Aircraft: _last_sort_criteria_aircraft = bv->sort_criteria; break;
       
   780 				}
   440 				GenerateBuildList(w);
   781 				GenerateBuildList(w);
   441 			}
   782 			}
   442 			SetWindowDirty(w);
   783 			SetWindowDirty(w);
   443 			break;
   784 			break;
   444 
   785 
   445 		case WE_RESIZE:
   786 		case WE_RESIZE:
   446 			w->vscroll.cap += e->we.sizing.diff.y / 24;
   787 			if (e->we.sizing.diff.y == 0) break;
       
   788 
       
   789 			w->vscroll.cap += e->we.sizing.diff.y / GetVehicleListHeight(bv->vehicle_type);
   447 			w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
   790 			w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
   448 			break;
   791 			break;
   449 	}
   792 	}
   450 }
   793 }
   451 
   794 
   452 static const WindowDesc _build_vehicle_desc = {
   795 static const WindowDesc _build_vehicle_desc = {
   453 	WDP_AUTO, WDP_AUTO, 240, 226,
   796 	WDP_AUTO, WDP_AUTO, 228, 226,
   454 	WC_BUILD_VEHICLE,0,
   797 	WC_BUILD_VEHICLE,0,
   455 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
   798 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
   456 	_build_vehicle_widgets,
   799 	_build_vehicle_widgets,
   457 	NewAircraftWndProc
   800 	NewVehicleWndProc
   458 };
   801 };
   459 
   802 
   460 void ShowBuildVehicleWindow(TileIndex tile, byte type)
   803 void ShowBuildVehicleWindow(TileIndex tile, byte type)
   461 {
   804 {
   462 	buildvehicle_d *bv;
   805 	buildvehicle_d *bv;
   463 	Window *w;
   806 	Window *w;
   464 
   807 
       
   808 	assert(IsPlayerBuildableVehicleType(type));
       
   809 
   465 	DeleteWindowById(WC_BUILD_VEHICLE, tile);
   810 	DeleteWindowById(WC_BUILD_VEHICLE, tile);
       
   811 
   466 	w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
   812 	w = AllocateWindowDescFront(&_build_vehicle_desc, tile);
       
   813 
   467 	if (w == NULL) return;
   814 	if (w == NULL) return;
   468 
   815 
   469 	w->caption_color = (tile != 0) ? GetTileOwner(tile) : _local_player;
   816 	w->caption_color = (tile != 0) ? GetTileOwner(tile) : _local_player;
   470 	w->resize.step_height = GetVehicleListHeight(type);
   817 	w->resize.step_height = GetVehicleListHeight(type);
   471 	w->vscroll.cap = 4;
   818 	w->vscroll.cap = w->resize.step_height == 24 ? 4 : 8;
   472 	w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
   819 	w->widget[BUILD_VEHICLE_WIDGET_LIST].data = (w->vscroll.cap << 8) + 1;
   473 
   820 
   474 	bv = &WP(w, buildvehicle_d);
   821 	bv = &WP(w, buildvehicle_d);
   475 	EngList_Create(&bv->eng_list);
   822 	EngList_Create(&bv->eng_list);
   476 	bv->sel_engine            = INVALID_ENGINE;
   823 	bv->sel_engine            = INVALID_ENGINE;
   477 	bv->sort_criteria         = _last_sort_criteria;
       
   478 	bv->descending_sort_order = _last_sort_order;
       
   479 
   824 
   480 	bv->vehicle_type = type;
   825 	bv->vehicle_type = type;
   481 
   826 
   482 	switch (type) {
   827 	switch (type) {
       
   828 		case VEH_Train:
       
   829 			WP(w,buildvehicle_d).filter.railtype = (tile == 0) ? RAILTYPE_END : GetRailType(tile);
       
   830 			ResizeWindow(w, 0, 16);
       
   831 			bv->sort_criteria         = _last_sort_criteria_train;
       
   832 			bv->descending_sort_order = _last_sort_order_train;
       
   833 			break;
   483 		case VEH_Aircraft: {
   834 		case VEH_Aircraft: {
   484 			AcceptPlanes acc_planes = (tile == 0) ? ALL : GetAirport(GetStationByTile(tile)->airport_type)->acc_planes;
   835 			AcceptPlanes acc_planes = (tile == 0) ? ALL : GetAirport(GetStationByTile(tile)->airport_type)->acc_planes;
   485 			bv->filter.acc_planes = acc_planes;
   836 			bv->filter.acc_planes = acc_planes;
   486 			break;
   837 			ResizeWindow(w, 12, 0);
   487 		}
   838 			bv->sort_criteria         = _last_sort_criteria_aircraft;
   488 		default: NOT_REACHED();
   839 			bv->descending_sort_order = _last_sort_order_aircraft;
   489 	}
   840 			break;
       
   841 		}
       
   842 	}
       
   843 	SetupWindowStrings(w, type);
       
   844 
       
   845 	w->resize.width  = w->width;
       
   846 	w->resize.height = w->height;
   490 
   847 
   491 	GenerateBuildList(w);
   848 	GenerateBuildList(w);
   492 	/* Select the first plane in the list as default when opening the window */
   849 	/* Select the first engine in the list as default when opening the window */
   493 	if (EngList_Count(&bv->eng_list) > 0) bv->sel_engine = bv->eng_list[0];
   850 	if (EngList_Count(&bv->eng_list) > 0) bv->sel_engine = bv->eng_list[0];
   494 }
   851 }