Implement DocumentWriter, control elements, and tests.

This commit is contained in:
Daniel Kraus
2015-07-25 14:33:48 +02:00
parent 659713abe3
commit 9df937138d
22 changed files with 722 additions and 151 deletions

View File

@ -36,11 +36,6 @@ namespace zaaReloaded2.Formatter
public Settings Settings { get; set; }
/// <summary>
/// Gets the working Word document.
/// </summary>
public Document Document { get; private set; }
/// <summary>
/// Gets or sets the <see cref="Laboratory"/> 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
/// </summary>
/// <param name="text">Text to write to the current document.
/// </param>
public void WriteToDocument(string text)
public void Write(string text)
{
if (Document != null)
{
Document.Range().InsertAfter(text);
}
_primaryBuffer.Write(text);
}
/// <summary>
/// Writes a paragraph to the document.
/// </summary>
/// <param name="text"></param>
public void WriteParagraph(string text)
{
_primaryBuffer.WriteLine(text);
}
/// <summary>
@ -109,9 +113,47 @@ namespace zaaReloaded2.Formatter
/// current position of the cursor).</param>
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<FormatElementBase> list = Settings.Elements
.Skip(current)
.Take(notAFormatElement - current)
.Cast<FormatElementBase>().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();
}
/// <summary>
/// Selects one time point per day in the laboratory.
/// </summary>
public void ProcessEachDay(ControlElementBase controlElement)
{
IEnumerable<DateTime> 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.
/// </summary>
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)
);
}
/// <summary>
/// Selects all time points for the first day in the
/// laboratory.
/// </summary>
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)
);
}
/// <summary>
/// Processes the FormatElementBase children of <paramref name="controlElement"/>
/// for each individual time point.
/// </summary>
/// <param name="controlElement">ControlElementBase descendant whose
/// FormatElementBase children to process.</param>
public void ProcessAllTimePoints(ControlElementBase controlElement)
{
ProcessAllTimePoints(controlElement.FormatElements);
}
#endregion
#region Protected methods
/// <summary>
/// Collects all consecutive FormatElements from Settings.Elements.
/// </summary>
/// <returns>Index of the first element that is not a FormatElement.
/// </returns>
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<FormatElementBase> formatElements)
{
if (formatElements != null)
{
foreach (ElementBase element in formatElements)
{
element.Run(this);
}
}
}
protected void ProcessAllTimePoints(IList<FormatElementBase> 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<DateTime, TimePointFormatter> 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
/// <summary>
/// Gets the working Word document.
/// </summary>
protected Document Document { get; set; }
#endregion
#region Fields
TimePointFormatterDictionary _timePointFormatters;
Laboratory _laboratory;
DocumentWriter _primaryBuffer;
DocumentWriter _secondaryBuffer;
#endregion
}