Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginAdministrator/3.3/PluginEditor.cs @ 3345

Last change on this file since 3345 was 3208, checked in by gkronber, 15 years ago

Implemented changes in plugin administrator UI as requested by swagner. #949 (Overhaul look and feel of plugin administrator)

File size: 12.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Data;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.MainForm;
31using HeuristicLab.PluginInfrastructure;
32using PluginDeploymentService = HeuristicLab.PluginInfrastructure.Advanced.DeploymentService;
33using HeuristicLab.PluginInfrastructure.Manager;
34using System.ServiceModel;
35using ICSharpCode.SharpZipLib.Zip;
36using System.IO;
37
38namespace HeuristicLab.PluginAdministrator {
39  internal partial class PluginEditor : HeuristicLab.MainForm.WindowsForms.View {
40    private Dictionary<IPluginDescription, PluginDeploymentService.PluginDescription> localAndServerPlugins;
41    private BackgroundWorker pluginUploadWorker;
42    private BackgroundWorker updateServerPluginsWorker;
43
44    public PluginEditor() {
45      InitializeComponent();
46      Caption = "Upload Plugins";
47
48      localAndServerPlugins = new Dictionary<IPluginDescription, PluginDeploymentService.PluginDescription>();
49
50      #region initialize backgroundworkers
51      pluginUploadWorker = new BackgroundWorker();
52      pluginUploadWorker.DoWork += new DoWorkEventHandler(pluginUploadWorker_DoWork);
53      pluginUploadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(pluginUploadWorker_RunWorkerCompleted);
54
55      updateServerPluginsWorker = new BackgroundWorker();
56      updateServerPluginsWorker.DoWork += new DoWorkEventHandler(updateServerPluginsWorker_DoWork);
57      updateServerPluginsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updateServerPluginsWorker_RunWorkerCompleted);
58      #endregion
59    }
60
61    #region refresh plugins from server backgroundworker
62    void updateServerPluginsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
63      if (!e.Cancelled && e.Result != null) {
64        // refresh local plugins
65        localAndServerPlugins.Clear();
66        foreach (var plugin in ApplicationManager.Manager.Plugins) {
67          localAndServerPlugins.Add(plugin, null);
68        }
69        // refresh server plugins (find matching local plugins)
70        var plugins = (PluginDeploymentService.PluginDescription[])e.Result;
71        foreach (var plugin in plugins) {
72          var matchingLocalPlugin = (from localPlugin in localAndServerPlugins.Keys
73                                     where localPlugin.Name == plugin.Name
74                                     where localPlugin.Version == localPlugin.Version
75                                     select localPlugin).SingleOrDefault();
76          if (matchingLocalPlugin != null) {
77            localAndServerPlugins[matchingLocalPlugin] = plugin;
78          }
79        }
80        // refresh the list view with plugins
81        listView.Items.Clear();
82        listView.CheckBoxes = false;
83        //suppressCheckedEvents = true;
84        foreach (var pair in localAndServerPlugins) {
85          var item = MakeListViewItem(pair.Key);
86          listView.Items.Add(item);
87        }
88        foreach (ColumnHeader column in listView.Columns)
89          column.Width = -1;
90        //listView.suppressCheckedEvents = false;
91        listView.CheckBoxes = true;
92        UpdateControlsConnectedState();
93      } else {
94        UpdateControlsDisconnectedState();
95      }
96      // make sure cursor is set correctly
97      Cursor = Cursors.Default;
98    }
99
100    void updateServerPluginsWorker_DoWork(object sender, DoWorkEventArgs e) {
101      try {
102        var client = PluginDeploymentService.UpdateClientFactory.CreateClient();
103        e.Result = client.GetPlugins();
104        e.Cancel = false;
105      }
106      catch (EndpointNotFoundException) {
107        e.Result = null;
108        e.Cancel = true;
109      }
110      catch (FaultException) {
111        e.Result = null;
112        e.Cancel = true;
113      }
114    }
115    #endregion
116
117    #region upload plugins to server backgroundworker
118    void pluginUploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
119      Cursor = Cursors.Default;
120      if (e.Cancelled) {
121        UpdateControlsDisconnectedState();
122      } else {
123        UpdateControlsConnectedState();
124        // start another async call to refresh plugin information from server
125        RefreshPluginsAsync();
126      }
127    }
128
129    void pluginUploadWorker_DoWork(object sender, DoWorkEventArgs e) {
130      try {
131        var selectedPlugins = (IEnumerable<IPluginDescription>)e.Argument;
132        PluginDeploymentService.AdminClient adminClient = PluginDeploymentService.AdminClientFactory.CreateClient();
133
134        foreach (var plugin in IteratePlugins(selectedPlugins)) {
135          SetMainFormStatusBar("Uploading", plugin);
136          adminClient.DeployPlugin(MakePluginDescription(plugin), CreateZipPackage(plugin));
137        }
138        e.Cancel = false;
139      }
140      catch (EndpointNotFoundException) {
141        e.Cancel = true;
142      }
143      catch (FaultException) {
144        e.Cancel = true;
145      }
146    }
147
148    #endregion
149
150
151    #region button events
152    private void uploadButton_Click(object sender, EventArgs e) {
153      var selectedPlugins = from item in listView.Items.Cast<ListViewItem>()
154                            where item.Checked
155                            where item.Tag is IPluginDescription
156                            select item.Tag as IPluginDescription;
157      if (selectedPlugins.Count() > 0) {
158        Cursor = Cursors.AppStarting;
159        DisableControl();
160        pluginUploadWorker.RunWorkerAsync(selectedPlugins.ToList());
161      }
162    }
163
164    private void refreshButton_Click(object sender, EventArgs e) {
165      DisableControl();
166      RefreshPluginsAsync();
167    }
168
169    #endregion
170
171    #region item list events
172    private void listView_ItemActivate(object sender, EventArgs e) {
173      foreach (var item in listView.SelectedItems) {
174        var plugin = (IPluginDescription)((ListViewItem)item).Tag;
175        var compView = new PluginComparisonView(plugin, localAndServerPlugins[plugin]);
176        compView.Show();
177      }
178    }
179
180    private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) {
181      List<IPluginDescription> modifiedPlugins = new List<IPluginDescription>();
182      if (e.Item.Checked) {
183        foreach (ListViewItem item in listView.SelectedItems) {
184          var plugin = (IPluginDescription)item.Tag;
185          // also check all dependencies
186          if (!modifiedPlugins.Contains(plugin))
187            modifiedPlugins.Add(plugin);
188          foreach (var dep in GetAllDependencies(plugin)) {
189            if (!modifiedPlugins.Contains(dep))
190              modifiedPlugins.Add(dep);
191          }
192        }
193        listView.CheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
194      } else {
195        foreach (ListViewItem item in listView.SelectedItems) {
196          var plugin = (IPluginDescription)item.Tag;
197          // also uncheck all dependent plugins
198          if (!modifiedPlugins.Contains(plugin))
199            modifiedPlugins.Add(plugin);
200          foreach (var dep in GetAllDependents(plugin)) {
201            if (!modifiedPlugins.Contains(dep))
202              modifiedPlugins.Add(dep);
203          }
204        }
205        listView.UncheckItems(modifiedPlugins.Select(x => FindItemForPlugin(x)));
206      }
207      uploadButton.Enabled = (from i in listView.Items.OfType<ListViewItem>()
208                              where i.Checked
209                              select i).Any();
210    }
211    #endregion
212
213    #region helper methods
214    private IEnumerable<IPluginDescription> GetAllDependents(IPluginDescription plugin) {
215      return from p in localAndServerPlugins.Keys
216             let matchingEntries = from dep in GetAllDependencies(p)
217                                   where dep.Name == plugin.Name
218                                   where dep.Version == plugin.Version
219                                   select dep
220             where matchingEntries.Any()
221             select p;
222    }
223
224    private IEnumerable<IPluginDescription> GetAllDependencies(IPluginDescription plugin) {
225      foreach (var dep in plugin.Dependencies) {
226        foreach (var recDep in GetAllDependencies(dep)) {
227          yield return recDep;
228        }
229        yield return dep;
230      }
231    }
232
233    private IEnumerable<IPluginDescription> IteratePlugins(IEnumerable<IPluginDescription> plugins) {
234      HashSet<IPluginDescription> yieldedItems = new HashSet<IPluginDescription>();
235      foreach (var plugin in plugins) {
236        foreach (var dependency in IteratePlugins(plugin.Dependencies)) {
237          if (!yieldedItems.Contains(dependency)) {
238            yieldedItems.Add(dependency);
239            yield return dependency;
240          }
241        }
242        if (!yieldedItems.Contains(plugin)) {
243          yieldedItems.Add(plugin);
244          yield return plugin;
245        }
246      }
247    }
248
249    private byte[] CreateZipPackage(IPluginDescription plugin) {
250      using (MemoryStream stream = new MemoryStream()) {
251        ZipFile zipFile = new ZipFile(stream);
252        zipFile.BeginUpdate();
253        foreach (var file in plugin.Files) {
254          zipFile.Add(file.Name);
255        }
256        zipFile.CommitUpdate();
257        stream.Seek(0, SeekOrigin.Begin);
258        return stream.GetBuffer();
259      }
260    }
261
262    private ListViewItem MakeListViewItem(IPluginDescription plugin) {
263      ListViewItem item;
264      if (localAndServerPlugins[plugin] != null) {
265        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
266          localAndServerPlugins[plugin].Version.ToString(), localAndServerPlugins[plugin].Description });
267      } else {
268        item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
269          string.Empty, plugin.Description });
270      }
271      item.Tag = plugin;
272      item.Checked = false;
273      return item;
274    }
275
276    private ListViewItem FindItemForPlugin(IPluginDescription dep) {
277      return (from i in listView.Items.Cast<ListViewItem>()
278              where i.Tag == dep
279              select i).Single();
280    }
281
282    private PluginDeploymentService.PluginDescription MakePluginDescription(IPluginDescription plugin) {
283      var dependencies = from dep in plugin.Dependencies
284                         select MakePluginDescription(dep);
285      return new PluginDeploymentService.PluginDescription(plugin.Name, plugin.Version, dependencies, plugin.ContactName, plugin.ContactEmail, plugin.LicenseText);
286    }
287
288    // start background process to refresh the plugin list (local and server)
289    private void RefreshPluginsAsync() {
290      Cursor = Cursors.AppStarting;
291      DisableControl();
292      updateServerPluginsWorker.RunWorkerAsync();
293    }
294
295    // is called by all methods that start a background process
296    // controls must be enabled manuall again when the backgroundworker finishes
297    private void DisableControl() {
298      MainFormManager.GetMainForm<MainForm>().ShowProgressBar();
299      foreach (Control ctrl in Controls)
300        ctrl.Enabled = false;
301    }
302
303    private void UpdateControlsDisconnectedState() {
304      refreshButton.Enabled = false;
305
306      localAndServerPlugins.Clear();
307      listView.Items.Clear();
308      listView.Enabled = false;
309      uploadButton.Enabled = false;
310      MainFormManager.GetMainForm<MainForm>().HideProgressBar();
311    }
312
313    private void UpdateControlsConnectedState() {
314      refreshButton.Enabled = true;
315      listView.Enabled = true;
316      uploadButton.Enabled = false;
317      MainFormManager.GetMainForm<MainForm>().HideProgressBar();
318    }
319    private void SetMainFormStatusBar(string p, IPluginDescription plugin) {
320      if (InvokeRequired) Invoke((Action<string, IPluginDescription>)SetMainFormStatusBar, p, plugin);
321      else {
322        MainFormManager.GetMainForm<MainForm>().SetStatusBarText(p + " " + plugin.ToString());
323      }
324    }
325
326    #endregion
327  }
328}
Note: See TracBrowser for help on using the repository browser.