Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 13656 was 13656, checked in by ascheibe, 8 years ago

#2582 created branch for Hive Web Job Manager

File size: 11.7 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
95    public virtual int Rows
96    {
97      get { return matrix.GetLength(0); }
98      protected set
99      {
100        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. StringMatrix is read-only.");
101        if (value != Rows) {
102          string[,] newMatrix = new string[value, Columns];
103          Array.Copy(matrix, newMatrix, Math.Min(value * Columns, matrix.Length));
104          matrix = newMatrix;
105          while (rowNames.Count > value)
106            rowNames.RemoveAt(rowNames.Count - 1);
107          while (rowNames.Count < value)
108            rowNames.Add("Row " + rowNames.Count);
109          OnRowsChanged();
110          OnRowNamesChanged();
111          OnReset();
112        }
113      }
114    }
115    public virtual int Columns
116    {
117      get { return matrix.GetLength(1); }
118      protected set
119      {
120        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. StringMatrix is read-only.");
121        if (value != Columns) {
122          string[,] newMatrix = new string[Rows, value];
123          for (int i = 0; i < Rows; i++)
124            Array.Copy(matrix, i * Columns, newMatrix, i * value, Math.Min(value, Columns));
125          matrix = newMatrix;
126          while (columnNames.Count > value)
127            columnNames.RemoveAt(columnNames.Count - 1);
128          while (columnNames.Count < value)
129            columnNames.Add("Column " + columnNames.Count);
130          OnColumnsChanged();
131          OnColumnNamesChanged();
132          OnReset();
133        }
134      }
135    }
136    public virtual string this[int rowIndex, int columnIndex]
137    {
138      get { return matrix[rowIndex, columnIndex]; }
139      set
140      {
141        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
142        if (value != matrix[rowIndex, columnIndex]) {
143          if ((value != null) || (matrix[rowIndex, columnIndex] != string.Empty)) {
144            matrix[rowIndex, columnIndex] = value != null ? value : string.Empty;
145            OnItemChanged(rowIndex, columnIndex);
146          }
147        }
148      }
149    }
150
151    [Storable]
152    protected bool readOnly;
153    public virtual bool ReadOnly
154    {
155      get { return readOnly; }
156    }
157
158    [StorableConstructor]
159    protected StringMatrix(bool deserializing) : base(deserializing) { }
160    protected StringMatrix(StringMatrix original, Cloner cloner)
161      : base(original, cloner) {
162      this.matrix = (string[,])original.matrix.Clone();
163      this.columnNames = new List<string>(original.columnNames);
164      this.rowNames = new List<string>(original.rowNames);
165      this.sortableView = original.sortableView;
166      this.readOnly = original.readOnly;
167    }
168    public StringMatrix() {
169      matrix = new string[0, 0];
170      columnNames = new List<string>();
171      rowNames = new List<string>();
172      sortableView = false;
173      readOnly = false;
174    }
175    public StringMatrix(int rows, int columns) {
176      matrix = new string[rows, columns];
177      for (int i = 0; i < matrix.GetLength(0); i++) {
178        for (int j = 0; j < matrix.GetLength(1); j++)
179          matrix[i, j] = string.Empty;
180      }
181      columnNames = new List<string>();
182      rowNames = new List<string>();
183      sortableView = false;
184      readOnly = false;
185    }
186    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames)
187      : this(rows, columns) {
188      ColumnNames = columnNames;
189    }
190    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
191      : this(rows, columns, columnNames) {
192      RowNames = rowNames;
193    }
194    public StringMatrix(string[,] elements) {
195      if (elements == null) throw new ArgumentNullException();
196      matrix = new string[elements.GetLength(0), elements.GetLength(1)];
197      for (int i = 0; i < matrix.GetLength(0); i++) {
198        for (int j = 0; j < matrix.GetLength(1); j++)
199          matrix[i, j] = elements[i, j] == null ? string.Empty : elements[i, j];
200      }
201      columnNames = new List<string>();
202      rowNames = new List<string>();
203      sortableView = false;
204      readOnly = false;
205    }
206    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
207      : this(elements) {
208      ColumnNames = columnNames;
209    }
210    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
211      : this(elements, columnNames) {
212      RowNames = rowNames;
213    }
214
215    public override IDeepCloneable Clone(Cloner cloner) {
216      return new StringMatrix(this, cloner);
217    }
218
219    public virtual StringMatrix AsReadOnly() {
220      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
221      readOnlyStringMatrix.readOnly = true;
222      return readOnlyStringMatrix;
223    }
224
225    public override string ToString() {
226      if (matrix.Length == 0) return "[]";
227
228      StringBuilder sb = new StringBuilder();
229      sb.Append("[");
230      for (int i = 0; i < Rows; i++) {
231        sb.Append("[").Append(matrix[i, 0]);
232        for (int j = 1; j < Columns; j++)
233          sb.Append(";").Append(matrix[i, j]);
234        sb.Append("]");
235
236        if (sb.Length > maximumToStringLength) {
237          sb.Append("[...]");
238          break;
239        }
240      }
241      sb.Append("]");
242
243      return sb.ToString();
244    }
245
246    public virtual IEnumerator<string> GetEnumerator() {
247      return matrix.Cast<string>().GetEnumerator();
248    }
249
250    IEnumerator IEnumerable.GetEnumerator() {
251      return GetEnumerator();
252    }
253
254    protected virtual bool Validate(string value, out string errorMessage) {
255      if (value == null) {
256        errorMessage = "Invalid Value (string must not be null)";
257        return false;
258      } else {
259        errorMessage = string.Empty;
260        return true;
261      }
262    }
263    protected virtual string GetValue(int rowIndex, int columIndex) {
264      return this[rowIndex, columIndex];
265    }
266    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
267      if (value != null) {
268        this[rowIndex, columnIndex] = value;
269        return true;
270      } else {
271        return false;
272      }
273    }
274
275    #region events
276    public event EventHandler ColumnsChanged;
277    protected virtual void OnColumnsChanged() {
278      EventHandler handler = ColumnsChanged;
279      if (handler != null)
280        handler(this, EventArgs.Empty);
281    }
282    public event EventHandler RowsChanged;
283    protected virtual void OnRowsChanged() {
284      EventHandler handler = RowsChanged;
285      if (handler != null)
286        handler(this, EventArgs.Empty);
287    }
288    public event EventHandler ColumnNamesChanged;
289    protected virtual void OnColumnNamesChanged() {
290      EventHandler handler = ColumnNamesChanged;
291      if (handler != null)
292        handler(this, EventArgs.Empty);
293    }
294    public event EventHandler RowNamesChanged;
295    protected virtual void OnRowNamesChanged() {
296      EventHandler handler = RowNamesChanged;
297      if (handler != null)
298        handler(this, EventArgs.Empty);
299    }
300    public event EventHandler SortableViewChanged;
301    protected virtual void OnSortableViewChanged() {
302      EventHandler handler = SortableViewChanged;
303      if (handler != null)
304        handler(this, EventArgs.Empty);
305    }
306    public event EventHandler<EventArgs<int, int>> ItemChanged;
307    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
308      if (ItemChanged != null)
309        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
310
311      //approximation to avoid firing of unnecessary ToStringChangedEvents
312      //columnIndex is not used, because always full rows are returned in the ToString method
313      if (rowIndex * Columns < maximumToStringLength)
314        OnToStringChanged();
315    }
316    public event EventHandler Reset;
317    protected virtual void OnReset() {
318      if (Reset != null)
319        Reset(this, EventArgs.Empty);
320      OnToStringChanged();
321    }
322    #endregion
323
324    #region IStringConvertibleMatrix Members
325    int IStringConvertibleMatrix.Rows
326    {
327      get { return Rows; }
328      set { Rows = value; }
329    }
330    int IStringConvertibleMatrix.Columns
331    {
332      get { return Columns; }
333      set { Columns = value; }
334    }
335    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
336      return Validate(value, out errorMessage);
337    }
338    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
339      return GetValue(rowIndex, columIndex);
340    }
341    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
342      return SetValue(value, rowIndex, columnIndex);
343    }
344    #endregion
345  }
346}
Note: See TracBrowser for help on using the repository browser.