Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringMatrix.cs @ 9308

Last change on this file since 9308 was 9308, checked in by sforsten, 11 years ago

#2018:

  • added column names to the ValueTypeArray and StringArray
  • added batch update methods to IStringConvertibleArray similar to methods in IStringConvertibleMatrix
File size: 12.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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    public static new Image StaticItemImage {
37      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
38    }
39
40    [Storable]
41    protected string[,] matrix;
42
43    [Storable]
44    protected List<string> columnNames;
45    public virtual IEnumerable<string> ColumnNames {
46      get { return this.columnNames; }
47      set {
48        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. StringMatrix is read-only.");
49        if (value == null || value.Count() == 0)
50          columnNames = new List<string>();
51        else if (value.Count() != Columns)
52          throw new ArgumentException("A column name must be specified for each column .");
53        else
54          columnNames = new List<string>(value);
55        OnColumnNamesChanged();
56      }
57    }
58    [Storable]
59    protected List<string> rowNames;
60    public virtual IEnumerable<string> RowNames {
61      get { return this.rowNames; }
62      set {
63        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. StringMatrix is read-only.");
64        if (value == null || value.Count() == 0)
65          rowNames = new List<string>();
66        else if (value.Count() != Rows)
67          throw new ArgumentException("A row name must be specified for each row.");
68        else
69          rowNames = new List<string>(value);
70        OnRowNamesChanged();
71      }
72    }
73    [Storable]
74    protected bool sortableView;
75    public virtual bool SortableView {
76      get { return sortableView; }
77      set {
78        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. StringMatrix is read-only.");
79        if (value != sortableView) {
80          sortableView = value;
81          OnSortableViewChanged();
82        }
83      }
84    }
85
86    public virtual int Rows {
87      get { return matrix.GetLength(0); }
88      protected set {
89        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. StringMatrix is read-only.");
90        if (value != Rows) {
91          string[,] newMatrix = new string[value, Columns];
92          Array.Copy(matrix, newMatrix, Math.Min(value * Columns, matrix.Length));
93          matrix = newMatrix;
94          while (rowNames.Count > value)
95            rowNames.RemoveAt(rowNames.Count - 1);
96          while (rowNames.Count < value)
97            rowNames.Add("Row " + rowNames.Count);
98          OnRowsChanged();
99          OnRowNamesChanged();
100          OnReset();
101        }
102      }
103    }
104    public virtual int Columns {
105      get { return matrix.GetLength(1); }
106      protected set {
107        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. StringMatrix is read-only.");
108        if (value != Columns) {
109          string[,] newMatrix = new string[Rows, value];
110          for (int i = 0; i < Rows; i++)
111            Array.Copy(matrix, i * Columns, newMatrix, i * value, Math.Min(value, Columns));
112          matrix = newMatrix;
113          while (columnNames.Count > value)
114            columnNames.RemoveAt(columnNames.Count - 1);
115          while (columnNames.Count < value)
116            columnNames.Add("Column " + columnNames.Count);
117          OnColumnsChanged();
118          OnColumnNamesChanged();
119          OnReset();
120        }
121      }
122    }
123    public virtual string this[int rowIndex, int columnIndex] {
124      get { return matrix[rowIndex, columnIndex]; }
125      set {
126        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
127        if (value != matrix[rowIndex, columnIndex]) {
128          if ((value != null) || (matrix[rowIndex, columnIndex] != string.Empty)) {
129            matrix[rowIndex, columnIndex] = value != null ? value : string.Empty;
130            OnItemsChanged(new List<MatrixPosition>(1) { new MatrixPosition(rowIndex, columnIndex) });
131          }
132        }
133      }
134    }
135
136    [Storable]
137    protected bool readOnly;
138    public virtual bool ReadOnly {
139      get { return readOnly; }
140    }
141
142    [StorableConstructor]
143    protected StringMatrix(bool deserializing) : base(deserializing) { }
144    protected StringMatrix(StringMatrix original, Cloner cloner)
145      : base(original, cloner) {
146      this.matrix = (string[,])original.matrix.Clone();
147      this.columnNames = new List<string>(original.columnNames);
148      this.rowNames = new List<string>(original.rowNames);
149      this.sortableView = original.sortableView;
150      this.readOnly = original.readOnly;
151    }
152    public StringMatrix() {
153      matrix = new string[0, 0];
154      columnNames = new List<string>();
155      rowNames = new List<string>();
156      sortableView = false;
157      readOnly = false;
158    }
159    public StringMatrix(int rows, int columns) {
160      matrix = new string[rows, columns];
161      for (int i = 0; i < matrix.GetLength(0); i++) {
162        for (int j = 0; j < matrix.GetLength(1); j++)
163          matrix[i, j] = string.Empty;
164      }
165      columnNames = new List<string>();
166      rowNames = new List<string>();
167      sortableView = false;
168      readOnly = false;
169    }
170    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames)
171      : this(rows, columns) {
172      ColumnNames = columnNames;
173    }
174    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
175      : this(rows, columns, columnNames) {
176      RowNames = rowNames;
177    }
178    public StringMatrix(string[,] elements) {
179      if (elements == null) throw new ArgumentNullException();
180      matrix = new string[elements.GetLength(0), elements.GetLength(1)];
181      for (int i = 0; i < matrix.GetLength(0); i++) {
182        for (int j = 0; j < matrix.GetLength(1); j++)
183          matrix[i, j] = elements[i, j] == null ? string.Empty : elements[i, j];
184      }
185      columnNames = new List<string>();
186      rowNames = new List<string>();
187      sortableView = false;
188      readOnly = false;
189    }
190    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
191      : this(elements) {
192      ColumnNames = columnNames;
193    }
194    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
195      : this(elements, columnNames) {
196      RowNames = rowNames;
197    }
198
199    public override IDeepCloneable Clone(Cloner cloner) {
200      return new StringMatrix(this, cloner);
201    }
202
203    public virtual StringMatrix AsReadOnly() {
204      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
205      readOnlyStringMatrix.readOnly = true;
206      return readOnlyStringMatrix;
207    }
208
209    public override string ToString() {
210      StringBuilder sb = new StringBuilder();
211      sb.Append("[");
212      if (matrix.Length > 0) {
213        for (int i = 0; i < Rows; i++) {
214          sb.Append("[").Append(matrix[i, 0]);
215          for (int j = 1; j < Columns; j++)
216            sb.Append(";").Append(matrix[i, j]);
217          sb.Append("]");
218        }
219      }
220      sb.Append("]");
221      return sb.ToString();
222    }
223
224    public virtual IEnumerator<string> GetEnumerator() {
225      return matrix.Cast<string>().GetEnumerator();
226    }
227
228    IEnumerator IEnumerable.GetEnumerator() {
229      return GetEnumerator();
230    }
231
232    protected virtual bool Validate(string value, out string errorMessage) {
233      if (value == null) {
234        errorMessage = "Invalid Value (string must not be null)";
235        return false;
236      } else {
237        errorMessage = string.Empty;
238        return true;
239      }
240    }
241    protected virtual string GetValue(int rowIndex, int columIndex) {
242      return this[rowIndex, columIndex];
243    }
244    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
245      if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
246      if (value != null) {
247        this[rowIndex, columnIndex] = value;
248        return true;
249      } else {
250        return false;
251      }
252    }
253    public virtual bool SetValue(IEnumerable<MatrixValue<string>> matrixValues) {
254      if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
255      if (!matrixValues.All(v => v.Value != null)) return false;
256      MatrixPosition pos;
257      foreach (var curValue in matrixValues) {
258        pos = curValue.Position;
259        matrix[pos.Row, pos.Column] = curValue.Value;
260      }
261      OnItemsChanged(matrixValues.Select(x => x.Position));
262      return true;
263    }
264
265    #region events
266    public event EventHandler ColumnsChanged;
267    protected virtual void OnColumnsChanged() {
268      EventHandler handler = ColumnsChanged;
269      if (handler != null)
270        handler(this, EventArgs.Empty);
271    }
272    public event EventHandler RowsChanged;
273    protected virtual void OnRowsChanged() {
274      EventHandler handler = RowsChanged;
275      if (handler != null)
276        handler(this, EventArgs.Empty);
277    }
278    public event EventHandler ColumnNamesChanged;
279    protected virtual void OnColumnNamesChanged() {
280      EventHandler handler = ColumnNamesChanged;
281      if (handler != null)
282        handler(this, EventArgs.Empty);
283    }
284    public event EventHandler RowNamesChanged;
285    protected virtual void OnRowNamesChanged() {
286      EventHandler handler = RowNamesChanged;
287      if (handler != null)
288        handler(this, EventArgs.Empty);
289    }
290    public event EventHandler SortableViewChanged;
291    protected virtual void OnSortableViewChanged() {
292      EventHandler handler = SortableViewChanged;
293      if (handler != null)
294        handler(this, EventArgs.Empty);
295    }
296    public event EventHandler<MatrixValuesChangedEventArgs> ItemsChanged;
297    protected virtual void OnItemsChanged(IEnumerable<MatrixPosition> positions) {
298      if (ItemsChanged != null)
299        ItemsChanged(this, new MatrixValuesChangedEventArgs(positions));
300      OnToStringChanged();
301    }
302    public event EventHandler Reset;
303    protected virtual void OnReset() {
304      if (Reset != null)
305        Reset(this, EventArgs.Empty);
306      OnToStringChanged();
307    }
308    #endregion
309
310    #region IStringConvertibleMatrix Members
311    int IStringConvertibleMatrix.Rows {
312      get { return Rows; }
313      set { Rows = value; }
314    }
315    int IStringConvertibleMatrix.Columns {
316      get { return Columns; }
317      set { Columns = value; }
318    }
319    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
320      return Validate(value, out errorMessage);
321    }
322    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
323      return GetValue(rowIndex, columIndex);
324    }
325    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
326      return SetValue(value, rowIndex, columnIndex);
327    }
328    public bool SetValue(MatrixValue<string> rowColumnValue) {
329      return SetValue(rowColumnValue.Value, rowColumnValue.Position.Row, rowColumnValue.Position.Column);
330    }
331    bool IStringConvertibleMatrix.SetValues(IEnumerable<MatrixValue<string>> rowColumnValues) {
332      return SetValue(rowColumnValues);
333    }
334    #endregion
335  }
336}
Note: See TracBrowser for help on using the repository browser.