diff --git a/src/command.cpp b/src/command.cpp index 0bed5b65f6..58998e35ee 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -140,6 +140,7 @@ CommandProc CmdRenamePresident; CommandProc CmdRenameStation; CommandProc CmdRenameDepot; +CommandProc CmdExchangeStationNames; CommandProc CmdSetStationCargoAllowedSupply; CommandProc CmdPlaceSign; @@ -397,6 +398,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdRenameStation, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_STATION DEF_CMD(CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_DEPOT + DEF_CMD(CmdExchangeStationNames, 0, CMDT_OTHER_MANAGEMENT ), // CMD_EXCHANGE_STATION_NAMES DEF_CMD(CmdSetStationCargoAllowedSupply, 0, CMDT_OTHER_MANAGEMENT ), // CMD_SET_STATION_CARGO_ALLOWED_SUPPLY DEF_CMD(CmdPlaceSign, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_PLACE_SIGN diff --git a/src/command_type.h b/src/command_type.h index fab1c4875c..c82cf9cf8a 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -362,6 +362,7 @@ enum Commands { CMD_RENAME_PRESIDENT, ///< change the president name CMD_RENAME_STATION, ///< rename a station CMD_RENAME_DEPOT, ///< rename a depot + CMD_EXCHANGE_STATION_NAMES, ///< exchange station names CMD_SET_STATION_CARGO_ALLOWED_SUPPLY, ///< set station cargo allowed supply CMD_PLACE_SIGN, ///< place a sign diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index 3341dd59a9..f9598133c4 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -2044,3 +2044,8 @@ STR_REFIT_WHOLE_SHIP :Whole ship STR_REFIT_SHIP_PART :Part {NUM} STR_VERY_REDUCED :Very reduced + +STR_STATION_VIEW_RENAME_TOOLTIP_EXTRA :{BLACK}{STRING}{}(Ctrl+Click "{STRING}" button to generate new default name).{}{}Ctrl+Click to exchange name with another station. +STR_ERROR_CAN_T_EXCHANGE_STATION_NAMES :{WHITE}Can't exchange station names... +STR_ERROR_STATIONS_NOT_IN_SAME_TOWN :{WHITE}... stations are not in the same town +STR_ERROR_STATION_ATTACHED_TO_INDUSTRY :{WHITE}... station is attached to an industry diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 3430f0026f..be59517812 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -4780,6 +4780,49 @@ CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uin return CommandCost(); } +/** + * Exchange station names + * @param tile tile of other station to exchange name with + * @param flags operation to perform + * @param p1 station ID to exchange name with + * @param p2 unused + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdExchangeStationNames(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + Station *st = Station::GetIfValid(p1); + if (st == nullptr) return CMD_ERROR; + + CommandCost ret = CheckOwnership(st->owner); + if (ret.Failed()) return ret; + + if (st->industry != nullptr) return CommandCost(STR_ERROR_STATION_ATTACHED_TO_INDUSTRY); + + if (!IsTileType(tile, MP_STATION)) return CommandCost(STR_ERROR_THERE_IS_NO_STATION); + Station *st2 = Station::GetByTile(tile); + + ret = CheckOwnership(st2->owner); + if (ret.Failed()) return ret; + + if (st2->industry != nullptr) return CommandCost(STR_ERROR_STATION_ATTACHED_TO_INDUSTRY); + + if (st->town != st2->town) return CommandCost(STR_ERROR_STATIONS_NOT_IN_SAME_TOWN); + + if (flags & DC_EXEC) { + st->cached_name.clear(); + st2->cached_name.clear(); + std::swap(st->name, st2->name); + std::swap(st->string_id, st2->string_id); + std::swap(st->extra_name_index, st2->extra_name_index); + st->UpdateVirtCoord(); + st2->UpdateVirtCoord(); + InvalidateWindowData(WC_STATION_LIST, st->owner, 1); + } + + return CommandCost(); +} + /** * Change whether a cargo may be supplied to a station * @param tile unused diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1fbdeab11b..a125a3525b 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -843,7 +843,7 @@ void ShowCompanyStations(CompanyID company) static const NWidgetPart _nested_station_view_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SV_RENAME), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_STATION_VIEW_RENAME_TOOLTIP), + NWidget(WWT_IMGBTN, COLOUR_GREY, WID_SV_RENAME), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, 0x0), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SV_CAPTION), SetDataTip(STR_STATION_VIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SV_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_STATION_VIEW_CENTER_TOOLTIP), NWidget(WWT_DEBUGBOX, COLOUR_GREY), @@ -1369,6 +1369,8 @@ struct StationViewWindow : public Window { CargoDataEntry cached_destinations; ///< Cache for the flows passing through this station. CargoDataVector displayed_rows; ///< Parent entry of currently displayed rows (including collapsed ones). + bool place_object_active = false; + StationViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), scroll_to_row(INT_MAX), grouping_index(0) { @@ -1580,6 +1582,14 @@ struct StationViewWindow : public Window { } } + virtual void OnHover(Point pt, int widget) override + { + if (widget == WID_SV_RENAME) { + uint64 args[] = { STR_STATION_VIEW_RENAME_TOOLTIP, STR_BUTTON_DEFAULT }; + GuiShowTooltips(this, STR_STATION_VIEW_RENAME_TOOLTIP_EXTRA, lengthof(args), args, TCC_HOVER); + } + } + void SetStringParameters(int widget) const override { const Station *st = Station::Get(this->window_number); @@ -2055,6 +2065,19 @@ struct StationViewWindow : public Window { } case WID_SV_RENAME: + if (_ctrl_pressed) { + this->ToggleWidgetLoweredState(widget); + this->SetWidgetDirty(widget); + if (this->IsWidgetLowered(widget)) { + this->place_object_active = true; + SetObjectToPlaceWnd(ANIMCURSOR_PICKSTATION, PAL_NONE, HT_RECT, this); + } else { + ResetObjectToPlace(); + } + break; + } + ResetObjectToPlace(); + this->HandleButtonClick(widget); SetDParam(0, this->window_number); ShowQueryString(STR_STATION_NAME, STR_STATION_VIEW_RENAME_STATION_CAPTION, MAX_LENGTH_STATION_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); @@ -2124,6 +2147,27 @@ struct StationViewWindow : public Window { } } + void OnPlaceObject(Point pt, TileIndex tile) override + { + DoCommandP(tile, this->window_number, 0, CMD_EXCHANGE_STATION_NAMES | CMD_MSG(STR_ERROR_CAN_T_EXCHANGE_STATION_NAMES)); + ResetObjectToPlace(); + } + + void OnPlaceObjectAbort() override + { + this->place_object_active = false; + this->RaiseWidget(WID_SV_RENAME); + this->SetWidgetDirty(WID_SV_RENAME); + } + + void OnTimeout() override + { + if (!this->place_object_active) { + this->RaiseWidget(WID_SV_RENAME); + this->SetWidgetDirty(WID_SV_RENAME); + } + } + /** * Select a new sort order for the cargo view. * @param order New sort order.