Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKB/HeuristicLab.OKB.Cockpit.Query/RunView.xaml.cs @ 4848

Last change on this file since 4848 was 4311, checked in by swagner, 14 years ago

Integrated OKB clients for HL 3.3 (#1166)

File size: 10.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Data;
6using System.Windows.Controls;
7using System.Windows.Data;
8using HeuristicLab.BackgroundProcessing;
9using System.ComponentModel;
10using System.Windows;
11using System.IO;
12using System.Threading;
13using System.Collections.Specialized;
14using HeuristicLab.MainForm.WPF;
15using HeuristicLab.OKB.Cockpit.Query.OKBQuery;
16using HeuristicLab.MainForm;
17using HeuristicLab.OKB.Client;
18
19namespace HeuristicLab.OKB.Cockpit.Query {
20
21  public partial class RunView : UserControl, IAutoView, IOKBCockpitItem {
22
23    private object selectorRefreshLock = new object();
24    private AttributeSelectors attributeSelectors;
25    private DataTable runTable;
26    private List<AttributeSelector> selectors = null;
27    private ManualResetEvent selectorsInitialized = new ManualResetEvent(false);
28
29    public RunView() {
30      InitializeComponent();
31      attributeSelectors = new AttributeSelectors();
32      GridView view = (GridView)Runs.View;
33      attributeSelectors.CollectionChanged += (sender, args) => {
34        if (args.Action == NotifyCollectionChangedAction.Add) {
35          foreach (AttributeSelector selector in args.NewItems) {
36            GridViewColumn column = new GridViewColumn() {
37              Header = selector,
38              DisplayMemberBinding = new Binding(selector.ColumnName),
39            };
40            view.Columns.Add(column);
41            selector.PropertyChanged += (s, a) => {
42              if (a.PropertyName == "ColumnName") {
43                column.DisplayMemberBinding = new Binding(selector.ColumnName);
44              }
45              Validate();
46            };
47          }
48        } else if (args.Action == NotifyCollectionChangedAction.Remove) {
49          foreach (AttributeSelector selector in args.OldItems) {
50            view.Columns.Remove(view.Columns.First(i => i.Header == selector));
51          }
52        }
53      };
54      attributeSelectors.Add(new AttributeSelector("Run", "Id", typeof(int)));
55      attributeSelectors.Add(new AttributeSelector("Run", "FinishedDate", typeof(DateTime)));
56      attributeSelectors.Add(new AttributeSelector("Algorithm", "Name", typeof(string)));
57      attributeSelectors.Add(new AttributeSelector("Problem", "Name", typeof(string)));
58      attributeSelectors.Add(new AttributeSelector("SolutionRepresentation", "Name", typeof(string)));
59      RefreshSelectors();
60    }
61
62    #region IView Members
63
64    public string Caption {
65      get { return "Run View"; }
66      set { throw new NotSupportedException(); }
67    }
68
69    public event EventHandler CaptionChanged;
70
71    public event EventHandler Changed;
72
73    protected void OnChanged() {
74      EventHandler handler = CaptionChanged;
75      if (handler != null)
76        handler(this, EventArgs.Empty);
77    }
78
79    public virtual void Close() {
80      MainFormManager.GetMainForm<WPFMainFormBase>().CloseView(this);
81      IsShown = false;
82    }
83
84    public void Hide() {
85      MainFormManager.GetMainForm<WPFMainFormBase>().HideView(this);
86      IsShown = false;
87    }
88
89    public bool IsShown { get; protected set; }
90
91    private bool readOnly = false;
92    public bool ReadOnly {
93      get {
94        return readOnly;
95      }
96      set {
97        if (value == readOnly) return;
98        readOnly = value;
99        OnReadOnlyChanged();
100      }
101    }
102    public event EventHandler ReadOnlyChanged;
103    protected void OnReadOnlyChanged() {
104      EventHandler handler = ReadOnlyChanged;
105      if (handler != null)
106        handler(this, EventArgs.Empty);
107    }
108
109    public void Show() {
110      MainFormManager.GetMainForm<WPFMainFormBase>().ShowView(this);
111      IsShown = true;
112    }
113
114    #endregion
115
116    protected void OnAddClicked(object sender, EventArgs args) {
117      AddItem();
118    }
119
120    protected void OnCheckClicked(object sender, EventArgs args) {
121      var loader = new ObservableBackgroundWorker("Checking Runs");
122      int? count = null;
123      bool failed = false;
124      loader.DoWork += (snd, arg) => {
125        try {
126          QueryServiceClient client = ClientFactory.Create<QueryServiceClient, IQueryService>();
127          client.PrepareQuery(attributeSelectors.ToList());
128          count = client.GetCount();
129          client.Terminate();
130          client.Close();
131        } catch {
132          failed = true;
133        }
134      };
135      loader.RunWorkerCompleted += (snd, arg) => {
136        if (failed) {
137          NrOfRunsLabel.Text = "?";
138          MessageBox.Show("Checking runs failed.", Caption);
139        } else {
140          NrOfRunsLabel.Text = count.ToString();
141        }
142      };
143      loader.RunWorkerAsync();
144    }
145
146
147    private void RefreshSelectors() {
148      ObservableBackgroundWorker loader = new ObservableBackgroundWorker("Fetching DB schema");
149      bool failed = false;
150      loader.DoWork += (s, a) => {
151        try {
152          QueryServiceClient client = ClientFactory.Create<QueryServiceClient, IQueryService>();
153          selectors = client.GetAllAttributeSelectors();
154        } catch {
155          failed = true;
156        } finally {
157          selectorsInitialized.Set();
158        }
159      };
160      loader.RunWorkerCompleted += (s, a) => {
161        if (failed) {
162          if (MessageBox.Show(
163                "Could not fetch DB Schema. Retry?", Caption,
164                MessageBoxButton.OKCancel) == MessageBoxResult.OK) {
165            selectorsInitialized.Reset();
166            RefreshSelectors();
167          }
168        }
169      };
170      loader.RunWorkerAsync();
171    }
172
173    protected void AddItem() {
174      BackgroundWorker waiter = new BackgroundWorker();
175      waiter.DoWork += (s, a) => selectorsInitialized.WaitOne();
176      waiter.RunWorkerCompleted += (s, a) => {
177        if (!VerifySelectors())
178          return;
179        var selector = new AttributeSelectorWindow(selectors) {
180          Owner = MainFormManager.GetMainForm<CockpitMainWindow>(),
181        };
182        if (selector.ShowDialog() == true) {
183          attributeSelectors.Add(selector.AttributeSelector);
184        }
185      };
186      waiter.RunWorkerAsync();
187    }
188
189    private bool VerifySelectors() {
190      if (selectors == null &&
191          MessageBox.Show(
192            "Schema information not available. Retry?",
193            this.Caption, MessageBoxButton.OKCancel) == MessageBoxResult.OK) {
194        selectorsInitialized.Reset();
195        RefreshSelectors();
196        return false;
197      }
198      return true;
199    }
200
201    protected void OnUpdateClicked(object sender, EventArgs args) {
202      var loader = new ObservableBackgroundWorker("Preparing Query") {
203        WorkerReportsProgress = true,
204        WorkerSupportsCancellation = true,
205      };
206      int total = 0;
207      loader.DoWork += (snd, arg) => {
208        loader.ReportProgress(0);
209        QueryServiceClient client = ClientFactory.Create<QueryServiceClient, IQueryService>();
210        runTable = client.PrepareQuery(attributeSelectors.ToList());
211        loader.ReportProgress(50);
212        total = client.GetCount();
213        int stepSize = Math.Max(1, Math.Min(total / 100, 100));
214        loader.ReportProgress(100);
215        Thread.Sleep(0);
216        loader.Name = "Loading Runs";
217        loader.ReportProgress(0);
218        if (total > 0) {
219          DataTable newRows = new DataTable();
220          do {
221            newRows = client.GetNextRows(stepSize);
222            runTable.Merge(newRows);
223            loader.ReportProgress(100 * runTable.Rows.Count / total);
224          } while (!loader.CancellationPending && newRows.Rows.Count > 0);
225        }
226        client.Terminate();
227        client.Close();
228        loader.ReportProgress(100);
229      };
230      loader.RunWorkerCompleted += (snd, arg) => {
231        if (arg.Error == null) {
232          NrOfRunsLabel.Text = total.ToString();
233          for (int i = 0; i < runTable.Columns.Count; i++) {
234            attributeSelectors[i].ColumnName = runTable.Columns[i].ColumnName;
235          }
236          Runs.DataContext = runTable;
237          Runs.SetBinding(ListView.ItemsSourceProperty, new Binding());
238        } else {
239          NrOfRunsLabel.Text = "?";
240        }
241      };
242      loader.RunWorkerAsync();
243    }
244
245    protected void ContextMenuClicked(object sender, RoutedEventArgs args) {
246      ContextMenu menu = sender as ContextMenu;
247      MenuItem item = args.Source as MenuItem;
248      AttributeSelector selector = menu.Tag as AttributeSelector;
249      if (menu == null || item == null || selector == null)
250        return;
251      if (item.Name == "ConfigureItem") {
252        BackgroundWorker waiter = new BackgroundWorker();
253        waiter.DoWork += (s, a) => selectorsInitialized.WaitOne();
254        waiter.RunWorkerCompleted += (s, a) => {
255          if (!VerifySelectors())
256            return;
257          var selectorView = new AttributeSelectorWindow(selectors) {
258            Owner = MainFormManager.GetMainForm<CockpitMainWindow>(),
259            AttributeSelector = selector,
260          };
261          selectorView.ShowDialog();
262        };
263        waiter.RunWorkerAsync();
264      } else if (item.Name == "RemoveItem") {
265        attributeSelectors.Remove(selector);
266      } else if (item.Name == "AddColumn") {
267        AddItem();
268      }
269    }
270
271    protected void OnCopyClicked(object sender, RoutedEventArgs args) {
272      ObservableBackgroundWorker copier = new ObservableBackgroundWorker("Copying to Clipboard") {
273        WorkerReportsProgress = true,
274        WorkerSupportsCancellation = true
275      };
276      StringBuilder sb = new StringBuilder();
277      copier.DoWork += (s, a) => {
278        sb.Append(
279          string.Join("\t",
280            runTable.Columns.Cast<DataColumn>()
281            .Select(c => c.ColumnName)
282            .ToArray()))
283          .Append('\n');
284        int i = 0;
285        int lastProgress = 0;
286        foreach (DataRow row in runTable.Rows) {
287          sb.Append(string.Join("\t", row.ItemArray.Select(v => v.ToString()).ToArray())).Append('\n');
288          i++;
289          int progress = 100 * i / runTable.Rows.Count;
290          if (progress > lastProgress) {
291            copier.ReportProgress(progress);
292            lastProgress = progress;
293            Thread.Sleep(0);
294          }
295          if (copier.CancellationPending) {
296            a.Cancel = true;
297            break;
298          }
299        }
300      };
301      copier.RunWorkerCompleted += (s, a) => {
302        if (!a.Cancelled)
303          Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
304      };
305      copier.RunWorkerAsync();
306    }
307
308    protected void Validate() {
309      CheckButton.IsEnabled = UpdateButton.IsEnabled = attributeSelectors.All(s => s.IsValid);
310      if (CheckButton.IsEnabled) {
311        ErrorMessages.Text = "";
312      } else {
313        ErrorMessages.Text = "Invalid attribute selector configuration";
314      }
315    }
316  }
317}
Note: See TracBrowser for help on using the repository browser.