diff --git a/src/EPPlus/ExcelRangeBase.cs b/src/EPPlus/ExcelRangeBase.cs index 00e24c551..1a3a6312c 100644 --- a/src/EPPlus/ExcelRangeBase.cs +++ b/src/EPPlus/ExcelRangeBase.cs @@ -2404,7 +2404,6 @@ private void DeleteThreadedComments(ExcelAddressBase Range) /// public void Dispose() { - //_worksheet = null; } #endregion diff --git a/src/EPPlus/ExcelWorksheet.cs b/src/EPPlus/ExcelWorksheet.cs index 18b066c35..846110cd3 100644 --- a/src/EPPlus/ExcelWorksheet.cs +++ b/src/EPPlus/ExcelWorksheet.cs @@ -3617,7 +3617,11 @@ internal void SetValueInner(int row, int col, object value) var styleId = -1; styleId = GetStyleId(row, col); - + if(_flags.GetFlagValue(row, col, CellFlags.RichText)) + { + var rtc = _values.GetValue(row, col)._value as ExcelRichTextCollection; + rtc?.Dispose(); + } if (FullPrecision) { _values.SetValue(row, col, value, styleId); diff --git a/src/EPPlus/Style/RichText/ExcelRichTextCollection.cs b/src/EPPlus/Style/RichText/ExcelRichTextCollection.cs index 8f4fcacd1..c256d25c0 100644 --- a/src/EPPlus/Style/RichText/ExcelRichTextCollection.cs +++ b/src/EPPlus/Style/RichText/ExcelRichTextCollection.cs @@ -29,12 +29,13 @@ namespace OfficeOpenXml.Style /// /// Collection of Richtext objects /// - public class ExcelRichTextCollection : IEnumerable + public class ExcelRichTextCollection : IEnumerable, IDisposable { List _list = new List(); internal ExcelRangeBase _cells = null; internal ExcelWorkbook _wb; internal bool _isComment=false; + private bool _isDisposed=false; internal ExcelRichTextCollection(ExcelWorkbook wb, ExcelRangeBase cells) { _wb = wb; @@ -51,7 +52,6 @@ internal ExcelRichTextCollection(string s, ExcelRangeBase cells) Add(s); } } - internal ExcelRichTextCollection(ExcelRichTextCollection rtc, ExcelRangeBase cells) { _wb = cells._workbook; @@ -115,10 +115,20 @@ public ExcelRichText this[int Index] { get { + CheckDeleted(); var item = _list[Index]; return item; } } + + private void CheckDeleted() + { + if(_isDisposed) + { + throw (new ObjectDisposedException(@"This RichText object has been overwritten by another value and has been disposed. Please use the .RichText object to initiaze a new object, if you want to set the cell/object to a rich text value.")); + } + } + /// /// Items in the list /// @@ -137,6 +147,7 @@ public int Count /// public ExcelRichText Add(string Text, bool NewParagraph = false) { + CheckDeleted(); if (NewParagraph) Text += "\n"; return Insert(_list.Count, Text); } @@ -149,6 +160,7 @@ public ExcelRichText Add(string Text, bool NewParagraph = false) /// public ExcelRichText Insert(int index, string text) { + CheckDeleted(); if (text == null) throw new ArgumentException("Text can't be null", "text"); var rt = new ExcelRichText(text, this); rt.PreserveSpace = true; @@ -195,7 +207,6 @@ public ExcelRichText Insert(int index, string text) if (_isComment == false) { _cells._worksheet._flags.SetFlagValue(_cells._fromRow, _cells._fromCol, true, CellFlags.RichText); - //_cells.SetIsRichTextFlag(true); } } _list.Insert(index, rt); @@ -207,12 +218,8 @@ public ExcelRichText Insert(int index, string text) /// public void Clear() { + CheckDeleted(); _list.Clear(); - if (_cells != null && _isComment == false) - { - _cells.DeleteMe(_cells, false, true, true, true, false, true, false, false, false); - _cells.SetIsRichTextFlag(false); - } } /// /// Removes an item at the specific index @@ -220,6 +227,7 @@ public void Clear() /// public void RemoveAt(int Index) { + CheckDeleted(); _list.RemoveAt(Index); if (_cells != null && _list.Count == 0 && _isComment == false) _cells.SetIsRichTextFlag(false); } @@ -229,6 +237,7 @@ public void RemoveAt(int Index) /// public void Remove(ExcelRichText Item) { + CheckDeleted(); _list.Remove(Item); if (_cells != null && _list.Count == 0 && _isComment == false) _cells.SetIsRichTextFlag(false); } @@ -248,6 +257,7 @@ public string Text } set { + CheckDeleted(); if (string.IsNullOrEmpty(value)) { Clear(); @@ -312,6 +322,12 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() return _list.GetEnumerator(); } + public void Dispose() + { + _cells.Dispose(); + _isDisposed = true; + } + #endregion } } diff --git a/src/EPPlusTest/Core/Range/RangeRichTextTests.cs b/src/EPPlusTest/Core/Range/RangeRichTextTests.cs index c5fc62281..03aa3181d 100644 --- a/src/EPPlusTest/Core/Range/RangeRichTextTests.cs +++ b/src/EPPlusTest/Core/Range/RangeRichTextTests.cs @@ -211,5 +211,53 @@ public void ValidateRichText_TextIsReflectedOnRemove() Assert.AreEqual(1, range.RichText.Count); Assert.AreEqual("1", range.Text); // FAILS as "12" } + [TestMethod] + public void ValidateRichText_ClearShould() + { + var package = new ExcelPackage(); + var ws = package.Workbook.Worksheets.Add("Test"); + var rtc = ws.Cells[1, 1].RichText; + var rt1 = rtc.Add("A"); + var rt2 = rtc.Add("B"); + + Assert.IsTrue(ws.Cells[1, 1].IsRichText); + + Assert.AreEqual("AB", rtc.Text); + Assert.AreEqual("AB", ws.Cells[1, 1].Text); + Assert.AreEqual("AB", ws.Cells[1, 1].RichText.Text); + + rtc.Clear(); + Assert.AreEqual("", rtc.Text); + Assert.AreEqual("", ws.Cells[1, 1].Text); + Assert.AreEqual("", ws.Cells[1, 1].RichText.Text); + Assert.IsFalse(ws.Cells[1, 1].IsRichText); + } + [TestMethod] + public void ValidateRichText_ShouldThrowWhenCellHasBeenOverwritten() + { + var package = new ExcelPackage(); + var ws = package.Workbook.Worksheets.Add("Test"); + var rtc = ws.Cells[1, 1].RichText; + var rt1 = rtc.Add("A"); + var rt2 = rtc.Add("B"); + + ws.Cells[1, 1].Value = "SomeValue"; + + Assert.ThrowsExactly(() =>{ + rtc.Add("c"); + }); + + Assert.ThrowsExactly(() => { + rtc.Insert(0, "d"); + }); + + Assert.ThrowsExactly(() => { + rtc.Clear(); + }); + + Assert.ThrowsExactly(() => { + rtc.Text = "ABCD"; + }); + } } } diff --git a/src/EPPlusTest/Issues/LegacyTests/Issues.cs b/src/EPPlusTest/Issues/LegacyTests/Issues.cs index 615741b90..092192669 100644 --- a/src/EPPlusTest/Issues/LegacyTests/Issues.cs +++ b/src/EPPlusTest/Issues/LegacyTests/Issues.cs @@ -4293,10 +4293,15 @@ public void s431() .Select(p => p as ExcelPicture).ToList(); var pic = pics.First(p => p.Name == "Image_ExistingInventoryImg"); - var image = File.ReadAllBytes("c:\\temp\\img1.png"); - pic.Image.SetImage(image, ePictureType.Png); - image = File.ReadAllBytes("c:\\temp\\img2.png"); - pics[1].Image.SetImage(image, ePictureType.Png); + var img1 = "c:\\temp\\img1.png"; + if (File.Exists(img1)) + { + var image = File.ReadAllBytes("c:\\temp\\img1.png"); + pic.Image.SetImage(image, ePictureType.Png); + + image = File.ReadAllBytes("c:\\temp\\img2.png"); + pics[1].Image.SetImage(image, ePictureType.Png); + } SaveAndCleanup(package); }