Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions spec/System/TestBuildExportPoE2_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,34 @@ Implicits: 0
after_each(function()
BuildExportPoE2.WriteFile = originalWriteFile
BuildExportPoE2.WriteAllLoadouts = originalWriteAllLoadouts
main.buildPlannerPath = nil
end)

it("uses the standard BuildPlanner folder when no path is configured", function()
main.buildPlannerPath = nil
assert.are.equal(BuildExportPoE2.StandardDir(), BuildExportPoE2.DefaultDir())
main.buildPlannerPath = " "
assert.are.equal(BuildExportPoE2.StandardDir(), BuildExportPoE2.DefaultDir())
end)

it("uses the configured build planner path", function()
main.buildPlannerPath = "C:\\Users\\Me\\OneDrive\\Documents\\My Games\\Path of Exile 2\\BuildPlanner"
assert.are.equal(main.buildPlannerPath .. "\\", BuildExportPoE2.DefaultDir())
assert.are.equal(main.buildPlannerPath .. "\\My Build.build", BuildExportPoE2.BuildPath("My Build"))
assert.are.equal("...\\Path of Exile 2\\BuildPlanner\\My Build.build", BuildExportPoE2.DisplayPath(BuildExportPoE2.BuildPath("My Build")))

main.buildPlannerPath = "/home/me/planner/"
assert.are.equal("/home/me/planner/", BuildExportPoE2.DefaultDir())
assert.are.equal(".../me/planner/My Build.build", BuildExportPoE2.DisplayPath(BuildExportPoE2.BuildPath("My Build")))
end)

it("resets the import tab export path to the configured folder", function()
local importTab = build.importTab
importTab.controls.buildPlannerBuildName:SetText("My Build", true)
main.buildPlannerPath = "/home/me/planner/"
importTab:ResetBuildPlannerPath()
local treeVersion = build.treeTab.specList[importTab.exportSpecIndex].treeVersion:gsub("_", ".")
assert.are.equal("/home/me/planner/My Build [" .. treeVersion .. "].build", importTab.controls.poe2ExportPath.buf)
end)

it("uses game ids for active and support gems", function()
Expand Down
8 changes: 8 additions & 0 deletions src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,14 @@ function ImportTabClass:ImportTab(build)
return self
end

-- Point the export path at the current default folder, e.g. after the "Build planner path" option changes.
function ImportTabClass:ResetBuildPlannerPath()
local BuildExportPoE2 = require("Modules.BuildExportPoE2")
local buildName = self.controls.buildPlannerBuildName.buf ~= "" and self.controls.buildPlannerBuildName.buf or self.controls.buildPlannerBuildName.placeholder
local spec = self.build.treeTab and self.build.treeTab.specList[self.exportSpecIndex]
self.controls.poe2ExportPath:SetText(BuildExportPoE2.BuildPath(buildName, spec and spec.treeVersion))
end

-- Metadata shared by both export buttons.
function ImportTabClass:GetBuildPlannerMetadata()
return {
Expand Down
20 changes: 18 additions & 2 deletions src/Modules/BuildExportPoE2.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,26 @@ local function treeVersionSuffix(treeVersion)
return treeVersion and " [" .. tostring(treeVersion):gsub("_", ".") .. "]" or ""
end

function M.DefaultDir()
--- The game's own BuildPlanner folder, ignoring any user override.
function M.StandardDir()
local home = os.getenv("USERPROFILE") or (GetScriptPath() .. "/../") or ""
local sep = home:find("\\") and "\\" or "/"
return home .. sep .. "Documents" .. sep .. "My Games" .. sep
.. "Path of Exile 2" .. sep .. "BuildPlanner" .. sep
end

--- The export folder: the "Build planner path" option if set, otherwise the standard folder.
function M.DefaultDir()
local custom = main and main.buildPlannerPath
if custom and custom:match("%S") then
if not custom:match("[/\\]$") then
custom = custom .. (custom:find("\\") and "\\" or "/")
end
return custom
end
return M.StandardDir()
end

function M.BuildPath(buildName, treeVersion, path)
local dir = path and (path:match("^(.*[/\\])") or "") or M.DefaultDir()
return dir .. safeFilename(buildName) .. treeVersionSuffix(treeVersion) .. ".build"
Expand All @@ -45,7 +58,10 @@ function M.DisplayPath(path)
local sep = defaultDir:find("\\") and "\\" or "/"
if path:sub(1, #defaultDir):lower() == defaultDir:lower() then
local fileName = path:sub(#defaultDir + 1)
return "..." .. sep .. "Path of Exile 2" .. sep .. "BuildPlanner" .. (fileName ~= "" and sep .. fileName or "")
-- Show the last two folders of the export directory, e.g. "...\Path of Exile 2\BuildPlanner\My Build.build"
local parent, leaf = defaultDir:gsub("[/\\]+$", ""):match("([^/\\]*)[/\\]+([^/\\]+)$")
local shownDir = parent and (parent ~= "" and parent .. sep or "") .. leaf or defaultDir:gsub("[/\\]+$", "")
return "..." .. sep .. shownDir .. (fileName ~= "" and sep .. fileName or "")
end
return "..." .. sep .. (path:gsub("[/\\]+$", ""):match("([^/\\]+)$") or "")
end
Expand Down
22 changes: 21 additions & 1 deletion src/Modules/Main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,9 @@ function main:LoadSettings(ignoreBuild)
if node.attrib.buildPath then
self.buildPath = node.attrib.buildPath
end
if node.attrib.buildPlannerPath then
self.buildPlannerPath = node.attrib.buildPlannerPath
end
if node.attrib.nodePowerTheme then
self.nodePowerTheme = node.attrib.nodePowerTheme
end
Expand Down Expand Up @@ -808,6 +811,7 @@ function main:SaveSettings()
connectionProtocol = tostring(launch.connectionProtocol),
proxyURL = launch.proxyURL,
buildPath = (self.buildPath ~= self.defaultBuildPath and self.buildPath or nil),
buildPlannerPath = self.buildPlannerPath,
nodePowerTheme = self.nodePowerTheme,
colorPositive = self.colorPositive,
colorNegative = self.colorNegative,
Expand Down Expand Up @@ -923,7 +927,7 @@ function main:OpenOptionsPopup(savedState)
}

-- NOTE: Height needs to be adjusted if more menu options are added
local oneColumnHeightReq = 850 -- Min height required to not split menu into two columns
local oneColumnHeightReq = 876 -- Min height required to not split menu into two columns
local columnWidth = 600

local startingY = 20
Expand Down Expand Up @@ -1016,6 +1020,14 @@ function main:OpenOptionsPopup(savedState)
end
controls.buildPath.tooltipText = "Overrides the default save location for builds.\nThe default location is: '"..self.defaultBuildPath.."'"

nextRow()
controls.buildPlannerPath = new("EditControl"):EditControl({ "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 290, 18 })
controls.buildPlannerPathLabel = new("LabelControl"):LabelControl({ "RIGHT", controls.buildPlannerPath, "LEFT" }, { defaultLabelSpacingPx, 0, 0, 16 }, "^7Build planner path:")
if self.buildPlannerPath then
controls.buildPlannerPath:SetText(self.buildPlannerPath)
end
controls.buildPlannerPath.tooltipText = "Overrides the folder used when exporting to the in-game build planner.\nUseful if your Documents folder is redirected (e.g. by OneDrive).\nThe default location is: '"..require("Modules.BuildExportPoE2").StandardDir().."'"

nextRow()
controls.nodePowerTheme = new("DropDownControl"):DropDownControl({ "TOPLEFT", controls.sectionAnchor, "TOPLEFT" }, { currentX + defaultLabelPlacementX, currentY, 100, 18 }, {
{ label = "Red & Blue", theme = "RED/BLUE" },
Expand Down Expand Up @@ -1237,6 +1249,14 @@ function main:OpenOptionsPopup(savedState)
else
self.buildPath = self.defaultBuildPath
end
local buildPlannerPath = controls.buildPlannerPath.buf:match("%S") and controls.buildPlannerPath.buf or nil
if buildPlannerPath ~= self.buildPlannerPath then
self.buildPlannerPath = buildPlannerPath
local importTab = self.modes.BUILD and self.modes.BUILD.importTab
if self.mode == "BUILD" and importTab then
importTab:ResetBuildPlannerPath()
end
end
if self.mode == "LIST" then
self.modes.LIST:BuildList()
end
Expand Down