Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Hive_Management_Console_Refactoring_Ticket508/HeuristicLab.Hive.Server.Console/HiveServerManagementConsole.cs @ 1451

Last change on this file since 1451 was 1451, checked in by aleitner, 15 years ago

change group of job if changed
check if client is offline
(#508)

File size: 23.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Data;
26using System.Drawing;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.Hive.Contracts.Interfaces;
31using HeuristicLab.Hive.Contracts.BusinessObjects;
32using HeuristicLab.Hive.Contracts;
33
34namespace HeuristicLab.Hive.Server.ServerConsole {
35
36  public delegate void closeForm(bool cf, bool error);
37
38  public partial class HiveServerManagementConsole : Form {
39
40    public event closeForm closeFormEvent;
41
42    #region private variables
43    private ResponseList<ClientGroup> clients = null;
44    private ResponseList<ClientInfo> clientInfo = null;
45    private ResponseList<Job> jobs = null;
46
47    private Dictionary<long, ListViewGroup> clientObjects;
48    private Dictionary<long, ListViewItem> clientInfoObjects;
49    private Dictionary<long, ListViewItem> jobObjects;
50
51    private Job currentJob = null;
52    private ClientInfo currentClient = null;
53    private string nameCurrentJob = "";
54    private string nameCurrentClient = "";
55    private string nameCurrentUser = "";
56    private bool flagJob = false;
57    private bool flagClient = false;
58    private bool flagUser = false;
59
60    private List<Changes> changes = new List<Changes>();
61
62    private ToolTip tt = new ToolTip();
63    #endregion
64
65    public HiveServerManagementConsole() {
66      InitializeComponent();
67      AddClients();
68      AddJobs();
69      timerSyncronize.Start();
70    }
71
72    /// <summary>
73    /// event on Ticker
74    /// </summary>
75    /// <param name="obj"></param>
76    /// <param name="e"></param>
77    private void TickSync(object obj, EventArgs e) {
78      if (!updaterWoker.IsBusy) {
79        updaterWoker.RunWorkerAsync();
80      }
81    }
82
83    /// <summary>
84    /// Adds clients to ListView and TreeView
85    /// </summary>
86    private void AddClients() {
87      try {
88        clientObjects = new Dictionary<long, ListViewGroup>();
89        clientInfoObjects = new Dictionary<long, ListViewItem>();
90        IClientManager clientManager =
91          ServiceLocator.GetClientManager();
92
93        clients = clientManager.GetAllClientGroups();
94        lvClientControl.Items.Clear();
95        tvClientControl.Nodes.Clear();
96        int count = 0;
97        List<long> inGroup = new List<long>();
98        foreach (ClientGroup cg in clients.List) {
99          tvClientControl.Nodes.Add(cg.Name);
100          ListViewGroup lvg = new ListViewGroup(cg.Name, HorizontalAlignment.Left);
101          foreach (ClientInfo ci in cg.Resources) {
102            tvClientControl.Nodes[tvClientControl.Nodes.Count - 1].Nodes.Add(ci.Name);
103            ListViewItem item = null;
104            if ((ci.State == State.offline) || (ci.State == State.nullState)) {
105              item = new ListViewItem(ci.Name, 3, lvg);
106            } else {
107              item = new ListViewItem(ci.Name, count, lvg);
108            }
109            lvClientControl.Items.Add(item);
110            clientInfoObjects.Add(ci.Id, item);
111            count = (count + 1) % 3;
112            inGroup.Add(ci.Id);
113           
114          }
115          lvClientControl.BeginUpdate();
116          lvClientControl.Groups.Add(lvg);
117          lvClientControl.EndUpdate();
118          clientObjects.Add(cg.Id, lvg);
119        } // Groups
120
121        clientInfo = clientManager.GetAllClients();
122        ListViewGroup lvunsorted = new ListViewGroup("no group", HorizontalAlignment.Left);
123        foreach (ClientInfo ci in clientInfo.List) {
124          bool help = false;
125          foreach (long client in inGroup) {
126            if (client == ci.Id) {
127              help = true;
128              break;
129            }
130          }
131          if (!help) {
132            tvClientControl.Nodes.Add(ci.Name);
133            ListViewItem item = null;
134            if ((ci.State == State.offline) || (ci.State == State.nullState)) {
135              item = new ListViewItem(ci.Name, 3, lvunsorted);
136            } else {
137              item = new ListViewItem(ci.Name, count, lvunsorted);
138            }
139
140            lvClientControl.Items.Add(item);
141            count = (count + 1) % 3;
142          }
143        }
144        lvClientControl.BeginUpdate();
145        lvClientControl.Groups.Add(lvunsorted);
146        lvClientControl.EndUpdate();
147        if (flagClient) {
148          ClientClicked();
149        }
150      }
151      catch (Exception ex) {
152        closeFormEvent(true, true);
153        this.Close();
154      }
155    }
156
157
158    List<ListViewGroup> jobGroup;
159    /// <summary>
160    /// Adds jobs to ListView and TreeView
161    /// </summary>
162    private void AddJobs() {
163      try {
164        jobObjects = new Dictionary<long, ListViewItem>();
165        IJobManager jobManager =
166          ServiceLocator.GetJobManager();
167        jobs = jobManager.GetAllJobs();
168
169        lvJobControl.Items.Clear();
170        tvJobControl.Nodes.Clear();
171
172        ListViewGroup lvJobCalculating = new ListViewGroup("calculating", HorizontalAlignment.Left);
173        ListViewGroup lvJobFinished = new ListViewGroup("finished", HorizontalAlignment.Left);
174        ListViewGroup lvJobPending = new ListViewGroup("pending", HorizontalAlignment.Left);
175
176        jobGroup = new List<ListViewGroup>();
177        jobGroup.Add(lvJobCalculating);
178        jobGroup.Add(lvJobFinished);
179        jobGroup.Add(lvJobPending);
180       
181        tvJobControl.Nodes.Add("calculating");
182        tvJobControl.Nodes.Add("finished");
183        tvJobControl.Nodes.Add("pending");
184        foreach (Job job in jobs.List) {
185          if (job.State == State.calculating) {
186            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobCalculating);
187            jobObjects.Add(job.Id, lvi);
188            tvJobControl.Nodes[0].Nodes.Add(job.Id.ToString());
189
190            //lvJobControl.Items.Add(lvi);
191           
192            lvi.ToolTipText = (job.Percentage * 100) + "% of job calculated";
193          } else if (job.State == State.finished) {
194            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobFinished);
195            jobObjects.Add(job.Id, lvi);
196            tvJobControl.Nodes[1].Nodes.Add(job.Id.ToString());
197            //lvJobControl.Items.Add(lvi);
198          } else if (job.State == State.offline) {
199            ListViewItem lvi = new ListViewItem(job.Id.ToString(), 0, lvJobPending);
200            jobObjects.Add(job.Id, lvi);
201            tvJobControl.Nodes[2].Nodes.Add(job.Id.ToString());
202            //lvJobControl.Items.Add(lvi);
203          }
204        } // Jobs
205        lvJobControl.BeginUpdate();
206        foreach (ListViewItem lvi in jobObjects.Values) {
207          lvJobControl.Items.Add(lvi);
208        }
209        lvJobControl.Groups.Add(lvJobCalculating);
210        lvJobControl.Groups.Add(lvJobFinished);
211        lvJobControl.Groups.Add(lvJobPending);
212        lvJobControl.EndUpdate();
213        if (flagJob) {
214          JobClicked();
215        }
216      }
217      catch (Exception ex) {
218        closeFormEvent(true, true);
219        this.Close();
220      }
221    }
222
223    /// <summary>
224    /// if one client is clicked, a panel is opened with the details
225    /// </summary>
226    private void ClientClicked() {
227      int i = 0;
228      while (clientInfo.List[i].Name != nameCurrentClient) {
229        i++;
230      }
231      currentClient = clientInfo.List[i];
232      scClientControl.Panel2.Controls.Clear();
233      scClientControl.Panel2.Controls.Add(plClientDetails);
234      pbClientControl.Image = ilClientControl.Images[0];
235      lblClientName.Text = currentClient.Name;
236      lblLogin.Text = currentClient.Login.ToString();
237      lblState.Text = currentClient.State.ToString();
238    }
239
240    /// <summary>
241    /// if one job is clicked, a panel is opened with the details
242    /// </summary>
243    private void JobClicked() {
244      int i = 0;
245      while (jobs.List[i].Id.ToString() != nameCurrentJob) {
246        i++;
247      }
248      lvSnapshots.Enabled = false;
249      int yPos = 0;
250      currentJob = jobs.List[i];
251      scJobControl.Panel2.Controls.Clear();
252      scJobControl.Panel2.Controls.Add(plJobDetails);
253      pbJobControl.Image = ilJobControl.Images[0];
254      lblJobName.Text = currentJob.Id.ToString();
255      progressJob.Value = (int)(currentJob.Percentage * 100);
256      yPos = progressJob.Location.Y;
257      yPos += 20;
258      lblProgress.Location = new Point(
259        lblProgress.Location.X, yPos);
260      lblProgress.Text = (int)(currentJob.Percentage * 100) + "% calculated";
261      yPos += 20;
262      lblUserCreatedJob.Location = new Point(
263        lblUserCreatedJob.Location.X, yPos);
264      lblUserCreatedJob.Text = /* currentJob.User.Name + */ " created Job";
265      yPos += 20;
266      lblJobCreated.Location = new Point(
267        lblJobCreated.Location.X, yPos);
268      lblJobCreated.Text = "Created at " + currentJob.DateCreated;
269      if (currentJob.ParentJob != null) {
270        yPos += 20;
271        lblParentJob.Location = new Point(
272          lblParentJob.Location.X, yPos);
273        lblParentJob.Text = currentJob.ParentJob.Id + " is parent job";
274      }
275      yPos += 20;
276      lblPriorityJob.Location = new Point(
277        lblPriorityJob.Location.X, yPos);
278      lblPriorityJob.Text = "Priority of job is " + currentJob.Priority;
279      if (currentJob.Client != null) {
280        yPos += 20;
281        lblClientCalculating.Location = new Point(
282          lblClientCalculating.Location.X, yPos);
283        lblClientCalculating.Text = currentJob.Client.Name + " calculated Job";
284        yPos += 20;
285        lblJobCalculationBegin.Location = new Point(
286          lblJobCalculationBegin.Location.X, yPos);
287        lblJobCalculationBegin.Text = "Startet calculation at " + currentJob.DateCalculated ;
288       
289        if (currentJob.State == State.finished) {
290          yPos += 20;
291          lblJobCalculationEnd.Location = new Point(
292            lblJobCalculationEnd.Location.X, yPos);
293
294          IJobManager jobManager =
295            ServiceLocator.GetJobManager();
296
297          ResponseObject<JobResult> jobRes = jobManager.GetLastJobResultOf(currentJob.Id);
298
299         
300          lblJobCalculationEnd.Text = "Calculation ended at " + jobRes.Obj.DateFinished;
301        }
302      }                       
303      if (currentJob.State != State.offline) {
304        yPos += 20;
305        lvSnapshots.Location = new Point(
306          lvSnapshots.Location.X, yPos);
307        lvSnapshots.Size = new Size(lvSnapshots.Size.Width,
308          plJobDetails.Size.Height - 10 - yPos);
309        lvSnapshots.Enabled = true;
310      }
311    }
312
313    private void Refresh() {
314      foreach (Changes change in changes) {
315        if (change.Types == Type.Job) {
316          RefreshJob(change);
317        } else if (change.Types == Type.Client) {
318          RefreshClient(change);
319        } else if (change.Types == Type.ClientGroup) {
320          RefreshClientGroup(change);
321        }
322      }
323    }
324
325    private void RefreshJob(Changes change) {
326      if (change.ChangeType == Change.Update) {
327        for (int i = 0; i < lvJobControl.Items.Count; i++) {
328          if (lvJobControl.Items[i].Text == change.ID.ToString()) {
329            State state = jobs.List[change.Position].State;
330            System.Diagnostics.Debug.WriteLine(lvJobControl.Items[i].Text.ToString());
331            if (state == State.finished) {
332              lvJobControl.Items[i].Group = jobGroup[1];
333              System.Diagnostics.Debug.WriteLine("finished");
334            } else if (state == State.calculating) {
335              lvJobControl.Items[i].Group = jobGroup[0];
336              System.Diagnostics.Debug.WriteLine("calculating");
337            } else if (state == State.offline) {
338              lvJobControl.Items[i].Group = jobGroup[2];
339              System.Diagnostics.Debug.WriteLine("offline");
340
341            }
342            lvJobControl.Refresh();
343          }
344        }
345      } else if (change.ChangeType == Change.Create) {
346        ListViewItem lvi = new ListViewItem(
347          change.ID.ToString(), 0, jobGroup[2]);
348        jobObjects.Add(change.ID, lvi);
349        lvJobControl.Items.Add(lvi);
350
351      } else if (change.ChangeType == Change.Delete) {
352        jobObjects.Remove(change.Position);
353        for (int i = 0; i < lvJobControl.Items.Count; i++) {
354          lvJobControl.Items[i].Remove();
355        }
356      }
357    }
358
359    private void RefreshClient(Changes change) {
360      if (change.ChangeType == Change.Update) {
361
362      } else if (change.ChangeType == Change.Create) {
363
364      } else if (change.ChangeType == Change.Delete) {
365
366      }
367    }
368
369    private void RefreshClientGroup(Changes change) {
370
371    }
372
373    #region Eventhandlers
374    /// <summary>
375    /// Send event to Login-GUI when closing
376    /// </summary>
377    /// <param name="sender"></param>
378    /// <param name="e"></param>
379    private void Close_Click(object sender, EventArgs e) {
380      if (closeFormEvent != null) {
381        closeFormEvent(true, false);
382      }
383      this.Close();
384    }
385
386    /// <summary>
387    /// Send evnt to Login-GUI when closing
388    /// </summary>
389    /// <param name="sender"></param>
390    /// <param name="e"></param>
391    private void HiveServerConsoleInformation_FormClosing(object sender, FormClosingEventArgs e) {
392      if (closeFormEvent != null) {
393        closeFormEvent(true, false);
394      }
395    }
396
397    private void AddJob_Click(object sender, EventArgs e) {
398      AddJobForm newForm = new AddJobForm();
399      newForm.Show();
400      //newForm.addJobEvent += new addDelegate(updaterWoker.RunWorkerAsync);
401    }
402
403    private void OnLVClientClicked(object sender, EventArgs e) {
404      nameCurrentClient = lvClientControl.SelectedItems[0].Text;
405      flagClient = true;
406      ClientClicked();
407    }
408
409    private void OnTVClientClicked(object sender, TreeViewEventArgs e) {
410      bool clientgroup = false;
411      foreach (ClientGroup cg in clients.List) {
412        if (tvClientControl.SelectedNode.Text == cg.Name) {
413          clientgroup = true;
414        }
415      }
416      if (clientgroup == false) {
417        nameCurrentClient = tvClientControl.SelectedNode.Text;
418        flagClient = true;
419        ClientClicked();
420      }
421
422    }
423
424    private void OnLVJobControlClicked(object sender, EventArgs e) {
425      nameCurrentJob = lvJobControl.SelectedItems[0].Text;
426      flagJob = true;
427      JobClicked();
428    }
429
430    private void OnTVJobControlClicked(object sender, TreeViewEventArgs e) {
431      try {
432        nameCurrentJob = Convert.ToInt32(tvJobControl.SelectedNode.Text).ToString();
433        flagJob = true;
434        JobClicked();
435      }
436      catch (Exception ex) { }
437
438    }
439
440    private void btnClientClose_Click(object sender, EventArgs e) {
441      scClientControl.Panel2.Controls.Clear();
442      scClientControl.Panel2.Controls.Add(lvClientControl);
443      flagClient = false;
444    }
445 
446    private void btnJobDetailClose_Click(object sender, EventArgs e) {
447      scJobControl.Panel2.Controls.Clear();
448      scJobControl.Panel2.Controls.Add(lvJobControl);
449      flagJob = false;
450    }
451
452    private void lvJobControl_MouseMove(object sender, MouseEventArgs e) {
453      if ((lvJobControl.GetItemAt(e.X, e.Y) != null) &&
454        (lvJobControl.GetItemAt(e.X, e.Y).ToolTipText != null)) {
455        tt.SetToolTip(lvJobControl, lvJobControl.GetItemAt(e.X, e.Y).ToolTipText);
456      }
457    }
458
459    private void updaterWoker_DoWork(object sender, DoWorkEventArgs e) {
460
461        changes.Clear();
462      IClientManager clientManager =
463          ServiceLocator.GetClientManager();
464     
465      #region ClientInfo
466      ResponseList<ClientInfo> clientInfoOld = clientInfo;
467      clientInfo = clientManager.GetAllClients();
468
469      IDictionary<int, ClientInfo> clientInfoOldHelp;
470
471      CloneList(clientInfoOld, out clientInfoOldHelp);
472
473      GetDelta(clientInfoOld.List, clientInfoOldHelp);
474      #endregion
475
476      #region Clients
477      ResponseList<ClientGroup> clientsOld = clients;
478     
479      clients = clientManager.GetAllClientGroups();
480
481      IDictionary<int, ClientGroup> clientsOldHelp;
482
483      CloneList(clientsOld, out clientsOldHelp);
484
485      GetDelta(clientsOld.List, clientsOldHelp);
486      #endregion
487
488      #region Job
489      ResponseList<Job> jobsOld = jobs;
490      IJobManager jobManager =
491          ServiceLocator.GetJobManager();
492
493      jobs = jobManager.GetAllJobs();
494
495      IDictionary<int, Job> jobsOldHelp;
496      CloneList(jobsOld, out jobsOldHelp);
497
498      GetDelta(jobsOld.List, jobsOldHelp);
499
500      #endregion
501
502      foreach (Changes change in changes) {
503        System.Diagnostics.Debug.WriteLine(change.ID + " " + change.ChangeType);
504      }
505
506    }
507    #endregion
508
509    #region Helper methods
510
511    private void CloneList(ResponseList<Job> oldList, out IDictionary<int, Job> newList) {
512      newList = new Dictionary<int, Job>();
513      for (int i = 0; i < oldList.List.Count; i++) {
514        newList.Add(i, oldList.List[i]);
515      }
516    }
517
518    private void CloneList(ResponseList<ClientInfo> oldList, out IDictionary<int, ClientInfo> newList) {
519      newList = new Dictionary<int, ClientInfo>();
520      for (int i = 0; i < oldList.List.Count; i ++) {
521        newList.Add(i, oldList.List[i]);
522      }
523    }
524
525    private void CloneList(ResponseList<ClientGroup> oldList, out IDictionary<int, ClientGroup> newList) {
526      newList = new Dictionary<int, ClientGroup>();
527      for (int i = 0; i < oldList.List.Count; i++) {
528        newList.Add(i, oldList.List[i]);
529      }
530    }
531
532    private bool IsEqual(ClientInfo ci1, ClientInfo ci2) {
533      if (ci2 == null) {
534        return false;
535      }
536      if (ci1.ClientId.Equals(ci2.ClientId)) {
537        return true;
538      } else return false;
539    }
540
541    private void GetDelta(IList<ClientInfo> oldClient, IDictionary<int, ClientInfo> helpClients) {
542      bool found = false;
543
544      for (int i = 0; i < clientInfo.List.Count; i ++) {
545        ClientInfo ci = clientInfo.List[i];
546        for (int j = 0; j < oldClient.Count; j++) {
547          ClientInfo cio = oldClient[j];
548          if (ci.Id.Equals(cio.Id)) {
549            found = true;
550            if (ci.State != cio.State) {
551              changes.Add(new Changes { Types = Type.Client, ID = ci.Id, ChangeType = Change.Update, Position = i });
552            }
553            int removeAt = -1;
554            foreach (KeyValuePair<int, ClientInfo> kvp in helpClients) {
555              if (cio.Id.Equals(kvp.Value.Id)) {
556                removeAt = kvp.Key;
557                break;
558              }
559            }
560            if (removeAt >= 0) {
561              helpClients.Remove(removeAt);
562            }
563            break;
564          }
565        }
566        if (found == false) {
567          changes.Add(new Changes { Types = Type.Client, ID = ci.Id, ChangeType = Change.Create });
568        }
569        found = false;
570      }
571      foreach (KeyValuePair<int, ClientInfo> kvp in helpClients) {
572        changes.Add(new Changes { Types = Type.Client, ID = kvp.Value.Id, ChangeType = Change.Delete, Position = kvp.Key });
573      }
574
575    }
576
577    private void GetDelta(IList<ClientGroup> oldClient, IDictionary<int, ClientGroup> helpClients) {
578
579      bool found = false;
580      for (int i = 0; i < clients.List.Count; i++) {
581        ClientGroup cg = clients.List[i];
582        for (int j = 0; j < oldClient.Count; i++) {
583          ClientGroup cgo = oldClient[j];
584          if (cg.Id.Equals(cgo.Id)) {
585            found = true;
586            foreach (Resource resource in cg.Resources) {
587              foreach (Resource resourceold in cgo.Resources) {
588                if (resource.Id.Equals(resourceold.Id)) {
589                  if (resourceold.Name != resource.Name) {
590                    changes.Add(new Changes { Types = Type.Client, ID = cg.Id, ChangeType = Change.Update, Position = i });
591                  }
592                }
593              }
594            }
595            for (int k = 0; k < helpClients.Count; k++) {
596              if (cgo.Id.Equals(helpClients[k].Id)) {
597                helpClients.Remove(k);
598                break;
599              }
600            }
601            break;
602          }
603        }
604        if (found == false) {
605          changes.Add(new Changes { Types = Type.ClientGroup, ID = cg.Id, ChangeType = Change.Create });
606        }
607        found = false;
608      }
609      foreach (KeyValuePair<int, ClientGroup> kvp in helpClients) {
610        changes.Add(new Changes { Types = Type.ClientGroup, ID = kvp.Value.Id, ChangeType = Change.Delete, Position = kvp.Key });
611      }
612    }
613
614    private void GetDelta(IList<Job> oldJobs, IDictionary<int, Job> helpJobs) {
615      bool found = false;
616      for (int i = 0; i < jobs.List.Count; i ++ ) {
617        Job job = jobs.List[i];
618        for (int j = 0; j < oldJobs.Count; j++) {
619
620          Job jobold = oldJobs[j];
621
622          if (job.Id.Equals(jobold.Id)) {
623
624            found = true;
625            if (job.State != State.offline) {
626              if (!IsEqual(job.Client, jobold.Client)) {
627                changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Update, Position = i });
628              } else if (job.State != jobold.State) {
629                changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Update, Position = i });
630              }
631            } else if (job.DateCalculated != jobold.DateCalculated) {
632              changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Update, Position = i });
633            }
634
635            int removeAt = -1;
636            foreach (KeyValuePair<int, Job> kvp in helpJobs) {
637              if (job.Id.Equals(kvp.Value.Id)) {
638                removeAt = kvp.Key;
639                break;
640              }
641            }
642            if (removeAt >= 0) {
643              helpJobs.Remove(removeAt);
644            }
645            break;
646          }
647
648        }
649        if (found == false) {
650          changes.Add(new Changes { Types = Type.Job, ID = job.Id, ChangeType = Change.Create });
651          System.Diagnostics.Debug.WriteLine("new Job: " + job.Id);
652        }
653        found = false;
654      }
655      foreach (KeyValuePair<int, Job> kvp in helpJobs) {
656        changes.Add(new Changes { Types = Type.Job, ID = kvp.Value.Id, ChangeType = Change.Delete, Position = kvp.Key });
657        System.Diagnostics.Debug.WriteLine("delete Job: " + kvp.Value.Id);
658      }
659    }
660
661
662    #endregion
663
664    private void updaterWoker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
665      Refresh();
666    }
667
668
669  }
670}
Note: See TracBrowser for help on using the repository browser.