/// <summary> /// Opens a window with the specified help topic. /// </summary> /// <param name="topic"></param> public static void ShowHelp(Topic topic) { if (!sTopicMap.TryGetValue(topic, out string fileName)) { Debug.Assert(false, "Unable to find " + topic + " in map"); return; } string helpFilePath = Path.Combine(RuntimeDataAccess.GetDirectory(), HELP_DIR, fileName); string url = "file://" + helpFilePath; //url = url.Replace("#", "%23"); Debug.WriteLine("Requesting help URL: " + url); ShellCommand.OpenUrl(url); }
/// <summary> /// Creates a new ExternalFile instance from a full path. /// </summary> /// <param name="pathName">Full path of external file, in canonical /// form.</param> /// <param name="projectDir">Full path to directory in which project file lives, in /// canonical form. If the project hasn't been saved yet, pass an empty string.</param> /// <returns>New object, or null if the path isn't valid.</returns> public static ExternalFile CreateFromPath(string pathName, string projectDir) { string stripDir; string rtDir = RuntimeDataAccess.GetDirectory(); string prefix; // Check path prefix for RT:, and full directory name for PROJ:. if (pathName.StartsWith(rtDir)) { stripDir = rtDir; prefix = RUNTIME_DIR_PREFIX; } else if (!string.IsNullOrEmpty(projectDir) && Path.GetDirectoryName(pathName) == projectDir) { stripDir = projectDir; prefix = PROJECT_DIR_PREFIX; } else { Debug.WriteLine("Path not in RuntimeData or project: " + pathName); return(null); } // Remove directory component. string partialPath = pathName.Substring(stripDir.Length); // If directory string didn't end with '/' or '\\', remove char from start. if (partialPath[0] == '\\' || partialPath[0] == '/') { partialPath = partialPath.Substring(1); } // Replace canonical path sep with '/'. partialPath = partialPath.Replace(Path.DirectorySeparatorChar, PATH_SEP_CHAR); string ident = prefix + partialPath; Debug.WriteLine("Converted path '" + pathName + "' to ident '" + ident + "'"); return(CreateFromIdent(ident)); }
/// <summary> /// Converts an identifier to a full path. For PROJ: identifiers, the project /// directory argument is used. /// </summary> /// <param name="ident">Identifier to convert.</param> /// <param name="projectDir">Full path to directory in which project file lives, in /// canonical form. If the project hasn't been saved yet, pass an empty string.</param> /// <returns>Full path, or null if the identifier points to a file outside the /// directory, or if this is a ProjectDir ident and the project dir isn't set.</returns> public string GetPathName(string projectDir) { string dir; bool subdirAllowed; switch (mIdentLocation) { case Location.RuntimeDir: dir = RuntimeDataAccess.GetDirectory(); if (string.IsNullOrEmpty(dir)) { // Could happen if we can't find the runtime data directory, though // we probably should've failed before now. Debug.Assert(false); return(null); } subdirAllowed = true; break; case Location.ProjectDir: if (string.IsNullOrEmpty(projectDir)) { // Shouldn't happen in practice -- we don't create PROJ: identifiers // unless a project directory has been established. Debug.Assert(false); return(null); } dir = projectDir; subdirAllowed = false; break; default: Debug.Assert(false); return(null); } int extLen = mIdent.IndexOf(':') + 1; string fullPath = Path.GetFullPath(Path.Combine(dir, mIdent.Substring(extLen))); // Confirm the file actually lives in the directory. RT: files can be anywhere // below the RuntimeData directory, while PROJ: files must live in the project // directory. if (subdirAllowed) { dir += Path.DirectorySeparatorChar; if (!fullPath.StartsWith(dir)) { Debug.WriteLine("WARNING: ident resolves outside subdir: " + mIdent); Debug.Assert(false); return(null); } } else { if (dir != Path.GetDirectoryName(fullPath)) { Debug.WriteLine("WARNING: ident resolves outside dir: " + mIdent); return(null); } } return(fullPath); }