Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/Starter/StarterForm.cs @ 6428

Last change on this file since 6428 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.7 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
21
22using System;
23using System.Collections.Generic;
24using System.Diagnostics;
25using System.IO;
26using System.Linq;
27using System.Threading;
28using System.Windows.Forms;
29using HeuristicLab.PluginInfrastructure.Advanced;
30using HeuristicLab.PluginInfrastructure.Manager;
31using System.Threading.Tasks;
32
33namespace HeuristicLab.PluginInfrastructure.Starter {
34  /// <summary>
35  /// The starter form is responsible for initializing the plugin infrastructure
36  /// and shows a list of installed applications.
37  /// </summary>
38  public partial class StarterForm : Form {
39    private const string pluginManagerItemName = "Plugin Manager";
40    private const string updatePluginsItemName = "Updates Available";
41
42
43    private ListViewItem pluginManagerListViewItem;
44    private bool abortRequested;
45    private PluginManager pluginManager;
46    private SplashScreen splashScreen;
47    private bool updatesAvailable = false;
48
49    /// <summary>
50    /// Initializes an instance of the starter form.
51    /// The starter form shows a splashscreen and initializes the plugin infrastructure.
52    /// </summary>
53    public StarterForm()
54      : base() {
55      InitializeComponent();
56      largeImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.HeuristicLab.ToBitmap());
57      largeImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.UpdateAvailable.ToBitmap());
58      smallImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.HeuristicLab.ToBitmap());
59      smallImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.UpdateAvailable.ToBitmap());
60      FileVersionInfo pluginInfrastructureVersion = FileVersionInfo.GetVersionInfo(GetType().Assembly.Location);
61      Text = "HeuristicLab " + pluginInfrastructureVersion.FileVersion;
62
63      string pluginPath = Path.GetFullPath(Application.StartupPath);
64      pluginManager = new PluginManager(pluginPath);
65      splashScreen = new SplashScreen(pluginManager, 1000);
66      splashScreen.Show(this, "Loading HeuristicLab...");
67
68      pluginManager.DiscoverAndCheckPlugins();
69      UpdateApplicationsList();
70
71      CheckUpdatesAvailableAsync(pluginPath);
72    }
73
74    private void CheckUpdatesAvailableAsync(string pluginPath) {
75      var task = Task.Factory.StartNew<bool>(() => {
76        var installationManager = new InstallationManager(pluginPath);
77        IEnumerable<IPluginDescription> installedPlugins = pluginManager.Plugins.OfType<IPluginDescription>();
78        var remotePlugins = installationManager.GetRemotePluginList();
79        // if there is a local plugin with same name and same major and minor version then it's an update
80        var pluginsToUpdate = from remotePlugin in remotePlugins
81                              let matchingLocalPlugins = from installedPlugin in installedPlugins
82                                                         where installedPlugin.Name == remotePlugin.Name
83                                                         where installedPlugin.Version.Major == remotePlugin.Version.Major
84                                                         where installedPlugin.Version.Minor == remotePlugin.Version.Minor
85                                                         where Util.IsNewerThan(remotePlugin, installedPlugin)
86                                                         select installedPlugin
87                              where matchingLocalPlugins.Count() > 0
88                              select remotePlugin;
89        return pluginsToUpdate.Count() > 0;
90      });
91      task.ContinueWith(t => {
92        updatesAvailable = t.Result;
93        UpdateApplicationsList();
94      }, TaskContinuationOptions.NotOnFaulted);
95    }
96
97    /// <summary>
98    /// Creates a new StarterForm and tries to start application with <paramref name="appName"/> immediately.
99    /// </summary>
100    /// <param name="appName">Name of the application</param>
101    public StarterForm(string appName)
102      : this() {
103      var appDesc = (from desc in pluginManager.Applications
104                     where desc.Name == appName
105                     select desc).SingleOrDefault();
106      if (appDesc != null) {
107        StartApplication(appDesc);
108      } else {
109        MessageBox.Show("Cannot start application " + appName + ".",
110                        "HeuristicLab",
111                        MessageBoxButtons.OK,
112                        MessageBoxIcon.Warning);
113      }
114    }
115
116    private void applicationsListView_ItemActivate(object sender, EventArgs e) {
117      if (applicationsListView.SelectedItems.Count > 0) {
118        ListViewItem selected = applicationsListView.SelectedItems[0];
119        if (selected.Text == pluginManagerItemName) {
120          if (pluginManager.Plugins.Any(x => x.PluginState == PluginState.Loaded)) {
121            MessageBox.Show("Installation Manager cannot be started while another HeuristicLab application is active." + Environment.NewLine +
122              "Please stop all active HeuristicLab applications and try again.", "Plugin Manager",
123              MessageBoxButtons.OK, MessageBoxIcon.Information);
124          } else {
125            try {
126              Cursor = Cursors.AppStarting;
127              using (InstallationManagerForm form = new InstallationManagerForm(pluginManager)) {
128                form.ShowDialog(this);
129              }
130              UpdateApplicationsList();
131            }
132            finally {
133              Cursor = Cursors.Arrow;
134            }
135          }
136        } else if (selected.Text == updatePluginsItemName) {
137          if (pluginManager.Plugins.Any(x => x.PluginState == PluginState.Loaded)) {
138            MessageBox.Show("Updating is not possible while another HeuristicLab application is active." + Environment.NewLine +
139              "Please stop all active HeuristicLab applications and try again.", "Update plugins",
140              MessageBoxButtons.OK, MessageBoxIcon.Information);
141          } else {
142            try {
143              Cursor = Cursors.AppStarting;
144              using (PluginUpdaterForm form = new PluginUpdaterForm(pluginManager)) {
145                form.ShowDialog(this);
146              }
147              UpdateApplicationsList();
148            }
149            finally {
150              Cursor = Cursors.Arrow;
151            }
152          }
153        } else {
154          ApplicationDescription app = (ApplicationDescription)applicationsListView.SelectedItems[0].Tag;
155          StartApplication(app);
156        }
157      }
158    }
159
160    private void UpdateApplicationsList() {
161      if (InvokeRequired) Invoke((Action)UpdateApplicationsList);
162      else {
163        applicationsListView.Items.Clear();
164        AddPluginManagerItem();
165        AddUpdatePluginsItem();
166
167        foreach (ApplicationDescription info in pluginManager.Applications) {
168          ListViewItem item = new ListViewItem(info.Name, 0);
169          item.Tag = info;
170          item.Group = applicationsListView.Groups["Applications"];
171          item.SubItems.Add(new ListViewItem.ListViewSubItem(item, info.Version.ToString()));
172          item.SubItems.Add(new ListViewItem.ListViewSubItem(item, info.Description));
173          item.ToolTipText = info.Description;
174          applicationsListView.Items.Add(item);
175        }
176        foreach (ColumnHeader column in applicationsListView.Columns) {
177          if (applicationsListView.Items.Count > 0)
178            column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
179          else column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
180        }
181      }
182    }
183
184    private void AddPluginManagerItem() {
185      if (HeuristicLab.PluginInfrastructure.Properties.Settings.Default.ShowPluginUploadControls) {
186        FileVersionInfo pluginInfrastructureVersion = FileVersionInfo.GetVersionInfo(GetType().Assembly.Location);
187        pluginManagerListViewItem = new ListViewItem(pluginManagerItemName, 0);
188        pluginManagerListViewItem.Group = applicationsListView.Groups["Plugin Management"];
189        pluginManagerListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(pluginManagerListViewItem, pluginInfrastructureVersion.FileVersion));
190        pluginManagerListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(pluginManagerListViewItem, "Install, upgrade or delete plugins"));
191        pluginManagerListViewItem.ToolTipText = "Install, upgrade or delete plugins";
192
193        applicationsListView.Items.Add(pluginManagerListViewItem);
194      }
195    }
196
197    private void AddUpdatePluginsItem() {
198      if (updatesAvailable) {
199        var updateListViewItem = new ListViewItem(updatePluginsItemName, 1);
200        updateListViewItem.Group = applicationsListView.Groups["Plugin Management"];
201        updateListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(updateListViewItem, ""));
202        updateListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(updateListViewItem, "Download and install updates"));
203        updateListViewItem.ToolTipText = "Download and install updates";
204
205        applicationsListView.Items.Add(updateListViewItem);
206      }
207    }
208
209    private void StartApplication(ApplicationDescription app) {
210      splashScreen.Show("Loading " + app.Name);
211      Thread t = new Thread(delegate() {
212        bool stopped = false;
213        do {
214          try {
215            if (!abortRequested) {
216              pluginManager.Run(app);
217            }
218            stopped = true;
219          }
220          catch (Exception ex) {
221            stopped = false;
222            ThreadPool.QueueUserWorkItem(delegate(object exception) { ErrorHandling.ShowErrorDialog(this, (Exception)exception); }, ex);
223            Thread.Sleep(5000); // sleep 5 seconds before autorestart
224          }
225        } while (!abortRequested && !stopped && app.AutoRestart);
226      });
227      t.SetApartmentState(ApartmentState.STA); // needed for the AdvancedOptimizationFrontent
228      t.Start();
229    }
230
231    private void applicationsListView_SelectedIndexChanged(object sender, EventArgs e) {
232      startButton.Enabled = applicationsListView.SelectedItems.Count > 0;
233    }
234
235    private void largeIconsButton_Click(object sender, EventArgs e) {
236      applicationsListView.View = View.LargeIcon;
237    }
238
239    private void detailsButton_Click(object sender, EventArgs e) {
240      applicationsListView.View = View.Details;
241      foreach (ColumnHeader column in applicationsListView.Columns) {
242        if (applicationsListView.Items.Count > 0)
243          column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
244        else column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
245      }
246    }
247
248    private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
249      splashScreen.Close();
250      abortRequested = true;
251    }
252
253    private void aboutButton_Click(object sender, EventArgs e) {
254      List<IPluginDescription> plugins = new List<IPluginDescription>(pluginManager.Plugins.OfType<IPluginDescription>());
255      using (var dialog = new AboutDialog(plugins)) {
256        dialog.ShowDialog();
257      }
258    }
259  }
260}
Note: See TracBrowser for help on using the repository browser.