diff --git a/Packages/MIES/MIES_MiesUtilities_GUI.ipf b/Packages/MIES/MIES_MiesUtilities_GUI.ipf index 508c341e0f..cc7ba740e4 100644 --- a/Packages/MIES/MIES_MiesUtilities_GUI.ipf +++ b/Packages/MIES/MIES_MiesUtilities_GUI.ipf @@ -11,6 +11,10 @@ /// @file MIES_MiesUtilities_GUI.ipf /// @brief This file holds MIES utility functions for GUI +Menu "GraphPopup" + "Export graph to SVG", /Q, ExportGraphToSVG(GetCurrentWindow()) +End + /// @brief Return the dimension label for the special, aka non-unique, controls Function/S GetSpecialControlLabel(variable channelType, variable controlType) @@ -845,3 +849,108 @@ Function StoreWindowCoordinatesHook(STRUCT WMWinHookStruct &s) return 0 End + +/// @brief Get Downloads folder path using PowerShell (Windows only) +/// +/// Returns a colon-delimited HFS path, including a terminating colon. +/// +/// @return Igor-formatted path to Downloads folder, or empty string on failure +static Function/S GetDownloadsPathIgor() + + string ps, cmd, native, igorPath + variable igorPathLen + + ps = "(New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path" + cmd = "powershell.exe -nologo -noprofile -command \"" + ps + "\"" + + // 10s timeout to avoid hanging on PowerShell invocation; ample for a shell lookup + ExecuteScriptText/B/Z/W=10 cmd + if(V_flag != 0) + DEBUGPRINT("Failed to determine Downloads folder via PowerShell") + return "" + endif + + native = S_value + + // Strip CR/LF aggressively + native = ReplaceString("\r", native, "") + native = ReplaceString("\n", native, "") + + if(IsEmpty(native)) + return "" + endif + + // Convert native Windows path to Igor's HFS format + igorPath = GetHFSPath(native) + if(IsEmpty(igorPath)) + DEBUGPRINT("Failed to convert Downloads path to HFS format") + return "" + endif + + igorPathLen = strlen(igorPath) + if(igorPathLen > 0 && cmpstr(igorPath[igorPathLen - 1], ":") != 0) + igorPath += ":" + endif + + return igorPath +End + +/// @brief Export a graph to SVG format +/// +/// Saves the graph as SVG to: +/// - Windows: Downloads folder (falls back to Documents if Downloads doesn't exist) +/// - Mac: Documents folder +/// @param winName Name of the window (graph) to export +/// @return 0 on success, NaN on failure +Function ExportGraphToSVG(string winName) + + string savePath, fileName, fullPath, baseName, timeStamp, documentsPath + variable maxFileNameLen = 240 + + ASSERT(!IsEmpty(winName), "Window name must not be empty (menu invocation failed)") + ASSERT(WindowExists(winName), "Graph window does not exist or is not accessible: " + winName) + + // Get Documents folder path as fallback + documentsPath = SpecialDirPath("Documents", 0, 0, 0) + ASSERT(!IsEmpty(documentsPath), "Could not determine Documents folder location.") + + savePath = documentsPath + +#ifdef WINDOWS + // On Windows, prefer Downloads folder over Documents + string downloadsPath = GetDownloadsPathIgor() + // Verify Downloads path exists in case the shell lookup returns an unavailable location + if(!IsEmpty(downloadsPath) && FolderExists(downloadsPath)) + savePath = downloadsPath + else + print "Info: Downloads folder unavailable, using Documents: " + documentsPath + endif +#endif // WINDOWS + + // Generate file name from window name and timestamp + baseName = CleanupName(winName, 0) + // localTimeZone is a boolean flag in GetISO8601TimeStamp; use local time for filenames + timeStamp = GetISO8601TimeStamp(localTimeZone = 1) + ASSERT(!IsEmpty(timeStamp), "Failed to generate timestamp for filename") + // Replace colons and hyphens with underscores for filename + timeStamp = ReplaceString(":", timeStamp, "_") + timeStamp = ReplaceString("-", timeStamp, "_") + // Cap filename at 240 chars to avoid extreme lengths; full path may still exceed Windows MAX_PATH + fileName = baseName + "_" + timeStamp + if(strlen(fileName) > maxFileNameLen) + fileName = fileName[0, maxFileNameLen - 1] + endif + fileName = fileName + ".svg" + ASSERT(!IsEmpty(fileName), "File name must not be empty") + fullPath = savePath + fileName + + // Save graph as SVG (E=-9 is SVG format) + try + SavePICT/O/E=-9/WIN=$winName as fullPath + print "Graph exported to SVG: " + fullPath + catch + ASSERT(0, "Failed to save SVG file: " + fullPath + "\r" + GetRTErrMessage()) + endtry + + return 0 +End