diff -r f661592a2917 src/build_vehicle_gui.cpp
--- src/build_vehicle_gui.cpp	Tue Jun 03 12:11:16 2008 +0000
+++ src/build_vehicle_gui.cpp	Tue Jun 03 21:10:28 2008 +0800
@@ -39,6 +39,7 @@
 	BUILD_VEHICLE_WIDGET_CAPTION,
 	BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING,
 	BUILD_VEHICLE_WIDGET_SORT_DROPDOWN,
+	BUILD_VEHICLE_WIDGET_CARGO_DROPDOWN,
 	BUILD_VEHICLE_WIDGET_LIST,
 	BUILD_VEHICLE_WIDGET_SCROLLBAR,
 	BUILD_VEHICLE_WIDGET_PANEL,
@@ -50,19 +51,30 @@
 
 static const Widget _build_vehicle_widgets[] = {
 	{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW },
-	{    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   239,     0,    13, 0x0,                     STR_018C_WINDOW_TITLE_DRAG_THIS },
-	{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,    80,    14,    25, STR_SORT_BY,             STR_SORT_ORDER_TIP},
-	{   WWT_DROPDOWN,  RESIZE_RIGHT,    14,    81,   239,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},
-	{     WWT_MATRIX,     RESIZE_RB,    14,     0,   227,    26,    39, 0x101,                   STR_NULL },
-	{  WWT_SCROLLBAR,    RESIZE_LRB,    14,   228,   239,    26,    39, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
-	{      WWT_PANEL,    RESIZE_RTB,    14,     0,   239,    40,   161, 0x0,                     STR_NULL },
+	{    WWT_CAPTION,  RESIZE_RIGHT,    14,    11,   293,     0,    13, 0x0,                     STR_018C_WINDOW_TITLE_DRAG_THIS },
+	{ WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,    60,    14,    25, STR_SORT_BY,             STR_SORT_ORDER_TIP},
+	{   WWT_DROPDOWN,   RESIZE_NONE,    14,    61,   190,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},
+	{   WWT_DROPDOWN,  RESIZE_RIGHT,    14,   191,   293,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},
+	{     WWT_MATRIX,     RESIZE_RB,    14,     0,   281,    26,    39, 0x101,                   STR_NULL },
+	{  WWT_SCROLLBAR,    RESIZE_LRB,    14,   282,   293,    26,    39, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST },
+	{      WWT_PANEL,    RESIZE_RTB,    14,     0,   293,    40,   161, 0x0,                     STR_NULL },
 
-	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   162,   173, 0x0,                     STR_NULL },
-	{ WWT_PUSHTXTBTN,    RESIZE_RTB,    14,   115,   227,   162,   173, 0x0,                     STR_NULL },
-	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   228,   239,   162,   173, 0x0,                     STR_RESIZE_BUTTON },
+	{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   114,   162,   173, 0x0,                         STR_NULL },
+	{ WWT_PUSHTXTBTN,    RESIZE_RTB,    14,   115,   281,   162,   173, 0x0,                         STR_NULL },
+	{  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   282,   293,   162,   173, 0x0,                         STR_RESIZE_BUTTON },
 	{   WIDGETS_END},
 };
 
+enum cargo_filter {
+	CF_SHOW_ALL = NUM_CARGO
+};
+
+static int _cargo_filter_train = CF_SHOW_ALL;
+static int _cargo_filter_road = CF_SHOW_ALL;
+static int _cargo_filter_ship = CF_SHOW_ALL;
+static int _cargo_filter_aircraft = CF_SHOW_ALL;
+static StringID _cargos_name_list[NUM_CARGO + 1];
+static int _cargos_dropdown_pos[NUM_CARGO + 1];
 static bool _internal_sort_order; // descending/ascending
 static byte _last_sort_criteria[]    = {0, 0, 0, 0};
 static bool _last_sort_order[]       = {false, false, false, false};
@@ -826,6 +838,21 @@
 		this->sel_engine      = INVALID_ENGINE;
 		this->regenerate_list = false;
 
+		/* Create cargo filter list  */
+		_cargos_name_list[0] = STR_PURCHASE_INFO_ALL_TYPES;
+		_cargos_dropdown_pos[CF_SHOW_ALL] = 0;
+
+		uint i = 1;
+		for (CargoID c = 0; c < NUM_CARGO; c++) {
+			if (!GetCargo(c)->IsValid()) continue;
+
+			_cargos_name_list[i] = GetCargo(c)->name;
+			_cargos_dropdown_pos[c] = i;
+
+			i++;
+		}
+		_cargos_name_list[i] = INVALID_STRING_ID;
+
 		this->sort_criteria         = _last_sort_criteria[type];
 		this->descending_sort_order = _last_sort_order[type];
 
@@ -920,6 +947,9 @@
 			if (this->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, this->filter.railtype)) continue;
 			if (!IsEngineBuildable(eid, VEH_TRAIN, _local_player)) continue;
 
+			uint32 cmask = EngInfo(eid)->refit_mask;
+			if (!((_cargo_filter_train == rvi->cargo_type && rvi->capacity > 0) || (HasBit(cmask, _cargo_filter_train))) && (_cargo_filter_train < CF_SHOW_ALL )) continue;
+
 			*this->eng_list.Append() = eid;
 
 			if (rvi->railveh_type != RAILVEH_WAGON) {
@@ -955,8 +985,11 @@
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
 			EngineID eid = e->index;
+			const RoadVehicleInfo *rvi = RoadVehInfo(eid);
 			if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue;
 			if (!HasBit(this->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue;
+			uint32 cmask = EngInfo(eid)->refit_mask;
+			if (!((_cargo_filter_road == rvi->cargo_type && rvi->capacity > 0) || (HasBit(cmask, _cargo_filter_road))) && (_cargo_filter_road < CF_SHOW_ALL )) continue;
 			*this->eng_list.Append() = eid;
 
 			if (eid == this->sel_engine) sel_id = eid;
@@ -973,7 +1006,10 @@
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) {
 			EngineID eid = e->index;
+			const ShipVehicleInfo *svi = ShipVehInfo(eid);
 			if (!IsEngineBuildable(eid, VEH_SHIP, _local_player)) continue;
+			uint32 cmask = EngInfo(eid)->refit_mask;
+			if (!((_cargo_filter_ship == svi->cargo_type && svi->capacity > 0) || (HasBit(cmask, _cargo_filter_ship))) && (_cargo_filter_ship < CF_SHOW_ALL )) continue;
 			*this->eng_list.Append() = eid;
 
 			if (eid == this->sel_engine) sel_id = eid;
@@ -995,10 +1031,13 @@
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) {
 			EngineID eid = e->index;
+			const AircraftVehicleInfo *avi = AircraftVehInfo(eid);
 			if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
 			/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
 			if (this->window_number > VEH_END && !CanAircraftUseStation(eid, this->window_number)) continue;
 
+			uint32 cmask = EngInfo(eid)->refit_mask;
+			if (!((_cargo_filter_aircraft == CT_PASSENGERS && avi->passenger_capacity > 0) || (_cargo_filter_aircraft == CT_MAIL && avi->mail_capacity > 0) || (HasBit(cmask, _cargo_filter_aircraft))) && (_cargo_filter_aircraft < CF_SHOW_ALL )) continue;
 			*this->eng_list.Append() = eid;
 			if (eid == this->sel_engine) sel_id = eid;
 		}
@@ -1049,6 +1088,19 @@
 			case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN: // Select sorting criteria dropdown menu
 				ShowDropDownMenu(this, _sort_listing[this->vehicle_type], this->sort_criteria, BUILD_VEHICLE_WIDGET_SORT_DROPDOWN, 0, 0);
 				break;
+
+			case BUILD_VEHICLE_WIDGET_CARGO_DROPDOWN: {
+				int cargo_filter = CF_SHOW_ALL;
+				switch (this->vehicle_type) {
+					default: NOT_REACHED();
+					case VEH_TRAIN:    cargo_filter = _cargo_filter_train;    break;
+					case VEH_ROAD:     cargo_filter = _cargo_filter_road;     break;
+					case VEH_SHIP:     cargo_filter = _cargo_filter_ship;     break;
+					case VEH_AIRCRAFT: cargo_filter = _cargo_filter_aircraft; break;
+				}
+				ShowDropDownMenu(this, _cargos_name_list, _cargos_dropdown_pos[cargo_filter], BUILD_VEHICLE_WIDGET_CARGO_DROPDOWN, 0, 0);
+				break;
+			}
 
 			case BUILD_VEHICLE_WIDGET_BUILD: {
 				EngineID sel_eng = this->sel_engine;
@@ -1108,6 +1160,15 @@
 
 		uint max = min(this->vscroll.pos + this->vscroll.cap, this->eng_list.Length());
 
+		int cargo_filter = CF_SHOW_ALL;
+		switch (this->vehicle_type) {
+			default: NOT_REACHED();
+			case VEH_TRAIN:    cargo_filter = _cargo_filter_train;    break;
+			case VEH_ROAD:     cargo_filter = _cargo_filter_road;     break;
+			case VEH_SHIP:     cargo_filter = _cargo_filter_ship;     break;
+			case VEH_AIRCRAFT: cargo_filter = _cargo_filter_aircraft; break;
+		}
+
 		this->SetWidgetDisabledState(BUILD_VEHICLE_WIDGET_BUILD, this->window_number <= VEH_END);
 
 		SetVScrollCount(this, this->eng_list.Length());
@@ -1115,6 +1176,7 @@
 
 		/* Set text of sort by dropdown */
 		this->widget[BUILD_VEHICLE_WIDGET_SORT_DROPDOWN].data = _sort_listing[this->vehicle_type][this->sort_criteria];
+		this->widget[BUILD_VEHICLE_WIDGET_CARGO_DROPDOWN].data = _cargos_name_list[_cargos_dropdown_pos[cargo_filter]];
 
 		this->DrawWidgets();
 
@@ -1160,11 +1222,41 @@
 
 	virtual void OnDropdownSelect(int widget, int index)
 	{
-		if (this->sort_criteria != index) {
-			this->sort_criteria = index;
-			_last_sort_criteria[this->vehicle_type] = this->sort_criteria;
-			this->regenerate_list = true;
-		}
+		switch (widget) {
+			case BUILD_VEHICLE_WIDGET_SORT_DROPDOWN:
+				if (this->sort_criteria != index) {
+					this->sort_criteria = index;
+					_last_sort_criteria[this->vehicle_type] = this->sort_criteria;
+				}
+				break;
+
+			case BUILD_VEHICLE_WIDGET_CARGO_DROPDOWN:
+				CargoID c;
+				int cargo_filter;
+
+				if (index > 0) {
+					int i = 1;
+					for (c = 0; c < NUM_CARGO; c++) {
+						if (!GetCargo(c)->IsValid()) continue;
+						if (index == i) break;
+						i++;
+					}
+					cargo_filter = c;
+				}
+				else {
+					cargo_filter = CF_SHOW_ALL;
+				}
+
+				switch (this->vehicle_type) {
+					default: NOT_REACHED();
+					case VEH_TRAIN:    _cargo_filter_train = cargo_filter;    break;
+					case VEH_ROAD:     _cargo_filter_road = cargo_filter;     break;
+					case VEH_SHIP:     _cargo_filter_ship = cargo_filter;     break;
+					case VEH_AIRCRAFT: _cargo_filter_aircraft = cargo_filter; break;
+				}				
+				break;
+		}	
+		this->regenerate_list = true;
 		this->SetDirty();
 	}
 
@@ -1179,7 +1271,7 @@
 };
 
 static const WindowDesc _build_vehicle_desc = {
-	WDP_AUTO, WDP_AUTO, 240, 174, 240, 256,
+	WDP_AUTO, WDP_AUTO, 294, 174, 294, 256,
 	WC_BUILD_VEHICLE, WC_NONE,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
 	_build_vehicle_widgets,
