/// <summary> /// Removes redaction marks from the specified range. /// </summary> /// <param name="Range">The Range from which to clear redaction marks.</param> /// <param name="UnmarkAll">True to also clear any subranges (e.g. text boxes), False otherwise.</param> private void UnmarkRange(Word.Range Range, bool UnmarkAll) { //text boxes in headers/footers aren't in the text box story if (UnmarkAll && (int)Range.StoryType > 5 && Range.ShapeRange.Count > 0) { foreach (Word.Shape Shape in Range.ShapeRange) { Word.Range ShapeRange = RedactCommon.RangeFromShape(Shape); if (ShapeRange != null) { UnmarkRange(ShapeRange, true); } } } //unmark the range List <RangeDataEx> RangeMarkers = RedactCommon.GetAllMarkedRanges(Range, ShadingColor, true); foreach (RangeDataEx UniqueRange in RangeMarkers) { Range.Start = UniqueRange.Start; Range.End = UniqueRange.End; Range.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic; } //also catch other instances of the same StoryRange if (UnmarkAll && Range.NextStoryRange != null) { UnmarkRange(Range.NextStoryRange, true); } }
/// <summary> /// Redact a story range (e.g. all textboxes, all first page headers, the main document). /// </summary> /// <param name="StoryRange">The story range to redact.</param> /// <param name="Worker">A BackgroundWorker on which to report progress.</param> private void RedactStoryRange(Word.Range StoryRange, BackgroundWorker Worker) { //textboxes in headers/footers/textboxes/etc. are not in the textbox story. if ((int)StoryRange.StoryType > 5 && StoryRange.ShapeRange.Count > 0) { foreach (Word.Shape Shape in StoryRange.ShapeRange) { Word.Range ShapeRange = RedactCommon.RangeFromShape(Shape); if (ShapeRange != null) { RedactStoryRange(ShapeRange, Worker); } } } //redact all shapes RedactShapes(StoryRange); //remove redaction marks from all paragraph mark glyphs Word.Range ParaMark = StoryRange.Duplicate; foreach (Word.Paragraph Paragraph in StoryRange.Paragraphs) { //select the para mark ParaMark.Start = Paragraph.Range.End - 1; ParaMark.End = ParaMark.Start + 1; if (RedactCommon.IsMarkedRange(ParaMark, ShadingColor)) { ParaMark.Font.Shading.BackgroundPatternColor = Word.WdColor.wdColorAutomatic; } } //run through the collection //since we're messing with the text, we need to go back to front. StoryRange.Collapse(ref CollapseEnd); while (FindPreviousMarkInCurrentStoryRange(ref StoryRange)) { Debug.Assert(StoryRange.Paragraphs.Count < 2, "redacting more than one paragraph - Selection.Move will behave incorrectly in tables"); //break up the range by formatting, so we can maintain layout through the redaction List <RangeDataEx> RangeMarkers = RedactCommon.GetAllMarkedRanges(StoryRange, ShadingColor, false); for (int i = RangeMarkers.Count - 1; i >= 0; i--) { StoryRange.Start = RangeMarkers[i].Start; StoryRange.End = RangeMarkers[i].End; RedactRange(StoryRange, RangeMarkers[i]); //update progress UI if (Worker != null && StoryRange.StoryType == Word.WdStoryType.wdMainTextStory) { Worker.ReportProgress((((StoryRange.StoryLength - RangeMarkers[i].Start) * 100) / StoryRange.StoryLength), null); } } } //get all other stories if (StoryRange.NextStoryRange != null) { RedactStoryRange(StoryRange.NextStoryRange, Worker); } //give each non-main story a small % of the progress bar if (Worker != null && StoryRange.StoryType != Word.WdStoryType.wdMainTextStory) { Worker.ReportProgress(100 + (int)StoryRange.StoryType); } }