00001
00002
00005 #include "stdafx.h"
00006 #include "gui.h"
00007 #include "window_gui.h"
00008 #include "textbuf_gui.h"
00009 #include "newgrf.h"
00010 #include "strings_func.h"
00011 #include "window_func.h"
00012 #include "string_func.h"
00013 #include "gfx_func.h"
00014 #include "gamelog.h"
00015 #include "settings_func.h"
00016 #include "widgets/dropdown_type.h"
00017 #include "network/network.h"
00018 #include "network/network_content.h"
00019
00020 #include "table/strings.h"
00021 #include "table/sprites.h"
00022
00029 static int parse_intlist(const char *p, int *items, int maxitems)
00030 {
00031 int n = 0, v;
00032 char *end;
00033
00034 for (;;) {
00035 v = strtol(p, &end, 0);
00036 if (p == end || n == maxitems) return -1;
00037 p = end;
00038 items[n++] = v;
00039 if (*p == '\0') break;
00040 if (*p != ',' && *p != ' ') return -1;
00041 p++;
00042 }
00043
00044 return n;
00045 }
00046
00047
00048 static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bottom, bool show_params)
00049 {
00050 char buff[256];
00051
00052 if (c->error != NULL) {
00053 char message[512];
00054 SetDParamStr(0, c->error->custom_message);
00055 SetDParam (1, STR_JUST_RAW_STRING);
00056 SetDParamStr(2, c->filename);
00057 SetDParam (3, STR_JUST_RAW_STRING);
00058 SetDParamStr(4, c->error->data);
00059 for (uint i = 0; i < c->error->num_params; i++) {
00060 SetDParam(5 + i, c->error->param_value[i]);
00061 }
00062 GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
00063
00064 SetDParamStr(0, message);
00065 y += DrawStringMultiLine(x, y, c->error->severity, w, bottom - y);
00066 }
00067
00068
00069 if (c->filename != NULL) {
00070 SetDParamStr(0, c->filename);
00071 y += DrawStringMultiLine(x, y, STR_NEWGRF_FILENAME, w, bottom - y);
00072 }
00073
00074
00075 snprintf(buff, lengthof(buff), "%08X", BSWAP32(c->grfid));
00076 SetDParamStr(0, buff);
00077 y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w, bottom - y);
00078
00079
00080 md5sumToString(buff, lastof(buff), c->md5sum);
00081 SetDParamStr(0, buff);
00082 y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w, bottom - y);
00083
00084
00085 if (show_params) {
00086 if (c->num_params > 0) {
00087 GRFBuildParamList(buff, c, lastof(buff));
00088 SetDParam(0, STR_JUST_RAW_STRING);
00089 SetDParamStr(1, buff);
00090 } else {
00091 SetDParam(0, STR_01A9_NONE);
00092 }
00093 y += DrawStringMultiLine(x, y, STR_NEWGRF_PARAMETER, w, bottom - y);
00094
00095
00096 SetDParamStr(0, c->windows_paletted ? "Windows" : "DOS");
00097 y += DrawStringMultiLine(x, y, STR_NEWGRF_PALETTE, w, bottom - y);
00098 }
00099
00100
00101 if (c->status == GCS_NOT_FOUND) y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w, bottom - y);
00102 if (c->status == GCS_DISABLED) y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w, bottom - y);
00103 if (HasBit(c->flags, GCF_COMPATIBLE)) y += DrawStringMultiLine(x, y, STR_NEWGRF_COMPATIBLE_LOADED, w, bottom - y);
00104
00105
00106 if (c->info != NULL && !StrEmpty(c->info)) {
00107 SetDParam(0, STR_JUST_RAW_STRING);
00108 SetDParamStr(1, c->info);
00109 y += DrawStringMultiLine(x, y, STR_02BD, w, bottom - y);
00110 } else {
00111 y += DrawStringMultiLine(x, y, STR_NEWGRF_NO_INFO, w, bottom - y);
00112 }
00113 }
00114
00115
00119 struct NewGRFAddWindow : public Window {
00120
00121 enum AddNewGRFWindowWidgets {
00122 ANGRFW_CLOSEBOX = 0,
00123 ANGRFW_CAPTION,
00124 ANGRFW_BACKGROUND,
00125 ANGRFW_GRF_LIST,
00126 ANGRFW_SCROLLBAR,
00127 ANGRFW_GRF_INFO,
00128 ANGRFW_ADD,
00129 ANGRFW_RESCAN,
00130 ANGRFW_RESIZE,
00131 };
00132
00133 GRFConfig **list;
00134 const GRFConfig *sel;
00135
00136 NewGRFAddWindow(const WindowDesc *desc, Window *parent, GRFConfig **list) : Window(desc, 0)
00137 {
00138 this->parent = parent;
00139 this->list = list;
00140 this->resize.step_height = 10;
00141
00142 this->FindWindowPlacementAndResize(desc);
00143 }
00144
00145 virtual void OnPaint()
00146 {
00147 const GRFConfig *c;
00148 const Widget *wl = &this->widget[ANGRFW_GRF_LIST];
00149 int n = 0;
00150
00151
00152 for (c = _all_grfs; c != NULL; c = c->next) n++;
00153
00154 this->vscroll.cap = (wl->bottom - wl->top) / 10;
00155 SetVScrollCount(this, n);
00156
00157 this->SetWidgetDisabledState(ANGRFW_ADD, this->sel == NULL || this->sel->IsOpenTTDBaseGRF());
00158 this->DrawWidgets();
00159
00160 GfxFillRect(wl->left + 1, wl->top + 1, wl->right, wl->bottom, 0xD7);
00161
00162 uint y = wl->top + 1;
00163 for (c = _all_grfs, n = 0; c != NULL && n < (this->vscroll.pos + this->vscroll.cap); c = c->next, n++) {
00164 if (n >= this->vscroll.pos) {
00165 bool h = c == this->sel;
00166 const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
00167
00168
00169 if (h) GfxFillRect(3, y, this->width - 15, y + 9, 156);
00170 DoDrawStringTruncated(text, 4, y, h ? TC_WHITE : TC_ORANGE, this->width - 18);
00171 y += 10;
00172 }
00173 }
00174
00175 if (this->sel != NULL) {
00176 const Widget *wi = &this->widget[ANGRFW_GRF_INFO];
00177 ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, false);
00178 }
00179 }
00180
00181 virtual void OnDoubleClick(Point pt, int widget)
00182 {
00183 if (widget == ANGRFW_GRF_LIST) this->OnClick(pt, ANGRFW_ADD);
00184 }
00185
00186 virtual void OnClick(Point pt, int widget)
00187 {
00188 switch (widget) {
00189 case ANGRFW_GRF_LIST: {
00190
00191 const GRFConfig *c;
00192 uint i = (pt.y - this->widget[ANGRFW_GRF_LIST].top) / 10 + this->vscroll.pos;
00193
00194 for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--) {}
00195 this->sel = c;
00196 this->SetDirty();
00197 break;
00198 }
00199
00200 case ANGRFW_ADD:
00201 if (this->sel != NULL) {
00202 const GRFConfig *src = this->sel;
00203 GRFConfig **list;
00204
00205
00206 for (list = this->list; *list != NULL; list = &(*list)->next) {
00207 if ((*list)->grfid == src->grfid) {
00208 ShowErrorMessage(INVALID_STRING_ID, STR_NEWGRF_DUPLICATE_GRFID, 0, 0);
00209 return;
00210 }
00211 }
00212
00213
00214 GRFConfig *c = CallocT<GRFConfig>(1);
00215 *c = *src;
00216 c->filename = strdup(src->filename);
00217 if (src->name != NULL) c->name = strdup(src->name);
00218 if (src->info != NULL) c->info = strdup(src->info);
00219 c->next = NULL;
00220
00221
00222 *list = c;
00223
00224 DeleteWindowByClass(WC_SAVELOAD);
00225 InvalidateWindowData(WC_GAME_OPTIONS, 0);
00226 }
00227 break;
00228
00229 case ANGRFW_RESCAN:
00230 this->sel = NULL;
00231 ScanNewGRFFiles();
00232 this->SetDirty();
00233 break;
00234 }
00235 }
00236 };
00237
00238
00239 static const Widget _newgrf_add_dlg_widgets[] = {
00240 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_GREY, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
00241 { WWT_CAPTION, RESIZE_RIGHT, COLOUR_GREY, 11, 306, 0, 13, STR_NEWGRF_ADD_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },
00242 { WWT_PANEL, RESIZE_RB, COLOUR_GREY, 0, 294, 14, 121, 0x0, STR_NULL },
00243 { WWT_INSET, RESIZE_RB, COLOUR_GREY, 2, 292, 16, 119, 0x0, STR_NULL },
00244 { WWT_SCROLLBAR, RESIZE_LRB, COLOUR_GREY, 295, 306, 14, 121, 0x0, STR_NULL },
00245 { WWT_PANEL, RESIZE_RTB, COLOUR_GREY, 0, 306, 122, 224, 0x0, STR_NULL },
00246 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_GREY, 0, 146, 225, 236, STR_NEWGRF_ADD_FILE, STR_NEWGRF_ADD_FILE_TIP },
00247 { WWT_PUSHTXTBTN, RESIZE_LRTB, COLOUR_GREY, 147, 294, 225, 236, STR_NEWGRF_RESCAN_FILES, STR_NEWGRF_RESCAN_FILES_TIP },
00248 { WWT_RESIZEBOX, RESIZE_LRTB, COLOUR_GREY, 295, 306, 225, 236, 0x0, STR_RESIZE_BUTTON },
00249 { WIDGETS_END },
00250 };
00251
00252
00253 static const WindowDesc _newgrf_add_dlg_desc(
00254 WDP_CENTER, WDP_CENTER, 307, 237, 307, 337,
00255 WC_SAVELOAD, WC_NONE,
00256 WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00257 _newgrf_add_dlg_widgets
00258 );
00259
00260 static GRFPresetList _grf_preset_list;
00261
00262 class DropDownListPresetItem : public DropDownListItem {
00263 public:
00264 DropDownListPresetItem(int result) : DropDownListItem(result, false) {}
00265
00266 virtual ~DropDownListPresetItem() {}
00267
00268 bool Selectable() const
00269 {
00270 return true;
00271 }
00272
00273 void Draw(int x, int y, uint width, uint height, bool sel, int bg_colour) const
00274 {
00275 DoDrawStringTruncated(_grf_preset_list[this->result], x + 2, y, sel ? TC_WHITE : TC_BLACK, x + width);
00276 }
00277 };
00278
00279 static void NewGRFConfirmationCallback(Window *w, bool confirmed);
00280
00284 struct NewGRFWindow : public Window {
00285
00286 enum ShowNewGRFStateWidgets {
00287 SNGRFS_CLOSEBOX = 0,
00288 SNGRFS_CAPTION,
00289 SNGRFS_BACKGROUND1,
00290 SNGRFS_PRESET_LIST,
00291 SNGRFS_PRESET_SAVE,
00292 SNGRFS_PRESET_DELETE,
00293 SNGRFS_BACKGROUND2,
00294 SNGRFS_ADD,
00295 SNGRFS_REMOVE,
00296 SNGRFS_MOVE_UP,
00297 SNGRFS_MOVE_DOWN,
00298 SNGRFS_FILE_LIST,
00299 SNGRFS_SCROLLBAR,
00300 SNGRFS_NEWGRF_INFO,
00301 SNGRFS_SET_PARAMETERS,
00302 SNGRFS_TOGGLE_PALETTE,
00303 SNGRFS_APPLY_CHANGES,
00304 SNGRFS_CONTENT_DOWNLOAD,
00305 SNGRFS_RESIZE,
00306 };
00307
00308 GRFConfig **orig_list;
00309 GRFConfig *list;
00310 GRFConfig *sel;
00311 bool editable;
00312 bool show_params;
00313 bool execute;
00314 int query_widget;
00315 int preset;
00316
00317 NewGRFWindow(const WindowDesc *desc, bool editable, bool show_params, bool exec_changes, GRFConfig **config) : Window(desc, 0)
00318 {
00319 this->resize.step_height = 14;
00320 this->sel = NULL;
00321 this->list = NULL;
00322 this->orig_list = config;
00323 this->editable = editable;
00324 this->execute = exec_changes;
00325 this->show_params = show_params;
00326 this->preset = -1;
00327
00328 CopyGRFConfigList(&this->list, *config, false);
00329 GetGRFPresetList(&_grf_preset_list);
00330
00331 this->FindWindowPlacementAndResize(desc);
00332 this->SetupNewGRFWindow();
00333 }
00334
00335 ~NewGRFWindow()
00336 {
00337 if (this->editable && !this->execute) {
00338 CopyGRFConfigList(this->orig_list, this->list, true);
00339 ResetGRFConfig(false);
00340 ReloadNewGRFData();
00341 }
00342
00343
00344 ClearGRFConfigList(&this->list);
00345 _grf_preset_list.Clear();
00346 }
00347
00348 void SetupNewGRFWindow()
00349 {
00350 const GRFConfig *c;
00351 int i;
00352
00353 for (c = this->list, i = 0; c != NULL; c = c->next, i++) {}
00354
00355 this->vscroll.cap = (this->widget[SNGRFS_FILE_LIST].bottom - this->widget[SNGRFS_FILE_LIST].top) / 14 + 1;
00356 SetVScrollCount(this, i);
00357
00358 this->SetWidgetsDisabledState(!this->editable,
00359 SNGRFS_PRESET_LIST,
00360 SNGRFS_ADD,
00361 SNGRFS_APPLY_CHANGES,
00362 SNGRFS_TOGGLE_PALETTE,
00363 WIDGET_LIST_END
00364 );
00365 }
00366
00367 virtual void OnPaint()
00368 {
00369 bool disable_all = this->sel == NULL || !this->editable;
00370
00371 this->SetWidgetsDisabledState(disable_all,
00372 SNGRFS_REMOVE,
00373 SNGRFS_MOVE_UP,
00374 SNGRFS_MOVE_DOWN,
00375 WIDGET_LIST_END
00376 );
00377 this->SetWidgetDisabledState(SNGRFS_SET_PARAMETERS, !this->show_params || disable_all);
00378 this->SetWidgetDisabledState(SNGRFS_TOGGLE_PALETTE, disable_all);
00379
00380 if (!disable_all) {
00381
00382 if (this->sel == this->list) this->DisableWidget(SNGRFS_MOVE_UP);
00383 if (this->sel->next == NULL) this->DisableWidget(SNGRFS_MOVE_DOWN);
00384 if (this->sel->IsOpenTTDBaseGRF()) this->DisableWidget(SNGRFS_REMOVE);
00385 }
00386
00387 if (this->preset == -1) {
00388 this->widget[SNGRFS_PRESET_LIST].data = STR_02BF_CUSTOM;
00389 } else {
00390 SetDParamStr(0, _grf_preset_list[this->preset]);
00391 this->widget[SNGRFS_PRESET_LIST].data = STR_JUST_RAW_STRING;
00392 }
00393 this->SetWidgetDisabledState(SNGRFS_PRESET_DELETE, this->preset == -1);
00394
00395 bool has_missing = false;
00396 bool has_compatible = false;
00397 for (const GRFConfig *c = this->list; !has_missing && c != NULL; c = c->next) {
00398 has_missing |= c->status == GCS_NOT_FOUND;
00399 has_compatible |= HasBit(c->flags, GCF_COMPATIBLE);
00400 }
00401 if (has_missing || has_compatible) {
00402 this->widget[SNGRFS_CONTENT_DOWNLOAD].data = STR_CONTENT_INTRO_MISSING_BUTTON;
00403 this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_MISSING_BUTTON_TIP;
00404 } else {
00405 this->widget[SNGRFS_CONTENT_DOWNLOAD].data = STR_CONTENT_INTRO_BUTTON;
00406 this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_BUTTON_TIP;
00407 }
00408 this->SetWidgetDisabledState(SNGRFS_PRESET_SAVE, has_missing);
00409
00410 this->DrawWidgets();
00411
00412
00413 int y = this->widget[SNGRFS_FILE_LIST].top;
00414 int i = 0;
00415 for (const GRFConfig *c = this->list; c != NULL; c = c->next, i++) {
00416 if (i >= this->vscroll.pos && i < this->vscroll.pos + this->vscroll.cap) {
00417 const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
00418 SpriteID pal;
00419 byte txtoffset;
00420
00421
00422 switch (c->status) {
00423 case GCS_NOT_FOUND:
00424 case GCS_DISABLED:
00425 pal = PALETTE_TO_RED;
00426 break;
00427 case GCS_ACTIVATED:
00428 pal = PALETTE_TO_GREEN;
00429 break;
00430 default:
00431 pal = PALETTE_TO_BLUE;
00432 break;
00433 }
00434
00435
00436 if (pal != PALETTE_TO_RED) {
00437 if (HasBit(c->flags, GCF_STATIC)) {
00438 pal = PALETTE_TO_GREY;
00439 } else if (HasBit(c->flags, GCF_COMPATIBLE)) {
00440 pal = PALETTE_TO_ORANGE;
00441 }
00442 }
00443
00444 DrawSprite(SPR_SQUARE, pal, 5, y + 2);
00445 if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, 20, y + 2);
00446 txtoffset = c->error != NULL ? 35 : 25;
00447 DoDrawStringTruncated(text, txtoffset, y + 3, this->sel == c ? TC_WHITE : TC_BLACK, this->width - txtoffset - 10);
00448 y += 14;
00449 }
00450 }
00451
00452 if (this->sel != NULL) {
00453
00454 const Widget *wi = &this->widget[SNGRFS_NEWGRF_INFO];
00455 ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, this->show_params);
00456 }
00457 }
00458
00459 virtual void OnClick(Point pt, int widget)
00460 {
00461 switch (widget) {
00462 case SNGRFS_PRESET_LIST: {
00463 DropDownList *list = new DropDownList();
00464
00465
00466 list->push_back(new DropDownListStringItem(STR_NONE, -1, false));
00467
00468 for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00469 if (_grf_preset_list[i] != NULL) {
00470 list->push_back(new DropDownListPresetItem(i));
00471 }
00472 }
00473
00474 ShowDropDownList(this, list, this->preset, SNGRFS_PRESET_LIST);
00475 break;
00476 }
00477
00478 case SNGRFS_PRESET_SAVE:
00479 this->query_widget = widget;
00480 ShowQueryString(STR_EMPTY, STR_NEWGRF_PRESET_SAVE_QUERY, 32, 100, this, CS_ALPHANUMERAL, QSF_NONE);
00481 break;
00482
00483 case SNGRFS_PRESET_DELETE:
00484 if (this->preset == -1) return;
00485
00486 DeleteGRFPresetFromConfig(_grf_preset_list[this->preset]);
00487 GetGRFPresetList(&_grf_preset_list);
00488 this->preset = -1;
00489 this->SetDirty();
00490 break;
00491
00492 case SNGRFS_ADD:
00493 DeleteWindowByClass(WC_SAVELOAD);
00494 new NewGRFAddWindow(&_newgrf_add_dlg_desc, this, &this->list);
00495 break;
00496
00497 case SNGRFS_REMOVE: {
00498 GRFConfig **pc, *c, *newsel;
00499
00500
00501 newsel = this->sel->next;
00502
00503 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00504
00505
00506 if (newsel == NULL && c->next == this->sel) newsel = c;
00507
00508 if (c == this->sel) {
00509 *pc = c->next;
00510 free(c);
00511 break;
00512 }
00513 }
00514
00515 this->sel = newsel;
00516 this->preset = -1;
00517 this->SetupNewGRFWindow();
00518 this->SetDirty();
00519 this->DeleteChildWindows(WC_QUERY_STRING);
00520 break;
00521 }
00522
00523 case SNGRFS_MOVE_UP: {
00524 GRFConfig **pc, *c;
00525 if (this->sel == NULL) break;
00526
00527 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00528 if (c->next == this->sel) {
00529 c->next = this->sel->next;
00530 this->sel->next = c;
00531 *pc = this->sel;
00532 break;
00533 }
00534 }
00535 this->preset = -1;
00536 this->SetDirty();
00537 break;
00538 }
00539
00540 case SNGRFS_MOVE_DOWN: {
00541 GRFConfig **pc, *c;
00542 if (this->sel == NULL) break;
00543
00544 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00545 if (c == this->sel) {
00546 *pc = c->next;
00547 c->next = c->next->next;
00548 (*pc)->next = c;
00549 break;
00550 }
00551 }
00552 this->preset = -1;
00553 this->SetDirty();
00554 break;
00555 }
00556
00557 case SNGRFS_FILE_LIST: {
00558 GRFConfig *c;
00559 uint i = (pt.y - this->widget[SNGRFS_FILE_LIST].top) / 14 + this->vscroll.pos;
00560
00561 for (c = this->list; c != NULL && i > 0; c = c->next, i--) {}
00562
00563 if (this->sel != c) this->DeleteChildWindows(WC_QUERY_STRING);
00564 this->sel = c;
00565
00566 this->SetDirty();
00567 break;
00568 }
00569
00570 case SNGRFS_APPLY_CHANGES:
00571 if (this->execute) {
00572 ShowQuery(
00573 STR_POPUP_CAUTION_CAPTION,
00574 STR_NEWGRF_CONFIRMATION_TEXT,
00575 this,
00576 NewGRFConfirmationCallback
00577 );
00578 } else {
00579 CopyGRFConfigList(this->orig_list, this->list, true);
00580 ResetGRFConfig(false);
00581 ReloadNewGRFData();
00582 }
00583 break;
00584
00585 case SNGRFS_SET_PARAMETERS: {
00586 if (this->sel == NULL) break;
00587
00588 this->query_widget = widget;
00589 static char buff[512];
00590 GRFBuildParamList(buff, this->sel, lastof(buff));
00591 SetDParamStr(0, buff);
00592 ShowQueryString(STR_JUST_RAW_STRING, STR_NEWGRF_PARAMETER_QUERY, 63, 250, this, CS_ALPHANUMERAL, QSF_NONE);
00593 break;
00594 }
00595
00596 case SNGRFS_TOGGLE_PALETTE:
00597 if (this->sel != NULL) {
00598 this->sel->windows_paletted ^= true;
00599 this->SetDirty();
00600 }
00601 break;
00602
00603 case SNGRFS_CONTENT_DOWNLOAD:
00604 if (!_network_available) {
00605 ShowErrorMessage(INVALID_STRING_ID, STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
00606 } else {
00607 #if defined(ENABLE_NETWORK)
00608
00609 ContentVector cv;
00610 for (const GRFConfig *c = this->list; c != NULL; c = c->next) {
00611 if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue;
00612
00613 ContentInfo *ci = new ContentInfo();
00614 ci->type = CONTENT_TYPE_NEWGRF;
00615 ci->state = ContentInfo::DOES_NOT_EXIST;
00616 ttd_strlcpy(ci->name, c->name != NULL ? c->name : c->filename, lengthof(ci->name));
00617 ci->unique_id = BSWAP32(c->grfid);
00618 memcpy(ci->md5sum, c->md5sum, sizeof(ci->md5sum));
00619 if (HasBit(c->flags, GCF_COMPATIBLE)) GamelogGetOriginalGRFMD5Checksum(c->grfid, ci->md5sum);
00620 *cv.Append() = ci;
00621 }
00622 ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF);
00623 #endif
00624 }
00625 break;
00626
00627 }
00628 }
00629
00630 virtual void OnDropdownSelect(int widget, int index)
00631 {
00632 if (index == -1) {
00633 ClearGRFConfigList(&this->list);
00634 this->preset = -1;
00635 } else {
00636 GRFConfig *c = LoadGRFPresetFromConfig(_grf_preset_list[index]);
00637
00638 if (c != NULL) {
00639 this->sel = NULL;
00640 ClearGRFConfigList(&this->list);
00641 this->list = c;
00642 this->preset = index;
00643 }
00644 }
00645
00646 this->sel = NULL;
00647 this->SetupNewGRFWindow();
00648 this->SetDirty();
00649 }
00650
00651 virtual void OnQueryTextFinished(char *str)
00652 {
00653 if (str == NULL) return;
00654
00655 switch (this->query_widget) {
00656 case SNGRFS_PRESET_SAVE:
00657 SaveGRFPresetToConfig(str, this->list);
00658 GetGRFPresetList(&_grf_preset_list);
00659
00660
00661 for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00662 if (_grf_preset_list[i] != NULL && strcmp(_grf_preset_list[i], str) == 0) {
00663 this->preset = i;
00664 break;
00665 }
00666 }
00667
00668 this->SetDirty();
00669 break;
00670
00671 case SNGRFS_SET_PARAMETERS: {
00672
00673 GRFConfig *c = this->sel;
00674 c->num_params = parse_intlist(str, (int*)c->param, lengthof(c->param));
00675
00676
00677 if (c->num_params == (byte)-1) c->num_params = 0;
00678
00679 this->preset = -1;
00680 this->SetDirty();
00681 break;
00682 }
00683 }
00684 }
00685
00686 virtual void OnResize(Point new_size, Point delta)
00687 {
00688 if (delta.x != 0) {
00689 ResizeButtons(this, SNGRFS_ADD, SNGRFS_MOVE_DOWN);
00690 ResizeButtons(this, SNGRFS_SET_PARAMETERS, SNGRFS_APPLY_CHANGES);
00691 }
00692
00693 this->vscroll.cap += delta.y / 14;
00694 this->widget[SNGRFS_FILE_LIST].data = (this->vscroll.cap << 8) + 1;
00695
00696 this->SetupNewGRFWindow();
00697 }
00698
00699 virtual void OnInvalidateData(int data)
00700 {
00701 switch (data) {
00702 default: NOT_REACHED();
00703 case 0:
00704 this->preset = -1;
00705 this->SetupNewGRFWindow();
00706 break;
00707
00708 case 1:
00709
00710 for (GRFConfig *c = this->list; c != NULL; c = c->next) {
00711 if (c->status != GCS_NOT_FOUND) continue;
00712
00713 const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
00714 if (f == NULL) continue;
00715
00716 free(c->filename);
00717 free(c->name);
00718 free(c->info);
00719
00720 c->filename = f->filename == NULL ? NULL : strdup(f->filename);
00721 c->name = f->name == NULL ? NULL : strdup(f->name);;
00722 c->info = f->info == NULL ? NULL : strdup(f->info);;
00723 c->status = GCS_UNKNOWN;
00724 }
00725 break;
00726 }
00727 }
00728 };
00729
00730
00731 static const Widget _newgrf_widgets[] = {
00732 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_MAUVE, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
00733 { WWT_CAPTION, RESIZE_RIGHT, COLOUR_MAUVE, 11, 299, 0, 13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },
00734 { WWT_PANEL, RESIZE_RIGHT, COLOUR_MAUVE, 0, 299, 14, 41, STR_NULL, STR_NULL },
00735 { WWT_DROPDOWN, RESIZE_RIGHT, COLOUR_YELLOW, 10, 103, 16, 27, STR_EMPTY, STR_NEWGRF_PRESET_LIST_TIP },
00736 { WWT_PUSHTXTBTN, RESIZE_LR, COLOUR_YELLOW, 104, 196, 16, 27, STR_NEWGRF_PRESET_SAVE, STR_NEWGRF_PRESET_SAVE_TIP },
00737 { WWT_PUSHTXTBTN, RESIZE_LR, COLOUR_YELLOW, 197, 289, 16, 27, STR_NEWGRF_PRESET_DELETE, STR_NEWGRF_PRESET_DELETE_TIP },
00738 { WWT_PANEL, RESIZE_RIGHT, COLOUR_MAUVE, 0, 299, 30, 45, STR_NULL, STR_NULL },
00739 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 10, 79, 32, 43, STR_NEWGRF_ADD, STR_NEWGRF_ADD_TIP },
00740 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 80, 149, 32, 43, STR_NEWGRF_REMOVE, STR_NEWGRF_REMOVE_TIP },
00741 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 150, 219, 32, 43, STR_NEWGRF_MOVEUP, STR_NEWGRF_MOVEUP_TIP },
00742 { WWT_PUSHTXTBTN, RESIZE_RIGHT, COLOUR_YELLOW, 220, 289, 32, 43, STR_NEWGRF_MOVEDOWN, STR_NEWGRF_MOVEDOWN_TIP },
00743 { WWT_MATRIX, RESIZE_RB, COLOUR_MAUVE, 0, 287, 46, 115, 0x501, STR_NEWGRF_FILE_TIP },
00744 { WWT_SCROLLBAR, RESIZE_LRB, COLOUR_MAUVE, 288, 299, 46, 115, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST },
00745 { WWT_PANEL, RESIZE_RTB, COLOUR_MAUVE, 0, 299, 116, 238, STR_NULL, STR_NULL },
00746 { WWT_PUSHTXTBTN, RESIZE_TB, COLOUR_MAUVE, 0, 99, 239, 250, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
00747 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 100, 199, 239, 250, STR_NEWGRF_TOGGLE_PALETTE, STR_NEWGRF_TOGGLE_PALETTE_TIP },
00748 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 200, 299, 239, 250, STR_NEWGRF_APPLY_CHANGES, STR_NULL },
00749 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 0, 287, 251, 262, STR_CONTENT_INTRO_BUTTON, STR_CONTENT_INTRO_BUTTON_TIP },
00750 { WWT_RESIZEBOX, RESIZE_LRTB, COLOUR_MAUVE, 288, 299, 251, 262, 0x0, STR_RESIZE_BUTTON },
00751 { WIDGETS_END },
00752 };
00753
00754
00755 static const WindowDesc _newgrf_desc(
00756 WDP_CENTER, WDP_CENTER, 300, 263, 300, 263,
00757 WC_GAME_OPTIONS, WC_NONE,
00758 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00759 _newgrf_widgets
00760 );
00761
00766 static void NewGRFConfirmationCallback(Window *w, bool confirmed)
00767 {
00768 if (confirmed) {
00769 NewGRFWindow *nw = dynamic_cast<NewGRFWindow*>(w);
00770 GRFConfig *c;
00771 int i = 0;
00772
00773 GamelogStartAction(GLAT_GRF);
00774 GamelogGRFUpdate(_grfconfig, nw->list);
00775 CopyGRFConfigList(nw->orig_list, nw->list, false);
00776 ReloadNewGRFData();
00777 GamelogStopAction();
00778
00779
00780 for (c = nw->list; c != NULL && c != nw->sel; c = c->next, i++) {}
00781 CopyGRFConfigList(&nw->list, *nw->orig_list, false);
00782 for (c = nw->list; c != NULL && i > 0; c = c->next, i--) {}
00783 nw->sel = c;
00784
00785 w->SetDirty();
00786 }
00787 }
00788
00789
00790
00797 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
00798 {
00799 DeleteWindowByClass(WC_GAME_OPTIONS);
00800 new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config);
00801 }