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
}
}