00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "openttd.h"
00014 #include "saveload/saveload.h"
00015 #include "gui.h"
00016 #include "gfx_func.h"
00017 #include "command_func.h"
00018 #include "network/network.h"
00019 #include "network/network_content.h"
00020 #include "strings_func.h"
00021 #include "fileio_func.h"
00022 #include "fios.h"
00023 #include "window_func.h"
00024 #include "tilehighlight_func.h"
00025 #include "querystring_gui.h"
00026 #include "engine_func.h"
00027 #include "landscape_type.h"
00028 #include "date_func.h"
00029 #include "core/geometry_func.hpp"
00030
00031 #include "table/sprites.h"
00032 #include "table/strings.h"
00033
00034 SaveLoadDialogMode _saveload_mode;
00035 LoadCheckData _load_check_data;
00036
00037 static bool _fios_path_changed;
00038 static bool _savegame_sort_dirty;
00039
00040
00044 void LoadCheckData::Clear()
00045 {
00046 this->checkable = false;
00047 this->error = INVALID_STRING_ID;
00048 free(this->error_data);
00049 this->error_data = NULL;
00050
00051 this->map_size_x = this->map_size_y = 256;
00052 this->current_date = 0;
00053 memset(&this->settings, 0, sizeof(this->settings));
00054
00055 const CompanyPropertiesMap::iterator end = this->companies.End();
00056 for (CompanyPropertiesMap::iterator it = this->companies.Begin(); it != end; it++) {
00057 delete it->second;
00058 }
00059 companies.Clear();
00060
00061 ClearGRFConfigList(&this->grfconfig);
00062 }
00063
00064
00065 enum SaveLoadWindowWidgets {
00066 SLWW_WINDOWTITLE,
00067 SLWW_SORT_BYNAME,
00068 SLWW_SORT_BYDATE,
00069 SLWW_BACKGROUND,
00070 SLWW_FILE_BACKGROUND,
00071 SLWW_HOME_BUTTON,
00072 SLWW_DRIVES_DIRECTORIES_LIST,
00073 SLWW_SCROLLBAR,
00074 SLWW_CONTENT_DOWNLOAD,
00075 SLWW_SAVE_OSK_TITLE,
00076 SLWW_DELETE_SELECTION,
00077 SLWW_SAVE_GAME,
00078 SLWW_CONTENT_DOWNLOAD_SEL,
00079 SLWW_DETAILS,
00080 SLWW_NEWGRF_INFO,
00081 SLWW_LOAD_BUTTON,
00082 };
00083
00085 static const NWidgetPart _nested_load_dialog_widgets[] = {
00086 NWidget(NWID_HORIZONTAL),
00087 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00088 NWidget(WWT_CAPTION, COLOUR_GREY, SLWW_WINDOWTITLE),
00089 EndContainer(),
00090 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(),
00091 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00092 NWidget(NWID_VERTICAL),
00093 NWidget(NWID_HORIZONTAL),
00094 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00095 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00096 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00097 EndContainer(),
00098 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SLWW_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON),
00099 EndContainer(),
00100 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_FILE_BACKGROUND),
00101 NWidget(NWID_HORIZONTAL),
00102 NWidget(WWT_INSET, COLOUR_GREY, SLWW_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2),
00103 SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(SLWW_SCROLLBAR), EndContainer(),
00104 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, SLWW_SCROLLBAR),
00105 EndContainer(),
00106 NWidget(NWID_SELECTION, INVALID_COLOUR, SLWW_CONTENT_DOWNLOAD_SEL),
00107 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_CONTENT_DOWNLOAD), SetResize(1, 0),
00108 SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
00109 EndContainer(),
00110 EndContainer(),
00111 EndContainer(),
00112 NWidget(WWT_PANEL, COLOUR_GREY),
00113 NWidget(WWT_EMPTY, INVALID_COLOUR, SLWW_DETAILS), SetResize(1, 1), SetFill(1, 1),
00114 NWidget(NWID_HORIZONTAL),
00115 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00116 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_NEWGRF_INFO), SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_NULL), SetFill(1, 0), SetResize(1, 0),
00117 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_LOAD_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
00118 EndContainer(),
00119 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
00120 EndContainer(),
00121 EndContainer(),
00122 EndContainer(),
00123 };
00124
00126 static const NWidgetPart _nested_load_heightmap_dialog_widgets[] = {
00127 NWidget(NWID_HORIZONTAL),
00128 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00129 NWidget(WWT_CAPTION, COLOUR_GREY, SLWW_WINDOWTITLE),
00130 EndContainer(),
00131 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(),
00132 NWidget(NWID_VERTICAL),
00133 NWidget(NWID_HORIZONTAL),
00134 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00135 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00136 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00137 EndContainer(),
00138 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SLWW_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON),
00139 EndContainer(),
00140 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_FILE_BACKGROUND),
00141 NWidget(NWID_HORIZONTAL),
00142 NWidget(WWT_INSET, COLOUR_GREY, SLWW_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2),
00143 SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(SLWW_SCROLLBAR), EndContainer(),
00144 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, SLWW_SCROLLBAR),
00145 EndContainer(),
00146 NWidget(NWID_HORIZONTAL),
00147 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_CONTENT_DOWNLOAD), SetResize(1, 0),
00148 SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
00149 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
00150 EndContainer(),
00151 EndContainer(),
00152 EndContainer(),
00153 };
00154
00156 static const NWidgetPart _nested_save_dialog_widgets[] = {
00157 NWidget(NWID_HORIZONTAL),
00158 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00159 NWidget(WWT_CAPTION, COLOUR_GREY, SLWW_WINDOWTITLE),
00160 EndContainer(),
00161 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(),
00162 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00163 NWidget(NWID_VERTICAL),
00164 NWidget(NWID_HORIZONTAL),
00165 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00166 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00167 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
00168 EndContainer(),
00169 NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SLWW_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON),
00170 EndContainer(),
00171 NWidget(WWT_PANEL, COLOUR_GREY, SLWW_FILE_BACKGROUND),
00172 NWidget(NWID_HORIZONTAL),
00173 NWidget(WWT_INSET, COLOUR_GREY, SLWW_DRIVES_DIRECTORIES_LIST), SetPadding(2, 1, 0, 2),
00174 SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(SLWW_SCROLLBAR), EndContainer(),
00175 NWidget(NWID_VSCROLLBAR, COLOUR_GREY, SLWW_SCROLLBAR),
00176 EndContainer(),
00177 NWidget(WWT_EDITBOX, COLOUR_GREY, SLWW_SAVE_OSK_TITLE), SetPadding(3, 2, 2, 2), SetFill(1, 0), SetResize(1, 0),
00178 SetDataTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP),
00179 EndContainer(),
00180 NWidget(NWID_HORIZONTAL),
00181 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_DELETE_SELECTION), SetDataTip(STR_SAVELOAD_DELETE_BUTTON, STR_SAVELOAD_DELETE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
00182 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_SAVE_GAME), SetDataTip(STR_SAVELOAD_SAVE_BUTTON, STR_SAVELOAD_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
00183 EndContainer(),
00184 EndContainer(),
00185 NWidget(WWT_PANEL, COLOUR_GREY),
00186 NWidget(WWT_EMPTY, INVALID_COLOUR, SLWW_DETAILS), SetResize(1, 1), SetFill(1, 1),
00187 NWidget(NWID_HORIZONTAL),
00188 NWidget(NWID_SPACER), SetResize(1, 0), SetFill(1, 1),
00189 NWidget(WWT_RESIZEBOX, COLOUR_GREY),
00190 EndContainer(),
00191 EndContainer(),
00192 EndContainer(),
00193 };
00194
00195
00196 const TextColour _fios_colours[] = {
00197 TC_LIGHT_BLUE, TC_DARK_GREEN, TC_DARK_GREEN, TC_ORANGE, TC_LIGHT_BROWN,
00198 TC_ORANGE, TC_LIGHT_BROWN, TC_ORANGE, TC_ORANGE, TC_YELLOW
00199 };
00200
00201 void BuildFileList()
00202 {
00203 _fios_path_changed = true;
00204 FiosFreeSavegameList();
00205
00206 switch (_saveload_mode) {
00207 case SLD_NEW_GAME:
00208 case SLD_LOAD_SCENARIO:
00209 case SLD_SAVE_SCENARIO:
00210 FiosGetScenarioList(_saveload_mode); break;
00211 case SLD_LOAD_HEIGHTMAP:
00212 FiosGetHeightmapList(_saveload_mode); break;
00213
00214 default: FiosGetSavegameList(_saveload_mode); break;
00215 }
00216 }
00217
00218 static void MakeSortedSaveGameList()
00219 {
00220 uint sort_start = 0;
00221 uint sort_end = 0;
00222
00223
00224
00225
00226
00227 for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
00228 switch (item->type) {
00229 case FIOS_TYPE_DIR: sort_start++; break;
00230 case FIOS_TYPE_PARENT: sort_start++; break;
00231 case FIOS_TYPE_DRIVE: sort_end++; break;
00232 default: break;
00233 }
00234 }
00235
00236 uint s_amount = _fios_items.Length() - sort_start - sort_end;
00237 QSortT(_fios_items.Get(sort_start), s_amount, CompareFiosItems);
00238 }
00239
00240 struct SaveLoadWindow : public QueryStringBaseWindow {
00241 private:
00242 FiosItem o_dir;
00243 const FiosItem *selected;
00244 Scrollbar *vscroll;
00245 public:
00246
00247 void GenerateFileName()
00248 {
00249 GenerateDefaultSaveName(this->edit_str_buf, &this->edit_str_buf[this->edit_str_size - 1]);
00250 }
00251
00252 SaveLoadWindow(const WindowDesc *desc, SaveLoadDialogMode mode) : QueryStringBaseWindow(64)
00253 {
00254 static const StringID saveload_captions[] = {
00255 STR_SAVELOAD_LOAD_CAPTION,
00256 STR_SAVELOAD_LOAD_SCENARIO,
00257 STR_SAVELOAD_SAVE_CAPTION,
00258 STR_SAVELOAD_SAVE_SCENARIO,
00259 STR_SAVELOAD_LOAD_HEIGHTMAP,
00260 };
00261 assert((uint)mode < lengthof(saveload_captions));
00262
00263
00264
00265 switch (mode) {
00266 case SLD_SAVE_GAME: this->GenerateFileName(); break;
00267 case SLD_SAVE_SCENARIO: strecpy(this->edit_str_buf, "UNNAMED", &this->edit_str_buf[edit_str_size - 1]); break;
00268 default: break;
00269 }
00270
00271 this->afilter = CS_ALPHANUMERAL;
00272 InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, 240);
00273
00274 this->CreateNestedTree(desc, true);
00275 if (mode == SLD_LOAD_GAME) this->GetWidget<NWidgetStacked>(SLWW_CONTENT_DOWNLOAD_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
00276 this->GetWidget<NWidgetCore>(SLWW_WINDOWTITLE)->widget_data = saveload_captions[mode];
00277 this->vscroll = this->GetScrollbar(SLWW_SCROLLBAR);
00278
00279 this->FinishInitNested(desc, 0);
00280
00281 this->LowerWidget(SLWW_DRIVES_DIRECTORIES_LIST);
00282
00283
00284
00285 if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) {
00286 DoCommandP(0, PM_PAUSED_SAVELOAD, 1, CMD_PAUSE);
00287 }
00288 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
00289
00290 this->OnInvalidateData(0);
00291
00292 ResetObjectToPlace();
00293
00294 o_dir.type = FIOS_TYPE_DIRECT;
00295 switch (_saveload_mode) {
00296 case SLD_SAVE_GAME:
00297 case SLD_LOAD_GAME:
00298 FioGetDirectory(o_dir.name, lengthof(o_dir.name), SAVE_DIR);
00299 break;
00300
00301 case SLD_SAVE_SCENARIO:
00302 case SLD_LOAD_SCENARIO:
00303 FioGetDirectory(o_dir.name, lengthof(o_dir.name), SCENARIO_DIR);
00304 break;
00305
00306 case SLD_LOAD_HEIGHTMAP:
00307 FioGetDirectory(o_dir.name, lengthof(o_dir.name), HEIGHTMAP_DIR);
00308 break;
00309
00310 default:
00311 strecpy(o_dir.name, _personal_dir, lastof(o_dir.name));
00312 }
00313
00314
00315 if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
00316 this->SetFocusedWidget(SLWW_SAVE_OSK_TITLE);
00317 }
00318 }
00319
00320 virtual ~SaveLoadWindow()
00321 {
00322
00323 if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
00324 DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
00325 }
00326 FiosFreeSavegameList();
00327 }
00328
00329 virtual void DrawWidget(const Rect &r, int widget) const
00330 {
00331 switch (widget) {
00332 case SLWW_SORT_BYNAME:
00333 case SLWW_SORT_BYDATE:
00334 if (((_savegame_sort_order & SORT_BY_NAME) != 0) == (widget == SLWW_SORT_BYNAME)) {
00335 this->DrawSortButtonState(widget, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
00336 }
00337 break;
00338
00339 case SLWW_BACKGROUND: {
00340 static const char *path = NULL;
00341 static StringID str = STR_ERROR_UNABLE_TO_READ_DRIVE;
00342 static uint64 tot = 0;
00343
00344 if (_fios_path_changed) {
00345 str = FiosGetDescText(&path, &tot);
00346 _fios_path_changed = false;
00347 }
00348
00349 if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
00350 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP, str);
00351 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, path, TC_BLACK);
00352 break;
00353 }
00354
00355 case SLWW_DRIVES_DIRECTORIES_LIST: {
00356 GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, 0xD7);
00357
00358 uint y = r.top + WD_FRAMERECT_TOP;
00359 for (uint pos = this->vscroll->GetPosition(); pos < _fios_items.Length(); pos++) {
00360 const FiosItem *item = _fios_items.Get(pos);
00361
00362 if (item == this->selected) {
00363 GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, 156);
00364 }
00365 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[item->type]);
00366 y += this->resize.step_height;
00367 if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
00368 }
00369 break;
00370 }
00371
00372 case SLWW_DETAILS: {
00373 GfxFillRect(r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP,
00374 r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL * 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, 0x0A);
00375 DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
00376
00377 if (this->selected == NULL) break;
00378
00379 uint y = r.top + FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
00380 uint y_max = r.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM;
00381
00382 if (y > y_max) break;
00383 if (!_load_check_data.checkable) {
00384
00385 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
00386 y += FONT_HEIGHT_NORMAL;
00387 } else if (_load_check_data.error != INVALID_STRING_ID) {
00388
00389 SetDParamStr(0, _load_check_data.error_data);
00390 y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT,
00391 y, r.bottom - WD_FRAMERECT_BOTTOM, _load_check_data.error, TC_RED);
00392 } else {
00393
00394 SetDParam(0, _load_check_data.map_size_x);
00395 SetDParam(1, _load_check_data.map_size_y);
00396 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE);
00397 y += FONT_HEIGHT_NORMAL;
00398 if (y > y_max) break;
00399
00400
00401 byte landscape = _load_check_data.settings.game_creation.landscape;
00402 if (landscape < NUM_LANDSCAPE) {
00403 SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + landscape);
00404 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE);
00405 y += FONT_HEIGHT_NORMAL;
00406 }
00407
00408 y += WD_PAR_VSEP_NORMAL;
00409 if (y > y_max) break;
00410
00411
00412 if (_load_check_data.settings.game_creation.starting_year != 0) {
00413 SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
00414 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE);
00415 y += FONT_HEIGHT_NORMAL;
00416 }
00417 if (y > y_max) break;
00418
00419
00420 if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
00421
00422 SetDParam(0, _load_check_data.current_date);
00423 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE);
00424 y += FONT_HEIGHT_NORMAL;
00425 }
00426
00427
00428 if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
00429 y += WD_PAR_VSEP_NORMAL;
00430 if (y > y_max) break;
00431
00432
00433 SetDParam(0, _load_check_data.grfconfig == NULL ? STR_NEWGRF_LIST_NONE :
00434 STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility);
00435 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_GRFSTATUS);
00436 y += FONT_HEIGHT_NORMAL;
00437 }
00438 if (y > y_max) break;
00439
00440
00441 if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
00442 y += FONT_HEIGHT_NORMAL;
00443 if (y > y_max) break;
00444
00445
00446 CompanyPropertiesMap::const_iterator end = _load_check_data.companies.End();
00447 for (CompanyPropertiesMap::const_iterator it = _load_check_data.companies.Begin(); it != end; it++) {
00448 SetDParam(0, it->first + 1);
00449 const CompanyProperties &c = *it->second;
00450 if (c.name != NULL) {
00451 SetDParam(1, STR_JUST_RAW_STRING);
00452 SetDParamStr(2, c.name);
00453 } else {
00454 SetDParam(1, c.name_1);
00455 SetDParam(2, c.name_2);
00456 }
00457 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_COMPANY_INDEX);
00458 y += FONT_HEIGHT_NORMAL;
00459 if (y > y_max) break;
00460 }
00461 }
00462 }
00463 break;
00464 }
00465 }
00466 }
00467
00468 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00469 {
00470 switch (widget) {
00471 case SLWW_BACKGROUND:
00472 size->height = 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
00473 break;
00474
00475 case SLWW_DRIVES_DIRECTORIES_LIST:
00476 resize->height = FONT_HEIGHT_NORMAL;
00477 size->height = resize->height * 10 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
00478 break;
00479 case SLWW_SORT_BYNAME:
00480 case SLWW_SORT_BYDATE: {
00481 Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
00482 d.width += padding.width + WD_SORTBUTTON_ARROW_WIDTH * 2;
00483 d.height += padding.height;
00484 *size = maxdim(*size, d);
00485 break;
00486 }
00487 }
00488 }
00489
00490 virtual void OnPaint()
00491 {
00492 if (_savegame_sort_dirty) {
00493 _savegame_sort_dirty = false;
00494 MakeSortedSaveGameList();
00495 }
00496
00497 this->vscroll->SetCount(_fios_items.Length());
00498 this->DrawWidgets();
00499
00500 if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
00501 this->DrawEditBox(SLWW_SAVE_OSK_TITLE);
00502 }
00503 }
00504
00505 virtual void OnClick(Point pt, int widget, int click_count)
00506 {
00507 switch (widget) {
00508 case SLWW_SORT_BYNAME:
00509 _savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
00510 SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
00511 _savegame_sort_dirty = true;
00512 this->SetDirty();
00513 break;
00514
00515 case SLWW_SORT_BYDATE:
00516 _savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
00517 SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
00518 _savegame_sort_dirty = true;
00519 this->SetDirty();
00520 break;
00521
00522 case SLWW_HOME_BUTTON:
00523 FiosBrowseTo(&o_dir);
00524 this->InvalidateData();
00525 break;
00526
00527 case SLWW_LOAD_BUTTON:
00528 if (this->selected != NULL && !_load_check_data.HasErrors() && (_load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs())) {
00529 _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD;
00530
00531 const char *name = FiosBrowseTo(this->selected);
00532 SetFiosType(this->selected->type);
00533
00534 strecpy(_file_to_saveload.name, name, lastof(_file_to_saveload.name));
00535 strecpy(_file_to_saveload.title, this->selected->title, lastof(_file_to_saveload.title));
00536
00537 delete this;
00538 }
00539 break;
00540
00541 case SLWW_NEWGRF_INFO:
00542 if (_load_check_data.HasNewGrfs()) {
00543 ShowNewGRFSettings(false, false, false, &_load_check_data.grfconfig);
00544 }
00545 break;
00546
00547 case SLWW_DRIVES_DIRECTORIES_LIST: {
00548 int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLWW_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP);
00549 if (y == INT_MAX) return;
00550
00551 const FiosItem *file = _fios_items.Get(y);
00552
00553 const char *name = FiosBrowseTo(file);
00554 if (name != NULL) {
00555 if (click_count == 1) {
00556 if (this->selected != file) {
00557 this->selected = file;
00558 _load_check_data.Clear();
00559
00560 if (file->type == FIOS_TYPE_FILE || file->type == FIOS_TYPE_SCENARIO) {
00561 SaveOrLoad(name, SL_LOAD_CHECK, NO_DIRECTORY, false);
00562 }
00563
00564 this->InvalidateData(1);
00565 }
00566 if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
00567
00568 ttd_strlcpy(this->text.buf, file->title, this->text.max_bytes);
00569 UpdateTextBufferSize(&this->text);
00570 this->SetWidgetDirty(SLWW_SAVE_OSK_TITLE);
00571 }
00572 } else if (!_load_check_data.HasErrors()) {
00573 this->selected = file;
00574 if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
00575 this->OnClick(pt, SLWW_LOAD_BUTTON, 1);
00576 } else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
00577 SetFiosType(file->type);
00578 strecpy(_file_to_saveload.name, name, lastof(_file_to_saveload.name));
00579 strecpy(_file_to_saveload.title, file->title, lastof(_file_to_saveload.title));
00580
00581 delete this;
00582 ShowHeightmapLoad();
00583 }
00584 }
00585 } else {
00586
00587 this->InvalidateData();
00588 }
00589 break;
00590 }
00591
00592 case SLWW_CONTENT_DOWNLOAD:
00593 if (!_network_available) {
00594 ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
00595 } else {
00596 #if defined(ENABLE_NETWORK)
00597 switch (_saveload_mode) {
00598 default: NOT_REACHED();
00599 case SLD_LOAD_SCENARIO: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_SCENARIO); break;
00600 case SLD_LOAD_HEIGHTMAP: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_HEIGHTMAP); break;
00601 }
00602 #endif
00603 }
00604 break;
00605
00606 case SLWW_DELETE_SELECTION: case SLWW_SAVE_GAME:
00607 break;
00608 }
00609 }
00610
00611 virtual void OnMouseLoop()
00612 {
00613 if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
00614 this->HandleEditBox(SLWW_SAVE_OSK_TITLE);
00615 }
00616 }
00617
00618 virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00619 {
00620 if (keycode == WKC_ESC) {
00621 delete this;
00622 return ES_HANDLED;
00623 }
00624
00625 EventState state = ES_NOT_HANDLED;
00626 if ((_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) &&
00627 this->HandleEditBoxKey(SLWW_SAVE_OSK_TITLE, key, keycode, state) == HEBR_CONFIRM) {
00628 this->HandleButtonClick(SLWW_SAVE_GAME);
00629 }
00630
00631 return state;
00632 }
00633
00634 virtual void OnTimeout()
00635 {
00636
00637
00638 if (!(_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO)) return;
00639
00640 if (this->IsWidgetLowered(SLWW_DELETE_SELECTION)) {
00641 if (!FiosDelete(this->text.buf)) {
00642 ShowErrorMessage(STR_ERROR_UNABLE_TO_DELETE_FILE, INVALID_STRING_ID, WL_ERROR);
00643 } else {
00644 this->InvalidateData();
00645
00646 if (_saveload_mode == SLD_SAVE_GAME) GenerateFileName();
00647 }
00648
00649 UpdateTextBufferSize(&this->text);
00650 } else if (this->IsWidgetLowered(SLWW_SAVE_GAME)) {
00651 _switch_mode = SM_SAVE;
00652 FiosMakeSavegameName(_file_to_saveload.name, this->text.buf, sizeof(_file_to_saveload.name));
00653
00654
00655 if (_game_mode == GM_EDITOR) StartupEngines();
00656 }
00657 }
00658
00659 virtual void OnResize()
00660 {
00661 this->vscroll->SetCapacityFromWidget(this, SLWW_DRIVES_DIRECTORIES_LIST);
00662 }
00663
00664 virtual void OnInvalidateData(int data)
00665 {
00666 switch (data) {
00667 case 0:
00668
00669 this->selected = NULL;
00670 _load_check_data.Clear();
00671 BuildFileList();
00672
00673 case 1:
00674
00675 if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
00676 this->SetWidgetDisabledState(SLWW_LOAD_BUTTON,
00677 this->selected == NULL || _load_check_data.HasErrors() || !(_load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()));
00678 this->SetWidgetDisabledState(SLWW_NEWGRF_INFO,
00679 !_load_check_data.HasNewGrfs());
00680 }
00681 break;
00682 }
00683 }
00684 };
00685
00687 static const WindowDesc _load_dialog_desc(
00688 WDP_CENTER, 500, 294,
00689 WC_SAVELOAD, WC_NONE,
00690 WDF_UNCLICK_BUTTONS,
00691 _nested_load_dialog_widgets, lengthof(_nested_load_dialog_widgets)
00692 );
00693
00695 static const WindowDesc _load_heightmap_dialog_desc(
00696 WDP_CENTER, 257, 320,
00697 WC_SAVELOAD, WC_NONE,
00698 WDF_UNCLICK_BUTTONS,
00699 _nested_load_heightmap_dialog_widgets, lengthof(_nested_load_heightmap_dialog_widgets)
00700 );
00701
00703 static const WindowDesc _save_dialog_desc(
00704 WDP_CENTER, 500, 294,
00705 WC_SAVELOAD, WC_NONE,
00706 WDF_UNCLICK_BUTTONS,
00707 _nested_save_dialog_widgets, lengthof(_nested_save_dialog_widgets)
00708 );
00709
00714 static const FileType _file_modetotype[] = {
00715 FT_SAVEGAME,
00716 FT_SCENARIO,
00717 FT_SAVEGAME,
00718 FT_SCENARIO,
00719 FT_HEIGHTMAP,
00720 FT_SAVEGAME,
00721 };
00722
00723 void ShowSaveLoadDialog(SaveLoadDialogMode mode)
00724 {
00725 DeleteWindowById(WC_SAVELOAD, 0);
00726
00727 const WindowDesc *sld;
00728 switch (mode) {
00729 case SLD_SAVE_GAME:
00730 case SLD_SAVE_SCENARIO:
00731 sld = &_save_dialog_desc; break;
00732 case SLD_LOAD_HEIGHTMAP:
00733 sld = &_load_heightmap_dialog_desc; break;
00734 default:
00735 sld = &_load_dialog_desc; break;
00736 }
00737
00738 _saveload_mode = mode;
00739 _file_to_saveload.filetype = _file_modetotype[mode];
00740
00741 new SaveLoadWindow(sld, mode);
00742 }
00743
00744 void SetFiosType(const byte fiostype)
00745 {
00746 switch (fiostype) {
00747 case FIOS_TYPE_FILE:
00748 case FIOS_TYPE_SCENARIO:
00749 _file_to_saveload.mode = SL_LOAD;
00750 break;
00751
00752 case FIOS_TYPE_OLDFILE:
00753 case FIOS_TYPE_OLD_SCENARIO:
00754 _file_to_saveload.mode = SL_OLD_LOAD;
00755 break;
00756
00757 #ifdef WITH_PNG
00758 case FIOS_TYPE_PNG:
00759 _file_to_saveload.mode = SL_PNG;
00760 break;
00761 #endif
00762
00763 case FIOS_TYPE_BMP:
00764 _file_to_saveload.mode = SL_BMP;
00765 break;
00766
00767 default:
00768 _file_to_saveload.mode = SL_INVALID;
00769 break;
00770 }
00771 }