Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/Advanced/AvailablePluginsView.cs @ 4068

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

Sorted usings and removed unused usings in entire solution (#1094)

File size: 14.8 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
21using System;
22using System.Collections.Generic;
23using System.ComponentModel;
24using System.Linq;
25using System.Windows.Forms;
26using HeuristicLab.PluginInfrastructure.Manager;
27
28namespace HeuristicLab.PluginInfrastructure.Advanced {
29  internal partial class AvailablePluginsView : InstallationManagerControl {
30    private class RefreshBackgroundWorkerResult {
31      public IEnumerable<IPluginDescription> RemotePlugins { get; set; }
32      public IEnumerable<DeploymentService.ProductDescription> RemoteProducts { get; set; }
33    }
34    private class UpdateOrInstallPluginsBackgroundWorkerArgument {
35      public IEnumerable<IPluginDescription> PluginsToUpdate { get; set; }
36      public IEnumerable<IPluginDescription> PluginsToInstall { get; set; }
37    }
38    private const string PluginDiscoveryMessage = "Looking for new plugins...";
39    private BackgroundWorker refreshServerPluginsBackgroundWorker;
40    private BackgroundWorker updateOrInstallPluginsBackgroundWorker;
41
42    private IEnumerable<DeploymentService.ProductDescription> products;
43    private IEnumerable<IPluginDescription> plugins;
44
45    private IEnumerable<IPluginDescription> CheckedPlugins {
46      get {
47        return (from item in pluginsListView.Items.OfType<ListViewItem>()
48                where item.Checked
49                let plugin = item.Tag as IPluginDescription
50                where plugin != null
51                select plugin).ToList();
52      }
53    }
54
55    private InstallationManager installationManager;
56    public InstallationManager InstallationManager {
57      get { return installationManager; }
58      set { installationManager = value; }
59    }
60    private PluginManager pluginManager;
61    public PluginManager PluginManager {
62      get { return pluginManager; }
63      set { pluginManager = value; }
64    }
65    public AvailablePluginsView() {
66      InitializeComponent();
67      productImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Setup_Install);
68      productLargeImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Setup_Install);
69      pluginsImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Plugin);
70      refreshServerPluginsBackgroundWorker = new BackgroundWorker();
71      refreshServerPluginsBackgroundWorker.DoWork += new DoWorkEventHandler(refreshServerPluginsBackgroundWorker_DoWork);
72      refreshServerPluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshServerPluginsBackgroundWorker_RunWorkerCompleted);
73
74      updateOrInstallPluginsBackgroundWorker = new BackgroundWorker();
75      updateOrInstallPluginsBackgroundWorker.DoWork += new DoWorkEventHandler(updateOrInstallPluginsBackgroundWorker_DoWork);
76      updateOrInstallPluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updateOrInstallPluginsBackgroundWorker_RunWorkerCompleted);
77    }
78
79
80    #region event handlers for refresh server plugins background worker
81    void refreshServerPluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
82      if (e.Error != null) {
83        StatusView.ShowError("Connection Error",
84          "There was an error while connecting to the server." + Environment.NewLine +
85          "Please check your connection settings and user credentials.");
86      } else {
87        RefreshBackgroundWorkerResult refreshResult = (RefreshBackgroundWorkerResult)e.Result;
88        products = refreshResult.RemoteProducts;
89        plugins = refreshResult.RemotePlugins;
90        UpdateControl();
91      }
92      StatusView.UnlockUI();
93      StatusView.RemoveMessage(PluginDiscoveryMessage);
94      StatusView.HideProgressIndicator();
95    }
96
97    void refreshServerPluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
98      RefreshBackgroundWorkerResult result = new RefreshBackgroundWorkerResult();
99      result.RemotePlugins = installationManager.GetRemotePluginList();
100      result.RemoteProducts = installationManager.GetRemoteProductList();
101      e.Result = result;
102    }
103    #endregion
104    #region event handlers for plugin update background worker
105    void updateOrInstallPluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
106      if (e.Error != null) {
107        StatusView.ShowError("Connection Error",
108          "There was an error while connecting to the server." + Environment.NewLine +
109          "Please check your connection settings and user credentials.");
110      } else {
111        UpdateControl();
112      }
113      StatusView.UnlockUI();
114      StatusView.HideProgressIndicator();
115    }
116
117    void updateOrInstallPluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
118      UpdateOrInstallPluginsBackgroundWorkerArgument info = (UpdateOrInstallPluginsBackgroundWorkerArgument)e.Argument;
119      if (info.PluginsToInstall.Count() > 0)
120        installationManager.Install(info.PluginsToInstall);
121      if (info.PluginsToUpdate.Count() > 0)
122        installationManager.Update(info.PluginsToUpdate);
123
124      if (info.PluginsToInstall.Count() > 0 || info.PluginsToUpdate.Count() > 0)
125        pluginManager.DiscoverAndCheckPlugins();
126    }
127    #endregion
128
129
130    #region button events
131    private void refreshRemoteButton_Click(object sender, EventArgs e) {
132      StatusView.LockUI();
133      StatusView.ShowProgressIndicator();
134      StatusView.ShowMessage(PluginDiscoveryMessage);
135      refreshServerPluginsBackgroundWorker.RunWorkerAsync();
136    }
137    private void installPluginsButton_Click(object sender, EventArgs e) {
138      StatusView.LockUI();
139      StatusView.ShowProgressIndicator();
140      var updateOrInstallInfo = new UpdateOrInstallPluginsBackgroundWorkerArgument();
141      // if there is a local plugin with same name and same major and minor version then it's an update
142      var pluginsToUpdate = from remotePlugin in CheckedPlugins
143                            let matchingLocalPlugins = from localPlugin in pluginManager.Plugins
144                                                       where localPlugin.Name == remotePlugin.Name
145                                                       where localPlugin.Version.Major == remotePlugin.Version.Major
146                                                       where localPlugin.Version.Minor == remotePlugin.Version.Minor
147                                                       where IsNewerThan(remotePlugin, localPlugin)
148                                                       select localPlugin
149                            where matchingLocalPlugins.Count() > 0
150                            select remotePlugin;
151
152      // otherwise install a new plugin
153      var pluginsToInstall = CheckedPlugins.Except(pluginsToUpdate);
154
155      updateOrInstallInfo.PluginsToInstall = pluginsToInstall;
156      updateOrInstallInfo.PluginsToUpdate = pluginsToUpdate;
157      updateOrInstallPluginsBackgroundWorker.RunWorkerAsync(updateOrInstallInfo);
158    }
159    private void installProductsButton_Click(object sender, EventArgs e) {
160      StatusView.LockUI();
161      StatusView.ShowProgressIndicator();
162      var updateOrInstallInfo = new UpdateOrInstallPluginsBackgroundWorkerArgument();
163      var selectedProduct = (DeploymentService.ProductDescription)productsListView.SelectedItems[0].Tag;
164      // if there is a local plugin with same name and same major and minor version then it's an update
165      var pluginsToUpdate = from plugin in selectedProduct.Plugins
166                            let matchingLocalPlugins = from localPlugin in pluginManager.Plugins
167                                                       where localPlugin.Name == plugin.Name
168                                                       where localPlugin.Version.Major == plugin.Version.Major
169                                                       where localPlugin.Version.Minor == plugin.Version.Minor
170                                                       where IsNewerThan(plugin, localPlugin)
171                                                       select localPlugin
172                            where matchingLocalPlugins.Count() > 0
173                            select plugin;
174
175      // otherwise install a new plugin
176      var pluginsToInstall = selectedProduct.Plugins.Except(pluginsToUpdate);
177
178      updateOrInstallInfo.PluginsToInstall = (IEnumerable<IPluginDescription>)pluginsToInstall.ToList();
179      updateOrInstallInfo.PluginsToUpdate = (IEnumerable<IPluginDescription>)pluginsToUpdate.ToList();
180      updateOrInstallPluginsBackgroundWorker.RunWorkerAsync(updateOrInstallInfo);
181    }
182
183    private void showLargeIconsButton_CheckedChanged(object sender, EventArgs e) {
184      productsListView.View = View.LargeIcon;
185    }
186
187    private void showDetailsButton_CheckedChanged(object sender, EventArgs e) {
188      productsListView.View = View.Details;
189    }
190
191    #endregion
192
193    private void UpdateControl() {
194      // clear products view
195      List<ListViewItem> productItemsToDelete = new List<ListViewItem>(productsListView.Items.OfType<ListViewItem>());
196      productItemsToDelete.ForEach(item => productsListView.Items.Remove(item));
197
198      // populate products list view
199      foreach (var product in products) {
200        var item = CreateListViewItem(product);
201        productsListView.Items.Add(item);
202      }
203      var allPluginsListViewItem = new ListViewItem();
204      allPluginsListViewItem.Text = "All Plugins";
205      allPluginsListViewItem.ImageIndex = 0;
206      productsListView.Items.Add(allPluginsListViewItem);
207      Util.ResizeColumns(productsListView.Columns.OfType<ColumnHeader>());
208    }
209
210    private void UpdatePluginsList() {
211      pluginsListView.Items.Clear();
212
213      // populate plugins list
214      if (productsListView.SelectedItems.Count > 0) {
215        pluginsListView.SuppressItemCheckedEvents = true;
216
217        var selectedItem = productsListView.SelectedItems[0];
218        if (selectedItem.Text == "All Plugins") {
219          foreach (var plugin in plugins) {
220            var item = CreateListViewItem(plugin);
221            pluginsListView.Items.Add(item);
222          }
223        } else {
224          var selectedProduct = (DeploymentService.ProductDescription)productsListView.SelectedItems[0].Tag;
225          foreach (var plugin in selectedProduct.Plugins) {
226            var item = CreateListViewItem(plugin);
227            pluginsListView.Items.Add(item);
228          }
229        }
230
231        Util.ResizeColumns(pluginsListView.Columns.OfType<ColumnHeader>());
232        pluginsListView.SuppressItemCheckedEvents = false;
233      }
234    }
235
236    private ListViewItem CreateListViewItem(DeploymentService.ProductDescription product) {
237      ListViewItem item = new ListViewItem(new string[] { product.Name, product.Version.ToString() });
238      item.Tag = product;
239      item.ImageIndex = 0;
240      return item;
241    }
242
243    private ListViewItem CreateListViewItem(IPluginDescription plugin) {
244      ListViewItem item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(), plugin.Description });
245      item.Tag = plugin;
246      item.ImageIndex = 0;
247      return item;
248    }
249
250    #region products list view events
251    private void productsListView_SelectedIndexChanged(object sender, EventArgs e) {
252      UpdatePluginsList();
253      installProductsButton.Enabled = (productsListView.SelectedItems.Count > 0 &&
254        productsListView.SelectedItems[0].Text != "All Plugins");
255    }
256    #endregion
257
258    #region item checked event handler
259    private void remotePluginsListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
260      foreach (ListViewItem item in pluginsListView.SelectedItems) {
261        IPluginDescription plugin = (IPluginDescription)item.Tag;
262        if (e.Item.Checked)
263          HandlePluginChecked(plugin);
264        else
265          HandlePluginUnchecked(plugin);
266      }
267      installPluginsButton.Enabled = pluginsListView.CheckedItems.Count > 0;
268    }
269
270    private void HandlePluginUnchecked(IPluginDescription plugin) {
271      // also uncheck all dependent plugins
272      List<ListViewItem> modifiedItems = new List<ListViewItem>();
273      modifiedItems.AddRange(FindItemsForPlugin(plugin));
274      var dependentPlugins = Util.GetAllDependents(plugin, plugins);
275      foreach (var dependentPlugin in dependentPlugins) {
276        // there can be multiple entries for a single plugin in different groups
277        foreach (var item in FindItemsForPlugin(dependentPlugin)) {
278          if (item != null && item.Checked) {
279            if (!modifiedItems.Contains(item))
280              modifiedItems.Add(item);
281          }
282        }
283      }
284      pluginsListView.UncheckItems(modifiedItems);
285    }
286
287    private void HandlePluginChecked(IPluginDescription plugin) {
288      // also check all dependencies
289      List<ListViewItem> modifiedItems = new List<ListViewItem>();
290      modifiedItems.AddRange(FindItemsForPlugin(plugin));
291      foreach (var dep in Util.GetAllDependencies(plugin)) {
292        // there can be multiple entries for a single plugin in different groups
293        foreach (ListViewItem item in FindItemsForPlugin(dep)) {
294          if (item != null && !item.Checked) {
295            if (!modifiedItems.Contains(item))
296              modifiedItems.Add(item);
297          }
298        }
299      }
300      pluginsListView.CheckItems(modifiedItems);
301    }
302
303    #endregion
304
305    #region helper methods
306    private IEnumerable<ListViewItem> FindItemsForPlugin(IPluginDescription plugin) {
307      return (from item in pluginsListView.Items.OfType<ListViewItem>()
308              let otherPlugin = item.Tag as IPluginDescription
309              where otherPlugin != null && otherPlugin.Name == plugin.Name && otherPlugin.Version == plugin.Version
310              select item);
311    }
312
313    private bool IsNewerThan(IPluginDescription plugin1, IPluginDescription plugin2) {
314      // newer: build version is higher, or if build version is the same revision is higher
315      if (plugin1.Version.Build < plugin2.Version.Build) return false;
316      else if (plugin1.Version.Build > plugin2.Version.Build) return true;
317      else return plugin1.Version.Revision > plugin2.Version.Revision;
318    }
319    #endregion
320
321  }
322}
Note: See TracBrowser for help on using the repository browser.