Initial implementation of ItemComments.
This commit is contained in:
parent
efbff88b1a
commit
a89a8103e5
@ -181,6 +181,28 @@ namespace Tests.Controller.Elements
|
||||
Assert.AreEqual(expected, _document.Range().Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ItemCommentWithoutHandler()
|
||||
{
|
||||
Laboratory lab = new Laboratory();
|
||||
TimePoint tp = new TimePoint();
|
||||
tp.TimeStamp = new DateTime(2015, 7, 13, 13, 31, 00);
|
||||
tp.AddItem(new LabItem("Na", "133", "133"));
|
||||
tp.AddItem(new LabItem("K", "6", "5"));
|
||||
lab.AddTimePoint(tp);
|
||||
|
||||
_formatter.Laboratory = lab;
|
||||
_formatter.Settings.Elements.Add(
|
||||
new zaa.Items("Na \"(Zielbereich: <> mmol/l)\""));
|
||||
_formatter.Run();
|
||||
string expected = (
|
||||
StripMarkup(
|
||||
TimePointFormatter.DateAndTimeHeader(new DateTime(2015, 07, 13, 13, 31, 00)) +
|
||||
"Na 133\r\r").Replace(Environment.NewLine, "\r")
|
||||
);
|
||||
Assert.AreEqual(expected, _document.Range().Text);
|
||||
}
|
||||
|
||||
static string StripMarkup(string s)
|
||||
{
|
||||
return _markupStripper.Replace(s, string.Empty);
|
||||
|
57
Tests/Formatter/ItemCommentTest.cs
Executable file
57
Tests/Formatter/ItemCommentTest.cs
Executable file
@ -0,0 +1,57 @@
|
||||
/* ItemCommentTest.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 ItemCommentTest
|
||||
{
|
||||
[Test]
|
||||
public void FactoryWithGoodDefinition()
|
||||
{
|
||||
ItemComment i = ItemComment.FromDefinition("TAC \"(Zielbereich: <4-7> µg/l)\"");
|
||||
Assert.IsNotNull(i);
|
||||
Assert.AreEqual("(Zielbereich: ", i.Prefix);
|
||||
Assert.AreEqual("4-7", i.Value);
|
||||
Assert.AreEqual(" µg/l)", i.Suffix);
|
||||
Assert.AreEqual("TAC", i.Item);
|
||||
Assert.AreEqual("(Zielbereich: 4-7 µg/l)", i.BuildComment());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FactoryWithBadDefinition()
|
||||
{
|
||||
ItemComment i = ItemComment.FromDefinition("some bogus definition");
|
||||
Assert.IsNull(i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EmptyValueProducesEmptyComment()
|
||||
{
|
||||
ItemComment i = ItemComment.FromDefinition("TAC \"(Zielbereich: <default> µg/l)\"");
|
||||
i.Value = String.Empty;
|
||||
Assert.AreEqual(String.Empty, i.BuildComment());
|
||||
}
|
||||
}
|
||||
}
|
@ -80,6 +80,7 @@
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="Formatter\ItemCommentTest.cs" />
|
||||
<Compile Include="SerializationTest.cs" />
|
||||
<Compile Include="Controller\SettingsRepositoryTest.cs" />
|
||||
<Compile Include="Controller\SettingsTest.cs" />
|
||||
|
@ -94,6 +94,15 @@ namespace zaaReloaded2.Controller.Elements
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Propagates the FillInComment events of collected items.
|
||||
/// </summary>
|
||||
public event EventHandler<ItemCommentEventArgs> FillInComment;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Items() : base() { }
|
||||
@ -123,7 +132,7 @@ namespace zaaReloaded2.Controller.Elements
|
||||
{
|
||||
_items = null;
|
||||
_caption = null;
|
||||
Regex r = new Regex(@"((?<caption>[^:]+):\s*)?((?<items>[^,]+),\s*)*(?<items>[^,]+)");
|
||||
Regex r = new Regex(@"((?<caption>[^:""]+):\s*)?((?<items>[^,]+),\s*)*(?<items>[^,]+)");
|
||||
Match m = r.Match(Content);
|
||||
if (m.Success)
|
||||
{
|
||||
@ -186,9 +195,22 @@ namespace zaaReloaded2.Controller.Elements
|
||||
/// <summary>
|
||||
/// Collects items for output by name.
|
||||
/// </summary>
|
||||
/// <param name="name">Item name to look for.</param>
|
||||
/// <param name="name">Item name to look for. If the item name contains
|
||||
/// a comment definition (see example in the description of the
|
||||
/// <see cref="RequestParameterComment"/> event), </param>
|
||||
List<ItemFormatter> CollectByName(zaaReloaded2.Formatter.Formatter formatter, string name)
|
||||
{
|
||||
// First, check if the item name contains an optional comment
|
||||
// definition
|
||||
ItemComment comment = ItemComment.FromDefinition(name);
|
||||
if (comment != null)
|
||||
{
|
||||
name = comment.Item;
|
||||
// Enable propagation of FillInComment events
|
||||
comment.FillInComment += comment_FillInComment;
|
||||
}
|
||||
|
||||
// Then, see if we have such an item
|
||||
List<ItemFormatter> items = new List<ItemFormatter>();
|
||||
TimePointFormatter tpf = formatter.WorkingTimePoints
|
||||
.FirstOrDefault(tp => tp.Value.ContainsItem(name))
|
||||
@ -200,19 +222,37 @@ namespace zaaReloaded2.Controller.Elements
|
||||
ItemFormatter i = tpf.ItemFormatters[name];
|
||||
i.HasBeenUsed = true;
|
||||
i.IncludeMaterial = false;
|
||||
i.Comment = comment;
|
||||
items.Add(i);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
void comment_FillInComment(object sender, ItemCommentEventArgs e)
|
||||
{
|
||||
OnFillInComment(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
|
||||
protected virtual void OnFillInComment(ItemCommentEventArgs args)
|
||||
{
|
||||
EventHandler<ItemCommentEventArgs> h = FillInComment;
|
||||
if (h != null)
|
||||
{
|
||||
h(this, args);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
string _caption;
|
||||
List<string> _items;
|
||||
static Regex _wildcard = new Regex(@"(?<material>[^-]+-)?\*");
|
||||
|
||||
static readonly Regex _wildcard = new Regex(@"(?<material>[^-]+-)?\*");
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,20 @@ namespace zaaReloaded2.Formatter
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public Settings Settings { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the Settings that this Formatter works with.
|
||||
/// </summary>
|
||||
public Settings Settings
|
||||
{
|
||||
get { return _settings; }
|
||||
set
|
||||
{
|
||||
_settings = value;
|
||||
// Listen to the FillInComment event of
|
||||
_settings.Elements.OfType<Items>().ToList().ForEach(
|
||||
items => items.FillInComment += items_FillInComment);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Laboratory"/> that shall be
|
||||
@ -66,9 +79,28 @@ namespace zaaReloaded2.Formatter
|
||||
|
||||
/// <summary>
|
||||
/// Is true if this Formatter object carries a Laboratory with
|
||||
/// at least one time point.
|
||||
/// at least one time point, and if there are Settings to work with.
|
||||
/// </summary>
|
||||
public bool CanRun { get { return Laboratory.TimePoints.Count > 0; } }
|
||||
public bool CanRun
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Settings != null)
|
||||
&& (Laboratory != null)
|
||||
&& (Laboratory.TimePoints.Count > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
/// <summary>
|
||||
/// Relays the FillInComment events of any Items elements
|
||||
/// in the Settings, which in turn relay the FillInComment
|
||||
/// events of their collected items' ItemComments.
|
||||
/// </summary>
|
||||
public event EventHandler<ItemCommentEventArgs> FillInComment;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -119,7 +151,14 @@ namespace zaaReloaded2.Formatter
|
||||
/// current position of the cursor).</param>
|
||||
public void Run()
|
||||
{
|
||||
if (!CanRun) throw new NoLaboratoryDataException("No laboratory data to format.");
|
||||
if (!CanRun)
|
||||
{
|
||||
if (Settings == null)
|
||||
throw new InvalidOperationException("No settings data to work with.");
|
||||
if ((Laboratory == null) || Laboratory.TimePoints.Count == 0)
|
||||
throw new NoLaboratoryDataException("No laboratory data to format.");
|
||||
throw new InvalidOperationException("Cannot run formatter.");
|
||||
}
|
||||
|
||||
int current = 0;
|
||||
while (current < Settings.Elements.Count)
|
||||
@ -147,12 +186,19 @@ namespace zaaReloaded2.Formatter
|
||||
}
|
||||
|
||||
// Write everything to the Word document
|
||||
Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord(
|
||||
String.Format("Laborformatierung ({0})", Properties.Settings.Default.AddinName)
|
||||
);
|
||||
bool hasAddin = Globals.ThisAddIn != null;
|
||||
if (hasAddin)
|
||||
{
|
||||
Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord(
|
||||
String.Format("Laborformatierung ({0})", Properties.Settings.Default.AddinName)
|
||||
);
|
||||
}
|
||||
CreateStyles();
|
||||
_secondaryBuffer.Flush();
|
||||
Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord();
|
||||
if (hasAddin)
|
||||
{
|
||||
Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -385,6 +431,23 @@ namespace zaaReloaded2.Formatter
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Relays the FillInComment event of Items elements in the
|
||||
/// Settings.
|
||||
/// </summary>
|
||||
void items_FillInComment(object sender, ItemCommentEventArgs e)
|
||||
{
|
||||
EventHandler<ItemCommentEventArgs> h = FillInComment;
|
||||
if (h != null)
|
||||
{
|
||||
h(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected properties
|
||||
|
||||
/// <summary>
|
||||
@ -396,6 +459,7 @@ namespace zaaReloaded2.Formatter
|
||||
|
||||
#region Fields
|
||||
|
||||
Settings _settings;
|
||||
TimePointFormatterDictionary _timePointFormatters;
|
||||
Laboratory _laboratory;
|
||||
DocumentWriter _primaryBuffer;
|
||||
|
184
zaaReloaded2/Formatter/ItemComment.cs
Executable file
184
zaaReloaded2/Formatter/ItemComment.cs
Executable file
@ -0,0 +1,184 @@
|
||||
/* ParameterComment.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 System.Text.RegularExpressions;
|
||||
|
||||
namespace zaaReloaded2.Formatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an optional comment for a laboratory item.
|
||||
/// The zaaReloaded2.Controller.Elements.Items class can
|
||||
/// parse these optional comment strings which may be used
|
||||
/// to prompt users to enter target ranges etc.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// TAC "(Zielspiegel: <8-10> µg/l)"
|
||||
/// </example>
|
||||
/// <remarks>
|
||||
/// In the example, the tacrolimus trough level TAC carries a comment about the
|
||||
/// recommended range. The comment must be enclosed in quotes in order for it
|
||||
/// to be recognized. The quotes will be stripped. The angle brackets denote
|
||||
/// a place holder that will be replaced by the comment that is set in the
|
||||
/// RequestParameterComment's event args. The text between the angle brackets
|
||||
/// ("8-10") is an optional default value. One could also just use 'empty'
|
||||
/// brackets ("<>").
|
||||
/// </remarks>
|
||||
public class ItemComment
|
||||
{
|
||||
#region Factory
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ItemComment object from a definition.
|
||||
/// </summary>
|
||||
/// <param name="definition">Definition string.</param>
|
||||
/// <returns>ItemComment object, or null if the
|
||||
/// <paramref name="definition"/> string could not be
|
||||
/// parsed.</returns>
|
||||
public static ItemComment FromDefinition(string definition)
|
||||
{
|
||||
ItemComment itemComment = null;
|
||||
// TODO: Maybe turn these to regexes into one.
|
||||
Match checkHasComment = _itemDefinition.Match(definition);
|
||||
if (checkHasComment.Success)
|
||||
{
|
||||
Match commentComponents =
|
||||
_commentDefinition.Match(checkHasComment.Groups["comment"].Value);
|
||||
if (commentComponents.Success)
|
||||
{
|
||||
itemComment = new ItemComment(
|
||||
checkHasComment.Groups["item"].Value.Trim(),
|
||||
commentComponents.Groups["prefix"].Value,
|
||||
commentComponents.Groups["value"].Value,
|
||||
commentComponents.Groups["suffix"].Value
|
||||
);
|
||||
}
|
||||
}
|
||||
return itemComment;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item name that this comment is for.
|
||||
/// </summary>
|
||||
public string Item { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prefix of this comment, e.g. "(target trough level: "
|
||||
/// </summary>
|
||||
public string Prefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of this comment; String.Empty represents a
|
||||
/// cancelled comment.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Suffix of this comment, e.g. " µg/l)"
|
||||
/// </summary>
|
||||
public string Suffix { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
/// <summary>
|
||||
/// Event that is raised when the comment value needs to be
|
||||
/// filled in by someone or something.
|
||||
/// </summary>
|
||||
public event EventHandler<ItemCommentEventArgs> FillInComment;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public ItemComment()
|
||||
{
|
||||
Item = String.Empty;
|
||||
Prefix = String.Empty;
|
||||
Value = String.Empty;
|
||||
Suffix = String.Empty;
|
||||
}
|
||||
|
||||
public ItemComment(string item, string prefix, string value, string suffix)
|
||||
{
|
||||
Item = item;
|
||||
Prefix = prefix;
|
||||
Value = value;
|
||||
Suffix = suffix;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Builds the comment string from the prefix, the value, and
|
||||
/// the suffix. Raises the FillInComment event to get the value
|
||||
/// first. If the value is an empty string, the entire comment
|
||||
/// string will be an empty string.
|
||||
/// </summary>
|
||||
/// <returns>Comment string with filled-in value, or String.Empty
|
||||
/// if the value is an empty string.</returns>
|
||||
public string BuildComment()
|
||||
{
|
||||
OnFillInComment();
|
||||
|
||||
if (String.IsNullOrEmpty(Value))
|
||||
return String.Empty;
|
||||
|
||||
return Prefix + Value + Suffix;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Raises the FillInComment event.
|
||||
/// </summary>
|
||||
protected virtual void OnFillInComment()
|
||||
{
|
||||
EventHandler<ItemCommentEventArgs> h = FillInComment;
|
||||
if (h != null)
|
||||
{
|
||||
ItemCommentEventArgs args = new ItemCommentEventArgs(this);
|
||||
h(this, args);
|
||||
if (args.IsCancelled)
|
||||
args.Comment.Value = String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
static readonly Regex _itemDefinition =
|
||||
new Regex(@"(?<item>[^""]+)""(?<comment>[^""]+)""");
|
||||
static readonly Regex _commentDefinition =
|
||||
new Regex(@"(?<prefix>[^<]+)<(?<value>[^>]*)>(?<suffix>[^""]+)");
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
54
zaaReloaded2/Formatter/ItemCommentEventArgs.cs
Executable file
54
zaaReloaded2/Formatter/ItemCommentEventArgs.cs
Executable file
@ -0,0 +1,54 @@
|
||||
/* ParameterCommentEventArgs.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.Formatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Event arguments used in item commenting.
|
||||
/// </summary>
|
||||
public class ItemCommentEventArgs : EventArgs
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the comment object for this parameter.
|
||||
/// </summary>
|
||||
public ItemComment Comment { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the commenting was cancelled.
|
||||
/// </summary>
|
||||
public bool IsCancelled { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ItemCommentEventArgs(
|
||||
ItemComment comment)
|
||||
{
|
||||
Comment = comment;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -70,6 +70,11 @@ namespace zaaReloaded2.Formatter
|
||||
/// </summary>
|
||||
public bool IsBlacklisted { get { return LabItem.IsBlacklisted; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item's comment.
|
||||
/// </summary>
|
||||
public ItemComment Comment { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
@ -184,6 +189,7 @@ namespace zaaReloaded2.Formatter
|
||||
output = AbnormalStyle.ToMarkup(false) + output + AbnormalStyle.ToMarkup(true);
|
||||
}
|
||||
|
||||
|
||||
formatter.Write(output);
|
||||
HasBeenUsed = true;
|
||||
}
|
||||
|
@ -195,6 +195,8 @@
|
||||
<Compile Include="Controller\Elements\ControlElementBase.cs" />
|
||||
<Compile Include="Controller\Elements\FormatElementBase.cs" />
|
||||
<Compile Include="Controller\Elements\NextColumn.cs" />
|
||||
<Compile Include="Formatter\ItemComment.cs" />
|
||||
<Compile Include="Formatter\ItemCommentEventArgs.cs" />
|
||||
<Compile Include="Controller\Elements\SelectEachDay.cs" />
|
||||
<Compile Include="Controller\Elements\SelectLastDay.cs" />
|
||||
<Compile Include="Controller\Elements\SelectFirstDay.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user