source: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/Advanced/InstalledPluginsView.cs @ 12012

Last change on this file since 12012 was 12012, checked in by ascheibe, 7 years ago

#2212 merged r12008, r12009, r12010 back into trunk

File size: 11.0 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.Generic;
24using System.ComponentModel;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.PluginInfrastructure.Manager;
28
29namespace HeuristicLab.PluginInfrastructure.Advanced {
30  internal partial class InstalledPluginsView : InstallationManagerControl {
31    private const string CheckingPluginsMessage = "Checking for updated plugins...";
32    private const string NoUpdatesAvailableMessage = "No updates available.";
33    private BackgroundWorker removePluginsBackgroundWorker;
34    private BackgroundWorker updatePluginsBackgroundWorker;
35
36    private ListViewGroup enabledPluginsGroup;
37    private ListViewGroup disabledPluginsGroup;
38
39    private PluginManager pluginManager;
40    public PluginManager PluginManager {
41      get { return pluginManager; }
42      set {
43        pluginManager = value;
44        UpdateControl();
45      }
46    }
47
48    private InstallationManager installationManager;
49    public InstallationManager InstallationManager {
50      get { return installationManager; }
51      set { installationManager = value; }
52    }
53
54    public InstalledPluginsView()
55      : base() {
56      InitializeComponent();
57      enabledPluginsGroup = localPluginsListView.Groups["activePluginsGroup"];
58      disabledPluginsGroup = localPluginsListView.Groups["disabledPluginsGroup"];
59      pluginImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Plugin);
60      removePluginsBackgroundWorker = new BackgroundWorker();
61      removePluginsBackgroundWorker.DoWork += new DoWorkEventHandler(removePluginsBackgroundWorker_DoWork);
62      removePluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(removePluginsBackgroundWorker_RunWorkerCompleted);
63      updatePluginsBackgroundWorker = new BackgroundWorker();
64      updatePluginsBackgroundWorker.DoWork += new DoWorkEventHandler(updatePluginsBackgroundWorker_DoWork);
65      updatePluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updatePluginsBackgroundWorker_RunWorkerCompleted);
66
67      UpdateControl();
68    }
69
70
71
72    #region event handlers for plugin removal background worker
73    void removePluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
74      if (e.Error != null) {
75        StatusView.ShowError("File Deletion Error", "There was problem while deleting files." + Environment.NewLine + e.Error.Message);
76      }
77      UpdateControl();
78      StatusView.HideProgressIndicator();
79      StatusView.UnlockUI();
80    }
81
82    void removePluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
83      IEnumerable<IPluginDescription> pluginsToRemove = (IEnumerable<IPluginDescription>)e.Argument;
84      if (pluginsToRemove.Count() > 0) {
85        installationManager.Remove(pluginsToRemove);
86        pluginManager.DiscoverAndCheckPlugins();
87      }
88    }
89    #endregion
90
91    #region event handlers for update plugins backgroundworker
92    void updatePluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
93      if (e.Error != null) {
94        StatusView.ShowError("Connection Error",
95          "There was an error while connecting to the server." + Environment.NewLine +
96           "Please check your connection settings and user credentials.");
97      }
98      StatusView.RemoveMessage(CheckingPluginsMessage);
99      StatusView.HideProgressIndicator();
100      UpdateControl();
101      StatusView.UnlockUI();
102    }
103
104    void updatePluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
105      IEnumerable<IPluginDescription> selectedPlugins = (IEnumerable<IPluginDescription>)e.Argument;
106      var remotePlugins = installationManager.GetRemotePluginList();
107      // if there is a local plugin with same name and same major and minor version then it's an update
108      var pluginsToUpdate = from remotePlugin in remotePlugins
109                            let matchingLocalPlugins = from installedPlugin in selectedPlugins
110                                                       where installedPlugin.Name == remotePlugin.Name
111                                                       where installedPlugin.Version.Major == remotePlugin.Version.Major
112                                                       where installedPlugin.Version.Minor == remotePlugin.Version.Minor
113                                                       where IsNewerThan(remotePlugin, installedPlugin)
114                                                       select installedPlugin
115                            where matchingLocalPlugins.Count() > 0
116                            select remotePlugin;
117      if (pluginsToUpdate.Count() > 0) {
118        bool cancelled;
119        installationManager.Update(pluginsToUpdate, out cancelled);
120        if (!cancelled) pluginManager.DiscoverAndCheckPlugins();
121      }
122    }
123
124    // compares for two plugins with same major and minor version if plugin1 is newer than plugin2
125    private static bool IsNewerThan(IPluginDescription plugin1, IPluginDescription plugin2) {
126      // newer: build version is higher, or if build version is the same revision is higher
127      return plugin1.Version.Build > plugin2.Version.Build ||
128        (plugin1.Version.Build == plugin2.Version.Build && plugin1.Version.Revision > plugin2.Version.Revision);
129    }
130    #endregion
131
132    private void UpdateControl() {
133      ClearPluginList();
134      if (pluginManager != null) {
135        localPluginsListView.SuppressItemCheckedEvents = true;
136        foreach (var plugin in pluginManager.Plugins) {
137          var item = CreateListViewItem(plugin);
138          if (plugin.PluginState == PluginState.Enabled) {
139            item.Group = enabledPluginsGroup;
140          } else if (plugin.PluginState == PluginState.Disabled) {
141            item.Group = disabledPluginsGroup;
142          }
143          localPluginsListView.Items.Add(item);
144        }
145        localPluginsListView.SuppressItemCheckedEvents = false;
146      }
147      removeButton.Enabled = localPluginsListView.CheckedItems.Count > 0;
148      updateSelectedButton.Enabled = localPluginsListView.CheckedItems.Count > 0;
149      Util.ResizeColumns(localPluginsListView.Columns.OfType<ColumnHeader>());
150    }
151
152    private void ClearPluginList() {
153      List<ListViewItem> itemsToRemove = new List<ListViewItem>(localPluginsListView.Items.OfType<ListViewItem>());
154      itemsToRemove.ForEach(item => localPluginsListView.Items.Remove(item));
155    }
156
157    private static ListViewItem CreateListViewItem(PluginDescription plugin) {
158      ListViewItem item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(), plugin.Description });
159      item.Tag = plugin;
160      item.ImageIndex = 0;
161      return item;
162    }
163
164    private void pluginsListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
165      // checked items are marked for removal
166      if (e.Item.Checked) {
167        List<ListViewItem> modifiedItems = new List<ListViewItem>();
168        foreach (ListViewItem item in localPluginsListView.SelectedItems) {
169          modifiedItems.Add(item);
170          int oldItemsCount = 0;
171          while (oldItemsCount < modifiedItems.Count) {
172            oldItemsCount = modifiedItems.Count;
173            var oldModifiedItems = new List<ListViewItem>(modifiedItems);
174            foreach (var modifiedItem in oldModifiedItems) {
175              var plugin = (IPluginDescription)modifiedItem.Tag;
176              // also check all dependent plugins
177              foreach (ListViewItem dependentItem in localPluginsListView.Items) {
178                var dependent = (IPluginDescription)dependentItem.Tag;
179                if (!modifiedItems.Contains(dependentItem) &&
180                  !dependentItem.Checked && (from dep in dependent.Dependencies
181                                             where dep.Name == plugin.Name
182                                             where dep.Version == plugin.Version
183                                             select dep).Any()) {
184                  modifiedItems.Add(dependentItem);
185                }
186              }
187            }
188          }
189        }
190        localPluginsListView.CheckItems(modifiedItems);
191      } else {
192        List<ListViewItem> modifiedItems = new List<ListViewItem>();
193        foreach (ListViewItem item in localPluginsListView.SelectedItems) {
194          modifiedItems.Add(item);
195        }
196        localPluginsListView.UncheckItems(modifiedItems);
197      }
198      OnItemsCheckedChanged(EventArgs.Empty);
199    }
200
201    private void localPluginsListView_ItemActivate(object sender, EventArgs e) {
202      if (localPluginsListView.SelectedItems.Count > 0) {
203        var plugin = (PluginDescription)localPluginsListView.SelectedItems[0].Tag;
204        PluginView pluginView = new PluginView(plugin);
205        pluginView.Show(this);
206      }
207    }
208
209    private void OnItemsCheckedChanged(EventArgs eventArgs) {
210      removeButton.Enabled = localPluginsListView.CheckedItems.Count > 0;
211      updateSelectedButton.Enabled = localPluginsListView.CheckedItems.Count > 0;
212    }
213
214    private void updateSelectedButton_Click(object sender, EventArgs e) {
215      StatusView.LockUI();
216      StatusView.ShowProgressIndicator();
217      StatusView.RemoveMessage(NoUpdatesAvailableMessage);
218      StatusView.ShowMessage(CheckingPluginsMessage);
219      var checkedPlugins = localPluginsListView.CheckedItems.OfType<ListViewItem>()
220        .Select(item => item.Tag)
221        .OfType<IPluginDescription>()
222        .ToList();
223      updatePluginsBackgroundWorker.RunWorkerAsync(checkedPlugins);
224    }
225
226    private void removeButton_Click(object sender, EventArgs e) {
227      StatusView.LockUI();
228      StatusView.ShowProgressIndicator();
229      var checkedPlugins = localPluginsListView.CheckedItems.OfType<ListViewItem>()
230        .Select(item => item.Tag)
231        .OfType<IPluginDescription>()
232        .ToList();
233      removePluginsBackgroundWorker.RunWorkerAsync(checkedPlugins);
234    }
235
236    private void refreshButton_Click(object sender, EventArgs e) {
237      StatusView.LockUI();
238      StatusView.ShowProgressIndicator();
239      // refresh = update empty list of plugins (plugins are reloaded)
240      updatePluginsBackgroundWorker.RunWorkerAsync(new IPluginDescription[0]);
241    }
242  }
243}
Note: See TracBrowser for help on using the repository browser.