From f393cecbf78aaa39a46407d146e20ec128ccd693 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 19 Feb 2013 19:46:46 +0000 Subject: [PATCH] (svn r25028) [1.3] -Backport from trunk: - Feature: Searching of (missing) content via GrfCrawler (r25024, r25023) - Fix: [SDL] Crash after bootstrap download of 32bits base set due to referencing a deleted mutex [FS#5466] (r25017) - Fix: [SDL] Improve 8bpp hardware palette support. Instead of always requesting SDL_HWPALETTE, it is now only done for 8bp blitters in fullscreen mode (r25003, r25002, r24993) --- src/lang/english.txt | 4 + src/network/network_content_gui.cpp | 111 +++++++++++++++++++++---- src/script/api/game/game_window.hpp.sq | 2 + src/script/api/script_window.hpp | 8 +- src/video/sdl_v.cpp | 36 ++++---- src/widgets/network_content_widget.h | 1 + 6 files changed, 127 insertions(+), 35 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index f2f28f7947..cdfd490c14 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -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_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 diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index efc3a93bb9..3c387c2d06 100644 --- 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 @@ class NetworkContentListWindow : public Window, ContentCallback { 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 @@ class NetworkContentListWindow : public Window, ContentCallback { /* 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 @@ public: 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 @@ public: 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 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { 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,13 +986,26 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { 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), + NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NCL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, 8, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_OPEN_URL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), EndContainer(), EndContainer(), @@ -924,19 +1013,9 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { 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(8, 8, 8), - 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(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_OPEN_URL), SetResize(1, 0), SetFill(1, 0), - SetDataTip(STR_CONTENT_OPEN_URL, STR_CONTENT_OPEN_URL_TOOLTIP), + 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), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCL_DOWNLOAD), SetResize(1, 0), SetFill(1, 0), diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index 51a281553c..057af86ed8 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -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_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"); @@ -1249,6 +1250,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_TOP_DETAILS, "WID_VD_TOP_DETAILS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_INCREASE_SERVICING_INTERVAL, "WID_VD_INCREASE_SERVICING_INTERVAL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_DECREASE_SERVICING_INTERVAL, "WID_VD_DECREASE_SERVICING_INTERVAL"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_SERVICE_INTERVAL_DROPDOWN, "WID_VD_SERVICE_INTERVAL_DROPDOWN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_SERVICING_INTERVAL, "WID_VD_SERVICING_INTERVAL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_MIDDLE_DETAILS, "WID_VD_MIDDLE_DETAILS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_VD_MATRIX, "WID_VD_MATRIX"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 4c570c9943..a59013b36c 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -866,7 +866,7 @@ public: WID_AID_SCRIPT_GAME = ::WID_AID_SCRIPT_GAME, ///< Game Script button. WID_AID_RELOAD_TOGGLE = ::WID_AID_RELOAD_TOGGLE, ///< Reload button. WID_AID_LOG_PANEL = ::WID_AID_LOG_PANEL, ///< Panel where the log is in. - WID_AID_SCROLLBAR = ::WID_AID_SCROLLBAR, ///< Scrollbar of the log pannel. + WID_AID_SCROLLBAR = ::WID_AID_SCROLLBAR, ///< Scrollbar of the log panel. WID_AID_COMPANY_BUTTON_START = ::WID_AID_COMPANY_BUTTON_START, ///< Buttons in the VIEW. WID_AID_COMPANY_BUTTON_END = ::WID_AID_COMPANY_BUTTON_END, ///< Last possible button in the VIEW. WID_AID_BREAK_STRING_WIDGETS = ::WID_AID_BREAK_STRING_WIDGETS, ///< The panel to handle the breaking on string. @@ -1611,6 +1611,7 @@ public: 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 */ @@ -1889,7 +1890,7 @@ public: WID_OSK_CANCEL = ::WID_OSK_CANCEL, ///< Cancel key. WID_OSK_OK = ::WID_OSK_OK, ///< Ok key. WID_OSK_BACKSPACE = ::WID_OSK_BACKSPACE, ///< Backspace key. - WID_OSK_SPECIAL = ::WID_OSK_SPECIAL, ///< Special key (at keyborads often used for tab key). + WID_OSK_SPECIAL = ::WID_OSK_SPECIAL, ///< Special key (at keyboards often used for tab key). WID_OSK_CAPS = ::WID_OSK_CAPS, ///< Capslock key. WID_OSK_SHIFT = ::WID_OSK_SHIFT, ///< Shift(lock) key. WID_OSK_SPACE = ::WID_OSK_SPACE, ///< Space bar. @@ -1911,7 +1912,7 @@ public: }; /* automatically generated from ../../widgets/rail_widget.h */ - /** Widgets of the #BuildRailToolbarWindow ckass. */ + /** Widgets of the #BuildRailToolbarWindow class. */ enum RailToolbarWidgets { /* Name starts with RA instead of R, because of collision with RoadToolbarWidgets */ WID_RAT_CAPTION = ::WID_RAT_CAPTION, ///< Caption of the window. @@ -2466,6 +2467,7 @@ public: WID_VD_TOP_DETAILS = ::WID_VD_TOP_DETAILS, ///< Panel with generic details. WID_VD_INCREASE_SERVICING_INTERVAL = ::WID_VD_INCREASE_SERVICING_INTERVAL, ///< Increase the servicing interval. WID_VD_DECREASE_SERVICING_INTERVAL = ::WID_VD_DECREASE_SERVICING_INTERVAL, ///< Decrease the servicing interval. + WID_VD_SERVICE_INTERVAL_DROPDOWN = ::WID_VD_SERVICE_INTERVAL_DROPDOWN, ///< Dropdown to select default/days/percent service interval. WID_VD_SERVICING_INTERVAL = ::WID_VD_SERVICING_INTERVAL, ///< Information about the servicing interval. WID_VD_MIDDLE_DETAILS = ::WID_VD_MIDDLE_DETAILS, ///< Details for non-trains. WID_VD_MATRIX = ::WID_VD_MATRIX, ///< List of details for trains. diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 20e1841604..a9b909b82e 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -46,6 +46,7 @@ static Palette _local_palette; static SDL_Rect _dirty_rects[MAX_DIRTY_RECTS]; static int _num_dirty_rects; static int _use_hwpalette; +static int _requested_hwpalette; /* Did we request a HWPALETTE for the current video mode? */ void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height) { @@ -326,20 +327,14 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) if (_sdl_screen != NULL && _sdl_screen != _sdl_realscreen) SDL_CALL SDL_FreeSurface(_sdl_screen); if (_sdl_realscreen != NULL) { - bool have_hwpalette = ((_sdl_realscreen->flags & SDL_HWPALETTE) == SDL_HWPALETTE); - if (have_hwpalette != want_hwpalette) { + if (_requested_hwpalette != want_hwpalette) { /* SDL (at least the X11 driver), reuses the * same window and palette settings when the bpp * (and a few flags) are the same. Since we need * to hwpalette value to change (in particular - * when switching betwen fullscreen and + * when switching between fullscreen and * windowed), we restart the entire video * subsystem to force creating a new window. - * - * Note that checking the SDL_HWPALETTE on the - * existing window might not be accurate when - * SDL is running with its own shadow surface, - * but this should not normally be a problem. */ DEBUG(driver, 0, "SDL: Restarting SDL video subsystem, to force hwpalette change"); SDL_CALL SDL_QuitSubSystem(SDL_INIT_VIDEO); @@ -347,6 +342,11 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) ClaimMousePointer(); } } + /* Remember if we wanted a hwpalette. We can't reliably query + * SDL for the SDL_HWPALETTE flag, since it might get set even + * though we didn't ask for it (when SDL creates a shadow + * surface, for example). */ + _requested_hwpalette = want_hwpalette; /* DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK */ newscreen = SDL_CALL SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE | (want_hwpalette ? SDL_HWPALETTE : 0) | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE)); @@ -690,6 +690,7 @@ void VideoDriver_SDL::MainLoop() if (!_draw_threaded) { _draw_mutex->EndCritical(); delete _draw_mutex; + _draw_mutex = NULL; } else { /* Wait till the draw mutex has started itself. */ _draw_mutex->WaitForSignal(); @@ -757,26 +758,26 @@ void VideoDriver_SDL::MainLoop() /* The gameloop is the part that can run asynchronously. The rest * except sleeping can't. */ - if (_draw_threaded) _draw_mutex->EndCritical(); + if (_draw_mutex != NULL) _draw_mutex->EndCritical(); GameLoop(); - if (_draw_threaded) _draw_mutex->BeginCritical(); + if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); UpdateWindows(); _local_palette = _cur_palette; } else { /* Release the thread while sleeping */ - if (_draw_threaded) _draw_mutex->EndCritical(); + if (_draw_mutex != NULL) _draw_mutex->EndCritical(); CSleep(1); - if (_draw_threaded) _draw_mutex->BeginCritical(); + if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); NetworkDrawChatMessage(); DrawMouseCursor(); } /* End of the critical part. */ - if (_draw_threaded && !HasModalProgress()) { + if (_draw_mutex != NULL && !HasModalProgress()) { _draw_mutex->SendSignal(); } else { /* Oh, we didn't have threads, then just draw unthreaded */ @@ -785,7 +786,7 @@ void VideoDriver_SDL::MainLoop() } } - if (_draw_threaded) { + if (_draw_mutex != NULL) { _draw_continue = false; /* Sending signal if there is no thread blocked * is very valid and results in noop */ @@ -795,14 +796,17 @@ void VideoDriver_SDL::MainLoop() delete _draw_mutex; delete _draw_thread; + + _draw_mutex = NULL; + _draw_thread = NULL; } } bool VideoDriver_SDL::ChangeResolution(int w, int h) { - if (_draw_threaded) _draw_mutex->BeginCritical(); + if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); bool ret = CreateMainSurface(w, h); - if (_draw_threaded) _draw_mutex->EndCritical(); + if (_draw_mutex != NULL) _draw_mutex->EndCritical(); return ret; } diff --git a/src/widgets/network_content_widget.h b/src/widgets/network_content_widget.h index d90afb3d4b..e659743d4f 100644 --- a/src/widgets/network_content_widget.h +++ b/src/widgets/network_content_widget.h @@ -45,6 +45,7 @@ enum NetworkContentListWidgets { 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 */