source: branches/eraser6/6.0/Eraser/MainForm.cs @ 1633

Revision 1633, 11.1 KB checked in by lowjoel, 5 years ago (diff)

Fixed regression introduced in r1490 where CreateControl? was called in MainForm?. CreateControl? however does not create handles when the control is not visible (delayed creation.) Since only SchedulerPanel? needs to have a handle created, we'll force creation of the handle there. In addition, remove an unnecessary call to UXThemeApi.UpdateControlTheme?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2009 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Data;
26using System.Drawing;
27using System.Drawing.Drawing2D;
28using System.Text;
29using System.Windows.Forms;
30using Eraser.Util;
31using Eraser.Manager;
32using Eraser.Properties;
33using System.IO;
34using System.Diagnostics;
35using System.Reflection;
36
37namespace Eraser
38{
39    public partial class MainForm : Form
40    {
41        private BasePanel CurrPage;
42        private SchedulerPanel SchedulerPage = new SchedulerPanel();
43        private SettingsPanel SettingsPage = new SettingsPanel();
44
45        public MainForm()
46        {
47            InitializeComponent();
48            contentPanel.Controls.Add(SchedulerPage);
49            contentPanel.Controls.Add(SettingsPage);
50
51            UXThemeApi.UpdateControlTheme(this);
52            UXThemeApi.UpdateControlTheme(notificationMenu);
53
54            //Connect to the executor task processing and processed events.
55            Program.eraserClient.TaskProcessing += OnTaskProcessing;
56            Program.eraserClient.TaskProcessed += OnTaskProcessed;
57
58            //Check the notification area context menu's minimise to tray item.
59            hideWhenMinimisedToolStripMenuItem.Checked = EraserSettings.Get().HideWhenMinimised;
60
61            //Set the docking style for each of the pages
62            SchedulerPage.Dock = DockStyle.Fill;
63            SettingsPage.Visible = false;
64
65            //Show the default page.
66            ChangePage(MainFormPage.Scheduler);
67        }
68
69        /// <summary>
70        /// Diplays the given title, message and icon as a system notification area balloon.
71        /// </summary>
72        /// <param name="title">The title of the balloon.</param>
73        /// <param name="message">The message to display.</param>
74        /// <param name="icon">The icon to show.</param>
75        public void ShowNotificationBalloon(string title, string message, ToolTipIcon icon)
76        {
77            notificationIcon.BalloonTipTitle = title;
78            notificationIcon.BalloonTipText = message;
79            notificationIcon.BalloonTipIcon = icon;
80            notificationIcon.ShowBalloonTip(0);
81        }
82
83        /// <summary>
84        /// Changes the active page displayed in the form.
85        /// </summary>
86        /// <param name="page">The new page to change to. No action is done when the
87        /// current page is the same as the new page requested</param>
88        public void ChangePage(MainFormPage page)
89        {
90            BasePanel oldPage = CurrPage;
91            switch (page)
92            {
93                case MainFormPage.Scheduler:
94                    CurrPage = SchedulerPage;
95                    break;
96                case MainFormPage.Settings:
97                    CurrPage = SettingsPage;
98                    break;
99            }
100
101            if (oldPage != CurrPage)
102            {
103                contentPanel.SuspendLayout();
104
105                //Hide the old page before showing the new one
106                if (oldPage != null)
107                    oldPage.Visible = false;
108
109                //If the page is not set to dock, we need to specify the dimensions of the page
110                //so it fits properly.
111                if (CurrPage.Dock == DockStyle.None)
112                {
113                    CurrPage.Anchor = AnchorStyles.Left | AnchorStyles.Right |
114                        AnchorStyles.Top;
115                    CurrPage.Left = 0;
116                    CurrPage.Top = 0;
117                    CurrPage.Width = contentPanel.Width;
118                }
119
120                //Show the new page then bring it to the top of the z-order.
121                CurrPage.Visible = true;
122                CurrPage.BringToFront();
123                contentPanel.ResumeLayout();
124            }
125        }
126
127        private static GraphicsPath CreateRoundRect(float X, float Y, float width,
128            float height, float radius)
129        {
130            GraphicsPath result = new GraphicsPath();
131
132            //Top line.
133            result.AddLine(X + radius, Y, X + width - 2 * radius, Y);
134
135            //Top-right corner
136            result.AddArc(X + width - 2 * radius, Y, 2 * radius, 2 * radius, 270, 90);
137
138            //Right line.
139            result.AddLine(X + width, Y + radius, X + width, Y + height - 2 * radius);
140
141            //Bottom-right corner
142            result.AddArc(X + width - 2 * radius, Y + height - 2 * radius, 2 * radius, 2 * radius, 0, 90);
143
144            //Bottom line.
145            result.AddLine(X + width - 2 * radius, Y + height, X + radius, Y + height);
146
147            //Bottom-left corner
148            result.AddArc(X, Y + height - 2 *radius, 2 * radius, 2 * radius, 90, 90);
149
150            //Left line
151            result.AddLine(X, Y + height - 2 * radius, X, Y + radius);
152
153            //Top-left corner
154            result.AddArc(X, Y, 2 * radius, 2 * radius, 180, 90);
155            result.CloseFigure();
156
157            return result;
158        }
159
160        private void DrawBackground(Graphics dc)
161        {
162            //Draw the base background
163            dc.FillRectangle(new SolidBrush(Color.FromArgb(unchecked((int)0xFF292929))),
164                new Rectangle(new Point(0, 0), Size));
165
166            //Then the side gradient
167            dc.FillRectangle(new LinearGradientBrush(new Rectangle(0, 0, 338, Math.Max(1, ClientSize.Height)),
168                    Color.FromArgb(unchecked((int)0xFF363636)),
169                    Color.FromArgb(unchecked((int)0xFF292929)), 0.0),
170                0, 0, 338, ClientSize.Height);
171
172            //Draw the top background
173            dc.FillRectangle(new SolidBrush(Color.FromArgb(unchecked((int)0xFF414141))),
174                new Rectangle(0, 0, ClientSize.Width, 32));
175
176            //The top gradient
177            dc.DrawImage(Properties.Resources.BackgroundGradient, new Point(0, 0));
178
179            dc.SmoothingMode = SmoothingMode.AntiAlias;
180            dc.FillPath(Brushes.White, CreateRoundRect(11, 74, contentPanel.Width + 8, ClientSize.Height - 85, 3));
181        }
182
183        private void MainForm_Paint(object sender, PaintEventArgs e)
184        {
185            e.Graphics.SetClip(new Rectangle(0, 0, Width, Height), CombineMode.Intersect);
186            DrawBackground(e.Graphics);
187        }
188
189        private void MainForm_Resize(object sender, EventArgs e)
190        {
191            if (WindowState != FormWindowState.Minimized)
192            {
193                Bitmap bmp = new Bitmap(Width, Height);
194                Graphics dc = Graphics.FromImage(bmp);
195                DrawBackground(dc);
196
197                CreateGraphics().DrawImage(bmp, new Point(0, 0));
198            }
199            else if (EraserSettings.Get().HideWhenMinimised)
200            {
201                Visible = false;
202            }
203        }
204
205        private void tbSchedule_Click(object sender, EventArgs e)
206        {
207            ChangePage(MainFormPage.Scheduler);
208        }
209
210        private void tbSettings_Click(object sender, EventArgs e)
211        {
212            ChangePage(MainFormPage.Settings);
213        }
214
215        private void newTaskToolStripMenuItem_Click(object sender, EventArgs e)
216        {
217            using (TaskPropertiesForm form = new TaskPropertiesForm())
218            {
219                if (form.ShowDialog() == DialogResult.OK)
220                {
221                    Task task = form.Task;
222                    Program.eraserClient.Tasks.Add(task);
223                }
224            }
225        }
226
227        private void exportTaskListToolStripMenuItem_Click(object sender, EventArgs e)
228        {
229            using (SaveFileDialog dialog = new SaveFileDialog())
230            {
231                dialog.Filter = "Eraser 6 task lists (*.ersx)|*.ersx";
232                dialog.DefaultExt = "ersx";
233                dialog.OverwritePrompt = true;
234
235                if (dialog.ShowDialog() == DialogResult.OK)
236                {
237                    using (FileStream stream = new FileStream(dialog.FileName,
238                        FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
239                    {
240                        Program.eraserClient.Tasks.SaveToStream(stream);
241                    }
242                }
243            }
244        }
245
246        private void importTaskListToolStripMenuItem_Click(object sender, EventArgs e)
247        {
248            using (OpenFileDialog dialog = new OpenFileDialog())
249            {
250                dialog.Filter = "Eraser 6 task lists (*.ersx)|*.ersx";
251                dialog.DefaultExt = "ersx";
252
253                if (dialog.ShowDialog() == DialogResult.OK)
254                {
255                    using (FileStream stream = new FileStream(dialog.FileName,
256                        FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
257                    {
258                        Program.eraserClient.Tasks.LoadFromStream(stream);
259                    }
260                }
261            }
262        }
263
264        private void tbHelp_Click(object sender, EventArgs e)
265        {
266            try
267            {
268                Process.Start(Path.Combine(Path.GetDirectoryName(
269                        Assembly.GetEntryAssembly().Location),
270                    "Eraser Documentation.pdf"));
271            }
272            catch (Win32Exception ex)
273            {
274                MessageBox.Show(this, S._("The Eraser documentation file could not be " +
275                    "opened. Check that Adobe Reader installed and that your Eraser " +
276                    "install is not corrupt.\n\nThe error returned was: {0}", ex.Message),
277                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error,
278                    MessageBoxDefaultButton.Button1, S.IsRightToLeft(this) ?
279                        MessageBoxOptions.RtlReading : 0);
280            }
281        }
282
283        private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
284        {
285            using (UpdateForm form = new UpdateForm())
286            {
287                form.ShowDialog();
288            }
289        }
290
291        private void aboutEraserToolStripMenuItem_Click(object sender, EventArgs e)
292        {
293            using (AboutForm form = new AboutForm(this))
294            {
295                form.ShowDialog();
296            }
297        }
298
299        private void eraserLogo_Click(object sender, EventArgs e)
300        {
301            Process.Start("http://eraser.heidi.ie/");
302        }
303
304        #region Task processing code (for notification area animation)
305        void OnTaskProcessing(object sender, TaskEventArgs e)
306        {
307            if (InvokeRequired)
308            {
309                Invoke(new EventHandler<TaskEventArgs>(OnTaskProcessing), sender, e);
310                return;
311            }
312
313            string iconText = S._("Eraser") + " - " + S._("Processing:") + ' ' + e.Task.UIText;
314            if (iconText.Length >= 64)
315                iconText = iconText.Remove(60) + "...";
316
317            ProcessingAnimationFrame = 0;
318            notificationIcon.Text = iconText;
319            notificationIconTimer.Enabled = true;
320        }
321
322        void OnTaskProcessed(object sender, TaskEventArgs e)
323        {
324            if (InvokeRequired)
325            {
326                Invoke(new EventHandler<TaskEventArgs>(OnTaskProcessed), sender, e);
327                return;
328            }
329
330            //Reset the notification area icon.
331            notificationIconTimer.Enabled = false;
332            if (notificationIcon.Icon != null)
333            {
334                ComponentResourceManager resources = new ComponentResourceManager(typeof(MainForm));
335                resources.ApplyResources(notificationIcon, "notificationIcon");
336            }
337        }
338
339        private void notificationIconTimer_Tick(object sender, EventArgs e)
340        {
341            notificationIcon.Icon = ProcessingAnimationFrames[ProcessingAnimationFrame++];
342            if (ProcessingAnimationFrame == ProcessingAnimationFrames.Length)
343                ProcessingAnimationFrame = 0;
344        }
345
346        private int ProcessingAnimationFrame;
347        private Icon[] ProcessingAnimationFrames = new Icon[] {
348            Resources.NotifyBusy1,
349            Resources.NotifyBusy2,
350            Resources.NotifyBusy3,
351            Resources.NotifyBusy4,
352            Resources.NotifyBusy5,
353            Resources.NotifyBusy4,
354            Resources.NotifyBusy3,
355            Resources.NotifyBusy2,
356            Resources.NotifyBusy1
357        };
358        #endregion
359
360        #region Minimise to tray code
361        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
362        {
363            if (EraserSettings.Get().HideWhenMinimised && e.CloseReason == CloseReason.UserClosing)
364            {
365                e.Cancel = true;
366                Visible = false;
367            }
368        }
369
370        private void MainForm_VisibleChanged(object sender, EventArgs e)
371        {
372            if (Visible)
373            {
374                WindowState = FormWindowState.Normal;
375                Activate();
376            }
377        }
378
379        private void openToolStripMenuItem_Click(object sender, EventArgs e)
380        {
381            Visible = true;
382        }
383
384        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
385        {
386            Application.Exit();
387        }
388
389        private void hideWhenMinimiseToolStripMenuItem_Click(object sender, EventArgs e)
390        {
391            EraserSettings.Get().HideWhenMinimised =
392                hideWhenMinimisedToolStripMenuItem.Checked;
393        }
394        #endregion
395    }
396
397    public enum MainFormPage
398    {
399        Scheduler = 0,
400        Settings
401    }
402}
Note: See TracBrowser for help on using the repository browser.