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