| @@ -159,7 +159,7 @@ namespace Xceed.Words.NET.Examples | |||
| c.AddSeries( s1 ); | |||
| // Insert chart into document | |||
| document.InsertParagraph( "Expenses(M$) for selected categories of Canada" ).FontSize( 15 ).SpacingAfter( 10d ); | |||
| document.InsertParagraph( "Expenses(M$) for selected categories in Canada" ).FontSize( 15 ).SpacingAfter( 10d ); | |||
| document.InsertChart( c ); | |||
| document.Save(); | |||
| @@ -195,7 +195,7 @@ namespace Xceed.Words.NET.Examples | |||
| c.AddSeries( s1 ); | |||
| // Insert chart into document | |||
| document.InsertParagraph( "Expenses(M$) for selected categories of Brazil" ).FontSize( 15 ).SpacingAfter( 10d ); | |||
| document.InsertParagraph( "Expenses(M$) for selected categories in Brazil" ).FontSize( 15 ).SpacingAfter( 10d ); | |||
| document.InsertChart( c ); | |||
| document.Save(); | |||
| @@ -79,15 +79,33 @@ namespace Xceed.Words.NET.Examples | |||
| p2.AppendHyperlink( h2 ).Color( Color.Blue ).UnderlineStyle( UnderlineStyle.singleLine ); | |||
| p2.Append( "." ).SpacingAfter( 40d ); | |||
| // Create a bookmark anchor. | |||
| var bookmarkAnchor = "bookmarkAnchor"; | |||
| // Add an Hyperlink to this document pointing to a bookmark anchor. | |||
| var h3 = document.AddHyperlink( "Special Data", bookmarkAnchor ); | |||
| // Add a paragraph. | |||
| var p3 = document.InsertParagraph( "An hyperlink pointing to a bookmark of this Document has been added at the end of this paragraph: " ); | |||
| // Append an hyperlink to a paragraph. | |||
| p3.AppendHyperlink( h3 ).Color( Color.Red ).UnderlineStyle( UnderlineStyle.singleLine ); | |||
| p3.Append( "." ).SpacingAfter( 40d ); | |||
| // Add an Hyperlink to this document. | |||
| var h3 = document.AddHyperlink( "microsoft", new Uri( "http://www.microsoft.com" ) ); | |||
| var h4 = document.AddHyperlink( "microsoft", new Uri( "http://www.microsoft.com" ) ); | |||
| // Add a paragraph | |||
| var p3 = document.InsertParagraph( "The hyperlink from this paragraph has been removed. " ); | |||
| var p4 = document.InsertParagraph( "The hyperlink from this paragraph has been removed. " ); | |||
| // Append an hyperlink to a paragraph. | |||
| p3.AppendHyperlink( h3 ).Color( Color.Green ).UnderlineStyle( UnderlineStyle.singleLine ).Italic(); | |||
| p4.AppendHyperlink( h4 ).Color( Color.Green ).UnderlineStyle( UnderlineStyle.singleLine ).Italic(); | |||
| // Remove the first hyperlink of paragraph 3. | |||
| p3.RemoveHyperlink( 0 ); | |||
| // Remove the first hyperlink of paragraph 4. | |||
| p4.RemoveHyperlink( 0 ); | |||
| // Add a paragraph. | |||
| var p5 = document.InsertParagraph( "This is a paragraph containing a" ); | |||
| // Add a bookmark into the paragraph by setting its bookmark anchor. | |||
| p5.AppendBookmark( bookmarkAnchor ); | |||
| p5.Append( " bookmark " ); | |||
| p5.Append( "referenced by a hyperlink defined in an earlier paragraph." ); | |||
| p5.SpacingBefore( 200d ); | |||
| document.Save(); | |||
| Console.WriteLine( "\tCreated: Hyperlinks.docx\n" ); | |||
| @@ -49,36 +49,42 @@ namespace Xceed.Words.NET.Examples | |||
| using( var document = DocX.Create( LineSample.LineSampleOutputDirectory + @"InsertHorizontalLine.docx" ) ) | |||
| { | |||
| // Add a title | |||
| document.InsertParagraph( "Adding bottom Horizontal lines" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | |||
| document.InsertParagraph( "Adding top or bottom Horizontal lines" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | |||
| // Add a paragraph with a single line. | |||
| var p = document.InsertParagraph(); | |||
| p.Append( "This is a paragraph with a single line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||
| p.InsertHorizontalLine( "single", 6, 1, "auto" ); | |||
| p.Append( "This is a paragraph with a single bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 6, 1, "auto" ); | |||
| p.SpacingAfter( 20 ); | |||
| // Add a paragraph with a double green line. | |||
| var p2 = document.InsertParagraph(); | |||
| p2.Append( "This is a paragraph with a double colored line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||
| p2.InsertHorizontalLine( "double", 6, 1, "green" ); | |||
| p2.Append( "This is a paragraph with a double bottom colored line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p2.InsertHorizontalLine( HorizontalBorderPosition.bottom, "double", 6, 1, "green" ); | |||
| p2.SpacingAfter( 20 ); | |||
| // Add a paragraph with a triple red line. | |||
| var p3 = document.InsertParagraph(); | |||
| p3.Append( "This is a paragraph with a triple colored line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||
| p3.InsertHorizontalLine( "triple", 6, 1, "red" ); | |||
| p3.Append( "This is a paragraph with a triple bottom colored line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p3.InsertHorizontalLine( HorizontalBorderPosition.bottom, "triple", 6, 1, "red" ); | |||
| p3.SpacingAfter( 20 ); | |||
| // Add a paragraph with a single spaced line. | |||
| var p4 = document.InsertParagraph(); | |||
| p4.Append( "This is a paragraph with a spaced line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||
| p4.InsertHorizontalLine( "single", 6, 12, "auto" ); | |||
| p4.Append( "This is a paragraph with a spaced bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p4.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 6, 12, "auto" ); | |||
| p4.SpacingAfter( 20 ); | |||
| // Add a paragraph with a single large line. | |||
| var p5 = document.InsertParagraph(); | |||
| p5.Append( "This is a paragraph with a large line." ).Font( new Font( "Arial" ) ).FontSize( 20 ); | |||
| p5.InsertHorizontalLine( "single", 25, 1, "auto" ); | |||
| p5.Append( "This is a paragraph with a large bottom line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p5.InsertHorizontalLine( HorizontalBorderPosition.bottom, "single", 25, 1, "auto" ); | |||
| p5.SpacingAfter( 60 ); | |||
| // Add a paragraph with a single blue top line. | |||
| var p6 = document.InsertParagraph(); | |||
| p6.Append( "This is a paragraph with a blue top line." ).Font( new Font( "Arial" ) ).FontSize( 15 ); | |||
| p6.InsertHorizontalLine( HorizontalBorderPosition.top, "single", 6, 1, "blue" ); | |||
| p5.SpacingAfter( 20 ); | |||
| document.Save(); | |||
| @@ -81,7 +81,17 @@ namespace Xceed.Words.NET.Examples | |||
| .Italic() | |||
| .Spacing( 5 ) | |||
| .Append( "highlight" ).Highlight( Highlight.yellow ).UnderlineColor( Color.Blue ).CapsStyle( CapsStyle.caps ) | |||
| .Append( " and strike through." ).StrikeThrough( StrikeThrough.strike ); | |||
| .Append( " and strike through." ).StrikeThrough( StrikeThrough.strike ) | |||
| .SpacingAfter( 40 ); | |||
| // Insert another Paragraph into this document. | |||
| var p3 = document.InsertParagraph(); | |||
| // Append some text with 2 TabStopPositions. | |||
| p3.InsertTabStopPosition( Alignment.center, 216f, TabStopPositionLeader.dot ) | |||
| .InsertTabStopPosition( Alignment.right, 432f, TabStopPositionLeader.dot ) | |||
| .Append( "Text with TabStopPositions on Left\tMiddle\tand Right" ) | |||
| .SpacingAfter( 40 ); | |||
| // Save this document to disk. | |||
| document.Save(); | |||
| @@ -205,6 +215,15 @@ namespace Xceed.Words.NET.Examples | |||
| // Replace "<COST>" with "$13.95" using an handler | |||
| p4.ReplaceText( "<(.*?)>", ReplaceTextHandler, false, RegexOptions.IgnoreCase, null, new Formatting() ); | |||
| p4.SpacingAfter( 30 ); | |||
| // Insert another Paragraph into this document. | |||
| var p5 = document.InsertParagraph(); | |||
| // Append some text with track changes | |||
| p5.Append( "This is a paragraph where tracking of modifications is used." ); | |||
| p5.ReplaceText( "modifications", "changes", true ); | |||
| // Save this document to disk. | |||
| document.Save(); | |||
| Console.WriteLine( "\tCreated: TextActions.docx\n" ); | |||
| @@ -216,7 +216,7 @@ namespace Xceed.Words.NET.Examples | |||
| document.InsertParagraph( "Columns width" ).FontSize( 15d ).SpacingAfter( 50d ).Alignment = Alignment.center; | |||
| // Insert a title paragraph. | |||
| var p = document.InsertParagraph( "In the following table, the cell's left margin has been removed for rows 2-5 as well as the top/bottom table's borders." ).Bold(); | |||
| var p = document.InsertParagraph( "In the following table, the cell's left margin has been removed for rows 2-6 as well as the top/bottom table's borders." ).Bold(); | |||
| p.Alignment = Alignment.center; | |||
| p.SpacingAfter( 40d ); | |||
| @@ -0,0 +1,3 @@ | |||
| <?xml version="1.0"?> | |||
| <configuration> | |||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> | |||
| @@ -0,0 +1,3 @@ | |||
| <?xml version="1.0"?> | |||
| <configuration> | |||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> | |||
| @@ -0,0 +1,11 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||
| <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |||
| <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> | |||
| <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> | |||
| <security> | |||
| <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> | |||
| <requestedExecutionLevel level="asInvoker" uiAccess="false"/> | |||
| </requestedPrivileges> | |||
| </security> | |||
| </trustInfo> | |||
| </assembly> | |||
| @@ -0,0 +1,3 @@ | |||
| <?xml version="1.0"?> | |||
| <configuration> | |||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> | |||
| @@ -0,0 +1,3 @@ | |||
| <?xml version="1.0"?> | |||
| <configuration> | |||
| <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> | |||
| @@ -0,0 +1,11 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||
| <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |||
| <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> | |||
| <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> | |||
| <security> | |||
| <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> | |||
| <requestedExecutionLevel level="asInvoker" uiAccess="false"/> | |||
| </requestedPrivileges> | |||
| </security> | |||
| </trustInfo> | |||
| </assembly> | |||
| @@ -0,0 +1 @@ | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Debug\Examples.exe.config | |||
| @@ -0,0 +1,5 @@ | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Examples.exe.config | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Examples.exe | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\bin\Release\Xceed.Words.NET.dll | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\obj\x86\Release\Xceed.Words.NET.Examples.csprojResolveAssemblyReference.cache | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Examples\obj\x86\Release\Examples.exe | |||
| @@ -19,7 +19,7 @@ | |||
| internal static class _XceedVersionInfo | |||
| { | |||
| [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | |||
| public const string BaseVersion = "1.1"; | |||
| public const string BaseVersion = "1.2"; | |||
| [System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields" )] | |||
| public const string Version = BaseVersion + | |||
| ".0.0"; | |||
| @@ -127,8 +127,8 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| XElement body = Xml.Element( XName.Get( "body", DocX.w.NamespaceName ) ); | |||
| XElement baseSectionXml = body?.Element( XName.Get( "sectPr", DocX.w.NamespaceName ) ); | |||
| var body = Xml.DescendantsAndSelf( XName.Get( "body", DocX.w.NamespaceName ) ).FirstOrDefault(); | |||
| var baseSectionXml = body?.Element( XName.Get( "sectPr", DocX.w.NamespaceName ) ); | |||
| if (baseSectionXml != null) | |||
| { | |||
| @@ -313,7 +313,8 @@ namespace Xceed.Words.NET | |||
| Formatting matchFormatting = null, | |||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | |||
| bool escapeRegEx = true, | |||
| bool useRegExSubstitutions = false ) | |||
| bool useRegExSubstitutions = false, | |||
| bool removeEmptyParagraph = true ) | |||
| { | |||
| if( string.IsNullOrEmpty( searchValue ) ) | |||
| { | |||
| @@ -332,7 +333,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| foreach( Paragraph p in h.Paragraphs ) | |||
| { | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| } | |||
| @@ -340,7 +341,7 @@ namespace Xceed.Words.NET | |||
| // ReplaceText int main body of document. | |||
| foreach( Paragraph p in this.Paragraphs ) | |||
| { | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||
| } | |||
| // ReplaceText in Footers of the document. | |||
| @@ -351,7 +352,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| foreach( Paragraph p in f.Paragraphs ) | |||
| { | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions ); | |||
| p.ReplaceText( searchValue, newValue, trackChanges, options, newFormatting, matchFormatting, fo, escapeRegEx, useRegExSubstitutions, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| } | |||
| @@ -367,13 +368,15 @@ namespace Xceed.Words.NET | |||
| /// <param name="newFormatting"></param> | |||
| /// <param name="matchFormatting"></param> | |||
| /// <param name="fo"></param> | |||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||
| public virtual void ReplaceText( string searchValue, | |||
| Func<string,string> regexMatchHandler, | |||
| bool trackChanges = false, | |||
| RegexOptions options = RegexOptions.None, | |||
| Formatting newFormatting = null, | |||
| Formatting matchFormatting = null, | |||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch ) | |||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | |||
| bool removeEmptyParagraph = true ) | |||
| { | |||
| if( string.IsNullOrEmpty( searchValue ) ) | |||
| { | |||
| @@ -401,14 +404,14 @@ namespace Xceed.Words.NET | |||
| { | |||
| foreach( var p in hf.Paragraphs ) | |||
| { | |||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo ); | |||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| } | |||
| foreach( var p in this.Paragraphs ) | |||
| { | |||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo ); | |||
| p.ReplaceText( searchValue, regexMatchHandler, trackChanges, options, newFormatting, matchFormatting, fo, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| @@ -916,7 +919,7 @@ namespace Xceed.Words.NET | |||
| var listItemType = HelperFunctions.GetListItemType( p, Document ); | |||
| if( listItemType != null ) | |||
| { | |||
| p.ListItemType = GetListItemType( HelperFunctions.GetListItemType( p, Document ) ); | |||
| p.ListItemType = GetListItemType( listItemType ); | |||
| } | |||
| } | |||
| @@ -55,6 +55,16 @@ namespace Xceed.Words.NET | |||
| private float _pageSizeMultiplier = 20.0f; | |||
| private readonly object nextFreeDocPrIdLock = new object(); | |||
| private long? nextFreeDocPrId; | |||
| #endregion | |||
| #region Internal Constants | |||
| internal const string RelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; | |||
| internal const string ContentTypeApplicationRelationShipXml = "application/vnd.openxmlformats-package.relationships+xml"; | |||
| #endregion | |||
| #region Internal Members | |||
| @@ -551,14 +561,14 @@ namespace Xceed.Words.NET | |||
| /// </code> | |||
| /// </example> | |||
| /// <seealso cref="AddImage(string)"/> | |||
| /// <seealso cref="AddImage(Stream)"/> | |||
| /// <seealso cref="AddImage(Stream, string)"/> | |||
| /// <seealso cref="Paragraph.Pictures"/> | |||
| /// <seealso cref="Paragraph.InsertPicture"/> | |||
| public List<Image> Images | |||
| { | |||
| get | |||
| { | |||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( RelationshipImage ); | |||
| if( imageRelationships.Any() ) | |||
| { | |||
| return | |||
| @@ -940,7 +950,7 @@ namespace Xceed.Words.NET | |||
| "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", | |||
| "application/vnd.openxmlformats-package.core-properties+xml", | |||
| "application/vnd.openxmlformats-officedocument.extended-properties+xml", | |||
| "application/vnd.openxmlformats-package.relationships+xml" | |||
| ContentTypeApplicationRelationShipXml | |||
| }; | |||
| var imageContentTypes = new List<string> | |||
| @@ -1520,9 +1530,7 @@ namespace Xceed.Words.NET | |||
| using( FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read, FileShare.Read ) ) | |||
| { | |||
| var data = new byte[ fs.Length ]; | |||
| fs.Read( data, 0, ( int )fs.Length ); | |||
| ms.Write( data, 0, ( int )fs.Length ); | |||
| CopyStream( fs, ms ); | |||
| } | |||
| // Open the docx package | |||
| @@ -1697,6 +1705,7 @@ namespace Xceed.Words.NET | |||
| /// Add an Image into this document from a fully qualified or relative filename. | |||
| /// </summary> | |||
| /// <param name="filename">The fully qualified or relative filename.</param> | |||
| /// <param name="contentType">MIME type of image, guessed if not given.</param> | |||
| /// <returns>An Image file.</returns> | |||
| /// <example> | |||
| /// Add an Image into this document from a fully qualified filename. | |||
| @@ -1712,7 +1721,7 @@ namespace Xceed.Words.NET | |||
| /// }// Release this document from memory. | |||
| /// </code> | |||
| /// </example> | |||
| /// <seealso cref="AddImage(System.IO.Stream)"/> | |||
| /// <seealso cref="AddImage(Stream, string)"/> | |||
| /// <seealso cref="Paragraph.InsertPicture"/> | |||
| public Image AddImage( string filename ) | |||
| { | |||
| @@ -1747,13 +1756,14 @@ namespace Xceed.Words.NET | |||
| break; | |||
| } | |||
| return AddImage( filename, contentType ); | |||
| return AddImage( filename as object, contentType ); | |||
| } | |||
| /// <summary> | |||
| /// Add an Image into this document from a Stream. | |||
| /// </summary> | |||
| /// <param name="stream">A Stream stream.</param> | |||
| /// <param name="contentType">MIME type of image.</param> | |||
| /// <returns>An Image file.</returns> | |||
| /// <example> | |||
| /// Add an Image into a document using a Stream. | |||
| @@ -1775,17 +1785,17 @@ namespace Xceed.Words.NET | |||
| /// </example> | |||
| /// <seealso cref="AddImage(string)"/> | |||
| /// <seealso cref="Paragraph.InsertPicture"/> | |||
| public Image AddImage( Stream stream ) | |||
| public Image AddImage( Stream stream, string contentType = "image/jpeg" ) | |||
| { | |||
| return AddImage( stream as object ); | |||
| return AddImage( stream as object, contentType ); | |||
| } | |||
| /// <summary> | |||
| /// Adds a hyperlink to a document and creates a Paragraph which uses it. | |||
| /// Adds a hyperlink with a uri to a document and creates a Paragraph which uses it. | |||
| /// </summary> | |||
| /// <param name="text">The text as displayed by the hyperlink.</param> | |||
| /// <param name="uri">The hyperlink itself.</param> | |||
| /// <returns>Returns a hyperlink that can be inserted into a Paragraph.</returns> | |||
| /// <returns>Returns a hyperlink with a uri that can be inserted into a Paragraph.</returns> | |||
| /// <example> | |||
| /// Adds a hyperlink to a document and creates a Paragraph which uses it. | |||
| /// <code> | |||
| @@ -1808,26 +1818,18 @@ namespace Xceed.Words.NET | |||
| /// </example> | |||
| public Hyperlink AddHyperlink( string text, Uri uri ) | |||
| { | |||
| var i = new XElement | |||
| ( | |||
| XName.Get( "hyperlink", w.NamespaceName ), | |||
| new XAttribute( r + "id", string.Empty ), | |||
| new XAttribute( w + "history", "1" ), | |||
| new XElement( XName.Get( "r", w.NamespaceName ), | |||
| new XElement( XName.Get( "rPr", w.NamespaceName ), | |||
| new XElement( XName.Get( "rStyle", w.NamespaceName ), | |||
| new XAttribute( w + "val", "Hyperlink" ) ) ), | |||
| new XElement( XName.Get( "t", w.NamespaceName ), text ) ) | |||
| ); | |||
| var h = new Hyperlink( this, this.PackagePart, i ); | |||
| h.text = text; | |||
| h.uri = uri; | |||
| this.AddHyperlinkStyleIfNotPresent(); | |||
| return this.AddHyperlink( text, uri, null ); | |||
| } | |||
| return h; | |||
| /// <summary> | |||
| /// Adds a hyperlink with an anchor to a document and creates a Paragraph which uses it. | |||
| /// </summary> | |||
| /// <param name="text">The text as displayed by the hyperlink.</param> | |||
| /// <param name="anchor">The anchor to a bookmark.</param> | |||
| /// <returns>Returns a hyperlink with an anchor that can be inserted into a Paragraph.</returns> | |||
| public Hyperlink AddHyperlink( string text, string anchor ) | |||
| { | |||
| return this.AddHyperlink( text, null, anchor ); | |||
| } | |||
| /// <summary> | |||
| @@ -2194,7 +2196,14 @@ namespace Xceed.Words.NET | |||
| { | |||
| using( FileStream fs = new FileStream( _filename, FileMode.Create ) ) | |||
| { | |||
| fs.Write( _memoryStream.ToArray(), 0, ( int )_memoryStream.Length ); | |||
| if( _memoryStream.CanSeek ) | |||
| { | |||
| // Write to the beginning of the stream | |||
| _memoryStream.Position = 0; | |||
| CopyStream( _memoryStream, fs ); | |||
| } | |||
| else | |||
| fs.Write( _memoryStream.ToArray(), 0, ( int )_memoryStream.Length ); | |||
| } | |||
| } | |||
| else if( _stream.CanSeek ) //Check if stream can be seeked to support System.Web.HttpResponseStream. | |||
| @@ -3040,11 +3049,7 @@ namespace Xceed.Words.NET | |||
| document.Document = document; | |||
| #region MainDocumentPart | |||
| document.PackagePart = package.GetParts().Where | |||
| ( | |||
| p => p.ContentType.Equals( HelperFunctions.DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( HelperFunctions.TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) | |||
| ).Single(); | |||
| document.PackagePart = HelperFunctions.GetMainDocumentPart( package ); | |||
| using( TextReader tr = new StreamReader( document.PackagePart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | |||
| { | |||
| @@ -3249,12 +3254,37 @@ namespace Xceed.Words.NET | |||
| var newImageStream = ( o is string ) ? new FileStream( o as string, FileMode.Open, FileAccess.Read ) : o as Stream; | |||
| // Get all image parts in word\document.xml | |||
| var ImageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| var imageParts = ImageRelationships.Select( ir => _package.GetParts().FirstOrDefault( p => p.Uri.ToString().EndsWith( ir.TargetUri.ToString() ) ) ) | |||
| .Where( x => ( x != null ) ) | |||
| .ToList(); | |||
| PackagePartCollection packagePartCollection = _package.GetParts(); | |||
| var parts = packagePartCollection.Select( x => new | |||
| { | |||
| UriString = x.Uri.ToString(), | |||
| Part = x | |||
| } ).ToList(); | |||
| var partLookup = parts.ToDictionary( x => x.UriString, x => x.Part, StringComparer.Ordinal ); | |||
| List<PackagePart> imageParts = new List<PackagePart>(); | |||
| foreach( var item in this.PackagePart.GetRelationshipsByType( RelationshipImage ) ) | |||
| { | |||
| var targetUri = item.TargetUri.ToString(); | |||
| PackagePart part; | |||
| if( partLookup.TryGetValue( targetUri, out part ) ) | |||
| { | |||
| imageParts.Add( part ); | |||
| } | |||
| } | |||
| IEnumerable<PackagePart> relsParts = parts | |||
| .Where( | |||
| part => | |||
| part.Part.ContentType.Equals( ContentTypeApplicationRelationShipXml, StringComparison.Ordinal ) && | |||
| part.UriString.IndexOf( "/word/", StringComparison.Ordinal ) > -1 ) | |||
| .Select( part => part.Part ); | |||
| XName xNameTarget = XName.Get( "Target" ); | |||
| XName xNameTargetMode = XName.Get( "TargetMode" ); | |||
| foreach( PackagePart relsPart in _package.GetParts().Where( part => part.Uri.ToString().Contains( "/word/" ) ).Where( part => part.ContentType.Equals( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) | |||
| foreach( PackagePart relsPart in relsParts ) | |||
| { | |||
| XDocument relsPartContent; | |||
| using( TextReader tr = new StreamReader( relsPart.GetStream( FileMode.Open, FileAccess.Read ) ) ) | |||
| @@ -3271,14 +3301,15 @@ namespace Xceed.Words.NET | |||
| foreach( XElement imageRelationship in imageRelationships ) | |||
| { | |||
| if( imageRelationship.Attribute( XName.Get( "Target" ) ) != null ) | |||
| XAttribute attribute = imageRelationship.Attribute( xNameTarget ); | |||
| if( attribute != null ) | |||
| { | |||
| var targetModeAttr = imageRelationship.Attribute( XName.Get( "TargetMode" ) ); | |||
| var targetModeAttr = imageRelationship.Attribute( xNameTargetMode ); | |||
| var targetMode = ( targetModeAttr != null ) ? targetModeAttr.Value : string.Empty; | |||
| if( !targetMode.Equals( "External" ) ) | |||
| { | |||
| var imagePartUri = Path.Combine( Path.GetDirectoryName( relsPart.Uri.ToString() ), imageRelationship.Attribute( XName.Get( "Target" ) ).Value ); | |||
| var imagePartUri = Path.Combine( Path.GetDirectoryName( relsPart.Uri.ToString() ), attribute.Value ); | |||
| imagePartUri = Path.GetFullPath( imagePartUri.Replace( "\\_rels", string.Empty ) ); | |||
| imagePartUri = imagePartUri.Replace( Path.GetFullPath( "\\" ), string.Empty ).Replace( "\\", "/" ); | |||
| @@ -3297,19 +3328,15 @@ namespace Xceed.Words.NET | |||
| // Loop through each image part in this document. | |||
| foreach( PackagePart pp in imageParts ) | |||
| { | |||
| // Open a tempory Stream to this image part. | |||
| // Get the image object for this image part. | |||
| using( Stream tempStream = pp.GetStream( FileMode.Open, FileAccess.Read ) ) | |||
| { | |||
| // Compare this image to the new image being added. | |||
| if( HelperFunctions.IsSameFile( tempStream, newImageStream ) ) | |||
| { | |||
| // Get the image object for this image part | |||
| var id = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ) | |||
| .Where( r => r.TargetUri == pp.Uri ) | |||
| .Select( r => r.Id ).First(); | |||
| // Return the Image object | |||
| return Images.Where( i => i.Id == id ).First(); | |||
| PackageRelationship relationship = this.PackagePart.GetRelationshipsByType( RelationshipImage ).First( x => x.TargetUri == pp.Uri ); | |||
| return new Image( this, relationship ); | |||
| } | |||
| } | |||
| } | |||
| @@ -3328,11 +3355,11 @@ namespace Xceed.Words.NET | |||
| } while( _package.PartExists( new Uri( imgPartUriPath, UriKind.Relative ) ) ); | |||
| // We are now guareenteed that imgPartUriPath is unique. | |||
| // We are now guaranteed that imgPartUriPath is unique. | |||
| var img = _package.CreatePart( new Uri( imgPartUriPath, UriKind.Relative ), contentType, CompressionOption.Normal ); | |||
| // Create a new image relationship | |||
| var rel = this.PackagePart.CreateRelationship( img.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| var rel = this.PackagePart.CreateRelationship( img.Uri, TargetMode.Internal, RelationshipImage ); | |||
| // Open a Stream to the newly created Image part. | |||
| using( Stream stream = new PackagePartStream( img.GetStream( FileMode.Create, FileAccess.Write ) ) ) | |||
| @@ -3340,9 +3367,7 @@ namespace Xceed.Words.NET | |||
| // Using the Stream to the real image, copy this streams data into the newly create Image part. | |||
| using( newImageStream ) | |||
| { | |||
| byte[] bytes = new byte[ newImageStream.Length ]; | |||
| newImageStream.Read( bytes, 0, ( int )newImageStream.Length ); | |||
| stream.Write( bytes, 0, ( int )newImageStream.Length ); | |||
| CopyStream( newImageStream, stream, bufferSize: 4096 ); | |||
| }// Close the Stream to the new image. | |||
| }// Close the Stream to the new image part. | |||
| @@ -3634,6 +3659,42 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Finds the next free Id for bookmarkStart/docPr. | |||
| /// </summary> | |||
| internal long GetNextFreeDocPrId() | |||
| { | |||
| lock( nextFreeDocPrIdLock ) | |||
| { | |||
| if( nextFreeDocPrId != null ) | |||
| { | |||
| nextFreeDocPrId++; | |||
| return nextFreeDocPrId.Value; | |||
| } | |||
| var xNameBookmarkStart = XName.Get( "bookmarkStart", DocX.w.NamespaceName ); | |||
| var xNameDocPr = XName.Get( "docPr", DocX.wp.NamespaceName ); | |||
| long newDocPrId = 1; | |||
| HashSet<string> existingIds = new HashSet<string>(); | |||
| foreach( var bookmarkId in Xml.Descendants() ) | |||
| { | |||
| if( bookmarkId.Name != xNameBookmarkStart && bookmarkId.Name != xNameDocPr ) | |||
| continue; | |||
| var idAtt = bookmarkId.Attributes().FirstOrDefault( x => x.Name.LocalName == "id" ); | |||
| if( idAtt != null ) | |||
| existingIds.Add( idAtt.Value ); | |||
| } | |||
| while( existingIds.Contains( newDocPrId.ToString() ) ) | |||
| newDocPrId++; | |||
| nextFreeDocPrId = newDocPrId; | |||
| return nextFreeDocPrId.Value; | |||
| } | |||
| } | |||
| #endregion | |||
| #region Private Methods | |||
| @@ -3774,16 +3835,11 @@ namespace Xceed.Words.NET | |||
| { | |||
| using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | |||
| { | |||
| var buffer = new byte[ 32768 ]; | |||
| int read; | |||
| while( ( read = s_read.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||
| { | |||
| s_write.Write( buffer, 0, read ); | |||
| } | |||
| CopyStream( s_read, s_write ); | |||
| } | |||
| } | |||
| var pr = this.PackagePart.CreateRelationship( new Uri( new_uri, UriKind.Relative ), TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| var pr = this.PackagePart.CreateRelationship( new Uri( new_uri, UriKind.Relative ), TargetMode.Internal, RelationshipImage ); | |||
| var new_Id = pr.Id; | |||
| @@ -3965,9 +4021,11 @@ namespace Xceed.Words.NET | |||
| private void merge_numbering( PackagePart remote_pp, PackagePart local_pp, XDocument remote_mainDoc, DocX remote ) | |||
| { | |||
| // Add each remote numbering to this document. | |||
| var abstractNumElement = _numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | |||
| var remote_abstractNums = remote._numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | |||
| int guidd = 0; | |||
| foreach( var an in remote_abstractNums ) | |||
| int guidd = -1; | |||
| foreach( var an in abstractNumElement ) | |||
| { | |||
| var a = an.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | |||
| if( a != null ) | |||
| @@ -3985,8 +4043,10 @@ namespace Xceed.Words.NET | |||
| guidd++; | |||
| var remote_nums = remote._numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | |||
| var numElement = _numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | |||
| int guidd2 = 0; | |||
| foreach( var an in remote_nums ) | |||
| foreach( var an in numElement ) | |||
| { | |||
| var a = an.Attribute( XName.Get( "numId", w.NamespaceName ) ); | |||
| if( a != null ) | |||
| @@ -4005,6 +4065,7 @@ namespace Xceed.Words.NET | |||
| foreach( XElement remote_abstractNum in remote_abstractNums ) | |||
| { | |||
| var currentGuidd2 = guidd2; | |||
| var abstractNumId = remote_abstractNum.Attribute( XName.Get( "abstractNumId", w.NamespaceName ) ); | |||
| if( abstractNumId != null ) | |||
| { | |||
| @@ -4013,38 +4074,51 @@ namespace Xceed.Words.NET | |||
| foreach( XElement remote_num in remote_nums ) | |||
| { | |||
| // in document | |||
| var numIds = remote_mainDoc.Descendants( XName.Get( "numId", w.NamespaceName ) ); | |||
| foreach( var numId in numIds ) | |||
| { | |||
| var attr = numId.Attribute( XName.Get( "val", w.NamespaceName ) ); | |||
| if( attr != null && attr.Value.Equals( remote_num.Attribute( XName.Get( "numId", w.NamespaceName ) ).Value ) ) | |||
| { | |||
| attr.SetValue( guidd2 ); | |||
| attr.SetValue( currentGuidd2 ); | |||
| } | |||
| } | |||
| remote_num.SetAttributeValue( XName.Get( "numId", w.NamespaceName ), guidd2 ); | |||
| remote_num.SetAttributeValue( XName.Get( "numId", w.NamespaceName ), currentGuidd2 ); | |||
| //abstractNumId of this remote_num | |||
| var e = remote_num.Element( XName.Get( "abstractNumId", w.NamespaceName ) ); | |||
| var a2 = e.Attribute( XName.Get( "val", w.NamespaceName ) ); | |||
| if ( a2 != null && a2.Value.Equals( abstractNumIdValue ) ) | |||
| if( a2 != null && a2.Value.Equals( abstractNumIdValue ) ) | |||
| a2.SetValue( guidd ); | |||
| guidd2++; | |||
| currentGuidd2++; | |||
| } | |||
| } | |||
| guidd++; | |||
| } | |||
| var abstractNumElement = _numbering.Root.Elements( XName.Get( "abstractNum", w.NamespaceName ) ); | |||
| if( ( abstractNumElement != null ) && ( abstractNumElement.Count() > 0 ) ) | |||
| if( abstractNumElement != null ) | |||
| { | |||
| abstractNumElement.Last().AddAfterSelf( remote_abstractNums ); | |||
| if( abstractNumElement.Count() > 0 ) | |||
| { | |||
| abstractNumElement.Last().AddAfterSelf( remote_abstractNums ); | |||
| } | |||
| else | |||
| { | |||
| _numbering.Root.Add( remote_abstractNums ); | |||
| } | |||
| } | |||
| var numElement = _numbering.Root.Elements( XName.Get( "num", w.NamespaceName ) ); | |||
| if( ( numElement != null ) && ( numElement.Count() > 0 ) ) | |||
| if( numElement != null ) | |||
| { | |||
| numElement.Last().AddAfterSelf( remote_nums ); | |||
| if( numElement.Count() > 0 ) | |||
| { | |||
| numElement.Last().AddAfterSelf( remote_nums ); | |||
| } | |||
| else | |||
| { | |||
| _numbering.Root.Add( remote_nums ); | |||
| } | |||
| } | |||
| } | |||
| @@ -4222,12 +4296,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| using( Stream s_write = new PackagePartStream( new_pp.GetStream( FileMode.Create ) ) ) | |||
| { | |||
| var buffer = new byte[ 32768 ]; | |||
| int read; | |||
| while( ( read = s_read.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||
| { | |||
| s_write.Write( buffer, 0, read ); | |||
| } | |||
| CopyStream( s_read, s_write ); | |||
| } | |||
| } | |||
| @@ -4365,6 +4434,16 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| private static void CopyStream( Stream input, Stream output, int bufferSize = 32768 ) | |||
| { | |||
| byte[] buffer = new byte[ bufferSize ]; | |||
| int read; | |||
| while( ( read = input.Read( buffer, 0, buffer.Length ) ) > 0 ) | |||
| { | |||
| output.Write( buffer, 0, read ); | |||
| } | |||
| } | |||
| private string GetNextFreeRelationshipID() | |||
| { | |||
| int id = | |||
| @@ -4396,6 +4475,34 @@ namespace Xceed.Words.NET | |||
| return result; | |||
| } | |||
| private Hyperlink AddHyperlink( string text, Uri uri, string anchor ) | |||
| { | |||
| var i = new XElement | |||
| ( | |||
| XName.Get( "hyperlink", w.NamespaceName ), | |||
| new XAttribute( r + "id", string.Empty ), | |||
| new XAttribute( w + "history", "1" ), | |||
| !string.IsNullOrEmpty( anchor ) ? new XAttribute( w + "anchor", anchor ) : null, | |||
| new XElement( XName.Get( "r", w.NamespaceName ), | |||
| new XElement( XName.Get( "rPr", w.NamespaceName ), | |||
| new XElement( XName.Get( "rStyle", w.NamespaceName ), | |||
| new XAttribute( w + "val", "Hyperlink" ) ) ), | |||
| new XElement( XName.Get( "t", w.NamespaceName ), text ) ) | |||
| ); | |||
| var h = new Hyperlink( this, this.PackagePart, i ); | |||
| h.text = text; | |||
| if( uri != null ) | |||
| { | |||
| h.uri = uri; | |||
| } | |||
| this.AddHyperlinkStyleIfNotPresent(); | |||
| return h; | |||
| } | |||
| #endregion | |||
| #region Constructors | |||
| @@ -14,6 +14,7 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Xml.Linq; | |||
| using System.IO.Packaging; | |||
| using System.Collections.ObjectModel; | |||
| @@ -88,6 +89,24 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| public List<Image> Images | |||
| { | |||
| get | |||
| { | |||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ); | |||
| if( imageRelationships.Count() > 0 ) | |||
| { | |||
| return | |||
| ( | |||
| from i in imageRelationships | |||
| select new Image( Document, i ) | |||
| ).ToList(); | |||
| } | |||
| return new List<Image>(); | |||
| } | |||
| } | |||
| #endregion | |||
| #region Constructors | |||
| @@ -34,6 +34,7 @@ namespace Xceed.Words.NET | |||
| private StrikeThrough? _strikethrough; | |||
| private Script? _script; | |||
| private Highlight? _highlight; | |||
| private Color? _shading; | |||
| private double? _size; | |||
| private Color? _fontColor; | |||
| private Color? _underlineColor; | |||
| @@ -45,6 +46,7 @@ namespace Xceed.Words.NET | |||
| private int? _kerning; | |||
| private int? _position; | |||
| private double? _spacing; | |||
| private string _styleName; | |||
| private CultureInfo _language; | |||
| @@ -294,6 +296,33 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Shading color. | |||
| /// </summary> | |||
| public Color? Shading | |||
| { | |||
| get | |||
| { | |||
| return _shading; | |||
| } | |||
| set | |||
| { | |||
| _shading = value; | |||
| } | |||
| } | |||
| public string StyleName | |||
| { | |||
| get | |||
| { | |||
| return _styleName; | |||
| } | |||
| set | |||
| { | |||
| _styleName = value; | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// The Underline style that this formatting applies. | |||
| /// </summary> | |||
| @@ -408,6 +437,11 @@ namespace Xceed.Words.NET | |||
| _rPr.Add( new XElement( XName.Get( "spacing", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _spacing.Value * 20 ) ) ); | |||
| } | |||
| if( !string.IsNullOrEmpty( _styleName ) ) | |||
| { | |||
| _rPr.Add( new XElement( XName.Get( "rStyle", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _styleName ) ) ); | |||
| } | |||
| if( _position.HasValue ) | |||
| { | |||
| _rPr.Add( new XElement( XName.Get( "position", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), _position.Value * 2 ) ) ); | |||
| @@ -429,7 +463,8 @@ namespace Xceed.Words.NET | |||
| ( | |||
| new XElement( XName.Get( "rFonts", DocX.w.NamespaceName ), new XAttribute( XName.Get( "ascii", DocX.w.NamespaceName ), _fontFamily.Name ), | |||
| new XAttribute( XName.Get( "hAnsi", DocX.w.NamespaceName ), _fontFamily.Name ), | |||
| new XAttribute( XName.Get( "cs", DocX.w.NamespaceName ), _fontFamily.Name ) ) | |||
| new XAttribute( XName.Get( "cs", DocX.w.NamespaceName ), _fontFamily.Name ), | |||
| new XAttribute( XName.Get( "eastAsia", DocX.w.NamespaceName ), _fontFamily.Name ) ) | |||
| ); | |||
| } | |||
| @@ -531,6 +566,11 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| if( _shading.HasValue ) | |||
| { | |||
| _rPr.Add( new XElement( XName.Get( "shd", DocX.w.NamespaceName ), new XAttribute( XName.Get( "fill", DocX.w.NamespaceName ), _shading.Value.ToHex() ) ) ); | |||
| } | |||
| if( _capsStyle.HasValue ) | |||
| { | |||
| switch( _capsStyle ) | |||
| @@ -583,6 +623,7 @@ namespace Xceed.Words.NET | |||
| clone.FontFamily = _fontFamily; | |||
| clone.Hidden = _hidden; | |||
| clone.Highlight = _highlight; | |||
| clone.Shading = _shading; | |||
| clone.Italic = _italic; | |||
| if( _kerning.HasValue ) | |||
| { | |||
| @@ -607,6 +648,10 @@ namespace Xceed.Words.NET | |||
| { | |||
| clone.Spacing = _spacing; | |||
| } | |||
| if( !string.IsNullOrEmpty( _styleName ) ) | |||
| { | |||
| clone.StyleName = _styleName; | |||
| } | |||
| clone.StrikeThrough = _strikethrough; | |||
| clone.UnderlineColor = _underlineColor; | |||
| clone.UnderlineStyle = _underlineStyle; | |||
| @@ -615,9 +660,15 @@ namespace Xceed.Words.NET | |||
| } | |||
| public static Formatting Parse( XElement rPr ) | |||
| public static Formatting Parse( XElement rPr, Formatting formatting = null ) | |||
| { | |||
| var formatting = new Formatting(); | |||
| if( formatting == null ) | |||
| { | |||
| formatting = new Formatting(); | |||
| } | |||
| if( rPr == null ) | |||
| return formatting; | |||
| // Build up the Formatting object. | |||
| foreach( XElement option in rPr.Elements() ) | |||
| @@ -634,7 +685,7 @@ namespace Xceed.Words.NET | |||
| formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||
| break; | |||
| case "kern": | |||
| formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||
| formatting.Kerning = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||
| break; | |||
| case "w": | |||
| formatting.PercentageScale = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | |||
| @@ -643,13 +694,18 @@ namespace Xceed.Words.NET | |||
| formatting.Size = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; | |||
| break; | |||
| case "rFonts": | |||
| formatting.FontFamily = new Font(option.GetAttribute(XName.Get("cs", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("ascii", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("eastAsia", DocX.w.NamespaceName))); | |||
| var fontName = option.GetAttribute( XName.Get( "cs", DocX.w.NamespaceName ), null ) | |||
| ?? option.GetAttribute( XName.Get( "ascii", DocX.w.NamespaceName ), null ) | |||
| ?? option.GetAttribute( XName.Get( "hAnsi", DocX.w.NamespaceName ), null ) | |||
| ?? option.GetAttribute( XName.Get( "hint", DocX.w.NamespaceName ), null ) | |||
| ?? option.GetAttribute( XName.Get( "eastAsia", DocX.w.NamespaceName ), null ); | |||
| formatting.FontFamily = new Font( fontName ?? "Calibri" ); | |||
| break; | |||
| case "color": | |||
| try | |||
| { | |||
| var color = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName)); | |||
| formatting.FontColor = System.Drawing.ColorTranslator.FromHtml(string.Format("#{0}", color)); | |||
| formatting.FontColor = ( color == "auto") ? Color.Black : ColorTranslator.FromHtml(string.Format("#{0}", color)); | |||
| } | |||
| catch (Exception) | |||
| { | |||
| @@ -660,7 +716,7 @@ namespace Xceed.Words.NET | |||
| formatting._hidden = true; | |||
| break; | |||
| case "b": | |||
| formatting.Bold = true; | |||
| formatting.Bold = option.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ) ) != "0"; | |||
| break; | |||
| case "i": | |||
| formatting.Italic = true; | |||
| @@ -718,13 +774,45 @@ namespace Xceed.Words.NET | |||
| case "strike": | |||
| formatting.StrikeThrough = NET.StrikeThrough.strike; | |||
| break; | |||
| case "dstrike": | |||
| formatting.StrikeThrough = NET.StrikeThrough.doubleStrike; | |||
| break; | |||
| case "u": | |||
| formatting.UnderlineStyle = HelperFunctions.GetUnderlineStyle(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); | |||
| try | |||
| { | |||
| var color = option.GetAttribute( XName.Get( "color", DocX.w.NamespaceName ) ); | |||
| if( !string.IsNullOrEmpty( color ) ) | |||
| { | |||
| formatting.UnderlineColor = System.Drawing.ColorTranslator.FromHtml( string.Format( "#{0}", color ) ); | |||
| } | |||
| } | |||
| catch( Exception ) | |||
| { | |||
| // ignore | |||
| } | |||
| break; | |||
| case "vertAlign": | |||
| case "vertAlign": //script | |||
| var script = option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null); | |||
| formatting.Script = (Script)Enum.Parse(typeof(Script), script); | |||
| break; | |||
| case "caps": | |||
| formatting.CapsStyle = NET.CapsStyle.caps; | |||
| break; | |||
| case "smallCaps": | |||
| formatting.CapsStyle = NET.CapsStyle.smallCaps; | |||
| break; | |||
| case "shd": | |||
| var fill = option.GetAttribute( XName.Get( "fill", DocX.w.NamespaceName ) ); | |||
| if( !string.IsNullOrEmpty( fill ) ) | |||
| { | |||
| formatting.Shading = System.Drawing.ColorTranslator.FromHtml( string.Format( "#{0}", fill ) ); | |||
| } | |||
| break; | |||
| case "rStyle": | |||
| var style = option.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ), null ); | |||
| formatting.StyleName = style; | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -755,6 +843,9 @@ namespace Xceed.Words.NET | |||
| if( other._highlight != _highlight ) | |||
| return -1; | |||
| if( other._shading != _shading ) | |||
| return -1; | |||
| if( other._size != _size ) | |||
| return -1; | |||
| @@ -788,6 +879,9 @@ namespace Xceed.Words.NET | |||
| if( other._spacing != _spacing ) | |||
| return -1; | |||
| if( other._styleName != _styleName ) | |||
| return -1; | |||
| if( !other._language.Equals(_language) ) | |||
| return -1; | |||
| @@ -102,7 +102,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| get | |||
| { | |||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| var imageRelationships = this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ); | |||
| if( imageRelationships.Count() > 0 ) | |||
| { | |||
| return | |||
| @@ -32,10 +32,19 @@ namespace Xceed.Words.NET | |||
| public const string DOCUMENT_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"; | |||
| public const string TEMPLATE_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml"; | |||
| public const string SETTING_DOCUMENTTYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"; | |||
| public const string MACRO_DOCUMENTTYPE = "application/vnd.ms-word.document.macroEnabled.main+xml"; | |||
| internal static readonly char[] RestrictedXmlCharacters = new char[] | |||
| { | |||
| '\x1','\x2','\x3','\x4','\x5','\x6','\x7','\x8','\xb','\xc','\xe','\xf', | |||
| '\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1e','\x1f', | |||
| '\x7f','\x80','\x81','\x82','\x83','\x84','\x86','\x87','\x88','\x89','\x8a','\x8b','\x8c','\x8d','\x8e','\x8f', | |||
| '\x90','\x91','\x92','\x93','\x94','\x95','\x96','\x97','\x98','\x99','\x9a','\x9b','\x9c','\x9d','\x9e','\x9f' | |||
| }; | |||
| internal static void CreateRelsPackagePart( DocX Document, Uri uri ) | |||
| { | |||
| PackagePart pp = Document._package.CreatePart( uri, "application/vnd.openxmlformats-package.relationships+xml", CompressionOption.Maximum ); | |||
| PackagePart pp = Document._package.CreatePart( uri, DocX.ContentTypeApplicationRelationShipXml, CompressionOption.Maximum ); | |||
| using( TextWriter tw = new StreamWriter( new PackagePartStream( pp.GetStream() ) ) ) | |||
| { | |||
| XDocument d = new XDocument | |||
| @@ -53,7 +62,7 @@ namespace Xceed.Words.NET | |||
| switch( Xml.Name.LocalName ) | |||
| { | |||
| case "tab": | |||
| return 1; | |||
| return (Xml.Parent.Name.LocalName != "tabs" ) ? 1 : 0; | |||
| case "br": | |||
| return 1; | |||
| case "t": | |||
| @@ -130,20 +139,23 @@ namespace Xceed.Words.NET | |||
| return null; | |||
| // e is a w:t element, it must exist inside a w:r element or a w:tabs, lets climb until we find it. | |||
| while( !e.Name.Equals( XName.Get( "r", DocX.w.NamespaceName ) ) && !e.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) ) ) | |||
| while( (e != null) && !e.Name.Equals( XName.Get( "r", DocX.w.NamespaceName ) ) && !e.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) ) ) | |||
| e = e.Parent; | |||
| // e is a w:r element, lets find the rPr element. | |||
| XElement rPr = e.Element( XName.Get( "rPr", DocX.w.NamespaceName ) ); | |||
| FormattedText ft = new FormattedText(); | |||
| ft.text = text; | |||
| ft.index = 0; | |||
| ft.formatting = null; | |||
| // Return text with formatting. | |||
| if( rPr != null ) | |||
| ft.formatting = Formatting.Parse( rPr ); | |||
| if( e != null ) | |||
| { | |||
| // e is a w:r element, lets find the rPr element. | |||
| XElement rPr = e.Element( XName.Get( "rPr", DocX.w.NamespaceName ) ); | |||
| // Return text with formatting. | |||
| if( rPr != null ) | |||
| ft.formatting = Formatting.Parse( rPr ); | |||
| } | |||
| return ft; | |||
| } | |||
| @@ -153,25 +165,15 @@ namespace Xceed.Words.NET | |||
| switch( e.Name.LocalName ) | |||
| { | |||
| case "tab": | |||
| return "\t"; | |||
| // Do not add "\t" for TabStopPositions defined in "tabs". | |||
| return ((e.Parent != null) && e.Parent.Name.Equals( XName.Get( "tabs", DocX.w.NamespaceName ) )) ? "" : "\t"; | |||
| case "br": | |||
| return "\n"; | |||
| case "t": | |||
| goto case "delText"; | |||
| case "delText": | |||
| { | |||
| if( e.Parent != null && e.Parent.Name.LocalName == "r" ) | |||
| { | |||
| XElement run = e.Parent; | |||
| var rPr = run.Elements().FirstOrDefault( a => a.Name.LocalName == "rPr" ); | |||
| if( rPr != null ) | |||
| { | |||
| var caps = rPr.Elements().FirstOrDefault( a => a.Name.LocalName == "caps" ); | |||
| if( caps != null ) | |||
| return e.Value.ToUpper(); | |||
| } | |||
| } | |||
| return e.Value; | |||
| } | |||
| @@ -203,6 +205,13 @@ namespace Xceed.Words.NET | |||
| ); | |||
| } | |||
| internal static PackagePart GetMainDocumentPart( Package package ) | |||
| { | |||
| return package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( MACRO_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||
| } | |||
| internal static PackagePart CreateOrGetSettingsPart( Package package ) | |||
| { | |||
| PackagePart settingsPart; | |||
| @@ -212,8 +221,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| settingsPart = package.CreatePart( settingsUri, HelperFunctions.SETTING_DOCUMENTTYPE, CompressionOption.Maximum ); | |||
| var mainDocPart = package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||
| var mainDocPart = GetMainDocumentPart( package ); | |||
| mainDocPart.CreateRelationship( settingsUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" ); | |||
| @@ -342,11 +350,7 @@ namespace Xceed.Words.NET | |||
| stylesDoc.Save( tw, SaveOptions.None ); | |||
| } | |||
| var mainDocumentPart = package.GetParts().Where | |||
| ( | |||
| p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) | |||
| ).Single(); | |||
| var mainDocumentPart = GetMainDocumentPart( package ); | |||
| mainDocumentPart.CreateRelationship( word_styles.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ); | |||
| return stylesDoc; | |||
| @@ -447,13 +451,13 @@ namespace Xceed.Words.NET | |||
| internal static Paragraph GetFirstParagraphEffectedByInsert( DocX document, int index ) | |||
| { | |||
| // This document contains no Paragraphs and insertion is at index 0 | |||
| if( document._paragraphLookup.Keys.Count() == 0 && index == 0 ) | |||
| if( document.Paragraphs.Count() == 0 && index == 0 ) | |||
| return null; | |||
| foreach( int paragraphEndIndex in document._paragraphLookup.Keys ) | |||
| foreach( Paragraph p in document.Paragraphs ) | |||
| { | |||
| if( paragraphEndIndex >= index ) | |||
| return document._paragraphLookup[ paragraphEndIndex ]; | |||
| if( p._endIndex >= index ) | |||
| return p; | |||
| } | |||
| throw new ArgumentOutOfRangeException(); | |||
| @@ -511,7 +515,8 @@ namespace Xceed.Words.NET | |||
| break; | |||
| default: | |||
| sb.Append( c ); | |||
| if( !RestrictedXmlCharacters.Contains( c ) ) | |||
| sb.Append( c ); | |||
| break; | |||
| } | |||
| @@ -618,8 +623,7 @@ namespace Xceed.Words.NET | |||
| numberingDoc.Save( tw, SaveOptions.None ); | |||
| } | |||
| var mainDocPart = package.GetParts().Single( p => p.ContentType.Equals( DOCUMENT_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) || | |||
| p.ContentType.Equals( TEMPLATE_DOCUMENTTYPE, StringComparison.CurrentCultureIgnoreCase ) ); | |||
| var mainDocPart = GetMainDocumentPart( package ); | |||
| mainDocPart.CreateRelationship(numberingPart.Uri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"); | |||
| return numberingDoc; | |||
| @@ -714,14 +718,16 @@ namespace Xceed.Words.NET | |||
| internal static string GetListItemType( Paragraph p, DocX document ) | |||
| { | |||
| var ilvlNode = p.ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||
| var ilvlValue = ilvlNode.Attribute( DocX.w + "val" ).Value; | |||
| var paragraphNumberPropertiesDescendants = p.ParagraphNumberProperties.Descendants(); | |||
| var ilvlNode = paragraphNumberPropertiesDescendants.FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||
| var ilvlValue = ( ilvlNode != null) ? ilvlNode.Attribute( DocX.w + "val" ).Value : null; | |||
| var numIdNode = p.ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "numId" ); | |||
| var numIdValue = numIdNode.Attribute( DocX.w + "val" ).Value; | |||
| var numIdNode = paragraphNumberPropertiesDescendants.FirstOrDefault( el => el.Name.LocalName == "numId" ); | |||
| var numIdValue = ( numIdNode != null ) ? numIdNode.Attribute( DocX.w + "val" ).Value : null; | |||
| //find num node in numbering | |||
| var numNodes = document._numbering.Descendants().Where( n => n.Name.LocalName == "num" ); | |||
| var documentNumberingDescendants = document._numbering.Descendants(); | |||
| var numNodes = documentNumberingDescendants.Where( n => n.Name.LocalName == "num" ); | |||
| XElement numNode = numNodes.FirstOrDefault( node => node.Attribute( DocX.w + "numId" ).Value.Equals( numIdValue ) ); | |||
| if( numNode != null ) | |||
| @@ -730,7 +736,7 @@ namespace Xceed.Words.NET | |||
| var abstractNumIdNode = numNode.Descendants().First( n => n.Name.LocalName == "abstractNumId" ); | |||
| var abstractNumNodeValue = abstractNumIdNode.Attribute( DocX.w + "val" ).Value; | |||
| var abstractNumNodes = document._numbering.Descendants().Where( n => n.Name.LocalName == "abstractNum" ); | |||
| var abstractNumNodes = documentNumberingDescendants.Where( n => n.Name.LocalName == "abstractNum" ); | |||
| XElement abstractNumNode = abstractNumNodes.FirstOrDefault( node => node.Attribute( DocX.w + "abstractNumId" ).Value.Equals( abstractNumNodeValue ) ); | |||
| //Find lvl node | |||
| @@ -743,13 +749,69 @@ namespace Xceed.Words.NET | |||
| lvlNode = node; | |||
| break; | |||
| } | |||
| else if( ilvlValue == null ) | |||
| { | |||
| var numStyleNode = node.Descendants().FirstOrDefault( n => n.Name.LocalName == "pStyle" ); | |||
| if( ( numStyleNode != null) && numStyleNode.GetAttribute( DocX.w + "val" ).Equals( p.StyleName ) ) | |||
| { | |||
| lvlNode = node; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| var numFmtNode = lvlNode.Descendants().First( n => n.Name.LocalName == "numFmt" ); | |||
| return numFmtNode.Attribute( DocX.w + "val" ).Value; | |||
| if( lvlNode != null ) | |||
| { | |||
| var numFmtNode = lvlNode.Descendants().First( n => n.Name.LocalName == "numFmt" ); | |||
| return numFmtNode.Attribute( DocX.w + "val" ).Value; | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| internal static string GetListItemStartValue( List list, int level ) | |||
| { | |||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||
| //Find lvl node | |||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||
| var startNode = lvlNode.Descendants().First( n => n.Name.LocalName == "start" ); | |||
| return startNode.GetAttribute( DocX.w + "val" ); | |||
| } | |||
| internal static string GetListItemTextFormat( List list, int level ) | |||
| { | |||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||
| //Find lvl node | |||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||
| var textFormatNode = lvlNode.Descendants().First( n => n.Name.LocalName == "lvlText" ); | |||
| return textFormatNode.GetAttribute( DocX.w + "val" ); | |||
| } | |||
| internal static XElement GetListItemAlignment( List list, int level ) | |||
| { | |||
| var abstractNumElement = list.GetAbstractNum( list.NumId ); | |||
| //Find lvl node | |||
| var lvlNodes = abstractNumElement.Descendants().Where( n => n.Name.LocalName == "lvl" ); | |||
| var lvlNode = lvlNodes.FirstOrDefault( n => n.GetAttribute( DocX.w + "ilvl" ).Equals( level.ToString() ) ); | |||
| var pPr = lvlNode.Descendants().FirstOrDefault( n => n.Name.LocalName == "pPr" ); | |||
| if( pPr != null ) | |||
| { | |||
| var ind = pPr.Descendants().FirstOrDefault( n => n.Name.LocalName == "ind" ); | |||
| if( ind != null ) | |||
| { | |||
| return ind; | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| } | |||
| @@ -148,7 +148,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| get | |||
| { | |||
| if( type == 0 && id != String.Empty ) | |||
| if( (type == 0) && !String.IsNullOrEmpty(id) ) | |||
| { | |||
| var r = this.PackagePart.GetRelationship( id ); | |||
| return r.TargetUri; | |||
| @@ -189,7 +189,11 @@ namespace Xceed.Words.NET | |||
| internal Hyperlink( DocX document, PackagePart mainPart, XElement i ) : base( document, i ) | |||
| { | |||
| this.type = 0; | |||
| this.id = i.Attribute( XName.Get( "id", DocX.r.NamespaceName ) ).Value; | |||
| var idAttribute = i.Attribute( XName.Get( "id", DocX.r.NamespaceName ) ); | |||
| if( idAttribute != null ) | |||
| { | |||
| this.id = idAttribute.Value; | |||
| } | |||
| StringBuilder sb = new StringBuilder(); | |||
| HelperFunctions.GetTextRecursive( i, ref sb ); | |||
| @@ -204,8 +208,10 @@ namespace Xceed.Words.NET | |||
| try | |||
| { | |||
| int start = instrText.Value.IndexOf( "HYPERLINK \"" ) + "HYPERLINK \"".Length; | |||
| int end = instrText.Value.IndexOf( "\"", start ); | |||
| int start = instrText.Value.IndexOf( "HYPERLINK \"" ); | |||
| if( start != -1 ) | |||
| start += "HYPERLINK \"".Length; | |||
| int end = instrText.Value.IndexOf( "\"", Math.Max( 0, start )); | |||
| if( start != -1 && end != -1 ) | |||
| { | |||
| this.uri = new Uri( instrText.Value.Substring( start, end - start ), UriKind.Absolute ); | |||
| @@ -189,8 +189,8 @@ namespace Xceed.Words.NET | |||
| internal XElement GetAbstractNum( int numId ) | |||
| { | |||
| var num = Document._numbering.Descendants().First( d => d.Name.LocalName == "num" && d.GetAttribute( DocX.w + "numId" ).Equals( numId.ToString() ) ); | |||
| var abstractNumId = num.Descendants().First( d => d.Name.LocalName == "abstractNumId" ); | |||
| return Document._numbering.Descendants().First( d => d.Name.LocalName == "abstractNum" && d.GetAttribute( "abstractNumId" ).Equals( abstractNumId.Value ) ); | |||
| var abstractNumId = num.Descendants().First( d => d.Name.LocalName == "abstractNumId" ).GetAttribute( DocX.w + "val" ); | |||
| return Document._numbering.Descendants().First( d => d.Name.LocalName == "abstractNum" && d.GetAttribute( DocX.w + "abstractNumId" ).Equals( abstractNumId ) ); | |||
| } | |||
| #endregion | |||
| @@ -24,7 +24,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| #region Private Members | |||
| private static readonly Mutex _mutex = new Mutex( false ); | |||
| private static readonly object lockObject = new object(); | |||
| private readonly Stream _stream; | |||
| #endregion | |||
| @@ -106,16 +106,18 @@ namespace Xceed.Words.NET | |||
| public override void Write( byte[] buffer, int offset, int count ) | |||
| { | |||
| _mutex.WaitOne( Timeout.Infinite, false ); | |||
| _stream.Write( buffer, offset, count ); | |||
| _mutex.ReleaseMutex(); | |||
| lock(lockObject) | |||
| { | |||
| _stream.Write( buffer, offset, count ); | |||
| } | |||
| } | |||
| public override void Flush() | |||
| { | |||
| _mutex.WaitOne( Timeout.Infinite, false ); | |||
| _stream.Flush(); | |||
| _mutex.ReleaseMutex(); | |||
| lock(lockObject) | |||
| { | |||
| _stream.Flush(); | |||
| } | |||
| } | |||
| public override void Close() | |||
| @@ -38,6 +38,8 @@ namespace Xceed.Words.NET | |||
| internal int _startIndex, _endIndex; | |||
| internal List<XElement> _styles = new List<XElement>(); | |||
| internal const float DefaultLineSpacing = 1.1f * 20.0f; | |||
| #endregion | |||
| #region Private Members | |||
| @@ -60,10 +62,12 @@ namespace Xceed.Words.NET | |||
| { | |||
| get; set; | |||
| } | |||
| private bool? IsListItemBacker | |||
| { | |||
| get; set; | |||
| } | |||
| private int? IndentLevelBacker | |||
| { | |||
| get; set; | |||
| @@ -107,6 +111,11 @@ namespace Xceed.Words.NET | |||
| { | |||
| get | |||
| { | |||
| if( Xml == null ) | |||
| { | |||
| return new List<Picture>(); | |||
| } | |||
| var pictures = this.GetPictures( "drawing", "blip", "embed" ); | |||
| var shapes = this.GetPictures( "pict", "imagedata", "id" ); | |||
| @@ -335,7 +344,7 @@ namespace Xceed.Words.NET | |||
| XAttribute firstLine = ind.Attribute( XName.Get( "firstLine", DocX.w.NamespaceName ) ); | |||
| if( firstLine != null ) | |||
| return float.Parse( firstLine.Value ); | |||
| return float.Parse( firstLine.Value ) / 570f; | |||
| return 0.0f; | |||
| } | |||
| @@ -413,7 +422,8 @@ namespace Xceed.Words.NET | |||
| firstLine.Remove(); | |||
| } | |||
| var indentation = ( ( indentationHanging / 0.1 ) * 57 ).ToString(); | |||
| var indentationValue = ( ( indentationHanging / 0.1 ) * 57 ); | |||
| var indentation = indentationValue.ToString(); | |||
| var hanging = ind.Attribute( XName.Get( "hanging", DocX.w.NamespaceName ) ); | |||
| if( hanging != null ) | |||
| { | |||
| @@ -423,6 +433,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| ind.Add( new XAttribute( XName.Get( "hanging", DocX.w.NamespaceName ), indentation ) ); | |||
| } | |||
| IndentationBefore = indentationHanging; | |||
| } | |||
| } | |||
| } | |||
| @@ -470,7 +481,7 @@ namespace Xceed.Words.NET | |||
| GetOrCreate_pPr(); | |||
| var ind = GetOrCreate_pPr_ind(); | |||
| var indentation = ( ( indentationBefore / 0.1 ) * 57 ).ToString(CultureInfo.GetCultureInfo("en-GB")); | |||
| var indentation = ( ( indentationBefore / 0.1 ) * 57 ).ToString(); | |||
| var left = ind.Attribute( XName.Get( "left", DocX.w.NamespaceName ) ); | |||
| if( left != null ) | |||
| @@ -518,7 +529,7 @@ namespace Xceed.Words.NET | |||
| var right = ind.Attribute( XName.Get( "right", DocX.w.NamespaceName ) ); | |||
| if( right != null ) | |||
| return float.Parse( right.Value ); | |||
| return float.Parse( right.Value ) / 570f; | |||
| return 0.0f; | |||
| } | |||
| @@ -680,7 +691,7 @@ namespace Xceed.Words.NET | |||
| XElement spacing = pPr.Element( XName.Get( "spacing", DocX.w.NamespaceName ) ); | |||
| if( spacing != null ) | |||
| { | |||
| { | |||
| XAttribute line = spacing.Attribute( XName.Get( "line", DocX.w.NamespaceName ) ); | |||
| if( line != null ) | |||
| { | |||
| @@ -691,7 +702,7 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| return 1.1f * 20.0f; | |||
| return Paragraph.DefaultLineSpacing; | |||
| } | |||
| set | |||
| @@ -747,7 +758,7 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| return 10.0f; | |||
| return 0.0f; | |||
| } | |||
| @@ -786,7 +797,12 @@ namespace Xceed.Words.NET | |||
| { | |||
| if( !IsListItem ) | |||
| return null; | |||
| return IndentLevelBacker ?? ( IndentLevelBacker = int.Parse( ParagraphNumberProperties.Descendants().First( el => el.Name.LocalName == "ilvl" ).GetAttribute( DocX.w + "val" ) ) ); | |||
| if( IndentLevelBacker != null ) | |||
| return IndentLevelBacker; | |||
| var ilvl = ParagraphNumberProperties.Descendants().FirstOrDefault( el => el.Name.LocalName == "ilvl" ); | |||
| return IndentLevelBacker = ( ilvl != null ) ? int.Parse( ilvl.GetAttribute( DocX.w + "val" ) ) : 0; | |||
| } | |||
| } | |||
| @@ -990,6 +1006,32 @@ namespace Xceed.Words.NET | |||
| return base.InsertTableAfterSelf( rowCount, columnCount ); | |||
| } | |||
| /// <summary> | |||
| /// Replaces an existing Picture with a new Picture. | |||
| /// </summary> | |||
| /// <param name="toBeReplaced">The picture object to be replaced.</param> | |||
| /// <param name="replaceWith">The picture object that should be inserted instead of <paramref name="toBeReplaced"/>.</param> | |||
| /// <returns>The new <see cref="Picture"/> object that replaces the old one.</returns> | |||
| public Picture ReplacePicture( Picture toBeReplaced, Picture replaceWith ) | |||
| { | |||
| var document = this.Document; | |||
| var newDocPrId = document.GetNextFreeDocPrId(); | |||
| var xml = XElement.Parse( toBeReplaced.Xml.ToString() ); | |||
| foreach( var element in xml.Descendants( XName.Get( "docPr", DocX.wp.NamespaceName ) ) ) | |||
| element.SetAttributeValue( XName.Get( "id" ), newDocPrId ); | |||
| foreach( var element in xml.Descendants( XName.Get( "blip", DocX.a.NamespaceName ) ) ) | |||
| element.SetAttributeValue( XName.Get( "embed", DocX.r.NamespaceName ), replaceWith.Id ); | |||
| var replacePicture = new Picture( document, xml, new Image( document, this.PackagePart.GetRelationship( replaceWith.Id ) ) ); | |||
| this.AppendPicture( replacePicture ); | |||
| toBeReplaced.Remove(); | |||
| return replacePicture; | |||
| } | |||
| /// <summary> | |||
| /// Insert a Paragraph before this Paragraph, this Paragraph may have come from the same or another document. | |||
| /// </summary> | |||
| @@ -1204,7 +1246,7 @@ namespace Xceed.Words.NET | |||
| XElement h_xml; | |||
| if( index == 0 ) | |||
| { | |||
| // Add this hyperlink as the last element. | |||
| // Add this hyperlink as the first element. | |||
| Xml.AddFirst( h.Xml ); | |||
| // Extract the picture back out of the DOM. | |||
| @@ -1246,6 +1288,7 @@ namespace Xceed.Words.NET | |||
| h_xml.SetAttributeValue( DocX.r + "id", Id ); | |||
| } | |||
| this._runs = Xml.Elements().Last().Elements( XName.Get( "r", DocX.w.NamespaceName ) ).ToList(); | |||
| return this; | |||
| } | |||
| @@ -1498,46 +1541,46 @@ namespace Xceed.Words.NET | |||
| // return newPicture; | |||
| //} | |||
| /// <summary> | |||
| /// Insert a Picture at the end of this paragraph. | |||
| /// </summary> | |||
| /// <param name="description">A string to describe this Picture.</param> | |||
| /// <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||
| /// <param name="name">The name of this image.</param> | |||
| /// <returns>A Picture.</returns> | |||
| /// <example> | |||
| /// <code> | |||
| /// // Create a document using a relative filename. | |||
| /// using (DocX document = DocX.Create(@"Test.docx")) | |||
| /// { | |||
| /// // Add a new Paragraph to this document. | |||
| /// Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||
| /// | |||
| /// // Add an Image to this document. | |||
| /// Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||
| /// | |||
| /// // Insert pic at the end of Paragraph p. | |||
| /// Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked."); | |||
| /// | |||
| /// // Rotate the Picture clockwise by 30 degrees. | |||
| /// pic.Rotation = 30; | |||
| /// | |||
| /// // Resize the Picture. | |||
| /// pic.Width = 400; | |||
| /// pic.Height = 300; | |||
| /// | |||
| /// // Set the shape of this Picture to be a cube. | |||
| /// pic.SetPictureShape(BasicShapes.cube); | |||
| /// | |||
| /// // Flip the Picture Horizontally. | |||
| /// pic.FlipHorizontal = true; | |||
| /// | |||
| /// // Save all changes made to this document. | |||
| /// document.Save(); | |||
| /// }// Release this document from memory. | |||
| /// </code> | |||
| /// </example> | |||
| /// Removed to simplify the API. | |||
| // <summary> | |||
| // Insert a Picture at the end of this paragraph. | |||
| // </summary> | |||
| // <param name="description">A string to describe this Picture.</param> | |||
| // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||
| // <param name="name">The name of this image.</param> | |||
| // <returns>A Picture.</returns> | |||
| // <example> | |||
| // <code> | |||
| // // Create a document using a relative filename. | |||
| // using (DocX document = DocX.Create(@"Test.docx")) | |||
| // { | |||
| // // Add a new Paragraph to this document. | |||
| // Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||
| // | |||
| // // Add an Image to this document. | |||
| // Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||
| // | |||
| // // Insert pic at the end of Paragraph p. | |||
| // Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked."); | |||
| // | |||
| // // Rotate the Picture clockwise by 30 degrees. | |||
| // pic.Rotation = 30; | |||
| // | |||
| // // Resize the Picture. | |||
| // pic.Width = 400; | |||
| // pic.Height = 300; | |||
| // | |||
| // // Set the shape of this Picture to be a cube. | |||
| // pic.SetPictureShape(BasicShapes.cube); | |||
| // | |||
| // // Flip the Picture Horizontally. | |||
| // pic.FlipHorizontal = true; | |||
| // | |||
| // // Save all changes made to this document. | |||
| // document.Save(); | |||
| // }// Release this document from memory. | |||
| // </code> | |||
| // </example> | |||
| // Removed to simplify the API. | |||
| //public Picture InsertPicture(string imageID, string name, string description) | |||
| //{ | |||
| // Picture p = CreatePicture(Document, imageID, name, description); | |||
| @@ -1581,47 +1624,47 @@ namespace Xceed.Words.NET | |||
| // return p; | |||
| //} | |||
| /// <summary> | |||
| /// Insert a Picture into this Paragraph at a specified index. | |||
| /// </summary> | |||
| /// <param name="description">A string to describe this Picture.</param> | |||
| /// <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||
| /// <param name="name">The name of this image.</param> | |||
| /// <param name="index">The index to insert this Picture at.</param> | |||
| /// <returns>A Picture.</returns> | |||
| /// <example> | |||
| /// <code> | |||
| /// // Create a document using a relative filename. | |||
| /// using (DocX document = DocX.Create(@"Test.docx")) | |||
| /// { | |||
| /// // Add a new Paragraph to this document. | |||
| /// Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||
| /// | |||
| /// // Add an Image to this document. | |||
| /// Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||
| /// | |||
| /// // Insert pic at the start of Paragraph p. | |||
| /// Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked."); | |||
| /// | |||
| /// // Rotate the Picture clockwise by 30 degrees. | |||
| /// pic.Rotation = 30; | |||
| /// | |||
| /// // Resize the Picture. | |||
| /// pic.Width = 400; | |||
| /// pic.Height = 300; | |||
| /// | |||
| /// // Set the shape of this Picture to be a cube. | |||
| /// pic.SetPictureShape(BasicShapes.cube); | |||
| /// | |||
| /// // Flip the Picture Horizontally. | |||
| /// pic.FlipHorizontal = true; | |||
| /// | |||
| /// // Save all changes made to this document. | |||
| /// document.Save(); | |||
| /// }// Release this document from memory. | |||
| /// </code> | |||
| /// </example> | |||
| /// Removed to simplify API. | |||
| // <summary> | |||
| // Insert a Picture into this Paragraph at a specified index. | |||
| // </summary> | |||
| // <param name="description">A string to describe this Picture.</param> | |||
| // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> | |||
| // <param name="name">The name of this image.</param> | |||
| // <param name="index">The index to insert this Picture at.</param> | |||
| // <returns>A Picture.</returns> | |||
| // <example> | |||
| // <code> | |||
| // // Create a document using a relative filename. | |||
| // using (DocX document = DocX.Create(@"Test.docx")) | |||
| // { | |||
| // // Add a new Paragraph to this document. | |||
| // Paragraph p = document.InsertParagraph("Here is Picture 1", false); | |||
| // | |||
| // // Add an Image to this document. | |||
| // Xceed.Words.NET.Image img = document.AddImage(@"Image.jpg"); | |||
| // | |||
| // // Insert pic at the start of Paragraph p. | |||
| // Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked."); | |||
| // | |||
| // // Rotate the Picture clockwise by 30 degrees. | |||
| // pic.Rotation = 30; | |||
| // | |||
| // // Resize the Picture. | |||
| // pic.Width = 400; | |||
| // pic.Height = 300; | |||
| // | |||
| // // Set the shape of this Picture to be a cube. | |||
| // pic.SetPictureShape(BasicShapes.cube); | |||
| // | |||
| // // Flip the Picture Horizontally. | |||
| // pic.FlipHorizontal = true; | |||
| // | |||
| // // Save all changes made to this document. | |||
| // document.Save(); | |||
| // }// Release this document from memory. | |||
| // </code> | |||
| // </example> | |||
| // Removed to simplify API. | |||
| //public Picture InsertPicture(int index, string imageID, string name, string description) | |||
| //{ | |||
| // Picture picture = CreatePicture(Document, imageID, name, description); | |||
| @@ -1703,23 +1746,13 @@ namespace Xceed.Words.NET | |||
| /// </code> | |||
| /// </example> | |||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||
| /// <param name="value">The System.String to insert.</param> | |||
| /// <param name="trackChanges">Flag this insert as a change.</param> | |||
| /// <param name="formatting">The text formatting.</param> | |||
| public void InsertText( string value, bool trackChanges = false, Formatting formatting = null ) | |||
| { | |||
| // Default values for optional parameters must be compile time constants. | |||
| // Would have like to write 'public void InsertText(string value, bool trackChanges = false, Formatting formatting = new Formatting()) | |||
| if( formatting == null ) | |||
| { | |||
| formatting = new Formatting(); | |||
| } | |||
| var newRuns = HelperFunctions.FormatInput( value, formatting.Xml ); | |||
| Xml.Add( newRuns ); | |||
| HelperFunctions.RenumberIDs( Document ); | |||
| this.InsertText( this.Text.Length, value, trackChanges, formatting ); | |||
| } | |||
| /// <summary> | |||
| @@ -1771,7 +1804,7 @@ namespace Xceed.Words.NET | |||
| /// </code> | |||
| /// </example> | |||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||
| /// <param name="index">The index position of the insertion.</param> | |||
| /// <param name="value">The System.String to insert.</param> | |||
| /// <param name="trackChanges">Flag this insert as a change.</param> | |||
| @@ -1889,22 +1922,16 @@ namespace Xceed.Words.NET | |||
| { | |||
| insert = CreateEdit( EditType.ins, insert_datetime, newRuns ); | |||
| } | |||
| // Special case to deal with Page Number elements. | |||
| //if (parentElement.Name.LocalName.Equals("fldSimple")) | |||
| // parentElement.AddBeforeSelf(insert); | |||
| else | |||
| { | |||
| // Split this run at the point you want to insert | |||
| var splitRun = Run.SplitRun( run, index ); | |||
| // Replace the origional run | |||
| run.Xml.ReplaceWith | |||
| ( | |||
| splitRun[ 0 ], | |||
| insert, | |||
| splitRun[ 1 ] | |||
| ); | |||
| } | |||
| // Split this run at the point you want to insert | |||
| var splitRun = Run.SplitRun( run, index ); | |||
| // Replace the origional run | |||
| run.Xml.ReplaceWith | |||
| ( | |||
| splitRun[ 0 ], | |||
| insert, | |||
| splitRun[ 1 ] | |||
| ); | |||
| break; | |||
| } | |||
| @@ -2025,6 +2052,10 @@ namespace Xceed.Words.NET | |||
| if( format.Highlight.HasValue ) | |||
| Highlight( format.Highlight.Value ); | |||
| // Shading | |||
| if( format.Shading.HasValue ) | |||
| Shading( format.Shading.Value ); | |||
| // Italic | |||
| if( format.Italic.HasValue && format.Italic.Value ) | |||
| Italic(); | |||
| @@ -2358,6 +2389,72 @@ namespace Xceed.Words.NET | |||
| return this; | |||
| } | |||
| /// <summary> | |||
| /// Add a new TabStopPosition in the current paragraph. | |||
| /// </summary> | |||
| /// <param name="alignment">Specifies the alignment of the Tab stop.</param> | |||
| /// <param name="position">Specifies the horizontal position of the tab stop.</param> | |||
| /// <param name="leader">Specifies the character used to fill in the space created by a tab.</param> | |||
| /// <returns>The modified Paragraph.</returns> | |||
| public Paragraph InsertTabStopPosition( Alignment alignment, float position, TabStopPositionLeader leader = TabStopPositionLeader.none ) | |||
| { | |||
| var pPr = GetOrCreate_pPr(); | |||
| var tabs = pPr.Element( XName.Get( "tabs", DocX.w.NamespaceName ) ); | |||
| if( tabs == null ) | |||
| { | |||
| tabs = new XElement( XName.Get( "tabs", DocX.w.NamespaceName ) ); | |||
| pPr.Add( tabs ); | |||
| } | |||
| var newTab = new XElement( XName.Get( "tab", DocX.w.NamespaceName ) ); | |||
| // Alignement | |||
| var alignmentString = string.Empty; | |||
| switch( alignment ) | |||
| { | |||
| case Alignment.left: | |||
| alignmentString = "left"; | |||
| break; | |||
| case Alignment.right: | |||
| alignmentString = "right"; | |||
| break; | |||
| case Alignment.center: | |||
| alignmentString = "center"; | |||
| break; | |||
| default: | |||
| throw new ArgumentException( "alignment", "Value must be left, right or center." ); | |||
| } | |||
| newTab.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), alignmentString ); | |||
| // Position | |||
| var posValue = position * 20.0f; | |||
| newTab.SetAttributeValue( XName.Get( "pos", DocX.w.NamespaceName ), posValue.ToString() ); | |||
| //Leader | |||
| var leaderString = string.Empty; | |||
| switch( leader ) | |||
| { | |||
| case TabStopPositionLeader.none: | |||
| leaderString = "none"; | |||
| break; | |||
| case TabStopPositionLeader.dot: | |||
| leaderString = "dot"; | |||
| break; | |||
| case TabStopPositionLeader.underscore: | |||
| leaderString = "underscore"; | |||
| break; | |||
| case TabStopPositionLeader.hyphen: | |||
| leaderString = "hyphen"; | |||
| break; | |||
| default: | |||
| throw new ArgumentException( "leader", "Unknown leader character." ); | |||
| } | |||
| newTab.SetAttributeValue( XName.Get( "leader", DocX.w.NamespaceName ), leaderString ); | |||
| tabs.Add( newTab ); | |||
| return this; | |||
| } | |||
| /// <summary> | |||
| /// Append text on a new line to this Paragraph. | |||
| /// </summary> | |||
| @@ -2748,6 +2845,38 @@ namespace Xceed.Words.NET | |||
| return this; | |||
| } | |||
| public Paragraph Shading( Color shading, ShadingType shadingType = ShadingType.Text ) | |||
| { | |||
| // Add to run | |||
| if( shadingType == ShadingType.Text ) | |||
| { | |||
| this.ApplyTextFormattingProperty( XName.Get( "shd", DocX.w.NamespaceName ), string.Empty, new XAttribute( XName.Get( "fill", DocX.w.NamespaceName ), shading.ToHex() ) ); | |||
| } | |||
| // Add to paragraph | |||
| else | |||
| { | |||
| var pPr = GetOrCreate_pPr(); | |||
| var shd = pPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); | |||
| if( shd == null ) | |||
| { | |||
| shd = new XElement( XName.Get( "shd", DocX.w.NamespaceName ) ); | |||
| pPr.Add( shd ); | |||
| } | |||
| var fillAttribute = shd.Attribute( XName.Get( "fill", DocX.w.NamespaceName ) ); | |||
| if( fillAttribute == null ) | |||
| { | |||
| shd.SetAttributeValue( XName.Get( "fill", DocX.w.NamespaceName ), shading.ToHex() ); | |||
| } | |||
| else | |||
| { | |||
| fillAttribute.SetValue( shading.ToHex() ); | |||
| } | |||
| } | |||
| return this; | |||
| } | |||
| /// <summary> | |||
| /// For use with Append() and AppendLine() | |||
| /// </summary> | |||
| @@ -3044,6 +3173,7 @@ namespace Xceed.Words.NET | |||
| /// </summary> | |||
| /// <param name="cp">The custom property to display.</param> | |||
| /// <param name="f">The formatting to use for this text.</param> | |||
| /// <param name="trackChanges"></param> | |||
| /// <example> | |||
| /// Create, add and display a custom property in a document. | |||
| /// <code> | |||
| @@ -3084,7 +3214,7 @@ namespace Xceed.Words.NET | |||
| /// Insert a field of type document property, this field will display the custom property cp, at the end of this paragraph. | |||
| /// </summary> | |||
| /// <param name="cp">The custom property to display.</param> | |||
| /// <param name="trackChanges"></param> | |||
| /// <param name="trackChanges">if the changes are tracked.</param> | |||
| /// <param name="f">The formatting to use for this text.</param> | |||
| /// <example> | |||
| /// Create, add and display a custom property in a document. | |||
| @@ -3166,7 +3296,8 @@ namespace Xceed.Words.NET | |||
| /// <param name="index">The position to begin deleting characters.</param> | |||
| /// <param name="count">The number of characters to delete</param> | |||
| /// <param name="trackChanges">Track changes</param> | |||
| public void RemoveText( int index, int count, bool trackChanges = false ) | |||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||
| public void RemoveText( int index, int count, bool trackChanges = false, bool removeEmptyParagraph = true ) | |||
| { | |||
| // Timestamp to mark the start of insert | |||
| var now = DateTime.Now; | |||
| @@ -3190,7 +3321,7 @@ namespace Xceed.Words.NET | |||
| var min = Math.Min( count - processed, run.Xml.ElementsAfterSelf().Sum( e => GetElementTextLength( e ) ) ); | |||
| var splitEditAfter = this.SplitEdit( parentElement, index + min, EditType.del ); | |||
| var temp = this.SplitEdit( splitEditBefore[ 1 ], index + min, EditType.del )[ 0 ]; | |||
| var temp = this.SplitEdit( splitEditBefore[ 1 ], index + min, EditType.del )[ 1 ]; | |||
| var middle = Paragraph.CreateEdit( EditType.del, remove_datetime, temp.Elements() ); | |||
| processed += Paragraph.GetElementTextLength( middle as XElement ); | |||
| @@ -3199,7 +3330,7 @@ namespace Xceed.Words.NET | |||
| middle = null; | |||
| } | |||
| parentElement.ReplaceWith( splitEditBefore[ 0 ], middle, splitEditAfter[ 1 ] ); | |||
| parentElement.ReplaceWith( splitEditBefore[ 0 ], middle, splitEditAfter[ 0 ] ); | |||
| processed += Paragraph.GetElementTextLength( middle as XElement ); | |||
| break; | |||
| @@ -3238,18 +3369,19 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| // If after this remove the parent element is empty, remove it. | |||
| if( Paragraph.GetElementTextLength( parentElement ) == 0 ) | |||
| // In some cases, removing an empty paragraph is allowed | |||
| var canRemove = removeEmptyParagraph && GetElementTextLength( parentElement ) == 0; | |||
| if( parentElement.Parent != null ) | |||
| { | |||
| if( ( parentElement.Parent != null ) && ( parentElement.Parent.Name.LocalName != "tc" ) ) | |||
| { | |||
| // Need to make sure there is no drawing element within the parent element. | |||
| // Picture elements contain no text length but they are still content. | |||
| if( parentElement.Descendants( XName.Get( "drawing", DocX.w.NamespaceName ) ).Count() == 0 ) | |||
| { | |||
| parentElement.Remove(); | |||
| } | |||
| } | |||
| // Need to make sure there is another paragraph in the parent cell | |||
| canRemove &= parentElement.Parent.Name.LocalName == "tc" && parentElement.Parent.Elements( XName.Get( "p", DocX.w.NamespaceName ) ).Count() > 1; | |||
| // Need to make sure there is no drawing element within the parent element. | |||
| // Picture elements contain no text length but they are still content. | |||
| canRemove &= parentElement.Descendants( XName.Get( "drawing", DocX.w.NamespaceName ) ).Count() == 0; | |||
| if( canRemove ) | |||
| parentElement.Remove(); | |||
| } | |||
| } | |||
| while( processed < count ); | |||
| @@ -3326,7 +3458,7 @@ namespace Xceed.Words.NET | |||
| /// }// Release this document from memory. | |||
| /// </code> | |||
| /// </example> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, int, bool, bool)"/> | |||
| /// <seealso cref="Paragraph.RemoveText(int, bool)"/> | |||
| /// <seealso cref="Paragraph.InsertText(int, string, bool, Formatting)"/> | |||
| /// <seealso cref="Paragraph.InsertText(string, bool, Formatting)"/> | |||
| @@ -3339,6 +3471,7 @@ namespace Xceed.Words.NET | |||
| /// <param name="fo">How should formatting be matched?</param> | |||
| /// <param name="escapeRegEx">True if the oldValue needs to be escaped, otherwise false. If it represents a valid RegEx pattern this should be false.</param> | |||
| /// <param name="useRegExSubstitutions">True if RegEx-like replace should be performed, i.e. if newValue contains RegEx substitutions. Does not perform named-group substitutions (only numbered groups).</param> | |||
| /// <param name="removeEmptyParagraph">Remove empty paragraph</param> | |||
| public void ReplaceText( string searchValue, | |||
| string newValue, | |||
| bool trackChanges = false, | |||
| @@ -3347,7 +3480,8 @@ namespace Xceed.Words.NET | |||
| Formatting matchFormatting = null, | |||
| MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, | |||
| bool escapeRegEx = true, | |||
| bool useRegExSubstitutions = false ) | |||
| bool useRegExSubstitutions = false, | |||
| bool removeEmptyParagraph = true ) | |||
| { | |||
| var mc = Regex.Matches( this.Text, escapeRegEx ? Regex.Escape( searchValue ) : searchValue, options ); | |||
| @@ -3430,13 +3564,13 @@ namespace Xceed.Words.NET | |||
| } | |||
| if( m.Length > 0 ) | |||
| { | |||
| this.RemoveText( m.Index, m.Length, trackChanges ); | |||
| this.RemoveText( m.Index, m.Length, trackChanges, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| public void ReplaceText( string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch ) | |||
| public void ReplaceText( string findPattern, Func<string, string> regexMatchHandler, bool trackChanges = false, RegexOptions options = RegexOptions.None, Formatting newFormatting = null, Formatting matchFormatting = null, MatchFormattingOptions fo = MatchFormattingOptions.SubsetMatch, bool removeEmptyParagraph = true ) | |||
| { | |||
| var matchCol = Regex.Matches( this.Text, findPattern, options ); | |||
| var reversedMatchCol = matchCol.Cast<Match>().Reverse(); | |||
| @@ -3474,7 +3608,7 @@ namespace Xceed.Words.NET | |||
| { | |||
| var newValue = regexMatchHandler.Invoke( match.Groups[ 1 ].Value ); | |||
| this.InsertText( match.Index + match.Value.Length, newValue, trackChanges, newFormatting ); | |||
| this.RemoveText( match.Index, match.Value.Length, trackChanges ); | |||
| this.RemoveText( match.Index, match.Value.Length, trackChanges, removeEmptyParagraph ); | |||
| } | |||
| } | |||
| } | |||
| @@ -4040,10 +4174,10 @@ namespace Xceed.Words.NET | |||
| tXElement.Value = text; | |||
| } | |||
| public void InsertHorizontalLine( string lineType = "single", int size = 6, int space = 1, string color = "auto" ) | |||
| public void InsertHorizontalLine( HorizontalBorderPosition position = HorizontalBorderPosition.bottom, string lineType = "single", int size = 6, int space = 1, string color = "auto" ) | |||
| { | |||
| var pBrXName = XName.Get( "pBdr", DocX.w.NamespaceName ); | |||
| var bottomXName = XName.Get( "bottom", DocX.w.NamespaceName ); | |||
| var borderPositionXName = ( position == HorizontalBorderPosition.bottom) ? XName.Get( "bottom", DocX.w.NamespaceName ) : XName.Get( "top", DocX.w.NamespaceName ); | |||
| var pPr = this.GetOrCreate_pPr(); | |||
| var pBdr = pPr.Element( pBrXName ); | |||
| @@ -4054,14 +4188,14 @@ namespace Xceed.Words.NET | |||
| pBdr = pPr.Element( pBrXName ); | |||
| //Add bottom | |||
| pBdr.Add( new XElement( bottomXName ) ); | |||
| var bottom = pBdr.Element( bottomXName ); | |||
| pBdr.Add( new XElement( borderPositionXName ) ); | |||
| var border = pBdr.Element( borderPositionXName ); | |||
| //Set bottom's attribute | |||
| bottom.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), lineType ); | |||
| bottom.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), size.ToString() ); | |||
| bottom.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), space.ToString() ); | |||
| bottom.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), color ); | |||
| //Set border's attribute | |||
| border.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), lineType ); | |||
| border.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), size.ToString() ); | |||
| border.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), space.ToString() ); | |||
| border.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), color ); | |||
| } | |||
| } | |||
| @@ -4131,6 +4265,13 @@ namespace Xceed.Words.NET | |||
| RemoveHyperlinkRecursive( e, index, ref count, ref found ); | |||
| } | |||
| internal void ResetBackers() | |||
| { | |||
| ParagraphNumberPropertiesBacker = null; | |||
| IsListItemBacker = null; | |||
| IndentLevelBacker = null; | |||
| } | |||
| /// <summary> | |||
| /// Create a new Picture. | |||
| /// </summary> | |||
| @@ -4144,45 +4285,17 @@ namespace Xceed.Words.NET | |||
| { | |||
| var part = document._package.GetPart( document.PackagePart.GetRelationship( id ).TargetUri ); | |||
| var newDocPrIdValue = 1; | |||
| var bookmarkIds = new List<string>(); | |||
| var bookmarks = document.Xml.Descendants( XName.Get( "bookmarkStart", DocX.wp.NamespaceName ) ); | |||
| foreach( var bookmark in bookmarks ) | |||
| { | |||
| var idAttr = bookmark.Attributes().FirstOrDefault( a => a.Name.LocalName == "id" ); | |||
| if( idAttr != null ) | |||
| { | |||
| bookmarkIds.Add( idAttr.Value ); | |||
| } | |||
| } | |||
| while( bookmarkIds.Contains( newDocPrIdValue.ToString() ) ) | |||
| { | |||
| ++newDocPrIdValue; | |||
| } | |||
| long newDocPrId = document.GetNextFreeDocPrId(); | |||
| int cx, cy; | |||
| var docPrs = document.Xml.Descendants( XName.Get( "docPr", DocX.wp.NamespaceName ) ); | |||
| foreach( var bookmark in docPrs ) | |||
| using( PackagePartStream packagePartStream = new PackagePartStream( part.GetStream() ) ) | |||
| { | |||
| var idAttr = bookmark.Attributes().FirstOrDefault( a => a.Name.LocalName == "id" ); | |||
| if( idAttr != null ) | |||
| using( System.Drawing.Image img = System.Drawing.Image.FromStream( packagePartStream, useEmbeddedColorManagement: false, validateImageData: false ) ) | |||
| { | |||
| bookmarkIds.Add( idAttr.Value ); | |||
| cx = img.Width * 9526; | |||
| cy = img.Height * 9526; | |||
| } | |||
| } | |||
| while( bookmarkIds.Contains( newDocPrIdValue.ToString() ) ) | |||
| { | |||
| ++newDocPrIdValue; | |||
| } | |||
| int cx, cy; | |||
| using( System.Drawing.Image img = System.Drawing.Image.FromStream( new PackagePartStream( part.GetStream() ) ) ) | |||
| { | |||
| cx = img.Width * 9526; | |||
| cy = img.Height * 9526; | |||
| } | |||
| var e = new XElement( DocX.w + "drawing" ); | |||
| var xml = XElement.Parse | |||
| ( string.Format( @" | |||
| @@ -4223,7 +4336,7 @@ namespace Xceed.Words.NET | |||
| </wp:inline> | |||
| </w:drawing> | |||
| </w:r> | |||
| ", cx, cy, id, name, descr, newDocPrIdValue.ToString() ) ); | |||
| ", cx, cy, id, name, descr, newDocPrId.ToString() ) ); | |||
| var picture = new Picture( document, xml, new Image( document, document.PackagePart.GetRelationship( id ) ) ); | |||
| if( width > -1 ) | |||
| @@ -4328,11 +4441,14 @@ namespace Xceed.Words.NET | |||
| } | |||
| count -= HelperFunctions.GetSize( Xml ); | |||
| count = Math.Max( 0, count ); | |||
| // We have found the element, now find the run it belongs to. | |||
| while( ( Xml.Name.LocalName != "r" ) && ( Xml.Name.LocalName != "pPr" ) ) | |||
| while( ( Xml.Name.LocalName != "r" ) ) | |||
| { | |||
| Xml = Xml.Parent; | |||
| if( Xml == null ) | |||
| return; | |||
| } | |||
| theOne = new Run( Document, Xml, count ); | |||
| @@ -4414,26 +4530,29 @@ namespace Xceed.Words.NET | |||
| string image_uri_string = p._img._pr.TargetUri.OriginalString; | |||
| // Search for a relationship with a TargetUri that points at this Image. | |||
| var Id = | |||
| ( | |||
| from r in this.PackagePart.GetRelationshipsByType( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ) | |||
| where r.TargetUri.OriginalString == image_uri_string | |||
| select r.Id | |||
| ).SingleOrDefault(); | |||
| string id = null; | |||
| foreach( var r in this.PackagePart.GetRelationshipsByType( DocX.RelationshipImage ) ) | |||
| { | |||
| if( string.Equals( r.TargetUri.OriginalString, image_uri_string, StringComparison.Ordinal ) ) | |||
| { | |||
| id = r.Id; | |||
| break; | |||
| } | |||
| } | |||
| // If such a relation dosen't exist, create one. | |||
| if( Id == null ) | |||
| // If such a relation doesn't exist, create one. | |||
| if( id == null ) | |||
| { | |||
| // Check to see if a relationship for this Picture exists and create it if not. | |||
| var pr = this.PackagePart.CreateRelationship( p._img._pr.TargetUri, TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ); | |||
| Id = pr.Id; | |||
| var pr = this.PackagePart.CreateRelationship( p._img._pr.TargetUri, TargetMode.Internal, DocX.RelationshipImage ); | |||
| id = pr.Id; | |||
| } | |||
| return Id; | |||
| return id; | |||
| } | |||
| internal string GetOrGenerateRel( Hyperlink h ) | |||
| { | |||
| string image_uri_string = h.Uri.OriginalString; | |||
| string image_uri_string = (h.Uri != null) ? h.Uri.OriginalString : null; | |||
| // Search for a relationship with a TargetUri that points at this Image. | |||
| var Id = | |||
| @@ -4444,7 +4563,7 @@ namespace Xceed.Words.NET | |||
| ).SingleOrDefault(); | |||
| // If such a relation dosen't exist, create one. | |||
| if( Id == null ) | |||
| if( (Id == null) && ( h.Uri != null) ) | |||
| { | |||
| // Check to see if a relationship for this Picture exists and create it if not. | |||
| var pr = this.PackagePart.CreateRelationship( h.Uri, TargetMode.External, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ); | |||
| @@ -4636,14 +4755,6 @@ namespace Xceed.Words.NET | |||
| private XElement GetParagraphNumberProperties() | |||
| { | |||
| var numPrNode = Xml.Descendants().FirstOrDefault( el => el.Name.LocalName == "numPr" ); | |||
| if( numPrNode != null ) | |||
| { | |||
| var numIdNode = numPrNode.Descendants().First( numId => numId.Name.LocalName == "numId" ); | |||
| var numIdAttribute = numIdNode.Attribute( DocX.w + "val" ); | |||
| if( numIdAttribute != null && numIdAttribute.Value.Equals( "0" ) ) | |||
| return null; | |||
| } | |||
| return numPrNode; | |||
| } | |||
| @@ -397,21 +397,7 @@ namespace Xceed.Words.NET | |||
| style.Remove(); | |||
| } | |||
| if( _design == TableDesign.Custom ) | |||
| { | |||
| if( string.IsNullOrEmpty( _customTableDesignName ) ) | |||
| { | |||
| _design = TableDesign.None; | |||
| if( style != null ) | |||
| style.Remove(); | |||
| } | |||
| else | |||
| { | |||
| val.Value = _customTableDesignName; | |||
| } | |||
| } | |||
| else | |||
| if( _design != TableDesign.Custom ) | |||
| { | |||
| switch( _design ) | |||
| { | |||
| @@ -750,9 +736,10 @@ namespace Xceed.Words.NET | |||
| let styleId = e.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ) | |||
| where ( styleId != null && styleId.Value == val.Value ) | |||
| select e | |||
| ).First(); | |||
| ).FirstOrDefault(); | |||
| Document._styles.Element( XName.Get( "styles", DocX.w.NamespaceName ) ).Add( styleElement ); | |||
| if( styleElement != null ) | |||
| Document._styles.Element( XName.Get( "styles", DocX.w.NamespaceName ) ).Add( styleElement ); | |||
| } | |||
| } | |||
| } | |||
| @@ -883,6 +870,30 @@ namespace Xceed.Words.NET | |||
| set; | |||
| } | |||
| public List<Double> ColumnWidths | |||
| { | |||
| get | |||
| { | |||
| var columnWidths = new List<Double>(); | |||
| // get the table grid property | |||
| XElement grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); | |||
| // get the columns properties | |||
| var columns = grid?.Elements( XName.Get( "gridCol", DocX.w.NamespaceName ) ); | |||
| if( columns == null ) | |||
| return null; | |||
| foreach( var column in columns ) | |||
| { | |||
| string value = column.GetAttribute( XName.Get( "w", DocX.w.NamespaceName ) ); | |||
| columnWidths.Add( Convert.ToDouble( value, new CultureInfo( "en-US" ) ) ); | |||
| } | |||
| return columnWidths; | |||
| } | |||
| } | |||
| #endregion | |||
| #region Constructors | |||
| @@ -1102,9 +1113,9 @@ namespace Xceed.Words.NET | |||
| /// Insert a copy of a row at the end of this table. | |||
| /// </summary> | |||
| /// <returns>A new row.</returns> | |||
| public Row InsertRow( Row row ) | |||
| public Row InsertRow( Row row, bool keepFormatting = false ) | |||
| { | |||
| return this.InsertRow( row, this.RowCount ); | |||
| return this.InsertRow( row, this.RowCount, keepFormatting ); | |||
| } | |||
| /// <summary> | |||
| @@ -1342,8 +1353,9 @@ namespace Xceed.Words.NET | |||
| /// </summary> | |||
| /// <param name="row">Row to copy and insert.</param> | |||
| /// <param name="index">Index to insert row at.</param> | |||
| /// <param name="keepFormatting">True to clone everithing, False to clone cell structure only.</param> | |||
| /// <returns>A new Row</returns> | |||
| public Row InsertRow( Row row, int index ) | |||
| public Row InsertRow( Row row, int index, bool keepFormatting = false ) | |||
| { | |||
| if( row == null ) | |||
| throw new ArgumentNullException( "row" ); | |||
| @@ -1351,8 +1363,13 @@ namespace Xceed.Words.NET | |||
| if( index < 0 || index > RowCount ) | |||
| throw new IndexOutOfRangeException(); | |||
| var content = row.Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ).Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||
| return this.InsertRow( content, index ); | |||
| List<XElement> content; | |||
| if( keepFormatting ) | |||
| content = row.Xml.Elements().Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||
| else | |||
| content = row.Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ).Select( element => HelperFunctions.CloneElement( element ) ).ToList(); | |||
| return InsertRow( content, index ); | |||
| } | |||
| /// <summary> | |||
| @@ -2265,30 +2282,6 @@ namespace Xceed.Words.NET | |||
| this.AutoFit = AutoFit.Fixed; | |||
| } | |||
| public List<Double> ColumnWidths | |||
| { | |||
| get | |||
| { | |||
| var columnWidths = new List<Double>(); | |||
| // get the table grid property | |||
| XElement grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); | |||
| // get the columns properties | |||
| var columns = grid?.Elements( XName.Get( "gridCol", DocX.w.NamespaceName ) ); | |||
| if( columns == null ) | |||
| return null; | |||
| foreach( var column in columns ) | |||
| { | |||
| string value = column.GetAttribute( XName.Get( "w", DocX.w.NamespaceName ) ); | |||
| columnWidths.Add( Convert.ToDouble( value, new CultureInfo("en-US" ) ) ); | |||
| } | |||
| return columnWidths; | |||
| } | |||
| } | |||
| public void SetTableCellMargin( TableCellMarginType type, double margin ) | |||
| { | |||
| var tblPr = this.GetOrCreate_tblPr(); | |||
| @@ -2666,6 +2659,13 @@ namespace Xceed.Words.NET | |||
| trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); | |||
| } | |||
| XElement tc = Xml.Element( XName.Get( "tc", DocX.w.NamespaceName ) ); | |||
| if( tc != null ) | |||
| { | |||
| trPr.Remove(); | |||
| tc.AddBeforeSelf( trPr ); | |||
| } | |||
| XElement trHeight = trPr.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); | |||
| if( trHeight == null ) | |||
| { | |||
| @@ -2677,7 +2677,7 @@ namespace Xceed.Words.NET | |||
| trHeight.SetAttributeValue( XName.Get( "hRule", DocX.w.NamespaceName ), isHeightExact ? "exact" : "atLeast" ); | |||
| // Using 20 to match DocX._pageSizeMultiplier. | |||
| trHeight.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( height * 20 ).ToString() ); | |||
| trHeight.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( ( int )( Math.Round( height * 20, 0 ) ) ).ToString( CultureInfo.InvariantCulture ) ); | |||
| } | |||
| #endregion | |||
| @@ -2807,45 +2807,45 @@ namespace Xceed.Words.NET | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Gets or Sets this Cells vertical alignment. | |||
| /// </summary> | |||
| /// <example> | |||
| /// Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options. | |||
| /// <code> | |||
| ///// Create a new document. | |||
| ///using(DocX document = DocX.Create("Test.docx")) | |||
| ///{ | |||
| /// // Insert a Table into this document. | |||
| /// Table t = document.InsertTable(3, 1); | |||
| /// | |||
| /// // Set the design of the Table such that we can easily identify cell boundaries. | |||
| /// t.Design = TableDesign.TableGrid; | |||
| /// | |||
| /// // Set the height of the row bigger than default. | |||
| /// // We need to be able to see the difference in vertical cell alignment options. | |||
| /// t.Rows[0].Height = 100; | |||
| /// | |||
| /// // Set the vertical alignment of cell0 to top. | |||
| /// Cell c0 = t.Rows[0].Cells[0]; | |||
| /// c0.InsertParagraph("VerticalAlignment.Top"); | |||
| /// c0.VerticalAlignment = VerticalAlignment.Top; | |||
| /// | |||
| /// // Set the vertical alignment of cell1 to center. | |||
| /// Cell c1 = t.Rows[0].Cells[1]; | |||
| /// c1.InsertParagraph("VerticalAlignment.Center"); | |||
| /// c1.VerticalAlignment = VerticalAlignment.Center; | |||
| /// | |||
| /// // Set the vertical alignment of cell2 to bottom. | |||
| /// Cell c2 = t.Rows[0].Cells[2]; | |||
| /// c2.InsertParagraph("VerticalAlignment.Bottom"); | |||
| /// c2.VerticalAlignment = VerticalAlignment.Bottom; | |||
| /// | |||
| /// // Save the document. | |||
| /// document.Save(); | |||
| ///} | |||
| /// </code> | |||
| /// </example> | |||
| // <summary> | |||
| // Gets or Sets this Cells vertical alignment. | |||
| // </summary> | |||
| // <example> | |||
| // Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options. | |||
| // <code> | |||
| // Create a new document. | |||
| //using(DocX document = DocX.Create("Test.docx")) | |||
| //{ | |||
| // // Insert a Table into this document. | |||
| // Table t = document.InsertTable(3, 1); | |||
| // | |||
| // // Set the design of the Table such that we can easily identify cell boundaries. | |||
| // t.Design = TableDesign.TableGrid; | |||
| // | |||
| // // Set the height of the row bigger than default. | |||
| // // We need to be able to see the difference in vertical cell alignment options. | |||
| // t.Rows[0].Height = 100; | |||
| // | |||
| // // Set the vertical alignment of cell0 to top. | |||
| // Cell c0 = t.Rows[0].Cells[0]; | |||
| // c0.InsertParagraph("VerticalAlignment.Top"); | |||
| // c0.VerticalAlignment = VerticalAlignment.Top; | |||
| // | |||
| // // Set the vertical alignment of cell1 to center. | |||
| // Cell c1 = t.Rows[0].Cells[1]; | |||
| // c1.InsertParagraph("VerticalAlignment.Center"); | |||
| // c1.VerticalAlignment = VerticalAlignment.Center; | |||
| // | |||
| // // Set the vertical alignment of cell2 to bottom. | |||
| // Cell c2 = t.Rows[0].Cells[2]; | |||
| // c2.InsertParagraph("VerticalAlignment.Bottom"); | |||
| // c2.VerticalAlignment = VerticalAlignment.Bottom; | |||
| // | |||
| // // Save the document. | |||
| // document.Save(); | |||
| //} | |||
| // </code> | |||
| // </example> | |||
| public VerticalAlignment VerticalAlignment | |||
| { | |||
| get | |||
| @@ -3633,36 +3633,36 @@ namespace Xceed.Words.NET | |||
| #region Public Methods | |||
| /// <summary> | |||
| /// Set the table cell border | |||
| /// </summary> | |||
| /// <example> | |||
| /// <code> | |||
| ///// Create a new document. | |||
| ///using (DocX document = DocX.Create("Test.docx")) | |||
| ///{ | |||
| /// // Insert a table into this document. | |||
| /// Table t = document.InsertTable(3, 3); | |||
| /// | |||
| /// // Get the center cell. | |||
| /// Cell center = t.Rows[1].Cells[1]; | |||
| /// | |||
| /// // Create a large blue border. | |||
| /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); | |||
| /// | |||
| /// // Set the center cells Top, Bottom, Left and Right Borders to b. | |||
| /// center.SetBorder(TableCellBorderType.Top, b); | |||
| /// center.SetBorder(TableCellBorderType.Bottom, b); | |||
| /// center.SetBorder(TableCellBorderType.Left, b); | |||
| /// center.SetBorder(TableCellBorderType.Right, b); | |||
| /// | |||
| /// // Save the document. | |||
| /// document.Save(); | |||
| ///} | |||
| /// </code> | |||
| /// </example> | |||
| /// <param name="borderType">Table Cell border to set</param> | |||
| /// <param name="border">Border object to set the table cell border</param> | |||
| // <summary> | |||
| // Set the table cell border | |||
| // </summary> | |||
| // <example> | |||
| // <code> | |||
| // Create a new document. | |||
| //using (DocX document = DocX.Create("Test.docx")) | |||
| //{ | |||
| // // Insert a table into this document. | |||
| // Table t = document.InsertTable(3, 3); | |||
| // | |||
| // // Get the center cell. | |||
| // Cell center = t.Rows[1].Cells[1]; | |||
| // | |||
| // // Create a large blue border. | |||
| // Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); | |||
| // | |||
| // // Set the center cells Top, Bottom, Left and Right Borders to b. | |||
| // center.SetBorder(TableCellBorderType.Top, b); | |||
| // center.SetBorder(TableCellBorderType.Bottom, b); | |||
| // center.SetBorder(TableCellBorderType.Left, b); | |||
| // center.SetBorder(TableCellBorderType.Right, b); | |||
| // | |||
| // // Save the document. | |||
| // document.Save(); | |||
| //} | |||
| // </code> | |||
| // </example> | |||
| // <param name="borderType">Table Cell border to set</param> | |||
| // <param name="border">Border object to set the table cell border</param> | |||
| public void SetBorder( TableCellBorderType borderType, Border border ) | |||
| { | |||
| /* | |||
| @@ -3947,29 +3947,29 @@ namespace Xceed.Words.NET | |||
| #endregion | |||
| /// <summary> | |||
| /// Gets or Sets the fill color of this Cell. | |||
| /// </summary> | |||
| /// <example> | |||
| /// <code> | |||
| /// // Create a new document. | |||
| /// using (DocX document = DocX.Create("Test.docx")) | |||
| /// { | |||
| /// // Insert a table into this document. | |||
| /// Table t = document.InsertTable(3, 3); | |||
| /// | |||
| /// // Fill the first cell as Blue. | |||
| /// t.Rows[0].Cells[0].FillColor = Color.Blue; | |||
| /// // Fill the middle cell as Red. | |||
| /// t.Rows[1].Cells[1].FillColor = Color.Red; | |||
| /// // Fill the last cell as Green. | |||
| /// t.Rows[2].Cells[2].FillColor = Color.Green; | |||
| /// | |||
| /// // Save the document. | |||
| /// document.Save(); | |||
| /// } | |||
| /// </code> | |||
| /// </example> | |||
| // <summary> | |||
| // Gets or Sets the fill color of this Cell. | |||
| // </summary> | |||
| // <example> | |||
| // <code> | |||
| // // Create a new document. | |||
| // using (DocX document = DocX.Create("Test.docx")) | |||
| // { | |||
| // // Insert a table into this document. | |||
| // Table t = document.InsertTable(3, 3); | |||
| // | |||
| // // Fill the first cell as Blue. | |||
| // t.Rows[0].Cells[0].FillColor = Color.Blue; | |||
| // // Fill the middle cell as Red. | |||
| // t.Rows[1].Cells[1].FillColor = Color.Red; | |||
| // // Fill the last cell as Green. | |||
| // t.Rows[2].Cells[2].FillColor = Color.Green; | |||
| // | |||
| // // Save the document. | |||
| // document.Save(); | |||
| // } | |||
| // </code> | |||
| // </example> | |||
| } | |||
| public class TableLook | |||
| @@ -258,6 +258,24 @@ namespace Xceed.Words.NET | |||
| return table; | |||
| } | |||
| public virtual List InsertListAfterSelf( List list ) | |||
| { | |||
| for( var i = list.Items.Count - 1; i >= 0; --i ) | |||
| { | |||
| this.Xml.AddAfterSelf( list.Items[ i ].Xml ); | |||
| } | |||
| return list; | |||
| } | |||
| public virtual List InsertListBeforeSelf( List list ) | |||
| { | |||
| foreach( var item in list.Items ) | |||
| { | |||
| this.Xml.AddBeforeSelf( item.Xml ); | |||
| } | |||
| return list; | |||
| } | |||
| #endregion | |||
| } | |||
| @@ -45,6 +45,12 @@ namespace Xceed.Words.NET | |||
| Body | |||
| } | |||
| public enum ShadingType | |||
| { | |||
| Text, | |||
| Paragraph | |||
| } | |||
| public enum PageNumberFormat | |||
| { | |||
| normal, | |||
| @@ -754,4 +760,18 @@ namespace Xceed.Words.NET | |||
| bottom, | |||
| top | |||
| } | |||
| public enum HorizontalBorderPosition | |||
| { | |||
| top, | |||
| bottom | |||
| } | |||
| public enum TabStopPositionLeader | |||
| { | |||
| none, | |||
| dot, | |||
| underscore, | |||
| hyphen | |||
| } | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\bin\Release\Xceed.Words.NET.dll | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\obj\Release\Xceed.Words.NET.csprojResolveAssemblyReference.cache | |||
| D:\Dev\DocumentLibraries\Release\1.2.0\OpenSource\Generated\Xceed.Words.NET\obj\Release\Xceed.Words.NET.dll | |||