예제 #1
0
        /// <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);

            if (!File.Exists(helpFilePath))
            {
                // Alternate path, used during development.  If it also doesn't exist, leave
                // the original path intact so the error message is useful.
                string altPath = Path.Combine(RuntimeDataAccess.GetDirectory() +
                                              "\\..\\..\\docs\\sgmanual",
                                              fileName);
                altPath = Path.GetFullPath(altPath);    // normalize
                if (File.Exists(altPath))
                {
                    helpFilePath = altPath;
                }
            }
            string url = "file://" + helpFilePath;

            //url = url.Replace("#", "%23");
            Debug.WriteLine("Requesting help URL: " + url);
            ShellCommand.OpenUrl(url);
        }
예제 #2
0
        /// <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();
                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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
            private static BitmapSource LoadImage(string fileName)
            {
                string pathName = RuntimeDataAccess.GetPathName(TIPS_DIR);

                pathName = Path.Combine(pathName, fileName);
                try {
                    BitmapImage bitmap = new BitmapImage();
                    bitmap.BeginInit();
                    bitmap.UriSource   = new Uri(pathName);
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;  // don't hold file open
                    bitmap.EndInit();
                    return(bitmap);
                } catch (Exception ex) {
                    Debug.WriteLine("Unable to load bitmap '" + fileName + "': " + ex);
                    return(null);
                }
            }
예제 #5
0
        /// <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));
        }
예제 #6
0
            private static BitmapSource LoadImage1(string fileName)
            {
                string pathName = RuntimeDataAccess.GetPathName(TIPS_DIR);

                pathName = Path.Combine(pathName, fileName);
                try {
                    // From "How to: Encode and Decode a PNG Image".
                    // Note: this holds the file open (try deleting the file).
                    BitmapSource bitmapSource;
                    Stream       imageStreamSource = new FileStream(pathName, FileMode.Open,
                                                                    FileAccess.Read, FileShare.Read);
                    PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource,
                                                                    BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                    bitmapSource = decoder.Frames[0];
                    //imageStreamSource.Dispose();  // image becomes blank
                    return(bitmapSource);
                } catch (IOException ex) {
                    Debug.WriteLine("Unable to load image '" + fileName + "': " + ex);
                    return(null);
                }
            }
예제 #7
0
        private bool DoLoadTips()
        {
            string pathName = RuntimeDataAccess.GetPathName(TIPS_DIR);

            pathName = Path.Combine(pathName, TIPS_FILE);
            string cereal;

            try {
                cereal = File.ReadAllText(pathName);
            } catch (IOException ex) {
                Debug.WriteLine("Failed reading tip file '" + pathName + "': " + ex.Message);
                return(false);
            }

            JavaScriptSerializer ser = new JavaScriptSerializer();
            SerTipFile           tipFile;

            try {
                tipFile = ser.Deserialize <SerTipFile>(cereal);
            } catch (Exception ex) {
                Debug.WriteLine("Failed deserializing tip JSON: " + ex.Message);
                return(false);
            }
            if (tipFile == null)
            {
                Debug.WriteLine("Failed to find tip list");
                return(false);
            }

            foreach (SerTip serTip in tipFile.Tips)
            {
                mTips.Add(new Tip(serTip.Text, serTip.Image));
            }

            return(true);
        }
예제 #8
0
        /// <summary>
        /// Generates HTML output to the specified path.
        /// </summary>
        /// <param name="pathName">Full pathname of output file (including ".html").  This
        ///   defines the root directory if there are additional files.</param>
        /// <param name="overwriteCss">If set, existing CSS file will be replaced.</param>
        public void OutputToHtml(string pathName, bool overwriteCss)
        {
            string exportTemplate = RuntimeDataAccess.GetPathName(HTML_EXPORT_TEMPLATE);
            string tmplStr;

            try {
                // exportTemplate will be null if Runtime access failed
                tmplStr = File.ReadAllText(exportTemplate);
            } catch (Exception ex) {
                string msg = string.Format(Res.Strings.ERR_FILE_READ_FAILED_FMT,
                                           pathName, ex.Message);
                MessageBox.Show(msg, Res.Strings.ERR_FILE_GENERIC_CAPTION,
                                MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // We should only need the _IMG directory if there are visualizations.
            if (GenerateImageFiles && mProject.VisualizationSets.Count != 0)
            {
                string imageDirName = Path.GetFileNameWithoutExtension(pathName) + "_IMG";
                string imageDirPath = Path.Combine(Path.GetDirectoryName(pathName), imageDirName);
                bool   exists       = false;
                try {
                    FileAttributes attr = File.GetAttributes(imageDirPath);
                    if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
                    {
                        string msg = string.Format(Res.Strings.ERR_FILE_EXISTS_NOT_DIR_FMT,
                                                   imageDirPath);
                        MessageBox.Show(msg, Res.Strings.ERR_FILE_GENERIC_CAPTION,
                                        MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                    exists = true;
                } catch (FileNotFoundException) {
                } catch (DirectoryNotFoundException) {
                }

                if (!exists)
                {
                    try {
                        Directory.CreateDirectory(imageDirPath);
                    } catch (Exception ex) {
                        string msg = string.Format(Res.Strings.ERR_DIR_CREATE_FAILED_FMT,
                                                   imageDirPath, ex.Message);
                        MessageBox.Show(msg, Res.Strings.ERR_FILE_GENERIC_CAPTION,
                                        MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                }

                // All good.
                mImageDirPath = imageDirPath;
            }

            // Perform some quick substitutions.  This could be done more efficiently,
            // but we're only doing this on the template file, which should be small.
            tmplStr = tmplStr.Replace("$ProjectName$", mProject.DataFileName);
            tmplStr = tmplStr.Replace("$AppVersion$", App.ProgramVersion.ToString());
            string expModeStr = ((Formatter.FormatConfig.ExpressionMode)
                                 AppSettings.Global.GetEnum(AppSettings.FMT_EXPRESSION_MODE,
                                                            typeof(Formatter.FormatConfig.ExpressionMode),
                                                            (int)Formatter.FormatConfig.ExpressionMode.Unknown)).ToString();

            tmplStr = tmplStr.Replace("$ExpressionStyle$", expModeStr);
            string dateStr = DateTime.Now.ToString("yyyy/MM/dd");
            string timeStr = DateTime.Now.ToString("HH:mm:ss zzz");

            tmplStr = tmplStr.Replace("$CurrentDate$", dateStr);
            tmplStr = tmplStr.Replace("$CurrentTime$", timeStr);
            tmplStr = tmplStr.Replace("$GenParameters$", GenerateParameterString());

            // Generate and substitute the symbol table.  This should be small enough that
            // we won't break the world by doing it with string.Replace().
            string symTabStr = GenerateHtmlSymbolTable();

            tmplStr = tmplStr.Replace("$SymbolTable$", symTabStr);

            // For the main event we split the template in half, and generate the code lines
            // directly into the stream writer.
            const string CodeLinesStr = "$CodeLines$";
            int          splitPoint   = tmplStr.IndexOf(CodeLinesStr);

            if (splitPoint < 0)
            {
                Debug.WriteLine("No place to put code");
                return;
            }
            string template1 = tmplStr.Substring(0, splitPoint);
            string template2 = tmplStr.Substring(splitPoint + CodeLinesStr.Length);

            // Generate UTF-8 text, without a byte-order mark.
            using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) {
                sw.Write(template1);

                //sw.Write("<code style=\"white-space: pre;\">");
                sw.Write("<pre>");
                StringBuilder sb = new StringBuilder(128);
                for (int lineIndex = 0; lineIndex < mCodeLineList.Count; lineIndex++)
                {
                    if (Selection != null && !Selection[lineIndex])
                    {
                        continue;
                    }

                    GenerateHtmlLine(lineIndex, sw, sb);
                }
                sw.WriteLine("</pre>\r\n");

                sw.Write(template2);
            }

            string cssFile    = RuntimeDataAccess.GetPathName(HTML_EXPORT_CSS_FILE);
            string outputDir  = Path.GetDirectoryName(pathName);
            string outputPath = Path.Combine(outputDir, HTML_EXPORT_CSS_FILE);

            if (File.Exists(cssFile) && (overwriteCss || !File.Exists(outputPath)))
            {
                Debug.WriteLine("Copying '" + cssFile + "' -> '" + outputPath + "'");
                try {
                    File.Copy(cssFile, outputPath, true);
                } catch (Exception ex) {
                    string msg = string.Format(Res.Strings.ERR_FILE_COPY_FAILED_FMT,
                                               cssFile, outputPath, ex.Message);
                    MessageBox.Show(msg, Res.Strings.ERR_FILE_GENERIC_CAPTION,
                                    MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
        }