#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HeuristicLab.PluginInfrastructure.Manager;
namespace HeuristicLab.PluginInfrastructure.UI {
///
/// The starter form is responsible for initializing the plugin infrastructure
/// and shows a list of installed applications.
///
public partial class StarterForm : Form {
private const string pluginManagerItemName = "Plugins";
// private const string updatePluginsItemName = "Updates Available";
private const string optimizerItemName = "Optimizer"; // TODO: encoding a specific name of an application here is problematic (applications are discovered dynamically)
private readonly ICommandLineArgument[] arguments;
private ListViewItem pluginManagerListViewItem;
private bool abortRequested; // TODO: necessary?
private PluginManager pluginManager;
private SplashScreen splashScreen;
///
/// Initializes an instance of the starter form.
/// The starter form shows a splashscreen and initializes the plugin infrastructure.
///
public StarterForm()
: base() {
InitializeComponent();
largeImageList.Images.Add(Resources.HeuristicLab.ToBitmap());
smallImageList.Images.Add(Resources.HeuristicLab.ToBitmap());
Text = "HeuristicLab " + AssemblyExtensions.GetFileVersion(GetType().Assembly);
string pluginPath = Path.GetFullPath(Application.StartupPath);
pluginManager = new PluginManager(pluginPath);
splashScreen = new SplashScreen(pluginManager, 1000);
splashScreen.VisibleChanged += new EventHandler(splashScreen_VisibleChanged);
splashScreen.Show(this, "Loading HeuristicLab...");
pluginManager.DiscoverAndCheckPlugins();
UpdateApplicationsList();
}
///
/// Creates a new StarterForm and passes the arguments in .
///
/// The arguments that should be processed
public StarterForm(string[] args)
: this() {
arguments = CommandLineArgumentHandling.GetArguments(args);
}
protected override void SetVisibleCore(bool value) {
value &= !(arguments.OfType().Any() || arguments.OfType().Any());
if (!value) HandleArguments();
base.SetVisibleCore(value);
}
#region Events
private void StarterForm_Load(object sender, EventArgs e) {
HandleArguments();
}
private void StarterForm_FormClosing(object sender, FormClosingEventArgs e) {
splashScreen.Close();
abortRequested = true;
}
private void applicationsListView_SelectedIndexChanged(object sender, EventArgs e) {
startButton.Enabled = applicationsListView.SelectedItems.Count > 0;
}
private void applicationsListView_ItemActivate(object sender, EventArgs e) {
if (applicationsListView.SelectedItems.Count > 0) {
ListViewItem selected = applicationsListView.SelectedItems[0];
if (selected.Text == pluginManagerItemName) {
try {
Cursor = Cursors.AppStarting;
using (var form = new PluginInformationDialog(pluginManager.Plugins)) {
form.ShowDialog(this);
}
} finally {
Cursor = Cursors.Arrow;
}
} else {
ApplicationDescription app = (ApplicationDescription)applicationsListView.SelectedItems[0].Tag;
StartApplication(app, arguments);
}
}
}
private void largeIconsButton_Click(object sender, EventArgs e) {
applicationsListView.View = View.LargeIcon;
}
private void detailsButton_Click(object sender, EventArgs e) {
applicationsListView.View = View.Details;
foreach (ColumnHeader column in applicationsListView.Columns) {
if (applicationsListView.Items.Count > 0)
column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
else column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
}
}
private void aboutButton_Click(object sender, EventArgs e) {
List plugins = new List(pluginManager.Plugins.OfType());
using (var dialog = new AboutDialog(plugins, Assembly.GetEntryAssembly())) {
dialog.ShowDialog();
}
}
private void splashScreen_VisibleChanged(object sender, EventArgs e) {
// close hidden starter form
if (!splashScreen.Visible && arguments != null &&
(arguments.OfType().Any() || arguments.OfType().Any()))
Close();
}
#endregion
#region Helpers
private void UpdateApplicationsList() {
if (InvokeRequired) Invoke((Action)UpdateApplicationsList);
else {
applicationsListView.Items.Clear();
AddPluginManagerItem();
foreach (ApplicationDescription info in pluginManager.Applications) {
ListViewItem item = new ListViewItem(info.Name, 0);
item.Tag = info;
item.Group = applicationsListView.Groups["Applications"];
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, info.Version.ToString()));
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, info.Description));
item.ToolTipText = info.Description;
applicationsListView.Items.Add(item);
}
foreach (ColumnHeader column in applicationsListView.Columns) {
if (applicationsListView.Items.Count > 0)
column.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
else column.AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
}
}
}
private void AddPluginManagerItem() {
pluginManagerListViewItem = new ListViewItem(pluginManagerItemName, 0);
pluginManagerListViewItem.Group = applicationsListView.Groups["Plugin Information"];
pluginManagerListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(pluginManagerListViewItem, AssemblyExtensions.GetFileVersion(GetType().Assembly)));
pluginManagerListViewItem.SubItems.Add(new ListViewItem.ListViewSubItem(pluginManagerListViewItem, "Show detailed plugin information"));
pluginManagerListViewItem.ToolTipText = "Show detailed plugin information";
applicationsListView.Items.Add(pluginManagerListViewItem);
}
private void HandleArguments() {
try {
if (arguments.OfType().Any() && !arguments.OfType().Any()) {
InitiateApplicationStart(optimizerItemName);
}
foreach (var argument in arguments) {
if (argument is StartArgument) {
var arg = (StartArgument)argument;
InitiateApplicationStart(arg.Value);
}
}
} catch (AggregateException ex) {
ShowErrorDialog(ex);
}
}
private void InitiateApplicationStart(string appName) {
var appDesc = (from desc in pluginManager.Applications
where desc.Name.Equals(appName)
select desc).SingleOrDefault();
if (appDesc != null) {
StartApplication(appDesc, arguments);
} else {
MessageBox.Show("Cannot start application " + appName + ".",
"HeuristicLab",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
private void StartApplication(ApplicationDescription app, ICommandLineArgument[] args) {
splashScreen.Show("Loading " + app.Name);
// STAThread is necessary for a UI component we are using in the application
var t = new Thread(() => pluginManager.Run(app, args));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
#endregion
private void ShowErrorDialog(Exception exception) {
MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}