Index: src/settings.cpp
===================================================================
--- src/settings.cpp	(revision 13592)
+++ src/settings.cpp	(working copy)
@@ -1532,6 +1532,7 @@
 	  SDTG_VAR("invisibility_options", SLE_UINT, S, 0, _invisibility_opt,  0,0, 0xFF,0, STR_NULL, NULL),
 	  SDTG_STR("keyboard",         SLE_STRB, S, 0, _keyboard_opt[0],       NULL,    STR_NULL, NULL),
 	  SDTG_STR("keyboard_caps",    SLE_STRB, S, 0, _keyboard_opt[1],       NULL,    STR_NULL, NULL),
+	  SDTG_LIST("newgrf_window_size",     SLE_UINT16, S, 0, _newgrf_window_size,   "607,237",    STR_NULL, NULL),
 	  SDTG_END()
 };
 
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt	(revision 13592)
+++ src/lang/english.txt	(working copy)
@@ -3143,11 +3143,12 @@
 
 STR_NEWGRF_SETTINGS_BUTTON                                      :{BLACK}NewGRF Settings
 STR_NEWGRF_SETTINGS_CAPTION                                     :{WHITE}NewGRF settings
-STR_NEWGRF_APPLY_CHANGES                                        :{BLACK}Apply changes
-STR_NEWGRF_SET_PARAMETERS                                       :{BLACK}Set parameters
+STR_NEWGRF_APPLY_CHANGES                                        :{BLACK}Apply
+STR_NEWGRF_SET_PARAMETERS                                       :{BLACK}Set params.
 STR_NEWGRF_TIP                                                  :{BLACK}A list of all the Newgrf sets that you have installed. Click a set to change the settings
 STR_NEWGRF_NO_FILES_INSTALLED                                   :{BLACK}There are currently no newgrf files installed! Please refer to the manual for instructions on installing new graphics
 STR_NEWGRF_FILENAME                                             :{BLACK}Filename: {SILVER}{STRING}
+STR_NEWGRF_NAME                                                 :{BLACK}Name: {SILVER}{STRING}
 STR_NEWGRF_GRF_ID                                               :{BLACK}GRF ID: {SILVER}{STRING}
 STR_NEWGRF_MD5SUM                                               :{BLACK}MD5sum: {SILVER}{STRING}
 STR_NEWGRF_CONFIRMATION_TEXT                                    :{YELLOW}You are about to make changes to a running game; this can crash OpenTTD.{}Are you absolutely sure about this?
@@ -3170,10 +3171,14 @@
 STR_NEWGRF_ADD                                                  :{BLACK}Add
 STR_NEWGRF_ADD_TIP                                              :{BLACK}Add a NewGRF file to the list
 STR_NEWGRF_REMOVE                                               :{BLACK}Remove
+STR_NEWGRF_JOINT_ADD                                            :{BLACK}>>
+STR_NEWGRF_JOINT_REMOVE                                         :{BLACK}<<
+STR_NEWGRF_TOGGLE_SHOW                                          :{BLACK}Disp. Mode
+STR_NEWGRF_TOGGLE_SHOW_TIP                                      :{BLACK}Toggles filtering of already selected grfs in the left list. Ctrl-click toggles show file names in stead of grf names.
 STR_NEWGRF_REMOVE_TIP                                           :{BLACK}Remove the selected NewGRF file from the list
-STR_NEWGRF_MOVEUP                                               :{BLACK}Move Up
+STR_NEWGRF_MOVEUP                                               :{BLACK}Up
 STR_NEWGRF_MOVEUP_TIP                                           :{BLACK}Move the selected NewGRF file up the list
-STR_NEWGRF_MOVEDOWN                                             :{BLACK}Move Down
+STR_NEWGRF_MOVEDOWN                                             :{BLACK}Down
 STR_NEWGRF_MOVEDOWN_TIP                                         :{BLACK}Move the selected NewGRF file down the list
 STR_NEWGRF_FILE_TIP                                             :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
 STR_NEWGRF_PARAMETER                                            :{BLACK}Parameters: {SILVER}{STRING}
@@ -3183,7 +3188,7 @@
 STR_NEWGRF_ADD_CAPTION                                          :{WHITE}Available NewGRF files
 STR_NEWGRF_ADD_FILE                                             :{BLACK}Add to selection
 STR_NEWGRF_ADD_FILE_TIP                                         :{BLACK}Add the selected NewGRF file to your configuration
-STR_NEWGRF_RESCAN_FILES                                         :{BLACK}Rescan files
+STR_NEWGRF_RESCAN_FILES                                         :{BLACK}Rescan
 STR_NEWGRF_RESCAN_FILES_TIP                                     :{BLACK}Update the list of available NewGRF files
 STR_NEWGRF_DUPLICATE_GRFID                                      :{WHITE}Cannot add file: duplicate GRF ID
 
Index: src/newgrf_gui.cpp
===================================================================
--- src/newgrf_gui.cpp	(revision 13592)
+++ src/newgrf_gui.cpp	(working copy)
@@ -15,6 +15,7 @@
 #include "core/alloc_func.hpp"
 #include "string_func.h"
 #include "gfx_func.h"
+#include "tilehighlight_func.h"
 #include "gamelog.h"
 
 #include "table/strings.h"
@@ -45,7 +46,7 @@
 }
 
 
-static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bottom, bool show_params)
+static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bottom, bool show_params, bool show_filenames)
 {
 	char buff[256];
 
@@ -70,8 +71,8 @@
 
 	/* Draw filename or not if it is not known (GRF sent over internet) */
 	if (c->filename != NULL) {
-		SetDParamStr(0, c->filename);
-		y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w, bottom - y);
+		SetDParamStr(0, (show_filenames) ? c->name : c->filename);
+		y += DrawStringMultiLine(x, y,  (show_filenames) ? STR_NEWGRF_NAME : STR_NEWGRF_FILENAME, w, bottom - y);
 	}
 
 	/* Prepare and draw GRF ID */
@@ -109,185 +110,56 @@
 	}
 }
 
-
-/**
- * Window for adding NewGRF files
- */
-struct NewGRFAddWindow : public Window {
-	/* Names of the add a newgrf window widgets */
-	enum AddNewGRFWindowWidgets {
-		ANGRFW_CLOSEBOX = 0,
-		ANGRFW_CAPTION,
-		ANGRFW_BACKGROUND,
-		ANGRFW_GRF_LIST,
-		ANGRFW_SCROLLBAR,
-		ANGRFW_GRF_INFO,
-		ANGRFW_ADD,
-		ANGRFW_RESCAN,
-		ANGRFW_RESIZE,
-	};
-
-	GRFConfig **list;
-	const GRFConfig *sel;
-
-	NewGRFAddWindow(const WindowDesc *desc, GRFConfig **list) : Window(desc, 0)
-	{
-		this->list = list;
-		this->resize.step_height = 10;
-
-		this->FindWindowPlacementAndResize(desc);
-	}
-
-	virtual void OnPaint()
-	{
-		const GRFConfig *c;
-		const Widget *wl = &this->widget[ANGRFW_GRF_LIST];
-		int n = 0;
-
-		/* Count the number of GRFs */
-		for (c = _all_grfs; c != NULL; c = c->next) n++;
-
-		this->vscroll.cap = (wl->bottom - wl->top) / 10;
-		SetVScrollCount(this, n);
-
-		this->SetWidgetDisabledState(ANGRFW_ADD, this->sel == NULL || this->sel->IsOpenTTDBaseGRF());
-		this->DrawWidgets();
-
-		GfxFillRect(wl->left + 1, wl->top + 1, wl->right, wl->bottom, 0xD7);
-
-		uint y = wl->top + 1;
-		for (c = _all_grfs, n = 0; c != NULL && n < (this->vscroll.pos + this->vscroll.cap); c = c->next, n++) {
-			if (n >= this->vscroll.pos) {
-				bool h = c == this->sel;
-				const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
-
-				/* Draw selection background */
-				if (h) GfxFillRect(3, y, this->width - 15, y + 9, 156);
-				DoDrawStringTruncated(text, 4, y, h ? TC_WHITE : TC_ORANGE, this->width - 18);
-				y += 10;
-			}
-		}
-
-		if (this->sel != NULL) {
-			const Widget *wi = &this->widget[ANGRFW_GRF_INFO];
-			ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, false);
-		}
-	}
-
-	virtual void OnDoubleClick(Point pt, int widget)
-	{
-		if (widget == ANGRFW_GRF_LIST) this->OnClick(pt, ANGRFW_ADD);
-	}
-
-	virtual void OnClick(Point pt, int widget)
-	{
-		switch (widget) {
-			case ANGRFW_GRF_LIST: {
-				/* Get row... */
-				const GRFConfig *c;
-				uint i = (pt.y - this->widget[ANGRFW_GRF_LIST].top) / 10 + this->vscroll.pos;
-
-				for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--) {}
-				this->sel = c;
-				this->SetDirty();
-				break;
-			}
-
-			case ANGRFW_ADD: // Add selection to list
-				if (this->sel != NULL) {
-					const GRFConfig *src = this->sel;
-					GRFConfig **list;
-
-					/* Find last entry in the list, checking for duplicate grfid on the way */
-					for (list = this->list; *list != NULL; list = &(*list)->next) {
-						if ((*list)->grfid == src->grfid) {
-							ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
-							return;
-						}
-					}
-
-					/* Copy GRF details from scanned list */
-					GRFConfig *c = CallocT<GRFConfig>(1);
-					*c = *src;
-					c->filename = strdup(src->filename);
-					if (src->name      != NULL) c->name      = strdup(src->name);
-					if (src->info      != NULL) c->info      = strdup(src->info);
-					c->next = NULL;
-
-					/* Append GRF config to configuration list */
-					*list = c;
-
-					DeleteWindowByClass(WC_SAVELOAD);
-					InvalidateWindowData(WC_GAME_OPTIONS, 0);
-				}
-				break;
-
-			case ANGRFW_RESCAN: // Rescan list
-				this->sel = NULL;
-				ScanNewGRFFiles();
-				this->SetDirty();
-				break;
-		}
-	}
-};
-
-/* Widget definition for the add a newgrf window */
-static const Widget _newgrf_add_dlg_widgets[] = {
-{   WWT_CLOSEBOX,    RESIZE_NONE, 14,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW },           // ANGRFW_CLOSEBOX
-{    WWT_CAPTION,   RESIZE_RIGHT, 14,  11, 306,   0,  13, STR_NEWGRF_ADD_CAPTION,  STR_018C_WINDOW_TITLE_DRAG_THIS }, // ANGRFW_CAPTION
-{      WWT_PANEL,      RESIZE_RB, 14,   0, 294,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_BACKGROUND
-{      WWT_INSET,      RESIZE_RB, 14,   2, 292,  16, 119, 0x0,                     STR_NULL },                        // ANGRFW_GRF_LIST
-{  WWT_SCROLLBAR,     RESIZE_LRB, 14, 295, 306,  14, 121, 0x0,                     STR_NULL },                        // ANGRFW_SCROLLBAR
-{      WWT_PANEL,     RESIZE_RTB, 14,   0, 306, 122, 224, 0x0,                     STR_NULL },                        // ANGRFW_GRF_INFO
-{ WWT_PUSHTXTBTN,     RESIZE_RTB, 14,   0, 146, 225, 236, STR_NEWGRF_ADD_FILE,     STR_NEWGRF_ADD_FILE_TIP },         // ANGRFW_ADD
-{ WWT_PUSHTXTBTN,    RESIZE_LRTB, 14, 147, 294, 225, 236, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP },     // ANGRFW_RESCAN
-{  WWT_RESIZEBOX,    RESIZE_LRTB, 14, 295, 306, 225, 236, 0x0,                     STR_RESIZE_BUTTON },               // ANGRFW_RESIZE
-{   WIDGETS_END },
-};
-
-/* Window definition for the add a newgrf window */
-static const WindowDesc _newgrf_add_dlg_desc = {
-	WDP_CENTER, WDP_CENTER, 307, 237, 307, 337,
-	WC_SAVELOAD, WC_NONE,
-	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
-	_newgrf_add_dlg_widgets,
-};
-
-
 static void NewGRFConfirmationCallback(Window *w, bool confirmed);
 
 /**
- * Window for showing NewGRF files
+ * Combined NewGrf Window 
  */
 struct NewGRFWindow : public Window {
-	/* Names of the manage newgrfs window widgets */
-	enum ShowNewGRFStateWidgets {
-		SNGRFS_CLOSEBOX = 0,
-		SNGRFS_CAPTION,
-		SNGRFS_BACKGROUND,
-		SNGRFS_ADD,
-		SNGRFS_REMOVE,
-		SNGRFS_MOVE_UP,
-		SNGRFS_MOVE_DOWN,
-		SNGRFS_FILE_LIST,
-		SNGRFS_SCROLLBAR,
-		SNGRFS_NEWGRF_INFO,
-		SNGRFS_SET_PARAMETERS,
-		SNGRFS_APPLY_CHANGES,
-		SNGRFS_RESIZE,
+
+	/* Names of the window widgets */
+	enum NewGRFListWindowWidgets {
+		NLW_WIDGET_CLOSE = 0,
+		NLW_WIDGET_CAPTION,
+		NLW_WIDGET_AVAILABLE_GRF_CAPTION,
+		NLW_WIDGET_EMPTY1,
+		NLW_WIDGET_AVAILABLE_GRF_LIST,
+		NLW_WIDGET_AVAILABLE_GRF_LIST_SCROLLBAR,
+		NLW_WIDGET_NEWGRF_INFO_LEFT,
+		NLW_WIDGET_RESCAN_FILES,
+		NLW_WIDGET_TOGGLE_SHOW_MODE,
+		NLW_WIDGET_EMPTY_MIDDLE,
+		NLW_WIDGET_EMPTY_BOTTOM_MIDDLE,
+		NLW_WIDGET_EMPTY_TOP_RIGHT,
+		NLW_WIDGET_ADD_FILE,
+		NLW_WIDGET_REMOVE,
+		NLW_WIDGET_MOVE_UP,
+		NLW_WIDGET_MOVE_DOWN,
+		NLW_WIDGET_FILE_LIST,
+		NLW_WIDGET_FILE_LIST_SCROLLBAR,
+		NLW_WIDGET_NEWGRF_INFO_RIGHT,
+		NLW_WIDGET_SET_PARAMETERS,
+		NLW_WIDGET_APPLY_CHANGES,
 	};
+	
+	const GRFConfig *sel_l;
+	GRFConfig **orig_list;   ///< grf list the window is shown with
+	GRFConfig *list;         ///< temporary grf list to which changes are made
+	GRFConfig *sel_r;        ///< selected grf item
+	bool editable;           ///< is the window editable
+	bool show_params;        ///< are the grf-parameters shown in the info-panel
+	bool execute;            ///< on pressing 'apply changes' are grf changes applied immediately, or only list is updated
+	bool show_all;
+	bool show_file_names;
 
-	GRFConfig **orig_list; ///< grf list the window is shown with
-	GRFConfig *list;       ///< temporary grf list to which changes are made
-	GRFConfig *sel;        ///< selected grf item
-	bool editable;         ///< is the window editable
-	bool show_params;      ///< are the grf-parameters shown in the info-panel
-	bool execute;          ///< on pressing 'apply changes' are grf changes applied immediately, or only list is updated
-
 	NewGRFWindow(const WindowDesc *desc, bool editable, bool show_params, bool exec_changes, GRFConfig **config) : Window(desc, 0)
 	{
-		this->resize.step_height = 14;
-		this->sel         = NULL;
+		this->resize.step_height = 13;
+		//this->resize.step_width = 8;
+		this->resize.height = this->height - 39;
+		this->resize.width  = (this->width - 1) / 2;
+
+		this->sel_r       = NULL;
 		this->list        = NULL;
 		this->orig_list   = config;
 		this->editable    = editable;
@@ -300,6 +172,7 @@
 		this->SetupNewGRFWindow();
 	}
 
+
 	~NewGRFWindow()
 	{
 		if (!this->execute) {
@@ -312,47 +185,68 @@
 		ClearGRFConfigList(&this->list);
 	}
 
-	void SetupNewGRFWindow()
+	virtual void OnPaint()
 	{
 		const GRFConfig *c;
-		int i;
 
-		for (c = this->list, i = 0; c != NULL; c = c->next, i++) {}
+		int i, y;
+		int n = 0;
 
-		this->vscroll.cap = (this->widget[SNGRFS_FILE_LIST].bottom - this->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
-		SetVScrollCount(this, i);
-
-		this->SetWidgetDisabledState(SNGRFS_ADD, !this->editable);
-		this->SetWidgetDisabledState(SNGRFS_APPLY_CHANGES, !this->editable);
-	}
-
-	virtual void OnPaint()
-	{
-		bool disable_all = this->sel == NULL || !this->editable;
-
+		bool disable_all = this->sel_r == NULL || !this->editable;
+			
 		this->SetWidgetsDisabledState(disable_all,
-			SNGRFS_REMOVE,
-			SNGRFS_MOVE_UP,
-			SNGRFS_MOVE_DOWN,
+			NLW_WIDGET_REMOVE,
+			NLW_WIDGET_MOVE_UP,
+			NLW_WIDGET_MOVE_DOWN,
 			WIDGET_LIST_END
 		);
-		this->SetWidgetDisabledState(SNGRFS_SET_PARAMETERS, !this->show_params || disable_all);
 
+		this->SetWidgetsDisabledState(!this->editable,
+			NLW_WIDGET_RESCAN_FILES,
+			NLW_WIDGET_NEWGRF_INFO_LEFT,
+			NLW_WIDGET_AVAILABLE_GRF_LIST,
+			WIDGET_LIST_END
+		);
+
+		this->SetWidgetDisabledState(NLW_WIDGET_ADD_FILE, !this->editable || this->sel_l == NULL || this->sel_l->IsOpenTTDBaseGRF());
+
+		this->SetWidgetDisabledState(NLW_WIDGET_SET_PARAMETERS, !this->show_params || disable_all);
+
 		if (!disable_all) {
 			/* All widgets are now enabled, so disable widgets we can't use */
-			if (this->sel == this->list)       this->DisableWidget(SNGRFS_MOVE_UP);
-			if (this->sel->next == NULL)       this->DisableWidget(SNGRFS_MOVE_DOWN);
-			if (this->sel->IsOpenTTDBaseGRF()) this->DisableWidget(SNGRFS_REMOVE);
+			if (this->sel_r == this->list) this->DisableWidget(NLW_WIDGET_MOVE_UP);
+			if (this->sel_r->next == NULL) this->DisableWidget(NLW_WIDGET_MOVE_DOWN);
+			if (this->sel_r->IsOpenTTDBaseGRF()) this->DisableWidget(NLW_WIDGET_REMOVE);
 		}
 
 		this->DrawWidgets();
 
+		DrawStringCentered((this->widget[NLW_WIDGET_AVAILABLE_GRF_CAPTION].right - this->widget[NLW_WIDGET_AVAILABLE_GRF_CAPTION].left) / 2, 16, STR_NEWGRF_ADD_CAPTION, TC_WHITE);
+		GfxFillRect(this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].left + 1, this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].top + 1, this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].right, this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].bottom, 0xD7);
+
+		n = 0;
+		y = this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].top + 2;
+		for (c = _all_grfs; c != NULL; c = c->next) {
+
+			if (IsInSelectedList(c->grfid)) continue;	
+			
+			if (n >= this->vscroll.pos && n < this->vscroll.pos + this->vscroll.cap) {
+				bool h = (c == this->sel_l);
+				const char *text = (c->name != NULL && !StrEmpty(c->name) && !this->show_file_names) ? c->name : c->filename;
+
+				/* Draw selection background */
+				if (h) GfxFillRect(3, y, this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].right - 4, y + 9, 156);
+				DoDrawStringTruncated(text, 4, y, h ? TC_WHITE : TC_ORANGE, this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].right - 7);
+				y += 10;
+			}
+			n++;
+		}
+
 		/* Draw NewGRF list */
-		int y = this->widget[SNGRFS_FILE_LIST].top;
-		int i = 0;
-		for (const GRFConfig *c = this->list; c != NULL; c = c->next, i++) {
-			if (i >= this->vscroll.pos && i < this->vscroll.pos + this->vscroll.cap) {
-				const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
+		y = this->widget[NLW_WIDGET_FILE_LIST].top;
+		for (c = this->list, i = 0; c != NULL; c = c->next, i++) {
+			if (i >= this->vscroll2.pos && i < this->vscroll2.pos + this->vscroll2.cap) {
+				const char *text = (c->name != NULL && !StrEmpty(c->name) && !this->show_file_names) ? c->name : c->filename;
 				SpriteID pal;
 				byte txtoffset;
 
@@ -379,62 +273,182 @@
 					}
 				}
 
-				DrawSprite(SPR_SQUARE, pal, 5, y + 2);
-				if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, 20, y + 2);
+				DrawSprite(SPR_SQUARE, pal, this->widget[NLW_WIDGET_FILE_LIST].left + 9, y + 1);
+				if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, this->widget[NLW_WIDGET_FILE_LIST].left + 21, y + 1);
 				txtoffset = c->error != NULL ? 35 : 25;
-				DoDrawStringTruncated(text, txtoffset, y + 3, this->sel == c ? TC_WHITE : TC_BLACK, this->width - txtoffset - 10);
-				y += 14;
+				DoDrawStringTruncated(text,
+						this->widget[NLW_WIDGET_FILE_LIST].left + txtoffset, y + 2,
+						this->sel_r == c ? TC_WHITE : TC_BLACK,
+						this->widget[NLW_WIDGET_FILE_LIST].right - this->widget[NLW_WIDGET_FILE_LIST].left - txtoffset);
+				y += 13;
 			}
 		}
 
-		if (this->sel != NULL) {
+		if (this->sel_r != NULL) {
 			/* Draw NewGRF file info */
-			const Widget *wi = &this->widget[SNGRFS_NEWGRF_INFO];
-			ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, this->show_params);
+			const Widget *wi = &this->widget[NLW_WIDGET_NEWGRF_INFO_RIGHT];
+			ShowNewGRFInfo(this->sel_r, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, this->show_params, this->show_file_names);
 		}
+
+		if (this->sel_l != NULL) {
+			const Widget *wi = &this->widget[NLW_WIDGET_NEWGRF_INFO_LEFT];
+			ShowNewGRFInfo(this->sel_l, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, false, this->show_file_names);
+		}
+
 	}
 
+	virtual void OnInvalidateData(int data = 0)
+	{
+		this->SetupNewGRFWindow();
+	}
+
+	virtual void OnDragDrop(Point pt, int widget)
+	{
+		if (widget != NLW_WIDGET_FILE_LIST) return;
+
+		GRFConfig **pc, *c, *source, *target;
+
+		if ((source = this->sel_r) == NULL) return;
+
+		uint i = (pt.y - this->widget[NLW_WIDGET_FILE_LIST].top) / 13 + this->vscroll2.pos;
+		for (c = this->list; c != NULL && i > 0; c = c->next, i--);
+		target = c;
+		
+		if (target == source) return;
+
+		for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
+			if (c == source)
+				*pc = c->next;
+			else if (c->next == source) {
+				c->next = c->next->next;
+			}
+		}
+
+		for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
+			if (c == target) {
+				*pc = source;
+				source->next = target;
+			}
+			else if (c->next == target) {
+				c->next = source;
+				source->next = target;
+			}
+		}
+
+		this->SetDirty();
+	}
+
+	virtual void OnDoubleClick(Point pt, int widget)
+	{
+		if (widget == NLW_WIDGET_AVAILABLE_GRF_LIST) this->OnClick(pt, NLW_WIDGET_ADD_FILE);
+	}
+
 	virtual void OnClick(Point pt, int widget)
 	{
 		switch (widget) {
-			case SNGRFS_ADD: // Add GRF
-				DeleteWindowByClass(WC_SAVELOAD);
-				new NewGRFAddWindow(&_newgrf_add_dlg_desc, &this->list);
+			case NLW_WIDGET_AVAILABLE_GRF_LIST: {
+				/* Get row... */
+				const GRFConfig *c;
+				uint i = ((pt.y) - this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].top) / 10 + this->vscroll.pos;
+				
+				c = _all_grfs;
+				while (IsInSelectedList(c->grfid) && c->next) {
+					c = c->next;
+				}
+				while (c != NULL && i > 0)
+				{
+					c = c->next;
+					while (c != NULL && IsInSelectedList(c->grfid) && c->next) {
+						c = c->next;
+					}
+					--i;
+				}
+				if (c && IsInSelectedList(c->grfid)) c = NULL;
+				this->sel_l = c;
+				this->SetDirty();
 				break;
+			}
 
-			case SNGRFS_REMOVE: { // Remove GRF
+			case NLW_WIDGET_ADD_FILE: // Add selection to list
+				if (this->sel_l != NULL && this->editable) {
+					const GRFConfig *src = this->sel_l;
+					GRFConfig **list;
+
+					/* Find last entry in the list, checking for duplicate grfid on the way */
+					for (list = &this->list; *list != NULL; list = &(*list)->next) {
+						if ((*list)->grfid == src->grfid) {
+							ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
+							return;
+						}
+					}
+
+					/* Copy GRF details from scanned list */
+					GRFConfig *c = CallocT<GRFConfig>(1);
+					*c = *src;
+					c->filename = strdup(src->filename);
+					if (src->name      != NULL) c->name      = strdup(src->name);
+					if (src->info      != NULL) c->info      = strdup(src->info);
+					c->next = NULL;
+
+					/* Append GRF config to configuration list */
+					*list = c;
+					this->sel_l = NULL;
+
+					this->SetupNewGRFWindow();
+					this->SetDirty();
+				}
+				break;
+
+			case NLW_WIDGET_RESCAN_FILES: // Rescan list
+				this->sel_l = NULL;
+				ScanNewGRFFiles();
+				this->SetDirty();
+				break;
+				
+			case NLW_WIDGET_TOGGLE_SHOW_MODE: // Toggle show mode
+				if (_ctrl_pressed) {
+					ToggleBit(this->show_file_names,0);
+				}
+				else {
+					ToggleBit(this->show_all,0);
+				}
+
+				this->SetupNewGRFWindow(); // Adjust scroll bars
+				this->SetDirty();
+				break;
+
+			case NLW_WIDGET_REMOVE: { // Remove GRF
 				GRFConfig **pc, *c, *newsel;
 
 				/* Choose the next GRF file to be the selected file */
-				newsel = this->sel->next;
+				newsel = this->sel_r->next;
 
 				for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
 					/* If the new selection is empty (i.e. we're deleting the last item
 					 * in the list, pick the file just before the selected file */
-					if (newsel == NULL && c->next == this->sel) newsel = c;
+					if (newsel == NULL && c->next == this->sel_r) newsel = c;
 
-					if (c == this->sel) {
+					if (c == this->sel_r) {
 						*pc = c->next;
 						free(c);
 						break;
 					}
 				}
 
-				this->sel = newsel;
-				this->SetupNewGRFWindow();
+				this->sel_r = newsel;
 				this->SetDirty();
 				break;
 			}
 
-			case SNGRFS_MOVE_UP: { // Move GRF up
+			case NLW_WIDGET_MOVE_UP: { // Move GRF up
 				GRFConfig **pc, *c;
-				if (this->sel == NULL) break;
+				if (this->sel_r == NULL) break;
 
 				for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
-					if (c->next == this->sel) {
-						c->next = this->sel->next;
-						this->sel->next = c;
-						*pc = this->sel;
+					if (c->next == this->sel_r) {
+						c->next = this->sel_r->next;
+						this->sel_r->next = c;
+						*pc = this->sel_r;
 						break;
 					}
 				}
@@ -442,12 +456,12 @@
 				break;
 			}
 
-			case SNGRFS_MOVE_DOWN: { // Move GRF down
+			case NLW_WIDGET_MOVE_DOWN: { // Move GRF down
 				GRFConfig **pc, *c;
-				if (this->sel == NULL) break;
+				if (this->sel_r == NULL) break;
 
 				for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
-					if (c == this->sel) {
+					if (c == this->sel_r) {
 						*pc = c->next;
 						c->next = c->next->next;
 						(*pc)->next = c;
@@ -458,18 +472,21 @@
 				break;
 			}
 
-			case SNGRFS_FILE_LIST: { // Select a GRF
+			case NLW_WIDGET_FILE_LIST: { // Select a GRF
 				GRFConfig *c;
-				uint i = (pt.y - this->widget[SNGRFS_FILE_LIST].top) / 14 + this->vscroll.pos;
+				uint i = (pt.y - this->widget[NLW_WIDGET_FILE_LIST].top) / 13 + this->vscroll2.pos;
 
-				for (c = this->list; c != NULL && i > 0; c = c->next, i--) {}
-				this->sel = c;
+				for (c = this->list; c != NULL && i > 0; c = c->next, i--);
+				this->sel_r = c;
 
+				/* Activate drag and drop */
+				SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, VHM_DRAG, this);
+				
 				this->SetDirty();
 				break;
 			}
 
-			case SNGRFS_APPLY_CHANGES: // Apply changes made to GRF list
+			case NLW_WIDGET_APPLY_CHANGES: // Apply changes made to GRF list
 				if (this->execute) {
 					ShowQuery(
 						STR_POPUP_CAUTION_CAPTION,
@@ -484,11 +501,11 @@
 				}
 				break;
 
-			case SNGRFS_SET_PARAMETERS: { // Edit parameters
-				if (this->sel == NULL) break;
+			case NLW_WIDGET_SET_PARAMETERS: { // Edit parameters
+				char buff[512];
+				if (this->sel_r == NULL) break;
 
-				char buff[512];
-				GRFBuildParamList(buff, this->sel, lastof(buff));
+				GRFBuildParamList(buff, this->sel_r, lastof(buff));
 				ShowQueryString(BindCString(buff), STR_NEWGRF_PARAMETER_QUERY, 63, 250, this, CS_ALPHANUMERAL);
 				break;
 			}
@@ -498,9 +515,9 @@
 	virtual void OnQueryTextFinished(char *str)
 	{
 		if (str == NULL) return;
-
+		
 		/* Parse our new "int list" */
-		GRFConfig *c = this->sel;
+		GRFConfig *c = this->sel_r;
 		c->num_params = parse_intlist(str, (int*)c->param, lengthof(c->param));
 
 		/* parse_intlist returns -1 on error */
@@ -511,47 +528,99 @@
 
 	virtual void OnResize(Point new_size, Point delta)
 	{
-		if (delta.x != 0) {
-			ResizeButtons(this, SNGRFS_ADD, SNGRFS_MOVE_DOWN);
-			ResizeButtons(this, SNGRFS_SET_PARAMETERS, SNGRFS_APPLY_CHANGES);
-		}
+		this->vscroll2.cap += delta.y / 13;
+		this->widget[NLW_WIDGET_FILE_LIST].data = (this->vscroll2.cap << 8) + 1;
 
-		this->vscroll.cap += delta.y / 14;
-		this->widget[SNGRFS_FILE_LIST].data = (this->vscroll.cap << 8) + 1;
+		int left_column_width  = (new_size.x - 31) / 2 + 4;
+		int right_column_width = left_column_width - 7;
+		
+		this->widget[NLW_WIDGET_RESCAN_FILES].right =
+				(left_column_width / 2) - 1;
 
+		this->widget[NLW_WIDGET_TOGGLE_SHOW_MODE].left =
+				(left_column_width / 2);
+
+		this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].right = 
+				left_column_width - 14;
+
+		this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST_SCROLLBAR].left =
+				left_column_width - 12;
+
+		this->widget[NLW_WIDGET_AVAILABLE_GRF_CAPTION].right =
+				this->widget[NLW_WIDGET_EMPTY1].right =
+				this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST_SCROLLBAR].right =
+				this->widget[NLW_WIDGET_TOGGLE_SHOW_MODE].right =
+				this->widget[NLW_WIDGET_NEWGRF_INFO_LEFT].right =
+				left_column_width - 1;
+
+		this->widget[NLW_WIDGET_EMPTY_MIDDLE].left =
+				this->widget[NLW_WIDGET_EMPTY_BOTTOM_MIDDLE].left =
+				left_column_width;
+
+		this->widget[NLW_WIDGET_ADD_FILE].left =
+				this->widget[NLW_WIDGET_REMOVE].left =
+				left_column_width + 5;
+
+		this->widget[NLW_WIDGET_ADD_FILE].right =
+				this->widget[NLW_WIDGET_REMOVE].right =
+				left_column_width + 25;
+
+		this->widget[NLW_WIDGET_EMPTY_MIDDLE].right =
+				this->widget[NLW_WIDGET_EMPTY_BOTTOM_MIDDLE].right =
+				left_column_width + 29;
+
+		this->widget[NLW_WIDGET_EMPTY_TOP_RIGHT].left =
+				this->widget[NLW_WIDGET_FILE_LIST].left =
+				this->widget[NLW_WIDGET_NEWGRF_INFO_RIGHT].left =
+				this->widget[NLW_WIDGET_SET_PARAMETERS].left =
+				left_column_width + 30;
+		
+		int spacing = (right_column_width - 72) / 3;
+		int pos     = left_column_width + 30 + spacing;
+
+		this->widget[NLW_WIDGET_MOVE_UP].left    = pos; pos += 36;
+		this->widget[NLW_WIDGET_MOVE_UP].right   = pos; pos += spacing;
+		this->widget[NLW_WIDGET_MOVE_DOWN].left  = pos; pos += 36;
+		this->widget[NLW_WIDGET_MOVE_DOWN].right = pos;
+
+		spacing = left_column_width + 30 + (right_column_width - 12) / 2;
+		this->widget[NLW_WIDGET_SET_PARAMETERS].right = spacing - 1;
+		this->widget[NLW_WIDGET_APPLY_CHANGES].left   = spacing;
+
 		this->SetupNewGRFWindow();
 	}
 
-	virtual void OnInvalidateData(int data = 0)
-	{
-		this->SetupNewGRFWindow();
+	bool IsInSelectedList(uint32 grfid) {
+		if (this->show_all) return false;
+		const GRFConfig *ctemp;
+		for (ctemp = this->list; ctemp != NULL; ctemp = ctemp->next) {
+			if (grfid == ctemp->grfid) return true;
+		}
+		return false;
 	}
-};
 
-/* Widget definition of the manage newgrfs window */
-static const Widget _newgrf_widgets[] = {
-{   WWT_CLOSEBOX,  RESIZE_NONE, 10,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW },            // SNGRFS_CLOSEBOX
-{    WWT_CAPTION, RESIZE_RIGHT, 10,  11, 299,   0,  13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },  // SNGRFS_CAPTION
-{      WWT_PANEL, RESIZE_RIGHT, 10,   0, 299,  14,  29, STR_NULL,                    STR_NULL },                         // SNGRFS_BACKGROUND
-{ WWT_PUSHTXTBTN,  RESIZE_NONE,  3,  10,  79,  16,  27, STR_NEWGRF_ADD,              STR_NEWGRF_ADD_TIP },               // SNGRFS_ADD
-{ WWT_PUSHTXTBTN,  RESIZE_NONE,  3,  80, 149,  16,  27, STR_NEWGRF_REMOVE,           STR_NEWGRF_REMOVE_TIP },            // SNGRFS_REMOVE
-{ WWT_PUSHTXTBTN,  RESIZE_NONE,  3, 150, 219,  16,  27, STR_NEWGRF_MOVEUP,           STR_NEWGRF_MOVEUP_TIP },            // SNGRFS_MOVE_UP
-{ WWT_PUSHTXTBTN, RESIZE_RIGHT,  3, 220, 289,  16,  27, STR_NEWGRF_MOVEDOWN,         STR_NEWGRF_MOVEDOWN_TIP },          // SNGRFS_MOVE_DOWN
-{     WWT_MATRIX,    RESIZE_RB, 10,   0, 287,  30,  99, 0x501,                       STR_NEWGRF_FILE_TIP },              // SNGRFS_FILE_LIST
-{  WWT_SCROLLBAR,   RESIZE_LRB, 10, 288, 299,  30,  99, 0x0,                         STR_0190_SCROLL_BAR_SCROLLS_LIST }, // SNGRFS_SCROLLBAR
-{      WWT_PANEL,   RESIZE_RTB, 10,   0, 299, 100, 212, STR_NULL,                    STR_NULL },                         // SNGRFS_NEWGRF_INFO
-{ WWT_PUSHTXTBTN,    RESIZE_TB, 10,   0, 143, 213, 224, STR_NEWGRF_SET_PARAMETERS,   STR_NULL },                         // SNGRFS_SET_PARAMETERS
-{ WWT_PUSHTXTBTN,   RESIZE_RTB, 10, 144, 287, 213, 224, STR_NEWGRF_APPLY_CHANGES,    STR_NULL },                         // SNGRFS_APPLY_CHANGES
-{  WWT_RESIZEBOX,  RESIZE_LRTB, 10, 288, 299, 213, 224, 0x0,                         STR_RESIZE_BUTTON },                // SNGRFS_RESIZE
-{ WIDGETS_END },
-};
+	void SetupNewGRFWindow()
+	{
+		const GRFConfig *c;
+		uint8 n;
 
-/* Window definition of the manage newgrfs window */
-static const WindowDesc _newgrf_desc = {
-	WDP_CENTER, WDP_CENTER, 300, 225, 300, 225,
-	WC_GAME_OPTIONS, WC_NONE,
-	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
-	_newgrf_widgets,
+		for (c = this->list, n = 0; c != NULL; c = c->next, n++);
+
+		this->vscroll2.cap = (this->widget[NLW_WIDGET_FILE_LIST].bottom - this->widget[NLW_WIDGET_FILE_LIST].top) / 13;
+
+		this->widget[NLW_WIDGET_FILE_LIST].data = (this->vscroll2.cap << 8) + 1;
+		SetVScroll2Count(this, n);
+		this->SetWidgetDisabledState(NLW_WIDGET_APPLY_CHANGES, !this->editable);
+
+		/* Count the number of GRFs */
+		for (c = _all_grfs, n = 0; c != NULL; c = c->next)
+		{
+			if (this->show_all || !IsInSelectedList(c->grfid)) n++;
+		}
+
+		this->vscroll.cap = (this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].bottom - this->widget[NLW_WIDGET_AVAILABLE_GRF_LIST].top) / 10;
+		SetVScrollCount(this, n);
+	}
 };
 
 /** Callback function for the newgrf 'apply changes' confirmation window
@@ -565,23 +634,58 @@
 		GRFConfig *c;
 		int i = 0;
 
-		GamelogStartAction(GLAT_GRF);
-		GamelogGRFUpdate(_grfconfig, nw->list); // log GRF changes
 		CopyGRFConfigList(nw->orig_list, nw->list, false);
 		ReloadNewGRFData();
-		GamelogStopAction();
 
 		/* Show new, updated list */
-		for (c = nw->list; c != NULL && c != nw->sel; c = c->next, i++) {}
+		for (c = nw->list; c != NULL && c != nw->sel_r; c = c->next, i++);
 		CopyGRFConfigList(&nw->list, *nw->orig_list, false);
-		for (c = nw->list; c != NULL && i > 0; c = c->next, i--) {}
-		nw->sel = c;
+		for (c = nw->list; c != NULL && i > 0; c = c->next, i--);
+		nw->sel_r = c;
 
 		w->SetDirty();
 	}
 }
 
+static const Widget _newgrf_widgets[] = {
+{   WWT_CLOSEBOX,  RESIZE_NONE, 10,   0,  10,   0,  13, STR_00C5,                    STR_018B_CLOSE_WINDOW },           // NLW_WIDGET_CLOSE
+{    WWT_CAPTION, RESIZE_RIGHT, 10,  11, 606,   0,  13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS }, // NLW_WIDGET_CAPTION
+/* List of files */
+{      WWT_PANEL, RESIZE_RIGHT, 10,   0, 291,  14,  25, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_AVAILABLE_GRF_CAPTION
+{      WWT_PANEL,    RESIZE_RB, 10,   0, 279,  26, 121, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_EMPTY1
+{      WWT_INSET,    RESIZE_RB, 10,   2, 277,  28, 119, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_AVAILABLE_GRF_LIST
+{  WWT_SCROLLBAR,   RESIZE_LRB, 10, 280, 291,  26, 121, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_AVAILABLE_GRF_LIST_SCROLLBAR
+/* NewGRF file info */
+{      WWT_PANEL,   RESIZE_RTB, 10,   0, 291, 122, 224, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_NEWGRF_INFO_LEFT
+{ WWT_PUSHTXTBTN,   RESIZE_RTB, 10,   0, 136, 225, 236, STR_NEWGRF_RESCAN_FILES,     STR_NEWGRF_RESCAN_FILES_TIP },     // NLW_WIDGET_RESCAN_FILES
+{ WWT_PUSHTXTBTN,  RESIZE_LRTB, 10, 137, 291, 225, 236, STR_NEWGRF_TOGGLE_SHOW,      STR_NEWGRF_TOGGLE_SHOW_TIP },      // NLW_WIDGET_TOGGLE_SHOW_MODE
+/* Middle Panel */
+{      WWT_PANEL,   RESIZE_LRB, 10, 292, 321,  14, 224, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_EMPTY_MIDDLE
+{      WWT_PANEL,  RESIZE_LRTB, 10, 292, 321, 225, 236, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_EMPTY_BOTTOM_MIDDLE
+/* NewGRF file Add, Remove, Move up, Move down */
+{      WWT_PANEL,    RESIZE_LR, 10, 322, 606,  14,  29, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_EMPTY_TOP_RIGHT
+{ WWT_PUSHTXTBTN,    RESIZE_LR,  3, 297, 316,  20,  42, STR_NEWGRF_JOINT_ADD,        STR_NEWGRF_ADD_TIP },              // NLW_WIDGET_ADD_FILE
+{ WWT_PUSHTXTBTN,    RESIZE_LR,  3, 297, 316,  50,  72, STR_NEWGRF_JOINT_REMOVE,     STR_NEWGRF_REMOVE_TIP },           // NLW_WIDGET_REMOVE
+{ WWT_PUSHTXTBTN,    RESIZE_LR,  3, 394, 430,  16,  27, STR_NEWGRF_MOVEUP,           STR_NEWGRF_MOVEUP_TIP },           // NLW_WIDGET_MOVE_UP
+{ WWT_PUSHTXTBTN,    RESIZE_LR,  3, 499, 535,  16,  27, STR_NEWGRF_MOVEDOWN,         STR_NEWGRF_MOVEDOWN_TIP },         // NLW_WIDGET_MOVE_DOWN
+/* NewGRF file list */
+{     WWT_MATRIX,   RESIZE_LRB, 10, 322, 594,  30, 121, 0x501,                       STR_NEWGRF_FILE_TIP },             // NLW_WIDGET_FILE_LIST
+{ WWT_SCROLL2BAR,   RESIZE_LRB, 10, 595, 606,  30, 121, STR_NULL,                    STR_0190_SCROLL_BAR_SCROLLS_LIST },// NLW_WIDGET_FILE_LIST_SCROLLBAR
+/* NewGRF file info */
+{      WWT_PANEL,  RESIZE_LRTB, 10, 322, 606, 122, 224, STR_NULL,                    STR_NULL },                        // NLW_WIDGET_NEWGRF_INFO_RIGHT
+/* Edit parameter and apply changes button... */
+{ WWT_PUSHTXTBTN,  RESIZE_LRTB, 10, 322, 458, 225, 236, STR_NEWGRF_SET_PARAMETERS,   STR_NULL },                        // NLW_WIDGET_SET_PARAMETERS
+{ WWT_PUSHTXTBTN,  RESIZE_LRTB, 10, 459, 594, 225, 236, STR_NEWGRF_APPLY_CHANGES,    STR_NULL },                        // NLW_WIDGET_APPLY_CHANGES
+{  WWT_RESIZEBOX,  RESIZE_LRTB, 10, 595, 606, 225, 236, STR_NULL,                    STR_RESIZE_BUTTON },
+{   WIDGETS_END },
+};
 
+static const WindowDesc _newgrf_desc = {
+	WDP_CENTER, WDP_CENTER, 607, 237, 607, 237,
+	WC_GAME_OPTIONS, WC_NONE,
+	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
+	_newgrf_widgets,
+};
 
 /** Setup the NewGRF gui
  * @param editable allow the user to make changes to the grfconfig in the window
@@ -592,5 +696,7 @@
 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
 {
 	DeleteWindowByClass(WC_GAME_OPTIONS);
+
 	new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config);
 }
+
Index: src/variables.h
===================================================================
--- src/variables.h	(revision 13592)
+++ src/variables.h	(working copy)
@@ -76,4 +76,6 @@
 /* Forking stuff */
 VARDEF bool _dedicated_forks;
 
+VARDEF uint16 _newgrf_window_size[2];
+
 #endif /* VARIABLES_H */
