using System; using System.IO; using System.Collections.Generic; using System.Security.AccessControl; using System.Windows; using System.Windows.Media; using SharpVectors.Renderers.Wpf; using SharpVectors.Converters.Utils; namespace SharpVectors.Converters { /// /// This converts a directory (and optionally the sub-directories) of SVG /// files to XAML files in a specified directory, maintaining the original /// directory structure. /// public sealed class DirectorySvgConverter : SvgConverter { #region Private Fields private int _convertedCount; private bool _isOverwrite; private bool _isRecursive; private bool _includeHidden; private bool _includeSecurity; private bool _writerErrorOccurred; private bool _fallbackOnWriterError; private string _errorFile; private DirectoryInfo _sourceDir; private DirectoryInfo _destinationDir; #endregion #region Constructors and Destructor /// /// Initializes a new instance of the /// class with the specified drawing or rendering settings. /// /// /// This specifies the settings used by the rendering or drawing engine. /// If this is , the default settings is used. /// public DirectorySvgConverter(WpfDrawingSettings settings) : base(settings) { _isOverwrite = true; _isRecursive = true; } #endregion #region Public Properties /// /// Gets or sets a value indicating whether the directory copying is /// recursive, that is includes the sub-directories. /// /// /// This property is if the sub-directories are /// included in the directory copy; otherwise, it is . /// The default is . /// public bool Recursive { get { return _isRecursive; } set { _isRecursive = value; } } /// /// Gets or sets a value indicating whether an existing file is overwritten. /// /// /// This property is if existing file is overwritten; /// otherwise, it is . The default is . /// public bool Overwrite { get { return _isOverwrite; } set { _isOverwrite = value; } } /// /// Gets or sets a value indicating whether the security settings of the /// copied file is retained. /// /// /// This property is if the security settings of the /// file is also copied; otherwise, it is . The /// default is . /// public bool IncludeSecurity { get { return _includeSecurity; } set { _includeSecurity = value; } } /// /// Gets or sets a value indicating whether the copy operation includes /// hidden directories and files. /// /// /// This property is if hidden directories and files /// are included in the copy operation; otherwise, it is /// . The default is . /// public bool IncludeHidden { get { return _includeHidden; } set { _includeHidden = value; } } /// /// Gets a value indicating whether a writer error occurred when /// using the custom XAML writer. /// /// /// This is if an error occurred when using /// the custom XAML writer; otherwise, it is . /// public bool WriterErrorOccurred { get { return _writerErrorOccurred; } } /// /// Gets or sets a value indicating whether to fall back and use /// the .NET Framework XAML writer when an error occurred in using the /// custom writer. /// /// /// This is if the converter falls back to using /// the system XAML writer when an error occurred in using the custom /// writer; otherwise, it is . If , /// an exception, which occurred in using the custom writer will be /// thrown. The default is . /// public bool FallbackOnWriterError { get { return _fallbackOnWriterError; } set { _fallbackOnWriterError = value; } } /// /// Gets the source directory of the SVG files to be converted. /// /// /// A specifying the source directory of /// the SVG files. /// public DirectoryInfo SourceDir { get { return _sourceDir; } } /// /// Gets the destination directory of the converted XAML files. /// /// /// A specifying the destination directory of /// the converted XAML files. /// public DirectoryInfo DestinationDir { get { return _destinationDir; } } /// /// Gets the full path of the last SVG file not successfully converted. /// /// /// A string containing the full path of the last SVG file not /// successfully converted to the XAML /// /// /// Whenever an error occurred in the conversion of a file, the /// conversion process will stop. Use this property to retrieve the full /// path of the SVG file causing the error. /// public string ErrorFile { get { return _errorFile; } } #endregion #region Public Methods /// /// Convert the SVG files in the specified source directory, saving the /// results in the specified destination directory. /// /// /// A specifying the source directory of /// the SVG files. /// /// /// A specifying the source directory of /// the SVG files. /// /// /// /// If the is . /// /// /// -or- /// /// /// If the is . /// /// /// /// If the directory specified by does not /// exists. /// public void Convert(DirectoryInfo sourceInfo, DirectoryInfo destInfo) { if (sourceInfo == null) { throw new ArgumentNullException("sourceInfo", "The source directory cannot be null (or Nothing)."); } if (destInfo == null) { throw new ArgumentNullException("destInfo", "The destination directory cannot be null (or Nothing)."); } if (!sourceInfo.Exists) { throw new ArgumentException( "The source directory must exists.", "sourceInfo"); } _convertedCount = 0; _sourceDir = sourceInfo; _destinationDir = destInfo; DirectorySecurity dirSecurity = null; if (_includeSecurity) { dirSecurity = sourceInfo.GetAccessControl(); } if (!destInfo.Exists) { if (dirSecurity != null) { destInfo.Create(dirSecurity); } else { destInfo.Create(); } destInfo.Attributes = sourceInfo.Attributes; } else { if (dirSecurity != null) { destInfo.SetAccessControl(dirSecurity); } } this.ProcessConversion(_sourceDir, _destinationDir); } #endregion #region Private Methods private void ProcessConversion(DirectoryInfo source, DirectoryInfo target) { // Convert the files in the specified directory... this.ConvertFiles(source, target); if (!_isRecursive) { return; } // If recursive, process any sub-directory... DirectoryInfo[] arrSourceInfo = source.GetDirectories(); int dirCount = (arrSourceInfo == null) ? 0 : arrSourceInfo.Length; for (int i = 0; i < dirCount; i++) { DirectoryInfo sourceInfo = arrSourceInfo[i]; FileAttributes fileAttr = sourceInfo.Attributes; if (!_includeHidden) { if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden) { continue; } } DirectoryInfo targetInfo = null; if (_includeSecurity) { targetInfo = target.CreateSubdirectory(sourceInfo.Name, sourceInfo.GetAccessControl()); } else { targetInfo = target.CreateSubdirectory(sourceInfo.Name); } targetInfo.Attributes = fileAttr; this.ProcessConversion(sourceInfo, targetInfo); } } private void ConvertFiles(DirectoryInfo source, DirectoryInfo target) { _errorFile = null; FileSvgConverter fileConverter = new FileSvgConverter(this.SaveXaml, this.SaveZaml, this.DrawingSettings); fileConverter.FallbackOnWriterError = _fallbackOnWriterError; string targetDirName = target.ToString(); string xamlFilePath; IEnumerable fileIterator = DirectoryUtils.FindFiles( source, "*.*", SearchOption.TopDirectoryOnly); foreach (string svgFileName in fileIterator) { string fileExt = Path.GetExtension(svgFileName); if (String.Equals(fileExt, ".svg", StringComparison.OrdinalIgnoreCase) || String.Equals(fileExt, ".svgz", StringComparison.OrdinalIgnoreCase)) { try { FileAttributes fileAttr = File.GetAttributes(svgFileName); if (!_includeHidden) { if ((fileAttr & FileAttributes.Hidden) == FileAttributes.Hidden) { continue; } } xamlFilePath = Path.Combine(targetDirName, Path.GetFileNameWithoutExtension(svgFileName) + ".xaml"); fileConverter.Convert(svgFileName, xamlFilePath); File.SetAttributes(xamlFilePath, fileAttr); // if required to set the security or access control if (_includeSecurity) { File.SetAccessControl(xamlFilePath, File.GetAccessControl(svgFileName)); } _convertedCount++; if (fileConverter.WriterErrorOccurred) { _writerErrorOccurred = true; } } catch { _errorFile = svgFileName; throw; } } } } #endregion } }