Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/3.3/Advanced/EditProductsView.cs @ 11121

Last change on this file since 11121 was 9456, checked in by swagner, 11 years ago

Updated copyright year and added some missing license headers (#1889)

File size: 17.9 KB
RevLine 
[3081]1#region License Information
2/* HeuristicLab
[9456]3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3081]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;
[2802]23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Linq;
[4068]26using System.ServiceModel;
[2802]27using System.Windows.Forms;
28
[3474]29namespace HeuristicLab.PluginInfrastructure.Advanced {
[3627]30  internal partial class EditProductsView : InstallationManagerControl {
[3612]31    private const string RefreshMessage = "Downloading product and plugin information...";
32    private const string UploadMessage = "Uploading product and plugin information...";
33    private const string DeleteProductMessage = "Deleting product...";
34
[2802]35    private BackgroundWorker refreshProductsWorker;
36    private BackgroundWorker uploadChangedProductsWorker;
[3612]37    private BackgroundWorker deleteProductWorker;
38
[3474]39    private List<DeploymentService.ProductDescription> products;
40    private List<DeploymentService.PluginDescription> plugins;
41    private HashSet<DeploymentService.ProductDescription> dirtyProducts;
[2802]42
[3627]43    public EditProductsView() {
[2802]44      InitializeComponent();
45
[3721]46      productImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Setup_Install);
47      productImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.ArrowUp);
48      pluginImageList.Images.Add(HeuristicLab.PluginInfrastructure.Resources.Plugin);
[3015]49
[3474]50      dirtyProducts = new HashSet<DeploymentService.ProductDescription>();
[2802]51      refreshProductsWorker = new BackgroundWorker();
52      refreshProductsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshProductsWorker_RunWorkerCompleted);
53      refreshProductsWorker.DoWork += new DoWorkEventHandler(refreshProductsWorker_DoWork);
54
55      uploadChangedProductsWorker = new BackgroundWorker();
56      uploadChangedProductsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(uploadChangedProductsWorker_RunWorkerCompleted);
57      uploadChangedProductsWorker.DoWork += new DoWorkEventHandler(uploadChangedProductsWorker_DoWork);
[3612]58
59      deleteProductWorker = new BackgroundWorker();
60      deleteProductWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(deleteProductWorker_RunWorkerCompleted);
61      deleteProductWorker.DoWork += new DoWorkEventHandler(deleteProductWorker_DoWork);
[2802]62    }
63
[3612]64    #region event handlers for delete product background worker
65    void deleteProductWorker_DoWork(object sender, DoWorkEventArgs e) {
66      var products = (IEnumerable<DeploymentService.ProductDescription>)e.Argument;
[4495]67      var adminClient = DeploymentService.AdminServiceClientFactory.CreateClient();
[3612]68      // upload
69      try {
70        foreach (var product in products) {
71          adminClient.DeleteProduct(product);
72        }
73        adminClient.Close();
74      }
75      catch (TimeoutException) {
76        adminClient.Abort();
77        throw;
78      }
79      catch (FaultException) {
80        adminClient.Abort();
81        throw;
82      }
83      catch (CommunicationException) {
84        adminClient.Abort();
85        throw;
86      }
87      // refresh     
[4495]88      var updateClient = DeploymentService.UpdateServiceClientFactory.CreateClient();
[3612]89      try {
90        e.Result = new object[] { updateClient.GetProducts(), updateClient.GetPlugins() };
91        updateClient.Close();
92      }
93      catch (TimeoutException) {
94        updateClient.Abort();
95        throw;
96      }
97      catch (FaultException) {
98        updateClient.Abort();
99        throw;
100      }
101      catch (CommunicationException) {
102        updateClient.Abort();
103        throw;
104      }
105    }
106
107    void deleteProductWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
108      if (e.Error != null) {
109        StatusView.ShowError("Connection Error",
110        "There was an error while connecting to the server." + Environment.NewLine +
111           "Please check your connection settings and user credentials.");
[3624]112        this.products.Clear();
113        this.plugins.Clear();
[3612]114      } else {
115        this.products = new List<DeploymentService.ProductDescription>(
116  (DeploymentService.ProductDescription[])((object[])e.Result)[0]);
117        this.plugins = new List<DeploymentService.PluginDescription>(
118          (DeploymentService.PluginDescription[])((object[])e.Result)[1]);
119
120        EnableControls();
121      }
[3624]122      UpdateProductsList();
123      dirtyProducts.Clear();
[3612]124      StatusView.HideProgressIndicator();
125      StatusView.RemoveMessage(DeleteProductMessage);
126      StatusView.UnlockUI();
127    }
128    #endregion
129
[3015]130    #region event handlers for upload products background worker
131    private void uploadChangedProductsWorker_DoWork(object sender, DoWorkEventArgs e) {
[3474]132      var products = (IEnumerable<DeploymentService.ProductDescription>)e.Argument;
[4495]133      var adminClient = DeploymentService.AdminServiceClientFactory.CreateClient();
[3612]134      // upload
135      try {
136        foreach (var product in products) {
[3772]137          adminClient.DeployProduct(product);
[3612]138        }
139        adminClient.Close();
[2802]140      }
[3612]141      catch (TimeoutException) {
142        adminClient.Abort();
143        throw;
144      }
145      catch (FaultException) {
146        adminClient.Abort();
147        throw;
148      }
149      catch (CommunicationException) {
150        adminClient.Abort();
151        throw;
152      }
153      // refresh     
[4495]154      var updateClient = DeploymentService.UpdateServiceClientFactory.CreateClient();
[3612]155      try {
156        e.Result = new object[] { updateClient.GetProducts(), updateClient.GetPlugins() };
157        updateClient.Close();
158      }
159      catch (TimeoutException) {
160        updateClient.Abort();
161        throw;
162      }
163      catch (FaultException) {
164        updateClient.Abort();
165        throw;
166      }
167      catch (CommunicationException) {
168        updateClient.Abort();
169        throw;
170      }
[2802]171    }
172
[3015]173    private void uploadChangedProductsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
[3547]174      if (e.Error != null) {
[3612]175        StatusView.ShowError("Connection Error",
176        "There was an error while connecting to the server." + Environment.NewLine +
[3547]177           "Please check your connection settings and user credentials.");
[3624]178        this.products.Clear();
179        this.plugins.Clear();
[3547]180      } else {
[3612]181        this.products = new List<DeploymentService.ProductDescription>(
182  (DeploymentService.ProductDescription[])((object[])e.Result)[0]);
183        this.plugins = new List<DeploymentService.PluginDescription>(
184          (DeploymentService.PluginDescription[])((object[])e.Result)[1]);
185
[3547]186      }
[3624]187      UpdateProductsList();
188      dirtyProducts.Clear();
189      EnableControls();
[3612]190      StatusView.HideProgressIndicator();
191      StatusView.RemoveMessage(UploadMessage);
192      StatusView.UnlockUI();
[2802]193    }
[3015]194    #endregion
[2802]195
[3015]196    #region event handlers for refresh products background worker
197    private void refreshProductsWorker_DoWork(object sender, DoWorkEventArgs e) {
[4495]198      var updateClient = DeploymentService.UpdateServiceClientFactory.CreateClient();
[3612]199      try {
200        e.Result = new object[] { updateClient.GetProducts(), updateClient.GetPlugins() };
201        updateClient.Close();
202      }
203      catch (TimeoutException) {
204        updateClient.Abort();
205        throw;
206      }
207      catch (FaultException) {
208        updateClient.Abort();
209        throw;
210      }
211      catch (CommunicationException) {
212        updateClient.Abort();
213        throw;
214      }
[2802]215    }
216
[3015]217    private void refreshProductsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
[3547]218      if (e.Error != null) {
[3612]219        StatusView.ShowError("Connection Error",
220          "There was an error while connecting to the server." + Environment.NewLine +
[3547]221                   "Please check your connection settings and user credentials.");
[3624]222        this.products.Clear();
223        this.plugins.Clear();
224
[3547]225      } else {
[3474]226        this.products = new List<DeploymentService.ProductDescription>(
227          (DeploymentService.ProductDescription[])((object[])e.Result)[0]);
228        this.plugins = new List<DeploymentService.PluginDescription>(
229          (DeploymentService.PluginDescription[])((object[])e.Result)[1]);
[3179]230      }
[3624]231      UpdateProductsList();
232      dirtyProducts.Clear();
233      EnableControls();
[3612]234      StatusView.HideProgressIndicator();
235      StatusView.RemoveMessage(RefreshMessage);
236      StatusView.UnlockUI();
[2802]237    }
[3015]238    #endregion
[2802]239
240    private void UpdateProductsList() {
[3624]241      productsListView.SelectedItems.Clear();
[3015]242      productsListView.Items.Clear();
[2802]243      foreach (var prodDesc in products) {
[3015]244        productsListView.Items.Add(CreateListViewItem(prodDesc));
[2802]245      }
[3624]246      Util.ResizeColumns(productsListView.Columns.OfType<ColumnHeader>());
[2802]247    }
248
249    private void productsListBox_SelectedIndexChanged(object sender, EventArgs e) {
[3208]250      bool productSelected = productsListView.SelectedItems.Count > 0;
251      detailsGroupBox.Enabled = productSelected;
[3624]252      UpdateProductButtons();
[3612]253      if (productSelected) {
254        DeploymentService.ProductDescription activeProduct = (DeploymentService.ProductDescription)((ListViewItem)productsListView.SelectedItems[0]).Tag;
255        nameTextBox.Text = activeProduct.Name;
256        versionTextBox.Text = activeProduct.Version.ToString();
[2802]257
[3612]258        // populate plugins list view
[3624]259        pluginListView.SuppressItemCheckedEvents = true;
[3612]260        foreach (var plugin in plugins.OfType<IPluginDescription>()) {
261          pluginListView.Items.Add(CreateListViewItem(plugin));
262        }
[3624]263        pluginListView.SuppressItemCheckedEvents = false;
264        foreach (var plugin in activeProduct.Plugins) {
265          pluginListView.CheckItems(FindItemsForPlugin(plugin));
266        }
[3612]267      } else {
268        nameTextBox.Text = string.Empty;
269        versionTextBox.Text = string.Empty;
270        pluginListView.Items.Clear();
271      }
[3624]272      Util.ResizeColumns(pluginListView.Columns.OfType<ColumnHeader>());
[2802]273    }
274
[3624]275    private void UpdateProductButtons() {
276      uploadButton.Enabled = dirtyProducts.Count > 0;
277      if (productsListView.SelectedItems.Count > 0) {
278        var selectedProduct = (DeploymentService.ProductDescription)productsListView.SelectedItems[0].Tag;
279        deleteProductButton.Enabled = !dirtyProducts.Contains(selectedProduct);
280      } else {
281        deleteProductButton.Enabled = false;
282      }
283    }
[3015]284
[3624]285
[3045]286    #region button event handlers
[2802]287    private void newProductButton_Click(object sender, EventArgs e) {
[3474]288      var newProduct = new DeploymentService.ProductDescription("New product", new Version("0.0.0.0"));
[3624]289      products.Add(newProduct);
290      UpdateProductsList();
[3015]291      MarkProductDirty(newProduct);
[2802]292    }
293
294    private void saveButton_Click(object sender, EventArgs e) {
[3612]295      StatusView.LockUI();
296      StatusView.ShowProgressIndicator();
297      StatusView.ShowMessage(UploadMessage);
[2802]298      uploadChangedProductsWorker.RunWorkerAsync(dirtyProducts);
299    }
[3045]300    private void refreshButton_Click(object sender, EventArgs e) {
[3612]301      StatusView.LockUI();
302      StatusView.ShowProgressIndicator();
303      StatusView.ShowMessage(RefreshMessage);
[3045]304      refreshProductsWorker.RunWorkerAsync();
305    }
[3612]306    private void deleteProductButton_Click(object sender, EventArgs e) {
307      StatusView.LockUI();
308      StatusView.ShowProgressIndicator();
309      StatusView.ShowMessage(DeleteProductMessage);
310      var selectedProducts = from item in productsListView.SelectedItems.OfType<ListViewItem>()
311                             select (DeploymentService.ProductDescription)item.Tag;
312      deleteProductWorker.RunWorkerAsync(selectedProducts.ToList());
313    }
[2802]314
[3045]315    #endregion
316
317    #region textbox changed event handlers
[2802]318    private void nameTextBox_TextChanged(object sender, EventArgs e) {
[3612]319      if (productsListView.SelectedItems.Count > 0) {
320        ListViewItem activeItem = (ListViewItem)productsListView.SelectedItems[0];
321        DeploymentService.ProductDescription activeProduct = (DeploymentService.ProductDescription)activeItem.Tag;
322        if (string.IsNullOrEmpty(nameTextBox.Name)) {
323          errorProvider.SetError(nameTextBox, "Invalid value");
324        } else {
325          if (activeProduct.Name != nameTextBox.Text) {
326            activeProduct.Name = nameTextBox.Text;
327            activeItem.SubItems[0].Text = activeProduct.Name;
328            errorProvider.SetError(nameTextBox, string.Empty);
329            MarkProductDirty(activeProduct);
330          }
[3015]331        }
[2802]332      }
333    }
334
[3015]335
[2802]336    private void versionTextBox_TextChanged(object sender, EventArgs e) {
[3612]337      if (productsListView.SelectedItems.Count > 0) {
338        ListViewItem activeItem = (ListViewItem)productsListView.SelectedItems[0];
339        DeploymentService.ProductDescription activeProduct = (DeploymentService.ProductDescription)activeItem.Tag;
340        try {
341          var newVersion = new Version(versionTextBox.Text);
342          if (activeProduct.Version != newVersion) {
343            activeProduct.Version = newVersion;
344            activeItem.SubItems[1].Text = versionTextBox.Text;
345            errorProvider.SetError(versionTextBox, string.Empty);
346            MarkProductDirty(activeProduct);
347          }
[3015]348        }
[3612]349        catch (OverflowException) {
350          errorProvider.SetError(versionTextBox, "Invalid value");
351        }
[2802]352
[3612]353        catch (ArgumentException) {
354          errorProvider.SetError(versionTextBox, "Invalid value");
355        }
356        catch (FormatException) {
357          errorProvider.SetError(versionTextBox, "Invalid value");
358        }
[2802]359      }
360    }
[3045]361    #endregion
[3015]362
[3045]363
364    #region plugin list view
[3624]365    private void OnItemChecked(ItemCheckedEventArgs e) {
[3045]366      ListViewItem activeItem = (ListViewItem)productsListView.SelectedItems[0];
[3474]367      DeploymentService.ProductDescription activeProduct = (DeploymentService.ProductDescription)activeItem.Tag;
[3612]368      activeProduct.Plugins = (from item in pluginListView.CheckedItems.OfType<ListViewItem>()
369                               select (DeploymentService.PluginDescription)item.Tag).ToArray();
[3045]370      MarkProductDirty(activeProduct);
371    }
[3624]372
373    private void listView_ItemChecked(object sender, ItemCheckedEventArgs e) {
374      List<IPluginDescription> modifiedPlugins = new List<IPluginDescription>();
375      if (e.Item.Checked) {
376        foreach (ListViewItem item in pluginListView.SelectedItems) {
377          var plugin = (IPluginDescription)item.Tag;
378          // also check all dependencies
379          if (!modifiedPlugins.Contains(plugin))
380            modifiedPlugins.Add(plugin);
[3627]381          foreach (var dep in Util.GetAllDependencies(plugin)) {
[3624]382            if (!modifiedPlugins.Contains(dep))
383              modifiedPlugins.Add(dep);
384          }
385        }
386        pluginListView.CheckItems(modifiedPlugins.Select(x => FindItemsForPlugin(x).Single()));
387        OnItemChecked(e);
388      } else {
389        foreach (ListViewItem item in pluginListView.SelectedItems) {
390          var plugin = (IPluginDescription)item.Tag;
391          // also uncheck all dependent plugins
392          if (!modifiedPlugins.Contains(plugin))
393            modifiedPlugins.Add(plugin);
[3627]394          foreach (var dep in Util.GetAllDependents(plugin, plugins.Cast<IPluginDescription>())) {
[3624]395            if (!modifiedPlugins.Contains(dep))
396              modifiedPlugins.Add(dep);
397          }
398
399        }
400        pluginListView.UncheckItems(modifiedPlugins.Select(x => FindItemsForPlugin(x).Single()));
401        OnItemChecked(e);
402      }
403    }
404
405
[3045]406    #endregion
407
[3612]408    #region helper
[3015]409    private void MarkProductDirty(HeuristicLab.PluginInfrastructure.Advanced.DeploymentService.ProductDescription activeProduct) {
410      if (!dirtyProducts.Contains(activeProduct)) {
411        dirtyProducts.Add(activeProduct);
412        var item = FindItemForProduct(activeProduct);
413        item.ImageIndex = 1;
[3624]414        UpdateProductButtons();
[3015]415      }
416    }
[3612]417    private ListViewItem CreateListViewItem(DeploymentService.ProductDescription productDescription) {
418      ListViewItem item = new ListViewItem(new string[] { productDescription.Name, productDescription.Version.ToString() });
419      item.Tag = productDescription;
420      item.ImageIndex = 0;
421      return item;
422    }
423
424    private ListViewItem CreateListViewItem(IPluginDescription plugin) {
425      ListViewItem item = new ListViewItem(new string[] { plugin.Name, plugin.Version.ToString(),
426          string.Empty, plugin.Description });
427      item.Tag = plugin;
428      item.ImageIndex = 0;
429      item.Checked = false;
430      return item;
431    }
432
[3015]433    private ListViewItem FindItemForProduct(HeuristicLab.PluginInfrastructure.Advanced.DeploymentService.ProductDescription activeProduct) {
434      return (from item in productsListView.Items.OfType<ListViewItem>()
[3474]435              let product = item.Tag as DeploymentService.ProductDescription
[3015]436              where product != null
437              where product == activeProduct
438              select item).Single();
439    }
[3624]440    private IEnumerable<ListViewItem> FindItemsForPlugin(IPluginDescription plugin) {
441      return from item in pluginListView.Items.OfType<ListViewItem>()
442             let p = item.Tag as IPluginDescription
443             where p.Name == plugin.Name
444             where p.Version == plugin.Version
445             select item;
[3612]446    }
447
448    private void EnableControls() {
449      newProductButton.Enabled = true;
450      productsListView.Enabled = true;
451    }
452    #endregion
453
[2802]454  }
455}
Note: See TracBrowser for help on using the repository browser.