Free cookie consent management tool by TermsFeed Policy Generator

source: branches/gp-crossover/HeuristicLab.PluginInfrastructure/3.3/Advanced/PluginUpdaterForm.cs @ 6996

Last change on this file since 6996 was 6413, checked in by gkronber, 13 years ago

#1536 implemented feature that checks for plugin updates on each application start and allows to install plugin updates easily. Removed more advanced plugin management features for all users except if it is manually reenabled in the HeuristicLab.config file.

File size: 11.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Diagnostics;
25using System.IO;
26using System.Linq;
27using System.Text;
28using System.Windows.Forms;
29using HeuristicLab.PluginInfrastructure.Manager;
30
31namespace HeuristicLab.PluginInfrastructure.Advanced {
32  internal partial class PluginUpdaterForm : Form, IStatusView {
33    private InstallationManager installationManager;
34    private PluginManager pluginManager;
35    private string pluginDir;
36    private BackgroundWorker updatePluginsBackgroundWorker;
37
38    public PluginUpdaterForm(PluginManager pluginManager)
39      : base() {
40      InitializeComponent();
41      FileVersionInfo pluginInfrastructureVersion = FileVersionInfo.GetVersionInfo(GetType().Assembly.Location);
42      Text = "HeuristicLab Plugin Manager " + pluginInfrastructureVersion.FileVersion;
43      pluginManager.PluginLoaded += pluginManager_PluginLoaded;
44      pluginManager.PluginUnloaded += pluginManager_PluginUnloaded;
45      pluginManager.Initializing += pluginManager_Initializing;
46      pluginManager.Initialized += pluginManager_Initialized;
47
48      pluginDir = Application.StartupPath;
49
50      installationManager = new InstallationManager(pluginDir);
51      installationManager.PluginInstalled += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginInstalled);
52      installationManager.PluginRemoved += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginRemoved);
53      installationManager.PluginUpdated += new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginUpdated);
54      installationManager.PreInstallPlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreInstallPlugin);
55      installationManager.PreRemovePlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreRemovePlugin);
56      installationManager.PreUpdatePlugin += new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreUpdatePlugin);
57
58      this.pluginManager = pluginManager;
59
60      updatePluginsBackgroundWorker = new BackgroundWorker();
61      updatePluginsBackgroundWorker.DoWork += new DoWorkEventHandler(updatePluginsBackgroundWorker_DoWork);
62      updatePluginsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(updatePluginsBackgroundWorker_RunWorkerCompleted);
63    }
64
65
66    private void PluginUpdaterForm_Load(object sender, EventArgs e) {
67      updatePluginsBackgroundWorker.RunWorkerAsync();
68      ShowProgressIndicator();
69      ShowMessage("Downloading and installing plugins...");
70    }
71
72    #region event handlers for update plugins backgroundworker
73    void updatePluginsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
74      if (e.Error != null) {
75        ShowError("Installation Error", "There was a problem while downloading and installing updates." + Environment.NewLine + "Please check your connection settings.");
76      } else {
77        Close();
78      }
79    }
80
81    void updatePluginsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
82      IEnumerable<IPluginDescription> installedPlugins = pluginManager.Plugins.OfType<IPluginDescription>().ToList();
83      var remotePlugins = installationManager.GetRemotePluginList();
84      // if there is a local plugin with same name and same major and minor version then it's an update
85      var pluginsToUpdate = from remotePlugin in remotePlugins
86                            let matchingLocalPlugins = from installedPlugin in installedPlugins
87                                                       where installedPlugin.Name == remotePlugin.Name
88                                                       where installedPlugin.Version.Major == remotePlugin.Version.Major
89                                                       where installedPlugin.Version.Minor == remotePlugin.Version.Minor
90                                                       where Util.IsNewerThan(remotePlugin, installedPlugin)
91                                                       select installedPlugin
92                            where matchingLocalPlugins.Count() > 0
93                            select remotePlugin;
94      if (pluginsToUpdate.Count() > 0) {
95        bool canceled;
96        installationManager.Update(pluginsToUpdate, out canceled);
97        if (!canceled)
98          pluginManager.DiscoverAndCheckPlugins();
99        e.Cancel = false;
100      }
101    }
102    #endregion
103
104    #region plugin manager event handlers
105    private void pluginManager_Initialized(object sender, PluginInfrastructureEventArgs e) {
106      SetStatusStrip("Initialized PluginInfrastructure");
107    }
108
109    private void pluginManager_Initializing(object sender, PluginInfrastructureEventArgs e) {
110      SetStatusStrip("Initializing PluginInfrastructure");
111    }
112
113    private void pluginManager_PluginUnloaded(object sender, PluginInfrastructureEventArgs e) {
114      SetStatusStrip("Unloaded " + e.Entity);
115    }
116
117    private void pluginManager_PluginLoaded(object sender, PluginInfrastructureEventArgs e) {
118      SetStatusStrip("Loaded " + e.Entity);
119    }
120    #endregion
121
122    #region installation manager event handlers
123    private void installationManager_PreUpdatePlugin(object sender, PluginInfrastructureCancelEventArgs e) {
124      if (e.Plugins.Count() > 0) {
125        e.Cancel = (bool)Invoke((Func<IEnumerable<IPluginDescription>, bool>)ConfirmUpdateAction, e.Plugins) == false;
126      }
127    }
128
129    private void installationManager_PreRemovePlugin(object sender, PluginInfrastructureCancelEventArgs e) {
130      if (e.Plugins.Count() > 0) {
131        e.Cancel = (bool)Invoke((Func<IEnumerable<IPluginDescription>, bool>)ConfirmRemoveAction, e.Plugins) == false;
132      }
133    }
134
135    private void installationManager_PreInstallPlugin(object sender, PluginInfrastructureCancelEventArgs e) {
136      if (e.Plugins.Count() > 0)
137        if ((bool)Invoke((Func<IEnumerable<IPluginDescription>, bool>)ConfirmInstallAction, e.Plugins) == true) {
138          SetStatusStrip("Installing " + e.Plugins.Aggregate("", (a, b) => a.ToString() + "; " + b.ToString()));
139          e.Cancel = false;
140        } else {
141          e.Cancel = true;
142          SetStatusStrip("Install canceled");
143        }
144    }
145
146    private void installationManager_PluginUpdated(object sender, PluginInfrastructureEventArgs e) {
147      SetStatusStrip("Updated " + e.Entity);
148    }
149
150    private void installationManager_PluginRemoved(object sender, PluginInfrastructureEventArgs e) {
151      SetStatusStrip("Removed " + e.Entity);
152    }
153
154    private void installationManager_PluginInstalled(object sender, PluginInfrastructureEventArgs e) {
155      SetStatusStrip("Installed " + e.Entity);
156    }
157    #endregion
158
159    #region confirmation dialogs
160    private bool ConfirmRemoveAction(IEnumerable<IPluginDescription> plugins) {
161      StringBuilder strBuilder = new StringBuilder();
162      foreach (var plugin in plugins) {
163        foreach (var file in plugin.Files) {
164          strBuilder.AppendLine(Path.GetFileName(file.Name));
165        }
166      }
167      using (var confirmationDialog = new ConfirmationDialog("Confirm Delete", "Do you want to delete following files?", strBuilder.ToString())) {
168        return (confirmationDialog.ShowDialog(this)) == DialogResult.OK;
169      }
170    }
171
172    private bool ConfirmUpdateAction(IEnumerable<IPluginDescription> plugins) {
173      StringBuilder strBuilder = new StringBuilder();
174      foreach (var plugin in plugins) {
175        strBuilder.AppendLine(plugin.ToString());
176      }
177      using (var confirmationDialog = new ConfirmationDialog("Confirm Update", "Do you want to update following plugins?", strBuilder.ToString())) {
178        return (confirmationDialog.ShowDialog(this)) == DialogResult.OK;
179      }
180    }
181
182    private bool ConfirmInstallAction(IEnumerable<IPluginDescription> plugins) {
183      foreach (var plugin in plugins) {
184        if (!string.IsNullOrEmpty(plugin.LicenseText)) {
185          using (var licenseConfirmationBox = new LicenseConfirmationDialog(plugin)) {
186            if (licenseConfirmationBox.ShowDialog(this) != DialogResult.OK)
187              return false;
188          }
189        }
190      }
191      return true;
192    }
193
194
195    #endregion
196
197    #region helper methods
198    private void SetStatusStrip(string msg) {
199      if (InvokeRequired) Invoke((Action<string>)SetStatusStrip, msg);
200      else {
201        statusLabel.Text = msg;
202      }
203    }
204
205    #endregion
206
207
208    protected override void OnClosing(CancelEventArgs e) {
209      installationManager.PluginInstalled -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginInstalled);
210      installationManager.PluginRemoved -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginRemoved);
211      installationManager.PluginUpdated -= new EventHandler<PluginInfrastructureEventArgs>(installationManager_PluginUpdated);
212      installationManager.PreInstallPlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreInstallPlugin);
213      installationManager.PreRemovePlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreRemovePlugin);
214      installationManager.PreUpdatePlugin -= new EventHandler<PluginInfrastructureCancelEventArgs>(installationManager_PreUpdatePlugin);
215      base.OnClosing(e);
216    }
217
218    #region IStatusView Members
219
220    public void ShowProgressIndicator(double percentProgress) {
221      if (percentProgress < 0.0 || percentProgress > 1.0) throw new ArgumentException("percentProgress");
222      progressBar.Visible = true;
223      progressBar.Style = ProgressBarStyle.Continuous;
224      int range = progressBar.Maximum - progressBar.Minimum;
225      progressBar.Value = (int)(percentProgress * range + progressBar.Minimum);
226    }
227
228    public void ShowProgressIndicator() {
229      progressBar.Visible = true;
230      progressBar.Style = ProgressBarStyle.Marquee;
231    }
232
233    public void HideProgressIndicator() {
234      progressBar.Visible = false;
235    }
236
237    public void ShowMessage(string message) {
238      statusLabel.Text = message;
239    }
240
241    public void RemoveMessage(string message) {
242      statusLabel.Text = string.Empty;
243    }
244
245    public void LockUI() {
246      Cursor = Cursors.AppStarting;
247    }
248    public void UnlockUI() {
249      Cursor = Cursors.Default;
250    }
251    public void ShowError(string shortMessage, string description) {
252      progressBar.Visible = false;
253      okButton.Visible = true;
254      statusLabel.Text = shortMessage + Environment.NewLine + description;
255      this.Cursor = Cursors.Default;
256    }
257    #endregion
258
259    private void okButton_Click(object sender, EventArgs e) {
260      Close();
261    }
262  }
263}
Note: See TracBrowser for help on using the repository browser.