/* Items.cs * part of zaaReloaded2 * * Copyright 2015-2017 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.RegularExpressions; using System.Diagnostics; using Microsoft.Office.Interop.Word; using zaaReloaded2.LabModel; using zaaReloaded2.Formatter; using System.Runtime.Serialization; using zaaReloaded2.Controller.Comments; namespace zaaReloaded2.Controller.Elements { /// /// This formatting element is concerned with writing s /// to a Word document. /// [Serializable] public class Items : CustomText { #region ElementBase implementation public override string Label { get { if (String.IsNullOrEmpty(Content)) { return "Laborparameter"; } else { return Content; } } } public override void Run(zaaReloaded2.Formatter.Formatter formatter) { ParseLine(); if (_items == null || _items.Count == 0) return; bool _needComma = false; // Find out if we have any items that we can write // to the document List items = CollectItems(formatter); // If there are items, write the caption (if any), then the items if (items.Count > 0) { if (!String.IsNullOrEmpty(_caption)) { formatter.Write(String.Format("{0}: ", _caption)); }; foreach (ItemFormatter i in items) { if (_needComma) { formatter.Write(", "); } else { _needComma = true; } i.WriteToDocument(formatter); } formatter.Write("\r"); } } protected override ElementBase CreateInstance() { Items clone = new Items(); clone.Content = Content; return clone; } #endregion #region Constructors public Items() : base() { } public Items(string content) : this() { Content = content; } /// /// Deserialization constructor. /// protected Items(SerializationInfo info, StreamingContext context) : base(info, context) { } #endregion #region Private methods /// /// Parses the Line and splits it into an optional caption and individual /// items. /// void ParseLine() { _items = null; _caption = null; Regex r = new Regex(@"((?[^:""]+):\s*)?((?[^,]+),\s*)*(?[^,]+)"); Match m = r.Match(Content); if (m.Success) { if (m.Groups["caption"].Success) { _caption = m.Groups["caption"].Value; } _items = m.Groups["items"].Captures .Cast() .Select(c => c.Value).ToList(); } } /// /// Searches the working time points of the Formatter object /// for items defined in the Line. /// List CollectItems(zaaReloaded2.Formatter.Formatter formatter) { List items = new List(); foreach (string itemName in _items) { Match match = _wildcard.Match(itemName); if (match.Success) { // If there is no capture group "material", the Value // will be String.Empty. items.AddRange(CollectByWildcard(formatter, match.Groups["material"].Value)); } else { items.AddRange(CollectByName(formatter, itemName)); } } return items; } /// /// Collects items for output by matching wildcard. /// /// Material (e.g., empty string for blood, /// or "U-" for spot urine, "SU-" for collected urin, and so on). List CollectByWildcard(zaaReloaded2.Formatter.Formatter formatter, string material) { List items = new List(); foreach (TimePointFormatter tpf in formatter.WorkingTimePoints.Values) { List newItems = tpf.ItemFormatters.Values .Where(i => !i.HasBeenUsed && !i.IsBlacklisted && i.LabItem.QualifiedName.StartsWith(material)) .ToList(); newItems.ForEach(i => i.HasBeenUsed = true); // Include the material prefix only if this item was collected by a // general wildcard ("*" rather than "SU-*" etc.). newItems.ForEach(i => i.IncludeMaterial = String.IsNullOrEmpty(material)); items.AddRange(newItems); } return items; } /// /// Collects items for output by name. /// /// Item name to look for. If the item name contains /// a comment definition (see example in the description of the /// event), List CollectByName(zaaReloaded2.Formatter.Formatter formatter, string name) { // First, check if the item name contains an optional comment // definition ItemComment comment = CommentPool.Default.GetCommentFor(name); if (comment != null) { name = comment.Item; } // Then, see if we have such an item List items = new List(); TimePointFormatter tpf = formatter.WorkingTimePoints .FirstOrDefault(tp => tp.Value.ContainsItem(name)) .Value; if (tpf != null) { // If tpf is not null, this means that it contains an // item with itemName. ItemFormatter i = tpf.ItemFormatters[name]; i.HasBeenUsed = true; i.IncludeMaterial = false; i.Comment = comment; items.Add(i); } return items; } #endregion #region Fields string _caption; List _items; static readonly Regex _wildcard = new Regex(@"^(?[^-]+-)?\*$"); #endregion } }