Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Hive.Client.Console/3.2/HiveClientConsole.cs @ 2062

Last change on this file since 2062 was 2062, checked in by whackl, 15 years ago

refactoring hive client console #663

File size: 25.1 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.Diagnostics;
25using System.Drawing;
26using System.Linq;
27using System.Net;
28using System.ServiceModel;
29using System.Windows.Forms;
30using Calendar;
31using HeuristicLab.Hive.Client.Console.ClientService;
32using ZedGraph;
33using HeuristicLab.Hive.Contracts;
34using System.Xml.Serialization;
35using System.IO;
36
37namespace HeuristicLab.Hive.Client.Console
38{
39
40    #region Delegates
41   
42    //delegate to write text in the textbox from another process
43    public delegate void AppendTextDelegate(String message);
44
45    //delegate to remove text in the textbox from another process
46    public delegate void RemoveTextDelegate(int newLength, int maxChars);
47
48    //delegate fired, if a dialog is being closed
49    public delegate void OnDialogClosedDelegate(RecurrentEvent e);
50
51    #endregion
52
53    public partial class HiveClientConsole : Form
54    {
55
56        #region Declarations
57
58        private const string ENDPOINTADRESS = "net.tcp://127.0.0.1:8000/ClientConsole/ClientConsoleCommunicator";
59
60        //the logfilereader
61        private LogFileReader logFileReader;
62
63        //communication with the client
64        private ClientConsoleCommunicatorClient clientCommunicator;
65
66        //the timer for refreshing the gui
67        private System.Windows.Forms.Timer refreshTimer;
68
69        //the list of appointments in the calender
70        [XmlArray("Appointments")]
71        [XmlArrayItem("Appointment", typeof(Appointment))]
72        public List<Appointment> onlineTimes = new List<Appointment>();
73
74        public OnDialogClosedDelegate dialogClosedDelegate;
75
76        #endregion
77
78        #region Constructor
79
80        public HiveClientConsole()
81        {
82            InitializeComponent();
83            InitTimer();
84            ConnectToClient();
85            RefreshGui();
86            InitCalender();
87            InitLogFileReader();
88        }
89
90        #endregion
91
92        #region Methods
93
94        #region Client connection
95
96        private void ConnectToClient()
97        {
98            try
99            {
100                clientCommunicator = new ClientConsoleCommunicatorClient(WcfSettings.GetBinding(), new EndpointAddress(ENDPOINTADRESS));
101                clientCommunicator.GetStatusInfosCompleted += new EventHandler<GetStatusInfosCompletedEventArgs>(clientCommunicator_GetStatusInfosCompleted);
102                clientCommunicator.GetCurrentConnectionCompleted += new EventHandler<GetCurrentConnectionCompletedEventArgs>(clientCommunicator_GetCurrentConnectionCompleted);
103                clientCommunicator.GetUptimeCalendarCompleted += new EventHandler<GetUptimeCalendarCompletedEventArgs>(clientCommunicator_GetUptimeCalendarCompleted);
104                clientCommunicator.SetUptimeCalendarCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(clientCommunicator_SetUptimeCalendarCompleted);
105            }
106            catch (Exception)
107            {
108                refreshTimer.Stop();
109                DialogResult res = MessageBox.Show("Connection Error, check if Hive Client is running!", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
110                if (res == DialogResult.OK)
111                    this.Close();
112            }
113        }
114
115        #endregion
116
117        #region Logging
118
119        private void InitLogFileReader()
120        {
121            logFileReader = new LogFileReader(Environment.CurrentDirectory + @"/Hive.log");
122            logFileReader.MoreData += new LogFileReader.MoreDataHandler(logFileReader_MoreData);
123            logFileReader.Start();
124        }
125
126        private void logFileReader_MoreData(object sender, string newData)
127        {
128            int maxChars = txtLog.MaxLength;
129            if (newData.Length > maxChars)
130            {
131                newData = newData.Remove(0, newData.Length - maxChars);
132            }
133            int newLength = this.txtLog.Text.Length + newData.Length;
134            if (newLength > maxChars)
135            {
136                RemoveText(newLength, maxChars);
137            }
138            AppendText(newData);
139        }
140
141        private void RemoveText(int newLength, int maxChars)
142        {
143            if (this.txtLog.InvokeRequired)
144            {
145                this.txtLog.Invoke(new
146                  RemoveTextDelegate(RemoveText), new object[] { newLength, maxChars });
147            }
148            else
149            {
150                this.txtLog.Text = this.txtLog.Text.Remove(0, newLength - (int)maxChars);
151            }
152        }
153
154        private void AppendText(string message)
155        {
156            if (this.txtLog.InvokeRequired)
157            {
158                this.txtLog.Invoke(new
159                  AppendTextDelegate(AppendText), new object[] { message });
160            }
161            else
162            {
163                this.txtLog.AppendText(message);
164            }
165        }
166
167        #endregion
168
169        #region Gui Refresh
170
171        private void InitTimer()
172        {
173            refreshTimer = new System.Windows.Forms.Timer();
174            refreshTimer.Interval = 1000;
175            refreshTimer.Tick += new EventHandler(refreshTimer_Tick);
176            refreshTimer.Start();
177        }
178
179        private void RefreshGui()
180        {
181            try
182            {
183                clientCommunicator.GetStatusInfosAsync();
184            }
185            catch (Exception ex)
186            {
187                refreshTimer.Stop();
188                DialogResult res = MessageBox.Show("Connection Error, check if Hive Client is running!" + ex.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
189                if (res == DialogResult.OK)
190                    this.Close();
191            }
192        }
193
194        private void UpdateGraph(JobStatus[] jobs)
195        {
196            ZedGraphControl zgc = new ZedGraphControl();
197            GraphPane myPane = zgc.GraphPane;
198            myPane.GraphObjList.Clear();
199
200            myPane.Title.IsVisible = false;  // no title
201            myPane.Border.IsVisible = false; // no border
202            myPane.Chart.Border.IsVisible = false; // no border around the chart
203            myPane.XAxis.IsVisible = false;  // no x-axis
204            myPane.YAxis.IsVisible = false;  // no y-axis
205            myPane.Legend.IsVisible = false; // no legend
206
207            myPane.Fill.Color = this.BackColor;
208
209            myPane.Chart.Fill.Type = FillType.None;
210            myPane.Fill.Type = FillType.Solid;
211
212            double allProgress = 0;
213            double done = 0;
214
215            if (jobs.Length == 0)
216            {
217                myPane.AddPieSlice(100, Color.Green, 0.1, "");
218            }
219            else
220            {
221                for (int i = 0; i < jobs.Length; i++)
222                {
223                    allProgress += jobs[i].Progress;
224                }
225
226                done = allProgress / jobs.Length;
227
228                myPane.AddPieSlice(done, Color.Green, 0, "");
229                myPane.AddPieSlice(1 - done, Color.Red, 0, "");
230            }
231            //Hides the slice labels
232            PieItem.Default.LabelType = PieLabelType.None;
233
234            myPane.AxisChange();
235
236            pbGraph.Image = zgc.GetImage();
237        }
238
239        #region Events
240
241        private void refreshTimer_Tick(object sender, EventArgs e)
242        {
243            RefreshGui();
244        }
245
246        #endregion
247
248
249        #endregion
250
251        #region Calendar stuff
252
253        private void InitCalender()
254        {
255            dvOnline.StartDate = DateTime.Now;
256            dvOnline.OnNewAppointment += new EventHandler<NewAppointmentEventArgs>(dvOnline_OnNewAppointment);
257            dvOnline.OnResolveAppointments += new EventHandler<ResolveAppointmentsEventArgs>(dvOnline_OnResolveAppointments);
258
259            //get calender from client
260            clientCommunicator.GetUptimeCalendarAsync();
261        }
262
263        private bool CreateAppointment()
264        {
265            DateTime from, to;
266
267            if (!string.IsNullOrEmpty(dtpFrom.Text) && !string.IsNullOrEmpty(dtpTo.Text))
268            {
269                if (chbade.Checked)
270                {
271                    //whole day appointment, only dates are visible
272                    if (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to)
273                        onlineTimes.Add(CreateAppointment(from, to.AddDays(1), true));
274                    else
275                        MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
276                }
277                else if (!string.IsNullOrEmpty(txttimeFrom.Text) && !string.IsNullOrEmpty(txttimeTo.Text))
278                {
279                    //Timeframe appointment
280                    if (DateTime.TryParse(dtpFrom.Text + " " + txttimeFrom.Text, out from) && DateTime.TryParse(dtpTo.Text + " " + txttimeTo.Text, out to) && from < to)
281                    {
282                        if (from.Date == to.Date)
283                            onlineTimes.Add(CreateAppointment(from, to, false));
284                        else
285                        {
286                            //more than 1 day selected
287                            while (from.Date != to.Date)
288                            {
289                                onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
290                                from = from.AddDays(1);
291                            }
292                            onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
293                        }
294                    }
295                    else
296                        MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
297                }
298                dvOnline.Invalidate();
299                return true;
300            }
301            else
302            {
303                MessageBox.Show("Error in create appointment, please fill out all textboxes!", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
304                return false;
305            }
306        }
307
308        private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay)
309        {
310            Appointment App = new Appointment();
311            App.StartDate = startDate;
312            App.EndDate = endDate;
313            App.AllDayEvent = allDay;
314            App.BorderColor = Color.Red;
315            App.Locked = true;
316            App.Subject = "Online";
317            App.Recurring = false;
318            return App;
319        }
320
321        private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay, bool recurring, Guid recurringId)
322        {
323            Appointment App = new Appointment();
324            App.StartDate = startDate;
325            App.EndDate = endDate;
326            App.AllDayEvent = allDay;
327            App.BorderColor = Color.Red;
328            App.Locked = true;
329            App.Subject = "Online";
330            App.Recurring = recurring;
331            App.RecurringId = recurringId;
332            return App;
333        }
334
335        private void DeleteAppointment()
336        {
337            onlineTimes.Remove(dvOnline.SelectedAppointment);
338        }
339
340        private void DeleteRecurringAppointment(Guid recurringId)
341        {
342            onlineTimes.RemoveAll(a => a.RecurringId.ToString() == dvOnline.SelectedAppointment.RecurringId.ToString());
343        }
344
345        private void ChangeRecurrenceAppointment(Guid recurringId)
346        {
347            int hourfrom = int.Parse(txttimeFrom.Text.Substring(0, txttimeFrom.Text.IndexOf(':')));
348            int hourTo = int.Parse(txttimeTo.Text.Substring(0, txttimeTo.Text.IndexOf(':')));
349            List<Appointment> recurringAppointments = onlineTimes.Where(appointment => appointment.RecurringId == recurringId).ToList();
350            recurringAppointments.ForEach(appointment => appointment.StartDate = new DateTime(appointment.StartDate.Year, appointment.StartDate.Month, appointment.StartDate.Day, hourfrom, 0, 0));
351            recurringAppointments.ForEach(appointment => appointment.EndDate = new DateTime(appointment.EndDate.Year, appointment.EndDate.Month, appointment.EndDate.Day, hourTo, 0, 0));
352
353            DeleteRecurringAppointment(recurringId);
354            onlineTimes.AddRange(recurringAppointments);
355        }
356
357        public void DialogClosed(RecurrentEvent e)
358        {
359            CreateDailyRecurrenceAppointments(e.DateFrom, e.DateTo, e.AllDay, e.IncWeeks, e.WeekDays);
360        }
361
362        private void CreateDailyRecurrenceAppointments(DateTime dateFrom, DateTime dateTo, bool allDay, int incWeek, HashSet<DayOfWeek> daysOfWeek)
363        {
364            DateTime incDate = dateFrom;
365            Guid guid = Guid.NewGuid();
366
367            while (incDate.Date <= dateTo.Date)
368            {
369                if (daysOfWeek.Contains(incDate.Date.DayOfWeek))
370                    onlineTimes.Add(CreateAppointment(incDate, new DateTime(incDate.Year, incDate.Month, incDate.Day, dateTo.Hour, dateTo.Minute, 0), allDay, true, guid));
371                incDate = incDate.AddDays(1);
372            }
373
374            dvOnline.Invalidate();
375        }
376
377        #region Calendar Events
378
379        private void btbDelete_Click(object sender, EventArgs e)
380        {
381            Appointment selectedAppointment = dvOnline.SelectedAppointment;
382            if (dvOnline.SelectedAppointment != null)
383            {
384                if (!selectedAppointment.Recurring)
385                    DeleteAppointment();
386                else
387                {
388                    DialogResult res = MessageBox.Show("Delete all events in this series?", "Delete recurrences", MessageBoxButtons.YesNo);
389                    if (res != DialogResult.Yes)
390                        DeleteAppointment();
391                    else
392                        DeleteRecurringAppointment(selectedAppointment.RecurringId);
393                }
394            }
395            dvOnline.Invalidate();
396        }
397
398        private void chbade_CheckedChanged(object sender, EventArgs e)
399        {
400            txttimeFrom.Visible = !chbade.Checked;
401            txttimeTo.Visible = !chbade.Checked;
402        }
403
404        private void dvOnline_OnSelectionChanged(object sender, EventArgs e)
405        {
406            //btCreate.Enabled = true;
407            if (dvOnline.Selection == SelectionType.DateRange)
408            {
409                dtpFrom.Text = dvOnline.SelectionStart.ToShortDateString();
410                dtpTo.Text = dvOnline.SelectionEnd.Date.ToShortDateString();
411                txttimeFrom.Text = dvOnline.SelectionStart.ToShortTimeString();
412                txttimeTo.Text = dvOnline.SelectionEnd.ToShortTimeString();
413
414                btCreate.Text = "Save";
415            }
416
417            if (dvOnline.Selection == SelectionType.Appointment)
418            {
419
420                dtpFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortDateString();
421                dtpTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortDateString();
422                txttimeFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortTimeString();
423                txttimeTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortTimeString();
424
425                if (dvOnline.SelectedAppointment.Recurring)
426                    //btCreate.Enabled = false;
427                    //also change the caption of the save button
428                    btCreate.Text = "Save changes";
429            }
430
431            if (dvOnline.Selection == SelectionType.None)
432            {
433                //also change the caption of the save button
434                btCreate.Text = "Save";
435            }
436
437        }
438
439        private void mcOnline_DateChanged(object sender, DateRangeEventArgs e)
440        {
441            dvOnline.StartDate = mcOnline.SelectionStart;
442        }
443
444        private void btCreate_Click(object sender, EventArgs e)
445        {
446            if (dvOnline.Selection != SelectionType.Appointment)
447            {
448                CreateAppointment();
449            }
450            else
451            {
452                //now we want to change an existing appointment
453                if (!dvOnline.SelectedAppointment.Recurring)
454                {
455                    if (CreateAppointment())
456                        DeleteAppointment();
457                }
458                else
459                {
460                    //change recurring appointment
461                    //check, if only selected appointment has to change or whole recurrence
462                    DialogResult res = MessageBox.Show("Change all events in this series?", "Change recurrences", MessageBoxButtons.YesNo);
463                    if (res != DialogResult.Yes)
464                    {
465                        if (CreateAppointment())
466                            DeleteAppointment();
467                    }
468                    else
469                        ChangeRecurrenceAppointment(dvOnline.SelectedAppointment.RecurringId);
470                }
471            }
472            dvOnline.Invalidate();
473        }
474
475        private void btnRecurrence_Click(object sender, EventArgs e)
476        {
477            Recurrence recurrence = new Recurrence();
478            recurrence.dialogClosedDelegate = new OnDialogClosedDelegate(this.DialogClosed);
479            recurrence.Show();
480        }
481
482        private void btnSaveCal_Click(object sender, EventArgs e)
483        {
484            clientCommunicator.SetUptimeCalendarAsync(onlineTimes.ToArray());
485        }
486
487        private void dvOnline_OnResolveAppointments(object sender, ResolveAppointmentsEventArgs e)
488        {
489            List<Appointment> Apps = new List<Appointment>();
490
491            foreach (Appointment m_App in onlineTimes)
492                if ((m_App.StartDate >= e.StartDate) &&
493                    (m_App.StartDate <= e.EndDate))
494                    Apps.Add(m_App);
495            e.Appointments = Apps;
496        }
497
498        private void dvOnline_OnNewAppointment(object sender, NewAppointmentEventArgs e)
499        {
500            Appointment Appointment = new Appointment();
501
502            Appointment.StartDate = e.StartDate;
503            Appointment.EndDate = e.EndDate;
504
505            onlineTimes.Add(Appointment);
506        }
507
508        #endregion
509
510        #endregion
511
512        #region Client communicator events
513
514        void clientCommunicator_SetUptimeCalendarCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
515        {
516            if (e.Error == null)
517            {
518                MessageBox.Show("Calendar successfully saved!", "Calender", MessageBoxButtons.OK, MessageBoxIcon.Information);
519            }
520            else
521            {
522                MessageBox.Show("Error saving calender \n" + e.Error.ToString(), "Calender", MessageBoxButtons.OK, MessageBoxIcon.Error);
523            }
524        }
525
526        void clientCommunicator_GetUptimeCalendarCompleted(object sender, GetUptimeCalendarCompletedEventArgs e)
527        {
528            if (e.Error == null)
529            {
530                if (e.Result != null)
531                {
532                    onlineTimes = e.Result.ToList<Appointment>();
533                    onlineTimes.ForEach(a => a.BorderColor = Color.Red);
534                }
535                else
536                {
537                    onlineTimes = new List<Appointment>();
538                }
539            }
540            //InitTestCalenderEntries();
541        }
542
543        private void clientCommunicator_GetCurrentConnectionCompleted(object sender, GetCurrentConnectionCompletedEventArgs e)
544        {
545            if (e.Error == null)
546            {
547                ConnectionContainer curConnection = e.Result;
548                tbIPAdress.Text = curConnection.IPAdress;
549                tbPort.Text = curConnection.Port.ToString();
550            }
551            else
552            {
553                refreshTimer.Stop();
554                DialogResult res = MessageBox.Show("Connection Error, check if Hive Client is running! - " + e.Error.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
555                if (res == DialogResult.OK)
556                    this.Close();
557            }
558        }
559
560        private void clientCommunicator_GetStatusInfosCompleted(object sender, GetStatusInfosCompletedEventArgs e)
561        {
562
563            if (e.Error == null)
564            {
565                StatusCommons sc = e.Result;
566
567                lbGuid.Text = sc.ClientGuid.ToString();
568                lbConnectionStatus.Text = sc.Status.ToString();
569                lbJobdone.Text = sc.JobsDone.ToString();
570                lbJobsAborted.Text = sc.JobsAborted.ToString();
571                lbJobsFetched.Text = sc.JobsFetched.ToString();
572
573                this.Text = "Client Console (" + sc.Status.ToString() + ")";
574
575                ListViewItem curJobStatusItem;
576
577                if (sc.Jobs != null)
578                {
579                    lvJobDetail.Items.Clear();
580                    double progress;
581                    foreach (JobStatus curJob in sc.Jobs)
582                    {
583                        curJobStatusItem = new ListViewItem(curJob.JobId.ToString());
584                        curJobStatusItem.SubItems.Add(curJob.Since.ToString());
585                        progress = curJob.Progress * 100;
586                        curJobStatusItem.SubItems.Add(progress.ToString());
587                        lvJobDetail.Items.Add(curJobStatusItem);
588                    }
589                    lvJobDetail.Sort();
590                }
591
592                UpdateGraph(sc.Jobs);
593
594                if (sc.Status == NetworkEnumWcfConnState.Connected || sc.Status == NetworkEnumWcfConnState.Loggedin)
595                {
596                    btConnect.Enabled = false;
597                    btnDisconnect.Enabled = true;
598                    lbCs.Text = sc.ConnectedSince.ToString();
599                    clientCommunicator.GetCurrentConnectionAsync();
600                }
601                else if (sc.Status == NetworkEnumWcfConnState.Disconnected)
602                {
603                    btConnect.Enabled = true;
604                    btnDisconnect.Enabled = false;
605                    lbCs.Text = String.Empty;
606                }
607                else if (sc.Status == NetworkEnumWcfConnState.Failed)
608                {
609                    btConnect.Enabled = true;
610                    btnDisconnect.Enabled = false;
611                    lbCs.Text = String.Empty;
612                }
613
614                clientCommunicator.GetCurrentConnection();
615            }
616            else
617            {
618                refreshTimer.Stop();
619                DialogResult res = MessageBox.Show("Connection Error, check if Hive Client is running! - " + e.Error.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
620                if (res == DialogResult.OK)
621                    this.Close();
622            }
623        }
624
625        #endregion
626
627        #endregion
628
629        #region GUI Events
630
631        private void btConnect_Click(object sender, EventArgs e)
632        {
633            IPAddress ipAdress;
634            int port;
635            ConnectionContainer cc = new ConnectionContainer();
636            if (IPAddress.TryParse(tbIPAdress.Text, out ipAdress) && int.TryParse(tbPort.Text, out port))
637            {
638                cc.IPAdress = tbIPAdress.Text;
639                cc.Port = port;
640                clientCommunicator.SetConnectionAsync(cc);
641            }
642            else
643            {
644                MessageBox.Show("IP Adress and/or Port Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
645            }
646        }
647
648        private void btnDisconnect_Click(object sender, EventArgs e)
649        {
650            clientCommunicator.DisconnectAsync();
651        }
652
653        private void btn_clientShutdown_Click(object sender, EventArgs e)
654        {
655            DialogResult res = MessageBox.Show("Do you really want to shutdown the Hive Client?", "Hive Client Console", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
656            if (res == DialogResult.Yes)
657            {
658                logFileReader.Stop();
659                clientCommunicator.ShutdownClient();
660                this.Close();
661            }
662        }
663
664        private void Connection_KeyPress(object sender, KeyPressEventArgs e)
665        {
666            if (e.KeyChar == (char)Keys.Return)
667                btConnect_Click(null, null);
668        }
669
670        #endregion
671
672    }
673}
Note: See TracBrowser for help on using the repository browser.