/*************************************************************************************
DocX – DocX is the community edition of Xceed Words for .NET
Copyright (C) 2009-2016 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features and fast professional support,
pick up Xceed Words for .NET at https://xceed.com/xceed-words-for-net/
***********************************************************************************/
using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace Xceed.Words.NET
{
///
/// Represents a table of contents in the document
///
public class TableOfContents : DocXElement
{
#region Private Constants
private const string HeaderStyle = "TOCHeading";
private const int RightTabPos = 9350;
#endregion
#region Internal Methods
internal static TableOfContents CreateTableOfContents( DocX document, string title, TableOfContentsSwitches switches, string headerStyle = null, int lastIncludeLevel = 3, int? rightTabPos = null )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsXmlBase, headerStyle ?? HeaderStyle, title, rightTabPos ?? RightTabPos, BuildSwitchString( switches, lastIncludeLevel ) ) ) );
var xml = XElement.Load( reader );
return new TableOfContents( document, xml, headerStyle );
}
#endregion
#region Private Methods
private void InitElement( string elementName, DocX document, string headerStyle = "" )
{
if( elementName == "updateFields" )
{
if( document._settings.Descendants().Any( x => x.Name.Equals( DocX.w + elementName ) ) )
return;
var element = new XElement( XName.Get( elementName, DocX.w.NamespaceName ), new XAttribute( DocX.w + "val", true ) );
document._settings.Root.Add( element );
}
else if( elementName == "styles" )
{
if( !HasStyle( document, headerStyle, "paragraph" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsHeadingStyleBase, headerStyle ?? HeaderStyle ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
if( !HasStyle( document, "TOC1", "paragraph" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsElementStyleBase, "TOC1", "toc 1" ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
if( !HasStyle( document, "TOC2", "paragraph" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsElementStyleBase, "TOC2", "toc 2" ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
if( !HasStyle( document, "TOC3", "paragraph" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsElementStyleBase, "TOC3", "toc 3" ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
if( !HasStyle( document, "TOC4", "paragraph" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsElementStyleBase, "TOC4", "toc 4" ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
if( !HasStyle( document, "Hyperlink", "character" ) )
{
var reader = XmlReader.Create( new StringReader( string.Format( XmlTemplates.TableOfContentsHyperLinkStyleBase ) ) );
var xml = XElement.Load( reader );
document._styles.Root.Add( xml );
}
}
}
private bool HasStyle( DocX document, string value, string type )
{
return document._styles.Descendants().Any( x => x.Name.Equals( DocX.w + "style" ) && ( x.Attribute( DocX.w + "type" ) == null || x.Attribute( DocX.w + "type" ).Value.Equals( type ) ) && x.Attribute( DocX.w + "styleId" ) != null && x.Attribute( DocX.w + "styleId" ).Value.Equals( value ) );
}
private static string BuildSwitchString( TableOfContentsSwitches switches, int lastIncludeLevel )
{
var allSwitches = Enum.GetValues( typeof( TableOfContentsSwitches ) ).Cast();
var switchString = "TOC";
foreach( var s in allSwitches.Where( s => s != TableOfContentsSwitches.None && switches.HasFlag( s ) ) )
{
switchString += " " + s.EnumDescription();
if( s == TableOfContentsSwitches.O )
{
switchString += string.Format( " '{0}-{1}'", 1, lastIncludeLevel );
}
}
return switchString;
}
#endregion
#region Constructor
private TableOfContents( DocX document, XElement xml, string headerStyle )
: base( document, xml )
{
InitElement( "updateFields", document );
InitElement( "styles", document, headerStyle );
}
#endregion
}
}