mirror of https://github.com/OpenTTD/OpenTTD
(svn r25024) -Feature: Searching of (missing) content via GrfCrawler.
parent
41cc06a83c
commit
1b10910af6
|
@ -2080,6 +2080,10 @@ STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Select u
|
||||||
STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}Mark all content that is an upgrade for existing content to be downloaded
|
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 :{BLACK}Unselect all
|
||||||
STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Mark all content to be not downloaded
|
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_FILTER_TITLE :{BLACK}Tag/name filter:
|
||||||
STR_CONTENT_OPEN_URL :{BLACK}Visit website
|
STR_CONTENT_OPEN_URL :{BLACK}Visit website
|
||||||
STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visit the website for this content
|
STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visit the website for this content
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "../table/sprites.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. */
|
/** Window for displaying the textfile of an item in the content list. */
|
||||||
struct ContentTextfileWindow : public TextfileWindow {
|
struct ContentTextfileWindow : public TextfileWindow {
|
||||||
const ContentInfo *ci; ///< View the textfile of this ContentInfo.
|
const ContentInfo *ci; ///< View the textfile of this ContentInfo.
|
||||||
|
@ -296,6 +301,63 @@ class NetworkContentListWindow : public Window, ContentCallback {
|
||||||
uint filesize_sum; ///< The sum of all selected file sizes
|
uint filesize_sum; ///< The sum of all selected file sizes
|
||||||
Scrollbar *vscroll; ///< Cache of the vertical scrollbar
|
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
|
* (Re)build the network game list as its amount has changed because
|
||||||
* an item has been added or deleted for example
|
* an item has been added or deleted for example
|
||||||
|
@ -307,10 +369,15 @@ class NetworkContentListWindow : public Window, ContentCallback {
|
||||||
/* Create temporary array of games to use for listing */
|
/* Create temporary array of games to use for listing */
|
||||||
this->content.Clear();
|
this->content.Clear();
|
||||||
|
|
||||||
|
bool all_available = true;
|
||||||
|
|
||||||
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
|
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->content.Append() = *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select && all_available);
|
||||||
|
|
||||||
this->FilterContentList();
|
this->FilterContentList();
|
||||||
this->content.Compact();
|
this->content.Compact();
|
||||||
this->content.RebuildDone();
|
this->content.RebuildDone();
|
||||||
|
@ -421,6 +488,7 @@ public:
|
||||||
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
|
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
|
||||||
this->filter_editbox.afilter = CS_ALPHANUMERAL;
|
this->filter_editbox.afilter = CS_ALPHANUMERAL;
|
||||||
this->SetFocusedWidget(WID_NCL_FILTER);
|
this->SetFocusedWidget(WID_NCL_FILTER);
|
||||||
|
this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select);
|
||||||
|
|
||||||
_network_content_client.AddCallback(this);
|
_network_content_client.AddCallback(this);
|
||||||
this->content.SetListing(this->last_sorting);
|
this->content.SetListing(this->last_sorting);
|
||||||
|
@ -721,6 +789,14 @@ public:
|
||||||
case WID_NCL_DOWNLOAD:
|
case WID_NCL_DOWNLOAD:
|
||||||
if (BringWindowToFrontById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) == NULL) new NetworkContentDownloadStatusWindow();
|
if (BringWindowToFrontById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) == NULL) new NetworkContentDownloadStatusWindow();
|
||||||
break;
|
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 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
|
||||||
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
|
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
|
||||||
/* Left side. */
|
/* Left side. */
|
||||||
NWidget(NWID_VERTICAL),
|
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(NWID_VERTICAL),
|
NWidget(NWID_VERTICAL),
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
@ -910,6 +986,16 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NCL_SCROLLBAR),
|
NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NCL_SCROLLBAR),
|
||||||
EndContainer(),
|
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(),
|
EndContainer(),
|
||||||
/* Right side. */
|
/* Right side. */
|
||||||
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
|
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
|
||||||
|
@ -927,16 +1013,8 @@ static const NWidgetPart _nested_network_content_list_widgets[] = {
|
||||||
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
|
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0),
|
||||||
/* Bottom. */
|
/* Bottom. */
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8),
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_SEARCH_EXTERNAL), SetResize(1, 0), SetFill(1, 0),
|
||||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NCL_SEL_ALL_UPDATE), SetResize(1, 0), SetFill(1, 0),
|
SetDataTip(STR_CONTENT_SEARCH_EXTERNAL, STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP),
|
||||||
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(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_CANCEL), SetResize(1, 0), SetFill(1, 0),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_CANCEL), SetResize(1, 0), SetFill(1, 0),
|
||||||
SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
|
SetDataTip(STR_BUTTON_CANCEL, STR_NULL),
|
||||||
|
|
|
@ -655,6 +655,7 @@ void SQGSWindow_Register(Squirrel *engine)
|
||||||
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_CANCEL, "WID_NCL_CANCEL");
|
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_DOWNLOAD, "WID_NCL_DOWNLOAD");
|
||||||
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCL_SEL_ALL_UPDATE, "WID_NCL_SEL_ALL_UPDATE");
|
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_MAIN, "WID_NG_MAIN");
|
||||||
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONNECTION, "WID_NG_CONNECTION");
|
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONNECTION, "WID_NG_CONNECTION");
|
||||||
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONN_BTN, "WID_NG_CONN_BTN");
|
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NG_CONN_BTN, "WID_NG_CONN_BTN");
|
||||||
|
|
|
@ -1611,6 +1611,7 @@ public:
|
||||||
WID_NCL_DOWNLOAD = ::WID_NCL_DOWNLOAD, ///< 'Download' button.
|
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_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 */
|
/* automatically generated from ../../widgets/network_widget.h */
|
||||||
|
|
|
@ -45,6 +45,7 @@ enum NetworkContentListWidgets {
|
||||||
WID_NCL_DOWNLOAD, ///< 'Download' button.
|
WID_NCL_DOWNLOAD, ///< 'Download' button.
|
||||||
|
|
||||||
WID_NCL_SEL_ALL_UPDATE, ///< #NWID_SELECTION widget for select all/update buttons..
|
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 */
|
#endif /* WIDGETS_NETWORK_CONTENT_WIDGET_H */
|
||||||
|
|
Loading…
Reference in New Issue