changeset 20090:b9d56c847a4f draft

(svn r25024) -Feature: Searching of (missing) content via GrfCrawler.
author frosch <frosch@openttd.org>
date Mon, 18 Feb 2013 19:30:24 +0000
parents 13865c252262
children 8c8bb88b9b81
files src/lang/english.txt src/network/network_content_gui.cpp src/script/api/game/game_window.hpp.sq src/script/api/script_window.hpp src/widgets/network_content_widget.h
diffstat 5 files changed, 96 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2080,6 +2080,10 @@
 STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP                      :{BLACK}Mark all content that is an upgrade for existing content to be downloaded
 STR_CONTENT_UNSELECT_ALL_CAPTION                                :{BLACK}Unselect all
 STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP                        :{BLACK}Mark all content to be not downloaded
+STR_CONTENT_SEARCH_EXTERNAL                                     :{BLACK}Search external websites
+STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP                             :{BLACK}Search content not available on OpenTTD's content service on websites not associated to OpenTTD
+STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION                  :{WHITE}You are leaving OpenTTD!
+STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER                          :{WHITE}The terms and conditions for downloading content from external websites vary.{}You will have to refer to the external sites for instructions how to install the content into OpenTTD.{}Do you want to continue?
 STR_CONTENT_FILTER_TITLE                                        :{BLACK}Tag/name filter:
 STR_CONTENT_OPEN_URL                                            :{BLACK}Visit website
 STR_CONTENT_OPEN_URL_TOOLTIP                                    :{BLACK}Visit the website for this content
--- a/src/network/network_content_gui.cpp
+++ b/src/network/network_content_gui.cpp
@@ -29,6 +29,11 @@
 #include "table/strings.h"
 #include "../table/sprites.h"
 
+
+/** Whether the user accepted to enter external websites during this session. */
+static bool _accepted_external_search = false;
+
+
 /** Window for displaying the textfile of an item in the content list. */
 struct ContentTextfileWindow : public TextfileWindow {
 	const ContentInfo *ci; ///< View the textfile of this ContentInfo.
@@ -296,6 +301,63 @@
 	uint filesize_sum;           ///< The sum of all selected file sizes
 	Scrollbar *vscroll;          ///< Cache of the vertical scrollbar
 
+	/** Search external websites for content */
+	void OpenExternalSearch()
+	{
+		extern void OpenBrowser(const char *url);
+
+		char url[1024];
+		const char *last = lastof(url);
+
+		char *pos = strecpy(url, "http://grfsearch.openttd.org/?", last);
+
+		if (this->auto_select) {
+			pos = strecpy(pos, "do=searchgrfid&q=", last);
+
+			bool first = true;
+			for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) {
+				const ContentInfo *ci = *iter;
+				if (ci->state != ContentInfo::DOES_NOT_EXIST) continue;
+
+				if (!first) pos = strecpy(pos, ",", last);
+				first = false;
+
+				pos += seprintf(pos, last, "%08X", ci->unique_id);
+				pos = strecpy(pos, ":", last);
+				pos = md5sumToString(pos, last, ci->md5sum);
+			}
+		} else {
+			pos = strecpy(pos, "do=searchtext&q=", last);
+
+			/* Escape search term */
+			for (const char *search = this->filter_editbox.text.buf; *search != '\0'; search++) {
+				/* Remove quotes */
+				if (*search == '\'' || *search == '"') continue;
+
+				/* Escape special chars, such as &%,= */
+				if (*search < 0x30) {
+					pos += seprintf(pos, last, "%%%02X", *search);
+				} else if (pos < last) {
+					*pos = *search;
+					*++pos = '\0';
+				}
+			}
+		}
+
+		OpenBrowser(url);
+	}
+
+	/**
+	 * Callback function for disclaimer about entering external websites.
+	 */
+	static void ExternalSearchDisclaimerCallback(Window *w, bool accepted)
+	{
+		if (accepted) {
+			_accepted_external_search = true;
+			((NetworkContentListWindow*)w)->OpenExternalSearch();
+		}
+	}
+
 	/**
 	 * (Re)build the network game list as its amount has changed because
 	 * an item has been added or deleted for example
@@ -307,10 +369,15 @@
 		/* Create temporary array of games to use for listing */
 		this->content.Clear();
 
+		bool all_available = true;
+
 		for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
+			if ((*iter)->state == ContentInfo::DOES_NOT_EXIST) all_available = false;
 			*this->content.Append() = *iter;
 		}
 
+		this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select && all_available);
+
 		this->FilterContentList();
 		this->content.Compact();
 		this->content.RebuildDone();
@@ -421,6 +488,7 @@
 		this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
 		this->filter_editbox.afilter = CS_ALPHANUMERAL;
 		this->SetFocusedWidget(WID_NCL_FILTER);
+		this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select);
 
 		_network_content_client.AddCallback(this);
 		this->content.SetListing(this->last_sorting);
@@ -721,6 +789,14 @@
 			case WID_NCL_DOWNLOAD:
 				if (BringWindowToFrontById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) == NULL) new NetworkContentDownloadStatusWindow();
 				break;
+
+			case WID_NCL_SEARCH_EXTERNAL:
+				if (_accepted_external_search) {
+					this->OpenExternalSearch();
+				} else {
+					ShowQuery(STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION, STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER, this, ExternalSearchDisclaimerCallback);
+				}
+				break;
 		}
 	}
 
@@ -896,7 +972,7 @@
 		NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
 		NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
 			/* Left side. */
-			NWidget(NWID_VERTICAL),
+			NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
 				NWidget(NWID_HORIZONTAL),
 					NWidget(NWID_VERTICAL),
 						NWidget(NWID_HORIZONTAL),
@@ -910,6 +986,16 @@
 					EndContainer(),
 					NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NCL_SCROLLBAR),
 				EndContainer(),
+				NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
+					NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE), SetResize(1, 0), SetFill(1, 0),
+						NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_UPDATE), SetResize(1, 0), SetFill(1, 0),
+												SetDataTip(STR_CONTENT_SELECT_UPDATES_CAPTION, STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP),
+						NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_ALL), SetResize(1, 0), SetFill(1, 0),
+												SetDataTip(STR_CONTENT_SELECT_ALL_CAPTION, STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP),
+					EndContainer(),
+					NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_UNSELECT), SetResize(1, 0), SetFill(1, 0),
+												SetDataTip(STR_CONTENT_UNSELECT_ALL_CAPTION, STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP),
+				EndContainer(),
 			EndContainer(),
 			/* Right side. */
 			NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
@@ -927,16 +1013,8 @@
 		NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
 		/* Bottom. */
 		NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
-			NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
-				NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE), SetResize(1, 0), SetFill(1, 0),
-					NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_UPDATE), SetResize(1, 0), SetFill(1, 0),
-											SetDataTip(STR_CONTENT_SELECT_UPDATES_CAPTION, STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP),
-					NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SELECT_ALL), SetResize(1, 0), SetFill(1, 0),
-											SetDataTip(STR_CONTENT_SELECT_ALL_CAPTION, STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP),
-				EndContainer(),
-				NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_UNSELECT), SetResize(1, 0), SetFill(1, 0),
-											SetDataTip(STR_CONTENT_UNSELECT_ALL_CAPTION, STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP),
-			EndContainer(),
+			NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SEARCH_EXTERNAL), SetResize(1, 0), SetFill(1, 0),
+										SetDataTip(STR_CONTENT_SEARCH_EXTERNAL, STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP),
 			NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
 				NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_CANCEL), SetResize(1, 0), SetFill(1, 0),
 											SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
--- a/src/script/api/game/game_window.hpp.sq
+++ b/src/script/api/game/game_window.hpp.sq
@@ -655,6 +655,7 @@
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_CANCEL,                            "WID_NCL_CANCEL");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_DOWNLOAD,                          "WID_NCL_DOWNLOAD");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_SEL_ALL_UPDATE,                    "WID_NCL_SEL_ALL_UPDATE");
+	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_SEARCH_EXTERNAL,                   "WID_NCL_SEARCH_EXTERNAL");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_MAIN,                               "WID_NG_MAIN");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONNECTION,                         "WID_NG_CONNECTION");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONN_BTN,                           "WID_NG_CONN_BTN");
--- a/src/script/api/script_window.hpp
+++ b/src/script/api/script_window.hpp
@@ -1611,6 +1611,7 @@
 		WID_NCL_DOWNLOAD                             = ::WID_NCL_DOWNLOAD,                             ///< 'Download' button.
 
 		WID_NCL_SEL_ALL_UPDATE                       = ::WID_NCL_SEL_ALL_UPDATE,                       ///< #NWID_SELECTION widget for select all/update buttons..
+		WID_NCL_SEARCH_EXTERNAL                      = ::WID_NCL_SEARCH_EXTERNAL,                      ///< Search external sites for missing NewGRF.
 	};
 
 	/* automatically generated from ../../widgets/network_widget.h */
--- a/src/widgets/network_content_widget.h
+++ b/src/widgets/network_content_widget.h
@@ -45,6 +45,7 @@
 	WID_NCL_DOWNLOAD,       ///< 'Download' button.
 
 	WID_NCL_SEL_ALL_UPDATE, ///< #NWID_SELECTION widget for select all/update buttons..
+	WID_NCL_SEARCH_EXTERNAL, ///< Search external sites for missing NewGRF.
 };
 
 #endif /* WIDGETS_NETWORK_CONTENT_WIDGET_H */