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 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 }