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 this->SetWidgetDisabledState(SNGRFS_PRESET_DELETE, this->preset == -1);
00398
00399 bool has_missing = false;
00400 bool has_compatible = false;
00401 for (const GRFConfig *c = this->list; !has_missing && c != NULL; c = c->next) {
00402 has_missing |= c->status == GCS_NOT_FOUND;
00403 has_compatible |= HasBit(c->flags, GCF_COMPATIBLE);
00404 }
00405 if (has_missing || has_compatible) {
00406 this->widget[SNGRFS_CONTENT_DOWNLOAD].data = STR_CONTENT_INTRO_MISSING_BUTTON;
00407 this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_MISSING_BUTTON_TIP;
00408 } else {
00409 this->widget[SNGRFS_CONTENT_DOWNLOAD].data = STR_CONTENT_INTRO_BUTTON;
00410 this->widget[SNGRFS_CONTENT_DOWNLOAD].tooltips = STR_CONTENT_INTRO_BUTTON_TIP;
00411 }
00412 this->SetWidgetDisabledState(SNGRFS_PRESET_SAVE, has_missing);
00413
00414 this->DrawWidgets();
00415
00416
00417 int y = this->widget[SNGRFS_FILE_LIST].top;
00418 int i = 0;
00419 for (const GRFConfig *c = this->list; c != NULL; c = c->next, i++) {
00420 if (i >= this->vscroll.pos && i < this->vscroll.pos + this->vscroll.cap) {
00421 const char *text = (c->name != NULL && !StrEmpty(c->name)) ? c->name : c->filename;
00422 SpriteID pal;
00423 byte txtoffset;
00424
00425
00426 switch (c->status) {
00427 case GCS_NOT_FOUND:
00428 case GCS_DISABLED:
00429 pal = PALETTE_TO_RED;
00430 break;
00431 case GCS_ACTIVATED:
00432 pal = PALETTE_TO_GREEN;
00433 break;
00434 default:
00435 pal = PALETTE_TO_BLUE;
00436 break;
00437 }
00438
00439
00440 if (pal != PALETTE_TO_RED) {
00441 if (HasBit(c->flags, GCF_STATIC)) {
00442 pal = PALETTE_TO_GREY;
00443 } else if (HasBit(c->flags, GCF_COMPATIBLE)) {
00444 pal = PALETTE_TO_ORANGE;
00445 }
00446 }
00447
00448 DrawSprite(SPR_SQUARE, pal, 5, y + 2);
00449 if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, 20, y + 2);
00450 txtoffset = c->error != NULL ? 35 : 25;
00451 DoDrawStringTruncated(text, txtoffset, y + 3, this->sel == c ? TC_WHITE : TC_BLACK, this->width - txtoffset - 10);
00452 y += 14;
00453 }
00454 }
00455
00456 if (this->sel != NULL) {
00457
00458 const Widget *wi = &this->widget[SNGRFS_NEWGRF_INFO];
00459 ShowNewGRFInfo(this->sel, wi->left + 2, wi->top + 2, wi->right - wi->left - 2, wi->bottom, this->show_params);
00460 }
00461 }
00462
00463 virtual void OnClick(Point pt, int widget)
00464 {
00465 switch (widget) {
00466 case SNGRFS_PRESET_LIST: {
00467 DropDownList *list = new DropDownList();
00468
00469
00470 list->push_back(new DropDownListStringItem(STR_NONE, -1, false));
00471
00472 for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00473 if (_grf_preset_list[i] != NULL) {
00474 list->push_back(new DropDownListPresetItem(i));
00475 }
00476 }
00477
00478 ShowDropDownList(this, list, this->preset, SNGRFS_PRESET_LIST);
00479 break;
00480 }
00481
00482 case SNGRFS_PRESET_SAVE:
00483 this->query_widget = widget;
00484 ShowQueryString(STR_EMPTY, STR_NEWGRF_PRESET_SAVE_QUERY, 32, 100, this, CS_ALPHANUMERAL, QSF_NONE);
00485 break;
00486
00487 case SNGRFS_PRESET_DELETE:
00488 if (this->preset == -1) return;
00489
00490 DeleteGRFPresetFromConfig(_grf_preset_list[this->preset]);
00491 GetGRFPresetList(&_grf_preset_list);
00492 this->preset = -1;
00493 this->SetDirty();
00494 break;
00495
00496 case SNGRFS_ADD:
00497 DeleteWindowByClass(WC_SAVELOAD);
00498 new NewGRFAddWindow(&_newgrf_add_dlg_desc, &this->list);
00499 break;
00500
00501 case SNGRFS_REMOVE: {
00502 GRFConfig **pc, *c, *newsel;
00503
00504
00505 newsel = this->sel->next;
00506
00507 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00508
00509
00510 if (newsel == NULL && c->next == this->sel) newsel = c;
00511
00512 if (c == this->sel) {
00513 *pc = c->next;
00514 free(c);
00515 break;
00516 }
00517 }
00518
00519 this->sel = newsel;
00520 this->preset = -1;
00521 this->SetupNewGRFWindow();
00522 this->SetDirty();
00523 break;
00524 }
00525
00526 case SNGRFS_MOVE_UP: {
00527 GRFConfig **pc, *c;
00528 if (this->sel == NULL) break;
00529
00530 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00531 if (c->next == this->sel) {
00532 c->next = this->sel->next;
00533 this->sel->next = c;
00534 *pc = this->sel;
00535 break;
00536 }
00537 }
00538 this->preset = -1;
00539 this->SetDirty();
00540 break;
00541 }
00542
00543 case SNGRFS_MOVE_DOWN: {
00544 GRFConfig **pc, *c;
00545 if (this->sel == NULL) break;
00546
00547 for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) {
00548 if (c == this->sel) {
00549 *pc = c->next;
00550 c->next = c->next->next;
00551 (*pc)->next = c;
00552 break;
00553 }
00554 }
00555 this->preset = -1;
00556 this->SetDirty();
00557 break;
00558 }
00559
00560 case SNGRFS_FILE_LIST: {
00561 GRFConfig *c;
00562 uint i = (pt.y - this->widget[SNGRFS_FILE_LIST].top) / 14 + this->vscroll.pos;
00563
00564 for (c = this->list; c != NULL && i > 0; c = c->next, i--) {}
00565 this->sel = c;
00566
00567 this->SetDirty();
00568 break;
00569 }
00570
00571 case SNGRFS_APPLY_CHANGES:
00572 if (this->execute) {
00573 ShowQuery(
00574 STR_POPUP_CAUTION_CAPTION,
00575 STR_NEWGRF_CONFIRMATION_TEXT,
00576 this,
00577 NewGRFConfirmationCallback
00578 );
00579 } else {
00580 CopyGRFConfigList(this->orig_list, this->list, true);
00581 ResetGRFConfig(false);
00582 ReloadNewGRFData();
00583 }
00584 break;
00585
00586 case SNGRFS_SET_PARAMETERS: {
00587 if (this->sel == NULL) break;
00588
00589 this->query_widget = widget;
00590 static char buff[512];
00591 GRFBuildParamList(buff, this->sel, lastof(buff));
00592 SetDParamStr(0, buff);
00593 ShowQueryString(STR_JUST_RAW_STRING, STR_NEWGRF_PARAMETER_QUERY, 63, 250, this, CS_ALPHANUMERAL, QSF_NONE);
00594 break;
00595 }
00596
00597 case SNGRFS_TOGGLE_PALETTE:
00598 if (this->sel != NULL) {
00599 this->sel->windows_paletted ^= true;
00600 this->SetDirty();
00601 }
00602 break;
00603
00604 case SNGRFS_CONTENT_DOWNLOAD:
00605 if (!_network_available) {
00606 ShowErrorMessage(INVALID_STRING_ID, STR_NETWORK_ERR_NOTAVAILABLE, 0, 0);
00607 } else {
00608 #if defined(ENABLE_NETWORK)
00609
00610 ContentVector cv;
00611 for (const GRFConfig *c = this->list; c != NULL; c = c->next) {
00612 if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue;
00613
00614 ContentInfo *ci = new ContentInfo();
00615 ci->type = CONTENT_TYPE_NEWGRF;
00616 ci->state = ContentInfo::DOES_NOT_EXIST;
00617 ttd_strlcpy(ci->name, c->name != NULL ? c->name : c->filename, lengthof(ci->name));
00618 ci->unique_id = BSWAP32(c->grfid);
00619 memcpy(ci->md5sum, c->md5sum, sizeof(ci->md5sum));
00620 if (HasBit(c->flags, GCF_COMPATIBLE)) GamelogGetOriginalGRFMD5Checksum(c->grfid, ci->md5sum);
00621 *cv.Append() = ci;
00622 }
00623 ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF);
00624 #endif
00625 }
00626 break;
00627
00628 }
00629 }
00630
00631 virtual void OnDropdownSelect(int widget, int index)
00632 {
00633 if (index == -1) {
00634 ClearGRFConfigList(&this->list);
00635 this->preset = -1;
00636 } else {
00637 GRFConfig *c = LoadGRFPresetFromConfig(_grf_preset_list[index]);
00638
00639 if (c != NULL) {
00640 this->sel = NULL;
00641 ClearGRFConfigList(&this->list);
00642 this->list = c;
00643 this->preset = index;
00644 }
00645 }
00646
00647 this->sel = NULL;
00648 this->SetupNewGRFWindow();
00649 this->SetDirty();
00650 }
00651
00652 virtual void OnQueryTextFinished(char *str)
00653 {
00654 if (str == NULL) return;
00655
00656 switch (this->query_widget) {
00657 case SNGRFS_PRESET_SAVE:
00658 SaveGRFPresetToConfig(str, this->list);
00659 GetGRFPresetList(&_grf_preset_list);
00660
00661
00662 for (uint i = 0; i < _grf_preset_list.Length(); i++) {
00663 if (_grf_preset_list[i] != NULL && strcmp(_grf_preset_list[i], str) == 0) {
00664 this->preset = i;
00665 break;
00666 }
00667 }
00668
00669 this->SetDirty();
00670 break;
00671
00672 case SNGRFS_SET_PARAMETERS: {
00673
00674 GRFConfig *c = this->sel;
00675 c->num_params = parse_intlist(str, (int*)c->param, lengthof(c->param));
00676
00677
00678 if (c->num_params == (byte)-1) c->num_params = 0;
00679
00680 this->preset = -1;
00681 this->SetDirty();
00682 break;
00683 }
00684 }
00685 }
00686
00687 virtual void OnResize(Point new_size, Point delta)
00688 {
00689 if (delta.x != 0) {
00690 ResizeButtons(this, SNGRFS_ADD, SNGRFS_MOVE_DOWN);
00691 ResizeButtons(this, SNGRFS_SET_PARAMETERS, SNGRFS_APPLY_CHANGES);
00692 }
00693
00694 this->vscroll.cap += delta.y / 14;
00695 this->widget[SNGRFS_FILE_LIST].data = (this->vscroll.cap << 8) + 1;
00696
00697 this->SetupNewGRFWindow();
00698 }
00699
00700 virtual void OnInvalidateData(int data)
00701 {
00702 switch (data) {
00703 default: NOT_REACHED();
00704 case 0:
00705 this->preset = -1;
00706 this->SetupNewGRFWindow();
00707 break;
00708
00709 case 1:
00710
00711 for (GRFConfig *c = this->list; c != NULL; c = c->next) {
00712 if (c->status != GCS_NOT_FOUND) continue;
00713
00714 const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
00715 if (f == NULL) continue;
00716
00717 free(c->filename);
00718 free(c->name);
00719 free(c->info);
00720
00721 c->filename = f->filename == NULL ? NULL : strdup(f->filename);
00722 c->name = f->name == NULL ? NULL : strdup(f->name);;
00723 c->info = f->info == NULL ? NULL : strdup(f->info);;
00724 c->status = GCS_UNKNOWN;
00725 }
00726 break;
00727 }
00728 }
00729 };
00730
00731
00732 static const Widget _newgrf_widgets[] = {
00733 { WWT_CLOSEBOX, RESIZE_NONE, COLOUR_MAUVE, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW },
00734 { WWT_CAPTION, RESIZE_RIGHT, COLOUR_MAUVE, 11, 299, 0, 13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS },
00735 { WWT_PANEL, RESIZE_RIGHT, COLOUR_MAUVE, 0, 299, 14, 41, STR_NULL, STR_NULL },
00736 { WWT_DROPDOWN, RESIZE_RIGHT, COLOUR_YELLOW, 10, 103, 16, 27, STR_EMPTY, STR_NEWGRF_PRESET_LIST_TIP },
00737 { WWT_PUSHTXTBTN, RESIZE_LR, COLOUR_YELLOW, 104, 196, 16, 27, STR_NEWGRF_PRESET_SAVE, STR_NEWGRF_PRESET_SAVE_TIP },
00738 { WWT_PUSHTXTBTN, RESIZE_LR, COLOUR_YELLOW, 197, 289, 16, 27, STR_NEWGRF_PRESET_DELETE, STR_NEWGRF_PRESET_DELETE_TIP },
00739 { WWT_PANEL, RESIZE_RIGHT, COLOUR_MAUVE, 0, 299, 30, 45, STR_NULL, STR_NULL },
00740 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 10, 79, 32, 43, STR_NEWGRF_ADD, STR_NEWGRF_ADD_TIP },
00741 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 80, 149, 32, 43, STR_NEWGRF_REMOVE, STR_NEWGRF_REMOVE_TIP },
00742 { WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_YELLOW, 150, 219, 32, 43, STR_NEWGRF_MOVEUP, STR_NEWGRF_MOVEUP_TIP },
00743 { WWT_PUSHTXTBTN, RESIZE_RIGHT, COLOUR_YELLOW, 220, 289, 32, 43, STR_NEWGRF_MOVEDOWN, STR_NEWGRF_MOVEDOWN_TIP },
00744 { WWT_MATRIX, RESIZE_RB, COLOUR_MAUVE, 0, 287, 46, 115, 0x501, STR_NEWGRF_FILE_TIP },
00745 { WWT_SCROLLBAR, RESIZE_LRB, COLOUR_MAUVE, 288, 299, 46, 115, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST },
00746 { WWT_PANEL, RESIZE_RTB, COLOUR_MAUVE, 0, 299, 116, 238, STR_NULL, STR_NULL },
00747 { WWT_PUSHTXTBTN, RESIZE_TB, COLOUR_MAUVE, 0, 99, 239, 250, STR_NEWGRF_SET_PARAMETERS, STR_NULL },
00748 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 100, 199, 239, 250, STR_NEWGRF_TOGGLE_PALETTE, STR_NEWGRF_TOGGLE_PALETTE_TIP },
00749 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 200, 299, 239, 250, STR_NEWGRF_APPLY_CHANGES, STR_NULL },
00750 { WWT_PUSHTXTBTN, RESIZE_RTB, COLOUR_MAUVE, 0, 287, 251, 262, STR_CONTENT_INTRO_BUTTON, STR_CONTENT_INTRO_BUTTON_TIP },
00751 { WWT_RESIZEBOX, RESIZE_LRTB, COLOUR_MAUVE, 288, 299, 251, 262, 0x0, STR_RESIZE_BUTTON },
00752 { WIDGETS_END },
00753 };
00754
00755
00756 static const WindowDesc _newgrf_desc = {
00757 WDP_CENTER, WDP_CENTER, 300, 263, 300, 263,
00758 WC_GAME_OPTIONS, WC_NONE,
00759 WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
00760 _newgrf_widgets,
00761 };
00762
00767 static void NewGRFConfirmationCallback(Window *w, bool confirmed)
00768 {
00769 if (confirmed) {
00770 NewGRFWindow *nw = dynamic_cast<NewGRFWindow*>(w);
00771 GRFConfig *c;
00772 int i = 0;
00773
00774 GamelogStartAction(GLAT_GRF);
00775 GamelogGRFUpdate(_grfconfig, nw->list);
00776 CopyGRFConfigList(nw->orig_list, nw->list, false);
00777 ReloadNewGRFData();
00778 GamelogStopAction();
00779
00780
00781 for (c = nw->list; c != NULL && c != nw->sel; c = c->next, i++) {}
00782 CopyGRFConfigList(&nw->list, *nw->orig_list, false);
00783 for (c = nw->list; c != NULL && i > 0; c = c->next, i--) {}
00784 nw->sel = c;
00785
00786 w->SetDirty();
00787 }
00788 }
00789
00790
00791
00798 void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config)
00799 {
00800 DeleteWindowByClass(WC_GAME_OPTIONS);
00801 new NewGRFWindow(&_newgrf_desc, editable, show_params, exec_changes, config);
00802 }