@@ -102,6 +102,7 @@ public class Document : Container, IDisposable
102102 #region Internal Constants
103103
104104 internal const string RelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ;
105+ internal const string RelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" ;
105106 internal const string ContentTypeApplicationRelationShipXml = "application/vnd.openxmlformats-package.relationships+xml" ;
106107
107108 #endregion
@@ -1112,6 +1113,40 @@ public override Section InsertSectionPageBreak( bool trackChanges = false )
11121113 return this . InsertSection ( trackChanges , true ) ;
11131114 }
11141115
1116+ public override List < string > FindUniqueByPattern ( string pattern , RegexOptions options )
1117+ {
1118+ // FindUniqueByPattern in the main body of document.
1119+ var items = base . FindUniqueByPattern ( pattern , options ) ;
1120+
1121+ // FindUniqueByPattern in Headers of the document.
1122+ foreach ( var section in this . Sections )
1123+ {
1124+ var headerList = new List < Header > ( ) { section . Headers . First , section . Headers . Even , section . Headers . Odd } ;
1125+ foreach ( var h in headerList )
1126+ {
1127+ if ( h != null )
1128+ {
1129+ items . AddRange ( h . FindUniqueByPattern ( pattern , options ) ) ;
1130+ }
1131+ }
1132+ }
1133+
1134+ // FindUniqueByPattern in Footers of the document.
1135+ foreach ( var section in this . Sections )
1136+ {
1137+ var footerList = new List < Footer > { section . Footers . First , section . Footers . Even , section . Footers . Odd } ;
1138+ foreach ( var f in footerList )
1139+ {
1140+ if ( f != null )
1141+ {
1142+ items . AddRange ( f . FindUniqueByPattern ( pattern , options ) ) ;
1143+ }
1144+ }
1145+ }
1146+
1147+ return items ;
1148+ }
1149+
11151150 public override void ReplaceText ( string searchValue ,
11161151 string newValue ,
11171152 bool trackChanges = false ,
@@ -2525,13 +2560,17 @@ public override Paragraph InsertParagraph( int index, string text, bool trackCha
25252560 var p = base . InsertParagraph ( index , text , trackChanges ) ;
25262561 p . PackagePart = this . PackagePart ;
25272562
2563+ // Inserting a paragraph at a specific index needs an update of Paragraph cache.
2564+ this . ClearParagraphsCache ( ) ;
2565+
25282566 return p ;
25292567 }
25302568
25312569 public override Paragraph InsertParagraph ( Paragraph p )
25322570 {
2533- // copy paragraph's pictures.
2571+ // copy paragraph's pictures and styles .
25342572 this . InsertParagraphPictures ( p ) ;
2573+ this . InsertParagraphStyles ( p ) ;
25352574
25362575 p . PackagePart = this . PackagePart ;
25372576
@@ -2540,19 +2579,28 @@ public override Paragraph InsertParagraph( Paragraph p )
25402579
25412580 public override Paragraph InsertParagraph ( int index , Paragraph p )
25422581 {
2543- // copy paragraph's pictures.
2582+ // copy paragraph's pictures and styles .
25442583 this . InsertParagraphPictures ( p ) ;
2584+ this . InsertParagraphStyles ( p ) ;
25452585
25462586 p . PackagePart = this . PackagePart ;
25472587
2548- return base . InsertParagraph ( index , p ) ;
2588+ var returnParagraph = base . InsertParagraph ( index , p ) ;
2589+
2590+ // Inserting a paragraph at a specific index needs an update of Paragraph cache.
2591+ this . ClearParagraphsCache ( ) ;
2592+
2593+ return returnParagraph ;
25492594 }
25502595
25512596 public override Paragraph InsertParagraph ( int index , string text , bool trackChanges , Formatting formatting )
25522597 {
25532598 var p = base . InsertParagraph ( index , text , trackChanges , formatting ) ;
25542599 p . PackagePart = this . PackagePart ;
25552600
2601+ // Inserting a paragraph at a specific index needs an update of Paragraph cache.
2602+ this . ClearParagraphsCache ( ) ;
2603+
25562604 return p ;
25572605 }
25582606
@@ -2893,19 +2941,11 @@ public void SetDefaultFont( Font fontFamily, double fontSize = 11d, Color? fontC
28932941
28942942
28952943
2896-
2897-
2898-
2899-
2900-
2901-
2902-
2903-
29042944 public T AddChart < T > ( ) where T : Chart , new ( )
29052945 {
2906- var chart = new T ( ) ;
2907- chart . PackagePart = CreateChartPackagePart ( ) ;
2908- chart . RelationPackage = CreateChartRelationShip ( chart . PackagePart ) ;
2946+ var chart = new T ( ) ;
2947+ chart . PackagePart = this . CreateChartPackagePart ( ) ;
2948+ chart . RelationPackage = this . CreateChartRelationShip ( chart . PackagePart ) ;
29092949 return chart ;
29102950 }
29112951 #endregion
@@ -3791,7 +3831,7 @@ internal void UpdateCacheSections()
37913831 // Save Headers/Footers in case they were modified. GetSectionCaches() will create new Sections based on them.
37923832 this . SaveHeadersFooters ( ) ;
37933833
3794- ClearParagraphsCache ( ) ;
3834+ this . ClearParagraphsCache ( ) ;
37953835 _cachedSections = this . GetSections ( ) ;
37963836 }
37973837
@@ -3828,17 +3868,17 @@ internal Paragraph GetPreviousParagraph( Paragraph refParagraph )
38283868 internal Paragraph CreateChartElement ( Chart chart , Paragraph paragraph , float width , float height )
38293869 {
38303870
3831- if ( chart . PackagePart == null )
3871+ if ( chart . PackagePart == null )
38323872 {
38333873 chart . PackagePart = this . CreateChartPackagePart ( ) ;
3834- chart . RelationPackage = this . CreateChartRelationShip ( chart . PackagePart ) ;
3874+ chart . RelationPackage = this . CreateChartRelationShip ( chart . PackagePart ) ;
38353875 }
38363876 var relID = chart . RelationPackage . Id . ToString ( ) ;
38373877
38383878 // Save a chart info the chartPackagePart
38393879 var p = ( paragraph == null ) ? InsertParagraph ( ) : paragraph ;
38403880
3841- using ( TextWriter tw = new StreamWriter ( chart . PackagePart . GetStream ( FileMode . Create , FileAccess . Write ) ) )
3881+ using ( TextWriter tw = new StreamWriter ( chart . PackagePart . GetStream ( FileMode . Create , FileAccess . Write ) ) )
38423882 {
38433883 chart . ExternalXml . Save ( tw ) ;
38443884 }
@@ -3860,7 +3900,7 @@ internal PackagePart CreateChartPackagePart()
38603900 {
38613901 chartPartUriPath = String . Format ( "/word/charts/chart{0}.xml" , chartIndex ) ;
38623902 chartIndex ++ ;
3863- } while ( _package . PartExists ( new Uri ( chartPartUriPath , UriKind . Relative ) ) ) ;
3903+ } while ( _package . PartExists ( new Uri ( chartPartUriPath , UriKind . Relative ) ) ) ;
38643904
38653905 // Create chart part.
38663906 var chartPackagePart = _package . CreatePart ( new Uri ( chartPartUriPath , UriKind . Relative ) , "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" , CompressionOption . Normal ) ;
@@ -3873,7 +3913,7 @@ internal PackageRelationship CreateChartRelationShip( PackagePart chartPackagePa
38733913 {
38743914 // Create a new chart relationship
38753915 var relID = this . GetNextFreeRelationshipID ( ) ;
3876- return this . PackagePart . CreateRelationship ( chartPackagePart . Uri , TargetMode . Internal , "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" , relID ) ;
3916+ return this . PackagePart . CreateRelationship ( chartPackagePart . Uri , TargetMode . Internal , Document . RelationshipChart , relID ) ;
38773917 }
38783918
38793919 #endregion
@@ -4099,7 +4139,12 @@ private void MergeDocumentsRelations( Document remote_document, XDocument remote
40994139 {
41004140 if ( _imageContentTypes . Contains ( remote_pp . ContentType ) )
41014141 {
4102- merge_images ( remote_pp , remote_document , remote_mainDoc , remote_pp . ContentType ) ;
4142+ this . MergeImages ( remote_pp , remote_document , remote_mainDoc , remote_pp . ContentType ) ;
4143+ }
4144+
4145+ if ( remote_pp . Uri . OriginalString . StartsWith ( "/word/charts/" ) )
4146+ {
4147+ this . MergeCharts ( remote_pp , remote_document , remote_mainDoc ) ;
41034148 }
41044149 }
41054150
@@ -4209,13 +4254,39 @@ private void InsertParagraphPictures( Paragraph p )
42094254 {
42104255 if ( _imageContentTypes . Contains ( remote_pp . ContentType ) )
42114256 {
4212- merge_images ( remote_pp , p . Document , p . Document . _mainDoc , remote_pp . ContentType ) ;
4257+ this . MergeImages ( remote_pp , p . Document , p . Document . _mainDoc , remote_pp . ContentType ) ;
42134258 }
42144259 }
42154260 }
42164261 }
42174262
4218- private void merge_images ( PackagePart remote_pp , Document remote_document , XDocument remote_mainDoc , String contentType )
4263+ private void InsertParagraphStyles ( Paragraph p )
4264+ {
4265+ // Check if style is already present in document.
4266+ if ( ( p != null ) && ( p . StyleId != this . GetNormalStyleId ( ) ) )
4267+ {
4268+ var styleToFind = HelperFunctions . GetStyle ( this , p . StyleId ) ;
4269+
4270+ // style is not there, we need to add it.
4271+ if ( styleToFind == null )
4272+ {
4273+ var styleIdToFind = p . StyleId ;
4274+ while ( ( styleIdToFind != null ) && ( styleIdToFind != this . GetNormalStyleId ( ) ) )
4275+ {
4276+ var styleToAdd = HelperFunctions . GetStyle ( p . Document , styleIdToFind ) ;
4277+ if ( styleToAdd != null )
4278+ {
4279+ _styles . Root . Add ( styleToAdd ) ;
4280+
4281+ var basedOn = styleToAdd . Element ( XName . Get ( "basedOn" , Document . w . NamespaceName ) ) ;
4282+ styleIdToFind = ( basedOn != null ) ? basedOn . Attribute ( XName . Get ( "val" , Document . w . NamespaceName ) ) . Value : null ;
4283+ }
4284+ }
4285+ }
4286+ }
4287+ }
4288+
4289+ private void MergeImages ( PackagePart remote_pp , Document remote_document , XDocument remote_mainDoc , String contentType )
42194290 {
42204291 // Before doing any other work, check to see if this image is actually referenced in the document.
42214292 // In my testing I have found cases of Images inside documents that are not referenced
@@ -4328,7 +4399,7 @@ private void MergeImagesCore( PackageRelationship relationship, PackagePart remo
43284399
43294400 private void CreateRelationshipForImage ( Uri newUri , string remote_Id , XDocument remote_mainDoc , PackagePart packagePartToSaveTo )
43304401 {
4331- var pr = packagePartToSaveTo . CreateRelationship ( newUri , TargetMode . Internal , RelationshipImage ) ;
4402+ var pr = packagePartToSaveTo . CreateRelationship ( newUri , TargetMode . Internal , Document . RelationshipImage ) ;
43324403 var new_Id = pr . Id ;
43334404
43344405 //Check if the remote relationship id is a default rId from Word
@@ -4350,6 +4421,46 @@ private void CreateRelationshipForImage( Uri newUri, string remote_Id, XDocument
43504421 this . ReplaceAllRemoteID ( remote_mainDoc , "imagedata" , "id" , v . NamespaceName , remote_Id , new_Id ) ;
43514422 }
43524423
4424+ private void CreateRelationshipForChart ( Uri newUri , string remote_Id , XDocument remote_mainDoc )
4425+ {
4426+ var relID = this . GetNextFreeRelationshipID ( ) ;
4427+ var pr = this . PackagePart . CreateRelationship ( newUri , TargetMode . Internal , Document . RelationshipChart , relID ) ;
4428+
4429+ // Replace all instances of remote_Id in the local document with local_Id
4430+ this . ReplaceAllRemoteID ( remote_mainDoc , "chart" , "id" , c . NamespaceName , remote_Id , pr . Id ) ;
4431+ }
4432+
4433+ private void MergeCharts ( PackagePart remote_pp , Document remote_document , XDocument remote_mainDoc )
4434+ {
4435+ var remote_rel = remote_document . PackagePart . GetRelationships ( ) . Where ( r => r . TargetUri . OriginalString . Equals ( remote_pp . Uri . OriginalString ) ) . FirstOrDefault ( ) ;
4436+
4437+ if ( remote_rel != null )
4438+ {
4439+ var remote_Id = remote_rel . Id ;
4440+
4441+ var new_uri = remote_pp . Uri . OriginalString ;
4442+ new_uri = new_uri . Remove ( new_uri . LastIndexOf ( "/" ) ) ;
4443+ new_uri += "/" + Guid . NewGuid ( ) ;
4444+ if ( ! new_uri . StartsWith ( "/" ) )
4445+ {
4446+ new_uri = "/" + new_uri ;
4447+ }
4448+
4449+ var new_pp = _package . CreatePart ( new Uri ( new_uri , UriKind . Relative ) , remote_pp . ContentType , CompressionOption . Normal ) ;
4450+
4451+ using ( Stream s_read = remote_pp . GetStream ( ) )
4452+ {
4453+ using ( Stream s_write = new PackagePartStream ( new_pp . GetStream ( FileMode . Create ) ) )
4454+ {
4455+ HelperFunctions . CopyStream ( s_read , s_write ) ;
4456+ }
4457+ }
4458+
4459+ this . CreateRelationshipForChart ( new Uri ( new_uri , UriKind . Relative ) , remote_Id , remote_mainDoc ) ;
4460+ }
4461+ }
4462+
4463+
43534464 private void ReplaceAllRemoteID ( XDocument remote_mainDoc , string localName , string localNameAttribute , string namespaceName , string remote_Id , string new_Id )
43544465 {
43554466 // Replace all instances of remote_Id in the local document with local_Id
0 commit comments