Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Data/3.3/StringMatrix.cs

Last change on this file was 13841, checked in by jlodewyc, 8 years ago

#2582 More parameter datatypes, splitting fileopening service, approving users, reopen last file, change name tasks and repetitions

File size: 12.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Data {
33  [Item("StringMatrix", "Represents a matrix of strings.")]
34  [StorableClass]
35  public class StringMatrix : Item, IEnumerable<string>, IStringConvertibleMatrix {
36    private const int maximumToStringLength = 100;
37
38    public static new Image StaticItemImage
39    {
40      get { return new Bitmap(25, 25); }
41    }
42
43    [Storable]
44    protected string[,] matrix;
45
46    [Storable]
47    protected List<string> columnNames;
48    public virtual IEnumerable<string> ColumnNames
49    {
50      get { return this.columnNames; }
51      set
52      {
53        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. StringMatrix is read-only.");
54        if (value == null || value.Count() == 0)
55          columnNames = new List<string>();
56        else if (value.Count() != Columns)
57          throw new ArgumentException("A column name must be specified for each column .");
58        else
59          columnNames = new List<string>(value);
60        OnColumnNamesChanged();
61      }
62    }
63    [Storable]
64    protected List<string> rowNames;
65    public virtual IEnumerable<string> RowNames
66    {
67      get { return this.rowNames; }
68      set
69      {
70        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. StringMatrix is read-only.");
71        if (value == null || value.Count() == 0)
72          rowNames = new List<string>();
73        else if (value.Count() != Rows)
74          throw new ArgumentException("A row name must be specified for each row.");
75        else
76          rowNames = new List<string>(value);
77        OnRowNamesChanged();
78      }
79    }
80    [Storable]
81    protected bool sortableView;
82    public virtual bool SortableView
83    {
84      get { return sortableView; }
85      set
86      {
87        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. StringMatrix is read-only.");
88        if (value != sortableView) {
89          sortableView = value;
90          OnSortableViewChanged();
91        }
92      }
93    }
94        public static StringMatrix Parse(string val)
95        {
96            try
97            {
98                val = val.Replace("]", string.Empty);
99
100                string[] parts = val.Split('[');
101                var r = parts.Length;
102                var c = parts[1].Split(';').Length;
103                val = val.Replace("\n", ";");
104                val = val.Replace("[", string.Empty);
105                string[] arr = System.Array.ConvertAll(val.Trim().Split(';'), p => p.Trim());
106                string[] a = arr.Where(s => s != "").ToArray();
107                string[,] b = new string[r, c];
108                var rowcount = 0;
109                for (int i = 0; i < a.Length;)
110                {
111                    for (int j = 0; j < c; j++)
112                    {
113                        b[rowcount, j] = a[i];
114                        i++;
115                    }
116                    rowcount++;
117                }
118                return new StringMatrix(b);
119            }
120            catch (System.FormatException e)
121            {
122                return null;
123            }
124        }
125        public virtual int Rows
126    {
127      get { return matrix.GetLength(0); }
128      protected set
129      {
130        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. StringMatrix is read-only.");
131        if (value != Rows) {
132          string[,] newMatrix = new string[value, Columns];
133          Array.Copy(matrix, newMatrix, Math.Min(value * Columns, matrix.Length));
134          matrix = newMatrix;
135          while (rowNames.Count > value)
136            rowNames.RemoveAt(rowNames.Count - 1);
137          while (rowNames.Count < value)
138            rowNames.Add("Row " + rowNames.Count);
139          OnRowsChanged();
140          OnRowNamesChanged();
141          OnReset();
142        }
143      }
144    }
145    public virtual int Columns
146    {
147      get { return matrix.GetLength(1); }
148      protected set
149      {
150        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. StringMatrix is read-only.");
151        if (value != Columns) {
152          string[,] newMatrix = new string[Rows, value];
153          for (int i = 0; i < Rows; i++)
154            Array.Copy(matrix, i * Columns, newMatrix, i * value, Math.Min(value, Columns));
155          matrix = newMatrix;
156          while (columnNames.Count > value)
157            columnNames.RemoveAt(columnNames.Count - 1);
158          while (columnNames.Count < value)
159            columnNames.Add("Column " + columnNames.Count);
160          OnColumnsChanged();
161          OnColumnNamesChanged();
162          OnReset();
163        }
164      }
165    }
166    public virtual string this[int rowIndex, int columnIndex]
167    {
168      get { return matrix[rowIndex, columnIndex]; }
169      set
170      {
171        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
172        if (value != matrix[rowIndex, columnIndex]) {
173          if ((value != null) || (matrix[rowIndex, columnIndex] != string.Empty)) {
174            matrix[rowIndex, columnIndex] = value != null ? value : string.Empty;
175            OnItemChanged(rowIndex, columnIndex);
176          }
177        }
178      }
179    }
180
181    [Storable]
182    protected bool readOnly;
183    public virtual bool ReadOnly
184    {
185      get { return readOnly; }
186    }
187
188    [StorableConstructor]
189    protected StringMatrix(bool deserializing) : base(deserializing) { }
190    protected StringMatrix(StringMatrix original, Cloner cloner)
191      : base(original, cloner) {
192      this.matrix = (string[,])original.matrix.Clone();
193      this.columnNames = new List<string>(original.columnNames);
194      this.rowNames = new List<string>(original.rowNames);
195      this.sortableView = original.sortableView;
196      this.readOnly = original.readOnly;
197    }
198    public StringMatrix() {
199      matrix = new string[0, 0];
200      columnNames = new List<string>();
201      rowNames = new List<string>();
202      sortableView = false;
203      readOnly = false;
204    }
205    public StringMatrix(int rows, int columns) {
206      matrix = new string[rows, columns];
207      for (int i = 0; i < matrix.GetLength(0); i++) {
208        for (int j = 0; j < matrix.GetLength(1); j++)
209          matrix[i, j] = string.Empty;
210      }
211      columnNames = new List<string>();
212      rowNames = new List<string>();
213      sortableView = false;
214      readOnly = false;
215    }
216    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames)
217      : this(rows, columns) {
218      ColumnNames = columnNames;
219    }
220    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
221      : this(rows, columns, columnNames) {
222      RowNames = rowNames;
223    }
224    public StringMatrix(string[,] elements) {
225      if (elements == null) throw new ArgumentNullException();
226      matrix = new string[elements.GetLength(0), elements.GetLength(1)];
227      for (int i = 0; i < matrix.GetLength(0); i++) {
228        for (int j = 0; j < matrix.GetLength(1); j++)
229          matrix[i, j] = elements[i, j] == null ? string.Empty : elements[i, j];
230      }
231      columnNames = new List<string>();
232      rowNames = new List<string>();
233      sortableView = false;
234      readOnly = false;
235    }
236    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
237      : this(elements) {
238      ColumnNames = columnNames;
239    }
240    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
241      : this(elements, columnNames) {
242      RowNames = rowNames;
243    }
244
245    public override IDeepCloneable Clone(Cloner cloner) {
246      return new StringMatrix(this, cloner);
247    }
248
249    public virtual StringMatrix AsReadOnly() {
250      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
251      readOnlyStringMatrix.readOnly = true;
252      return readOnlyStringMatrix;
253    }
254
255    public override string ToString() {
256      if (matrix.Length == 0) return "[]";
257
258      StringBuilder sb = new StringBuilder();
259      sb.Append("[");
260      for (int i = 0; i < Rows; i++) {
261        sb.Append("[").Append(matrix[i, 0]);
262        for (int j = 1; j < Columns; j++)
263          sb.Append(";").Append(matrix[i, j]);
264        sb.Append("]");
265
266        if (sb.Length > maximumToStringLength) {
267          sb.Append("[...]");
268          break;
269        }
270      }
271      sb.Append("]");
272
273      return sb.ToString();
274    }
275
276    public virtual IEnumerator<string> GetEnumerator() {
277      return matrix.Cast<string>().GetEnumerator();
278    }
279
280    IEnumerator IEnumerable.GetEnumerator() {
281      return GetEnumerator();
282    }
283
284    protected virtual bool Validate(string value, out string errorMessage) {
285      if (value == null) {
286        errorMessage = "Invalid Value (string must not be null)";
287        return false;
288      } else {
289        errorMessage = string.Empty;
290        return true;
291      }
292    }
293    protected virtual string GetValue(int rowIndex, int columIndex) {
294      return this[rowIndex, columIndex];
295    }
296    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
297      if (value != null) {
298        this[rowIndex, columnIndex] = value;
299        return true;
300      } else {
301        return false;
302      }
303    }
304
305    #region events
306    public event EventHandler ColumnsChanged;
307    protected virtual void OnColumnsChanged() {
308      EventHandler handler = ColumnsChanged;
309      if (handler != null)
310        handler(this, EventArgs.Empty);
311    }
312    public event EventHandler RowsChanged;
313    protected virtual void OnRowsChanged() {
314      EventHandler handler = RowsChanged;
315      if (handler != null)
316        handler(this, EventArgs.Empty);
317    }
318    public event EventHandler ColumnNamesChanged;
319    protected virtual void OnColumnNamesChanged() {
320      EventHandler handler = ColumnNamesChanged;
321      if (handler != null)
322        handler(this, EventArgs.Empty);
323    }
324    public event EventHandler RowNamesChanged;
325    protected virtual void OnRowNamesChanged() {
326      EventHandler handler = RowNamesChanged;
327      if (handler != null)
328        handler(this, EventArgs.Empty);
329    }
330    public event EventHandler SortableViewChanged;
331    protected virtual void OnSortableViewChanged() {
332      EventHandler handler = SortableViewChanged;
333      if (handler != null)
334        handler(this, EventArgs.Empty);
335    }
336    public event EventHandler<EventArgs<int, int>> ItemChanged;
337    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
338      if (ItemChanged != null)
339        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
340
341      //approximation to avoid firing of unnecessary ToStringChangedEvents
342      //columnIndex is not used, because always full rows are returned in the ToString method
343      if (rowIndex * Columns < maximumToStringLength)
344        OnToStringChanged();
345    }
346    public event EventHandler Reset;
347    protected virtual void OnReset() {
348      if (Reset != null)
349        Reset(this, EventArgs.Empty);
350      OnToStringChanged();
351    }
352    #endregion
353
354    #region IStringConvertibleMatrix Members
355    int IStringConvertibleMatrix.Rows
356    {
357      get { return Rows; }
358      set { Rows = value; }
359    }
360    int IStringConvertibleMatrix.Columns
361    {
362      get { return Columns; }
363      set { Columns = value; }
364    }
365    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
366      return Validate(value, out errorMessage);
367    }
368    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
369      return GetValue(rowIndex, columIndex);
370    }
371    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
372      return SetValue(value, rowIndex, columnIndex);
373    }
374    #endregion
375  }
376}
Note: See TracBrowser for help on using the repository browser.