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