diff --git a/Tests/Controller/Elements/ItemsTest.cs b/Tests/Controller/Elements/ItemsTest.cs index a57c665..7fa49d3 100755 --- a/Tests/Controller/Elements/ItemsTest.cs +++ b/Tests/Controller/Elements/ItemsTest.cs @@ -30,19 +30,21 @@ namespace Tests.Controller.Elements [TestFixture] class ItemsTest { + Document _document; zaaReloaded2.Formatter.Formatter _formatter; [SetUp] public void SetUp() { - _formatter = new zaaReloaded2.Formatter.Formatter(new Document()); + _document = new Document(); + _formatter = new zaaReloaded2.Formatter.Formatter(_document); _formatter.Settings.ReferenceStyle = ReferenceStyle.IfAbnormal; } [TearDown] public void TearDown() { - ((_Document)_formatter.Document).Close(WdSaveOptions.wdDoNotSaveChanges); + ((_Document)_document).Close(WdSaveOptions.wdDoNotSaveChanges); } [Test] @@ -57,10 +59,9 @@ namespace Tests.Controller.Elements lab.AddTimePoint(tp); _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Na, K, Cl")); _formatter.Run(); - Assert.AreEqual("Na 133, K 6 (5)\r", _formatter.Document.Range().Text); + Assert.AreEqual("Na 133, K 6 (5)\r", _document.Range().Text); } [Test] @@ -75,10 +76,9 @@ namespace Tests.Controller.Elements lab.AddTimePoint(tp); _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Klinische Chemie: Na, K, Cl")); _formatter.Run(); - Assert.AreEqual("Klinische Chemie: Na 133, K 6 (5)\r", _formatter.Document.Range().Text); + Assert.AreEqual("Klinische Chemie: Na 133, K 6 (5)\r", _document.Range().Text); } [Test] @@ -93,10 +93,9 @@ namespace Tests.Controller.Elements lab.AddTimePoint(tp); _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Klinische Chemie: this, does, not, exist")); _formatter.Run(); - Assert.AreEqual("\r", _formatter.Document.Range().Text); + Assert.AreEqual("\r", _document.Range().Text); } [Test] @@ -112,11 +111,10 @@ namespace Tests.Controller.Elements _formatter.Settings.ReferenceStyle = ReferenceStyle.Never; _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Klinische Chemie: Na, *")); _formatter.Run(); Assert.AreEqual("Klinische Chemie: Na 133, Cl 110, K 6\r", - _formatter.Document.Range().Text); + _document.Range().Text); } [Test] @@ -133,11 +131,10 @@ namespace Tests.Controller.Elements _formatter.Settings.ReferenceStyle = ReferenceStyle.Never; _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Klinische Chemie: Na, SU-*")); _formatter.Run(); Assert.AreEqual("Klinische Chemie: Na 133, SU-Protein 2,8\r", - _formatter.Document.Range().Text); + _document.Range().Text); } [Test] @@ -154,11 +151,10 @@ namespace Tests.Controller.Elements _formatter.Settings.ReferenceStyle = ReferenceStyle.Never; _formatter.Laboratory = lab; - _formatter.SelectFirstDay(); _formatter.Settings.Elements.Add(new zaa.Items("Klinische Chemie: Na, SU-*, *")); _formatter.Run(); Assert.AreEqual("Klinische Chemie: Na 133, SU-Protein 2,8, Cl 110, U-Na 99\r", - _formatter.Document.Range().Text); + _document.Range().Text); } } } diff --git a/Tests/Controller/Elements/SelectFirstDayTest.cs b/Tests/Controller/Elements/SelectFirstDayTest.cs deleted file mode 100755 index 6b06a47..0000000 --- a/Tests/Controller/Elements/SelectFirstDayTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* SelectFirstDayTest.cs - * part of zaaReloaded2 - * - * Copyright 2015 Daniel Kraus - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using f = zaaReloaded2.Formatter; -using zaaReloaded2.Importer.ZaaImporter; -using zaaReloaded2.Controller.Elements; - -namespace Tests.Controller.Elements -{ - [TestFixture] - class SelectFirstDayTest - { - [Test] - public void SelectFirstDay() - { - SelectFirstDay element = new SelectFirstDay(); - ZaaImporter importer = TestHelpers.ZaaImporterFromResource(); - f.Formatter formatter = new f.Formatter(); - formatter.Laboratory = importer.Laboratory; - element.Run(formatter); - Assert.AreEqual(5, formatter.WorkingTimePoints.Count); - DateTime firstDay = new DateTime(2015, 07, 04); - Assert.AreEqual(firstDay.Date, formatter.WorkingTimePoints.First().Key.Date); - } - } -} diff --git a/Tests/Controller/Elements/SelectLastDayTest.cs b/Tests/Controller/Elements/SelectLastDayTest.cs deleted file mode 100755 index 107e863..0000000 --- a/Tests/Controller/Elements/SelectLastDayTest.cs +++ /dev/null @@ -1,49 +0,0 @@ -/* SelectFirstDayTest - Copy.cs - * part of zaaReloaded2 - * - * Copyright 2015 Daniel Kraus - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NUnit.Framework; -using f = zaaReloaded2.Formatter; -using zaaReloaded2.Importer.ZaaImporter; -using zaaReloaded2.Controller.Elements; - -namespace Tests.Controller.Elements -{ - [TestFixture] - class SelectLastDayTest - { - [Test] - public void SelectLastDay() - { - SelectLastDay element = new SelectLastDay(); - ZaaImporter importer = TestHelpers.ZaaImporterFromResource(); - f.Formatter formatter = new f.Formatter(); - formatter.Laboratory = importer.Laboratory; - element.Run(formatter); - // There are two time points of 6-July-2015 in the demo output file, - // but since they have the exact same time stamps, they are merged - // into one! - Assert.AreEqual(1, formatter.WorkingTimePoints.Count); - DateTime firstDay = new DateTime(2015, 07, 06); - Assert.AreEqual(firstDay.Date, formatter.WorkingTimePoints.First().Key.Date); - } - } -} diff --git a/Tests/Formatter/DocumentWriterTest.cs b/Tests/Formatter/DocumentWriterTest.cs new file mode 100755 index 0000000..f3e201e --- /dev/null +++ b/Tests/Formatter/DocumentWriterTest.cs @@ -0,0 +1,99 @@ +/* DocumentWriterClass.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using zaaReloaded2.Formatter; + +namespace Tests.Formatter +{ + [TestFixture] + class DocumentWriterTest + { + DocumentWriter _docWriter; + + [SetUp] + public void SetUp() + { + _docWriter = new DocumentWriter(); + } + + [TearDown] + public void TearDown() + { + } + + [Test] + public void AddText() + { + string s = "hello world"; + _docWriter.Write(s); + Assert.AreEqual(s, _docWriter.ToString()); + } + + [Test] + public void AddLine() + { + string s = "hello world"; + _docWriter.WriteLine(s); + Assert.AreEqual(s + Environment.NewLine, _docWriter.ToString()); + } + + [Test] + public void PrependText() + { + string first = "first"; + string second = "second"; + _docWriter.Write(first); + _docWriter.Prepend(second); + Assert.AreEqual(second + first, _docWriter.ToString()); + } + + [Test] + public void FlushingThrowsWithoutTarget() + { + _docWriter.Write("asdf"); + Assert.Throws(_docWriter.Flush); + } + + [Test] + public void FlushBuffer() + { + DocumentWriter parent = new DocumentWriter(); + _docWriter.Parent = parent; + string s = "hello world"; + _docWriter.Write(s); + _docWriter.Flush(); + Assert.AreEqual(s, parent.ToString()); + } + + [Test] + public void BufferIsEmptyAfterFlush() + { + DocumentWriter parent = new DocumentWriter(); + _docWriter.Parent = parent; + string s = "hello world"; + _docWriter.Write(s); + _docWriter.Flush(); + Assert.IsFalse(_docWriter.HasBufferedText); + Assert.AreEqual(String.Empty, _docWriter.ToString()); + } + } +} diff --git a/Tests/Formatter/FormatterTest-all.txt b/Tests/Formatter/FormatterTest-all.txt new file mode 100755 index 0000000..1db9686 --- /dev/null +++ b/Tests/Formatter/FormatterTest-all.txt @@ -0,0 +1,7 @@ + +04.07.2015 12:31:00: +Klinische Chemie: Na 144 mM, K 4,3 mM + +06.07.2015 10:28:00: +Klinische Chemie: Na 138 mM, K 4,6 mM + diff --git a/Tests/Formatter/FormatterTest-eachday.txt b/Tests/Formatter/FormatterTest-eachday.txt new file mode 100755 index 0000000..d7ddc76 --- /dev/null +++ b/Tests/Formatter/FormatterTest-eachday.txt @@ -0,0 +1,7 @@ + +04.07.2015: +Klinische Chemie: Na 144 mM, K 4,3 mM + +06.07.2015: +Klinische Chemie: Na 138 mM, K 4,6 mM + diff --git a/Tests/Formatter/FormatterTest-firstday.txt b/Tests/Formatter/FormatterTest-firstday.txt new file mode 100755 index 0000000..352e4ff --- /dev/null +++ b/Tests/Formatter/FormatterTest-firstday.txt @@ -0,0 +1,4 @@ + +04.07.2015: +Klinische Chemie: Na 144 mM, K 4,3 mM + diff --git a/Tests/Formatter/FormatterTest-lastday.txt b/Tests/Formatter/FormatterTest-lastday.txt new file mode 100755 index 0000000..a69af35 --- /dev/null +++ b/Tests/Formatter/FormatterTest-lastday.txt @@ -0,0 +1,4 @@ + +06.07.2015: +Klinische Chemie: Na 138 mM, K 4,6 mM + diff --git a/Tests/Formatter/FormatterTest.cs b/Tests/Formatter/FormatterTest.cs index 18fb188..7437d6b 100755 --- a/Tests/Formatter/FormatterTest.cs +++ b/Tests/Formatter/FormatterTest.cs @@ -25,23 +25,95 @@ using zaaReloaded2.LabModel; using zaaReloaded2.Importer.ZaaImporter; using zaaReloaded2.Controller.Elements; using Microsoft.Office.Interop.Word; +using System.IO; namespace Tests.Formatter { [TestFixture] class FormatterTest { + Document _document; + f.Formatter _formatter; + + [SetUp] + public void SetUp() + { + _document = new Document(); + ZaaImporter importer = TestHelpers.ZaaImporterFromResource(); + _formatter = new f.Formatter(_document); + _formatter.Laboratory = importer.Laboratory; + } + + [TearDown] + public void TearDown() + { + ((_Document)_document).Close(WdSaveOptions.wdDoNotSaveChanges); + } + [Test] public void FormatLaboratory() { - Document document = new Document(); - ZaaImporter importer = TestHelpers.ZaaImporterFromResource(); - f.Formatter formatter = new f.Formatter(document); - formatter.Laboratory = importer.Laboratory; - formatter.Settings.Elements.Add(new Items("Klinische Chemie: Na, K, Cl")); - formatter.Run(); - Assert.AreEqual("Klinische Chemie: Na 144 mM, K 4,3 mM\r", document.Range().Text); - ((_Document)document).Close(WdSaveOptions.wdDoNotSaveChanges); + _formatter.Settings.Elements.Add(new Items("Klinische Chemie: Na, K, Cl")); + _formatter.Run(); + Assert.AreEqual( + GetResourceText("Tests.Formatter.FormatterTest-all.txt"), + _document.Range().Text); + } + + [Test] + public void SelectEachDay() + { + _formatter.Settings.Elements.Add( + new SelectEachDay( + new Items("Klinische Chemie: Na, K, Cl")) + ); + _formatter.Run(); + Assert.AreEqual( + GetResourceText("Tests.Formatter.FormatterTest-eachday.txt"), + _document.Range().Text); + } + + [Test] + public void SelectFirstDay() + { + _formatter.Settings.Elements.Add( + new SelectFirstDay( + new Items("Klinische Chemie: Na, K, Cl")) + ); + _formatter.Run(); + Assert.AreEqual( + GetResourceText("Tests.Formatter.FormatterTest-firstday.txt"), + _document.Range().Text); + } + + [Test] + public void SelectLastDay() + { + _formatter.Settings.Elements.Add( + new SelectLastDay( + new Items("Klinische Chemie: Na, K, Cl")) + ); + _formatter.Run(); + Assert.AreEqual( + GetResourceText("Tests.Formatter.FormatterTest-lastday.txt"), + _document.Range().Text); + } + + string GetResourceText(string resource) + { + try + { + Stream s = this.GetType().Assembly + .GetManifestResourceStream(resource); + StreamReader sr = new StreamReader(s); + // Need to replace \r\n with \r because this is the newline character + // that Word uses. + return sr.ReadToEnd().Replace("\r\n", "\r"); + } + catch (Exception e) + { + throw new IOException("Unable to read " + resource, e); + } } } } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 908cf84..48f28f4 100755 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -66,9 +66,8 @@ - - + @@ -98,7 +97,18 @@ - + + + + + + + + + + + + diff --git a/zaaReloaded2/Controller/Elements/ControlElementBase.cs b/zaaReloaded2/Controller/Elements/ControlElementBase.cs new file mode 100755 index 0000000..f23b9de --- /dev/null +++ b/zaaReloaded2/Controller/Elements/ControlElementBase.cs @@ -0,0 +1,45 @@ +/* ControlElementBase.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System.Collections.Generic; + +namespace zaaReloaded2.Controller.Elements +{ + /// + /// Base class for control elements that control e.g. the working + /// set of time points in a Formatter object. + /// + public abstract class ControlElementBase : ElementBase + { + /// + /// Gets a list of child elements, all of which must be derived + /// from FormatElementBase. + /// + public IList FormatElements { get; private set; } + + public ControlElementBase() { } + + public ControlElementBase(IList formatElements) + { + FormatElements = formatElements; + } + + public ControlElementBase(FormatElementBase formatElement) + : this(new List() { formatElement }) + { } + } +} diff --git a/zaaReloaded2/Controller/Elements/CustomText.cs b/zaaReloaded2/Controller/Elements/CustomText.cs index 988bf9f..1061b17 100755 --- a/zaaReloaded2/Controller/Elements/CustomText.cs +++ b/zaaReloaded2/Controller/Elements/CustomText.cs @@ -34,7 +34,7 @@ namespace zaaReloaded2.Controller.Elements public override void Run(Formatter.Formatter formatter) { - formatter.WriteToDocument(Text); + formatter.Write(Text); } /// diff --git a/zaaReloaded2/Controller/Elements/FormatElementBase.cs b/zaaReloaded2/Controller/Elements/FormatElementBase.cs new file mode 100755 index 0000000..8a0db99 --- /dev/null +++ b/zaaReloaded2/Controller/Elements/FormatElementBase.cs @@ -0,0 +1,27 @@ +/* FormatElementBase.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace zaaReloaded2.Controller.Elements +{ + /// + /// Base class for elements that perform actual formatting. + /// + public abstract class FormatElementBase : ElementBase + { + } +} diff --git a/zaaReloaded2/Controller/Elements/Items.cs b/zaaReloaded2/Controller/Elements/Items.cs index c58cadf..fa31de6 100755 --- a/zaaReloaded2/Controller/Elements/Items.cs +++ b/zaaReloaded2/Controller/Elements/Items.cs @@ -31,7 +31,7 @@ namespace zaaReloaded2.Controller.Elements /// to a Word document. /// [Serializable] - class Items : ElementBase + class Items : FormatElementBase { #region ElementBase implementation @@ -55,15 +55,13 @@ namespace zaaReloaded2.Controller.Elements { if (!String.IsNullOrEmpty(_caption)) { - formatter.Document.Range().InsertAfter( - String.Format("{0}: ", _caption) - ); + formatter.Write(String.Format("{0}: ", _caption)); }; foreach (ItemFormatter i in items) { if (_needComma) { - formatter.Document.Range().InsertAfter(", "); + formatter.Write(", "); } else { @@ -71,6 +69,7 @@ namespace zaaReloaded2.Controller.Elements } i.WriteToDocument(formatter); } + formatter.Write("\r"); } } diff --git a/zaaReloaded2/Controller/Elements/SelectEachDay.cs b/zaaReloaded2/Controller/Elements/SelectEachDay.cs new file mode 100755 index 0000000..50eaea3 --- /dev/null +++ b/zaaReloaded2/Controller/Elements/SelectEachDay.cs @@ -0,0 +1,43 @@ +/* SelectEachDay.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace zaaReloaded2.Controller.Elements +{ + class SelectEachDay : ControlElementBase + { + public override string Label + { + get { return "Jeden Tag auswählen"; } + } + + public override void Run(Formatter.Formatter formatter) + { + formatter.ProcessEachDay(this); + } + + public SelectEachDay() : base() { } + + public SelectEachDay(FormatElementBase formatElement) + : base(formatElement) + { } + } +} diff --git a/zaaReloaded2/Controller/Elements/SelectFirstDay.cs b/zaaReloaded2/Controller/Elements/SelectFirstDay.cs index a12dd69..116055f 100755 --- a/zaaReloaded2/Controller/Elements/SelectFirstDay.cs +++ b/zaaReloaded2/Controller/Elements/SelectFirstDay.cs @@ -26,7 +26,7 @@ namespace zaaReloaded2.Controller.Elements /// Selects the time points of the first day in a given Formatter /// object. /// - class SelectFirstDay : ElementBase + class SelectFirstDay : ControlElementBase { public override string Label { @@ -35,7 +35,13 @@ namespace zaaReloaded2.Controller.Elements public override void Run(Formatter.Formatter formatter) { - formatter.SelectFirstDay(); + formatter.ProcessFirstDay(this); } + + public SelectFirstDay() : base() { } + + public SelectFirstDay(FormatElementBase formatElement) + : base(formatElement) + { } } } diff --git a/zaaReloaded2/Controller/Elements/SelectLastDay.cs b/zaaReloaded2/Controller/Elements/SelectLastDay.cs index dd17918..d836e02 100755 --- a/zaaReloaded2/Controller/Elements/SelectLastDay.cs +++ b/zaaReloaded2/Controller/Elements/SelectLastDay.cs @@ -27,7 +27,7 @@ namespace zaaReloaded2.Controller.Elements /// Selects the time points of the last day in a given Formatter /// object. /// - class SelectLastDay : ElementBase + class SelectLastDay : ControlElementBase { public override string Label { @@ -36,7 +36,13 @@ namespace zaaReloaded2.Controller.Elements public override void Run(Formatter.Formatter formatter) { - formatter.SelectLastDay(); + formatter.ProcessLastDay(this); } + + public SelectLastDay() : base() { } + + public SelectLastDay(FormatElementBase formatElement) + : base(formatElement) + { } } } diff --git a/zaaReloaded2/Formatter/DocumentWriter.cs b/zaaReloaded2/Formatter/DocumentWriter.cs new file mode 100755 index 0000000..6953f92 --- /dev/null +++ b/zaaReloaded2/Formatter/DocumentWriter.cs @@ -0,0 +1,162 @@ +/* DocumentWriter.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Office.Interop.Word; + +namespace zaaReloaded2.Formatter +{ + /// + /// Helper class that serves to write text to a Word document or + /// to a linked DocumentWriter. Provides a buffer that can be + /// appended or prepended to, which facilitates conditional output + /// depending on whether there is text in the buffer or not. + /// + /// + /// Linking several DocumentWriters permits a cascading work flow + /// with several buffers. + /// + class DocumentWriter + { + #region Properties + + /// + /// Gets the Document associated with this DocumentWriter, + /// or null if there is no associated Document. + /// + public Document Document { get; set; } + + /// + /// Gets the parent DocumentWriter (if any). + /// + public DocumentWriter Parent { get; set; } + + /// + /// Returns true if there is text in the buffer. + /// + public bool HasBufferedText { get { return _buffer.Length > 0; } } + + #endregion + + #region Constructors + + public DocumentWriter() + { + _buffer = new StringBuilder(); + } + + /// + /// Creates a new DocumentWriter instance that is associated + /// with a Word Document. + /// + /// + public DocumentWriter(Document document) + : this() + { + Document = document; + } + + /// + /// Creates a new DocumentWriter instance that is associated + /// with a parent DocumentWriter. + /// + /// + public DocumentWriter(DocumentWriter parent) + : this() + { + Parent = parent; + } + + #endregion + + #region Overrides + + public override string ToString() + { + return _buffer.ToString(); + } + + #endregion + + #region Public methods + + /// + /// Flushes the buffer to the associated Word document and/or the + /// parent DocumentWriter. + /// + public void Flush() + { + if (!HasBufferedText) return; + + if (Document == null && Parent == null) + { + throw new InvalidOperationException( + "No document and no parent buffer to flush into."); + } + + if (Document != null) + { + Document.Range().Text = _buffer.ToString(); + } + if (Parent != null) + { + Parent.Write(_buffer.ToString()); + } + + _buffer.Clear(); + } + + /// + /// Writes text to the buffer. + /// + /// Text to write to the buffer. + public void Write(string text) + { + _buffer.Append(text); + } + + /// + /// Appends a line of text to the buffer. + /// + /// Text to append. + public void WriteLine(string text) + { + _buffer.AppendLine(text); + } + + /// + /// Inserts text at the start of the buffer. + /// + /// Text to insert at the start of the + /// buffer. + public void Prepend(string text) + { + _buffer.Insert(0, text); + } + + #endregion + + #region Fields + + StringBuilder _buffer; + + #endregion + } +} diff --git a/zaaReloaded2/Formatter/Formatter.cs b/zaaReloaded2/Formatter/Formatter.cs index f19e380..86fae29 100755 --- a/zaaReloaded2/Formatter/Formatter.cs +++ b/zaaReloaded2/Formatter/Formatter.cs @@ -36,11 +36,6 @@ namespace zaaReloaded2.Formatter public Settings Settings { get; set; } - /// - /// Gets the working Word document. - /// - public Document Document { get; private set; } - /// /// Gets or sets the that shall be /// formatted. @@ -76,12 +71,15 @@ namespace zaaReloaded2.Formatter public Formatter() { Settings = new Settings(); + _secondaryBuffer = new DocumentWriter(); + _primaryBuffer = new DocumentWriter(_secondaryBuffer); } public Formatter(Document document) : this() { Document = document; + _secondaryBuffer.Document = document; } #endregion @@ -94,12 +92,18 @@ namespace zaaReloaded2.Formatter /// /// Text to write to the current document. /// - public void WriteToDocument(string text) + public void Write(string text) { - if (Document != null) - { - Document.Range().InsertAfter(text); - } + _primaryBuffer.Write(text); + } + + /// + /// Writes a paragraph to the document. + /// + /// + public void WriteParagraph(string text) + { + _primaryBuffer.WriteLine(text); } /// @@ -109,9 +113,47 @@ namespace zaaReloaded2.Formatter /// current position of the cursor). public void Run() { - foreach (ElementBase element in Settings.Elements) + int current = 0; + while (current < Settings.Elements.Count) { - element.Run(this); + // If there are FormatElements in the first level of the + // elements list, collect all consecutive ones and process + // them for each individual time point. + if (Settings.Elements[current] is FormatElementBase) + { + int notAFormatElement = CollectFormatElements(current); + IList list = Settings.Elements + .Skip(current) + .Take(notAFormatElement - current) + .Cast().ToList(); + ProcessAllTimePoints(list); + current = notAFormatElement; + } + else + { + // The current element is not derived from FormatElementBase; + // so go ahead and 'run' it. + Settings.Elements[current].Run(this); + current++; + } + } + _secondaryBuffer.Flush(); + } + + /// + /// Selects one time point per day in the laboratory. + /// + public void ProcessEachDay(ControlElementBase controlElement) + { + IEnumerable days = _timePointFormatters.Keys.Select(k => k.Date).Distinct(); + foreach (DateTime day in days) + { + ProcessDay( + controlElement, + _timePointFormatters + .Where(kv => kv.Key.Date == day.Date) + .ToDictionary(kv => kv.Key, kv => kv.Value) + ); } } @@ -119,32 +161,131 @@ namespace zaaReloaded2.Formatter /// Selects all time points for the first day in the /// laboratory. /// - public void SelectFirstDay() + public void ProcessFirstDay(ControlElementBase controlElement) { DateTime first = _timePointFormatters.First().Key; - WorkingTimePoints = _timePointFormatters - .Where(kv => kv.Key.Date == first.Date) - .ToDictionary(kv => kv.Key, kv => kv.Value); + ProcessDay( + controlElement, + _timePointFormatters + .Where(kv => kv.Key.Date == first.Date) + .ToDictionary(kv => kv.Key, kv => kv.Value) + ); } /// /// Selects all time points for the first day in the /// laboratory. /// - public void SelectLastDay() + public void ProcessLastDay(ControlElementBase controlElement) { DateTime last = _timePointFormatters.Last().Key; - WorkingTimePoints = _timePointFormatters - .Where(kv => kv.Key.Date == last.Date) - .ToDictionary(kv => kv.Key, kv => kv.Value); + ProcessDay( + controlElement, + _timePointFormatters + .Where(kv => kv.Key.Date == last.Date) + .ToDictionary(kv => kv.Key, kv => kv.Value) + ); } + /// + /// Processes the FormatElementBase children of + /// for each individual time point. + /// + /// ControlElementBase descendant whose + /// FormatElementBase children to process. + public void ProcessAllTimePoints(ControlElementBase controlElement) + { + ProcessAllTimePoints(controlElement.FormatElements); + } + + #endregion + + #region Protected methods + + /// + /// Collects all consecutive FormatElements from Settings.Elements. + /// + /// Index of the first element that is not a FormatElement. + /// + protected int CollectFormatElements(int startIndex) + { + int i = startIndex; + while (i < Settings.Elements.Count) + { + if (!(Settings.Elements[i] is FormatElementBase)) + { + break; + } + i++; + } + return i; + } + + protected void ProcessElements(IList formatElements) + { + if (formatElements != null) + { + foreach (ElementBase element in formatElements) + { + element.Run(this); + } + } + } + + protected void ProcessAllTimePoints(IList formatElements) + { + for (int i = 0; i < _timePointFormatters.Count; i++) + { + WorkingTimePoints = _timePointFormatters + .Skip(i) + .Take(1) + .ToDictionary(kv => kv.Key, kv => kv.Value); + ProcessElements(formatElements); + if (_primaryBuffer.HasBufferedText) + { + _primaryBuffer.Prepend( + WorkingTimePoints.First().Value.GetDateAndTimeHeader() + ); + } + _primaryBuffer.Flush(); + } + } + + protected void ProcessDay( + ControlElementBase controlElement, + Dictionary workingTimePoints) + { + if (workingTimePoints == null) + throw new ArgumentNullException("workingTimePoints"); + + WorkingTimePoints = workingTimePoints; + ProcessElements(controlElement.FormatElements); + if (_primaryBuffer.HasBufferedText) + { + _primaryBuffer.Prepend( + WorkingTimePoints.First().Value.GetDateHeader()); + } + _primaryBuffer.Flush(); + + } + + #endregion + + #region Protected properties + + /// + /// Gets the working Word document. + /// + protected Document Document { get; set; } + #endregion #region Fields TimePointFormatterDictionary _timePointFormatters; Laboratory _laboratory; + DocumentWriter _primaryBuffer; + DocumentWriter _secondaryBuffer; #endregion } diff --git a/zaaReloaded2/Formatter/ItemFormatter.cs b/zaaReloaded2/Formatter/ItemFormatter.cs index 39c3bb7..df8796c 100755 --- a/zaaReloaded2/Formatter/ItemFormatter.cs +++ b/zaaReloaded2/Formatter/ItemFormatter.cs @@ -134,7 +134,7 @@ namespace zaaReloaded2.Formatter } // Insert the formatted text into the document. - formatter.WriteToDocument( + formatter.Write( String.Format( "{0} {1}{2}{3}", LabItem.QualifiedName, diff --git a/zaaReloaded2/Formatter/TimePointFormatter.cs b/zaaReloaded2/Formatter/TimePointFormatter.cs index 56c6fa3..6248775 100755 --- a/zaaReloaded2/Formatter/TimePointFormatter.cs +++ b/zaaReloaded2/Formatter/TimePointFormatter.cs @@ -71,6 +71,39 @@ namespace zaaReloaded2.Formatter return ItemFormatters.ContainsKey(itemName); } + /// + /// Creates a header text line with the time point's date. + /// + /// + public string GetDateHeader() + { + return FormatHeader(TimeStamp.ToShortDateString()); + } + + + /// + /// Creates a header text line with the time point's date + /// and time. + /// + /// + public string GetDateAndTimeHeader() + { + return FormatHeader(TimeStamp.ToString()); + } + + #endregion + + #region Private methods + + string FormatHeader(string text) + { + return String.Format("{0}{1}:{2}", + Environment.NewLine, + text, + Environment.NewLine + ); + } + #endregion } -} +} \ No newline at end of file diff --git a/zaaReloaded2/zaaReloaded2.csproj b/zaaReloaded2/zaaReloaded2.csproj index f1e0b56..265d0a5 100755 --- a/zaaReloaded2/zaaReloaded2.csproj +++ b/zaaReloaded2/zaaReloaded2.csproj @@ -163,11 +163,15 @@ can be found. --> + + + +