diff --git a/src/fileio_type.h b/src/fileio_type.h index c871c1c14b..26b0ab2948 100644 --- a/src/fileio_type.h +++ b/src/fileio_type.h @@ -18,6 +18,7 @@ enum AbstractFileType { FT_SAVEGAME, ///< old or new savegame FT_SCENARIO, ///< old or new scenario FT_HEIGHTMAP, ///< heightmap file + FT_ORDERLIST, ///< orderlist file FT_INVALID = 7, ///< Invalid or unknown file type. FT_NUMBITS = 3, ///< Number of bits required for storing a #AbstractFileType value. @@ -34,6 +35,9 @@ enum DetailedFileType { DFT_HEIGHTMAP_BMP, ///< BMP file. DFT_HEIGHTMAP_PNG, ///< PNG file. + /* Orderlist files */ + DFT_ORDERLIST, ///< XML file. + /* fios 'files' */ DFT_FIOS_DRIVE, ///< A drive (letter) entry. DFT_FIOS_PARENT, ///< A parent directory entry. @@ -76,6 +80,7 @@ enum FiosType { FIOS_TYPE_OLD_SCENARIO = MAKE_FIOS_TYPE(FT_SCENARIO, DFT_OLD_GAME_FILE), FIOS_TYPE_PNG = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_PNG), FIOS_TYPE_BMP = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_BMP), + FIOS_TYPE_ORDERLIST = MAKE_FIOS_TYPE(FT_ORDERLIST, DFT_ORDERLIST), FIOS_TYPE_INVALID = MAKE_FIOS_TYPE(FT_INVALID, DFT_INVALID), }; diff --git a/src/fios.cpp b/src/fios.cpp index d34f6070a0..28a1a92f5a 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -33,6 +33,9 @@ #include "safeguards.h" +/*For some reason I need to pre-declare this function specifically, otherwise the whole thing just won't compile*/ +void FiosGetOrderlistList(SaveLoadOperation fop, bool show_dirs, FileList &file_list); + /* Variables to display file lists */ static std::string *_fios_path = nullptr; SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING; @@ -91,6 +94,10 @@ void FileList::BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperati FiosGetHeightmapList(fop, show_dirs, *this); break; + case FT_ORDERLIST: + FiosGetOrderlistList(fop, show_dirs, *this); + break; + default: NOT_REACHED(); } @@ -185,6 +192,7 @@ bool FiosBrowseTo(const FiosItem *item) case FIOS_TYPE_OLDFILE: case FIOS_TYPE_SCENARIO: case FIOS_TYPE_OLD_SCENARIO: + case FIOS_TYPE_ORDERLIST: case FIOS_TYPE_PNG: case FIOS_TYPE_BMP: return false; @@ -499,6 +507,52 @@ void FiosGetSavegameList(SaveLoadOperation fop, bool show_dirs, FileList &file_l FiosGetFileList(fop, show_dirs, &FiosGetSavegameListCallback, NO_DIRECTORY, file_list); } +/** + * Callback for FiosGetOrderlistList. It tells if a file is a orederlist or not. + * @param fop Purpose of collecting the list. + * @param file Name of the file to check. + * @param ext A pointer to the extension identifier inside file + * @param title Buffer if a callback wants to lookup the title of the file; nullptr to skip the lookup + * @param last Last available byte in buffer (to prevent buffer overflows); not used when title == nullptr + * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame + * @see FiosGetFileList + * @see FiosGetOrderlistList + */ +FiosType FiosGetOrderlistListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last) +{ + /* Show orderlist files + * .XML orderlist files + */ + + /* Don't crash if we supply no extension */ + if (ext == nullptr) ext = ""; + + if (StrEqualsIgnoreCase(ext, ".xml")) { + GetFileTitle(file, title, last, SAVE_DIR); + return FIOS_TYPE_ORDERLIST; + } + + return FIOS_TYPE_INVALID; +} + +/** + * Get a list of orderlists. + * @param fop Purpose of collecting the list. + * @param show_dirs Whether to show directories. + * @param file_list Destination of the found files. + * @see FiosGetFileList + */ +void FiosGetOrderlistList(SaveLoadOperation fop, bool show_dirs, FileList &file_list) +{ + static std::optional fios_save_path; + + if (!fios_save_path) fios_save_path = FioFindDirectory(SAVE_DIR); + + _fios_path = &(*fios_save_path); + + FiosGetFileList(fop, show_dirs, &FiosGetOrderlistListCallback, NO_DIRECTORY, file_list); +} + /** * Callback for FiosGetFileList. It tells if a file is a scenario or not. * @param fop Purpose of collecting the list. diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index e4b4318372..75b75acca2 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -234,6 +234,99 @@ static constexpr NWidgetPart _nested_save_dialog_widgets[] = { EndContainer(), }; +/** Save Orderlist */ +static constexpr NWidgetPart _nested_save_orderlist_dialog_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + EndContainer(), + /* Current directory and free space */ + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + /* Left side : filter box and available files */ + NWidget(NWID_VERTICAL), + /* Filter box with label */ + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + EndContainer(), + /* Sort buttons */ + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), + EndContainer(), + /* Files */ + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), + NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetPadding(2, 2, 2, 2), + SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_SAVE_OSK_TITLE), SetPadding(2, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP), + EndContainer(), + /* Save/delete buttons */ + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_DELETE_SELECTION), SetDataTip(STR_SAVELOAD_DELETE_BUTTON, STR_SAVELOAD_DELETE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SAVE_GAME), SetDataTip(STR_SAVELOAD_SAVE_BUTTON, STR_SAVELOAD_SAVE_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), + EndContainer(), +}; + +/** Load Orderlist */ +static constexpr NWidgetPart _nested_load_orderlist_dialog_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + EndContainer(), + /* Current directory and free space */ + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), + + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + /* Left side : filter box and available files */ + NWidget(NWID_VERTICAL), + /* Filter box with label */ + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + EndContainer(), + /* Sort buttons */ + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), + EndContainer(), + /* Files */ + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), + NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2), + SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), + EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), +}; + /** Text colours of #DetailedFileType fios entries in the window. */ static const TextColour _fios_colours[] = { TC_LIGHT_BROWN, // DFT_OLD_GAME_FILE @@ -325,6 +418,7 @@ public: case FT_SCENARIO: case FT_HEIGHTMAP: + case FT_ORDERLIST: this->filename_editbox.text.Assign("UNNAMED"); break; @@ -355,6 +449,10 @@ public: caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_HEIGHTMAP : STR_SAVELOAD_LOAD_HEIGHTMAP; break; + case FT_ORDERLIST: + caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_ORDERLIST : STR_SAVELOAD_LOAD_ORDERLIST; + break; + default: NOT_REACHED(); } @@ -672,6 +770,8 @@ public: break; case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox + printf("test"); + auto it = this->vscroll->GetScrolledItemFromWidget(this->display_list, pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top); if (it == this->display_list.end()) return; @@ -685,13 +785,18 @@ public: } if (click_count == 1) { + if (this->selected != file) { + this->selected = file; _load_check_data.Clear(); - if (GetDetailedFileType(file->type) == DFT_GAME_FILE) { - /* Other detailed file types cannot be checked before. */ - SaveOrLoad(file->name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false); + auto type = GetDetailedFileType(file->type); + + switch (type) { + case DFT_GAME_FILE: SaveOrLoad(file->name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false); break; + case DFT_ORDERLIST: break; + default: break; } this->InvalidateData(SLIWD_SELECTION_CHANGES); @@ -704,7 +809,7 @@ public: } else if (!_load_check_data.HasErrors()) { this->selected = file; if (this->fop == SLO_LOAD) { - if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) { + if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO || this->abstract_filetype == FT_ORDERLIST) { this->OnClick(pt, WID_SL_LOAD_BUTTON, 1); } else { assert(this->abstract_filetype == FT_HEIGHTMAP); @@ -911,9 +1016,8 @@ public: !_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility == GLC_ALL_GOOD); break; } - - default: - NOT_REACHED(); + + default: break; } break; @@ -948,6 +1052,14 @@ static WindowDesc _load_heightmap_dialog_desc(__FILE__, __LINE__, std::begin(_nested_load_heightmap_dialog_widgets), std::end(_nested_load_heightmap_dialog_widgets) ); +/** Load orderlist*/ +static WindowDesc _load_orderlist_dialog_desc(__FILE__, __LINE__, + WDP_CENTER, "load_orderlist", 257, 320, + WC_SAVELOAD, WC_NONE, + 0, + std::begin(_nested_load_orderlist_dialog_widgets), std::end(_nested_load_orderlist_dialog_widgets) +); + /** Save game/scenario */ static WindowDesc _save_dialog_desc(__FILE__, __LINE__, WDP_CENTER, "save_game", 500, 294, @@ -956,6 +1068,14 @@ static WindowDesc _save_dialog_desc(__FILE__, __LINE__, std::begin(_nested_save_dialog_widgets), std::end(_nested_save_dialog_widgets) ); +/** Load orderlist*/ +static WindowDesc _save_orderlist_dialog_desc(__FILE__, __LINE__, + WDP_CENTER, "save_orderlist", 257, 320, + WC_SAVELOAD, WC_NONE, + 0, + std::begin(_nested_save_orderlist_dialog_widgets), std::end(_nested_save_orderlist_dialog_widgets) +); + /** * Launch save/load dialog in the given mode. * @param abstract_filetype Kind of file to handle. @@ -966,7 +1086,15 @@ void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fo CloseWindowById(WC_SAVELOAD, 0); WindowDesc *sld; - if (fop == SLO_SAVE) { + if (abstract_filetype == FT_ORDERLIST){ + + if (fop == SLO_SAVE) { + sld = &_save_orderlist_dialog_desc; + } else if (fop == SLO_LOAD) { + sld = &_load_orderlist_dialog_desc; + } + + } else if (fop == SLO_SAVE) { sld = &_save_dialog_desc; } else { /* Dialogue for loading a file. */ diff --git a/src/lang/english.txt b/src/lang/english.txt index 529743ab61..3c6cd68de6 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3257,8 +3257,10 @@ STR_SAVELOAD_SAVE_CAPTION :{WHITE}Save Gam STR_SAVELOAD_LOAD_CAPTION :{WHITE}Load Game STR_SAVELOAD_SAVE_SCENARIO :{WHITE}Save Scenario STR_SAVELOAD_LOAD_SCENARIO :{WHITE}Load Scenario -STR_SAVELOAD_LOAD_HEIGHTMAP :{WHITE}Load Heightmap STR_SAVELOAD_SAVE_HEIGHTMAP :{WHITE}Save Heightmap +STR_SAVELOAD_LOAD_HEIGHTMAP :{WHITE}Load Heightmap +STR_SAVELOAD_SAVE_ORDERLIST :{WHITE}Save Orderlist +STR_SAVELOAD_LOAD_ORDERLIST :{WHITE}Load Orderlist STR_SAVELOAD_HOME_BUTTON :{BLACK}Click here to jump to the current default save/load directory STR_SAVELOAD_BYTES_FREE :{BLACK}{BYTES} free STR_SAVELOAD_LIST_TOOLTIP :{BLACK}List of drives, directories and saved-game files diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 77cd5bb91c..db6aff6828 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -35,6 +35,7 @@ #include "tracerestrict.h" #include "scope.h" #include "core/backup_type.hpp" +#include "fios.h" #include "widgets/order_widget.h" @@ -3490,8 +3491,8 @@ public: switch (index) { case 0: this->OrderClick_ReverseOrderList(0); break; case 1: this->OrderClick_ReverseOrderList(1); break; - case 2: /*TODO:Copy order list as Unified Order List Format*/break; - case 3: /*TODO:Pase order list as Unified Order List Format*/break; + case 2: ShowSaveLoadDialog(FT_ORDERLIST, SLO_SAVE); break; + case 3: ShowSaveLoadDialog(FT_ORDERLIST, SLO_LOAD); break; default: NOT_REACHED(); } break;