/src/MainForm.cs
C# | 1334 lines | 1048 code | 212 blank | 74 comment | 177 complexity | 6cc722d9bb955b107958493113e6dc1a MD5 | raw file
Possible License(s): Unlicense
- /////////////////////////////////////////////////////////////////////////////////
- // Paint.NET //
- // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
- // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
- // See src/Resources/Files/License.txt for full licensing and attribution //
- // details. //
- // . //
- /////////////////////////////////////////////////////////////////////////////////
-
- using PaintDotNet.Actions;
- using PaintDotNet.Effects;
- using PaintDotNet.Menus;
- using PaintDotNet.SystemLayer;
- using PaintDotNet.Tools;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.Globalization;
- using System.IO;
- using System.Net;
- using System.Reflection;
- using System.Resources;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
-
- namespace PaintDotNet
- {
- internal sealed class MainForm
- : PdnBaseForm
- {
- private AppWorkspace appWorkspace;
- private Button defaultButton;
- private FloatingToolForm[] floaters;
- private System.Windows.Forms.Timer floaterOpacityTimer;
- private System.Windows.Forms.Timer deferredInitializationTimer;
- private System.ComponentModel.IContainer components;
- private bool killAfterInit = false;
- private SplashForm splashForm = null;
- private SingleInstanceManager singleInstanceManager = null;
- private List<string> queuedInstanceMessages = new List<string>();
-
- public SingleInstanceManager SingleInstanceManager
- {
- get
- {
- return this.singleInstanceManager;
- }
-
- set
- {
- if (this.singleInstanceManager != null)
- {
- this.singleInstanceManager.InstanceMessageReceived -= new EventHandler(SingleInstanceManager_InstanceMessageReceived);
- this.singleInstanceManager.SetWindow(null);
- }
-
- this.singleInstanceManager = value;
-
- if (this.singleInstanceManager != null)
- {
- this.singleInstanceManager.SetWindow(this);
- this.singleInstanceManager.InstanceMessageReceived += new EventHandler(SingleInstanceManager_InstanceMessageReceived);
- }
- }
- }
-
- private void SingleInstanceManager_InstanceMessageReceived(object sender, EventArgs e)
- {
- BeginInvoke(new Procedure(ProcessQueuedInstanceMessages), null);
- }
-
- public MainForm()
- : this(new string[0])
- {
- }
-
- protected override void WndProc(ref Message m)
- {
- if (this.singleInstanceManager != null)
- {
- this.singleInstanceManager.FilterMessage(ref m);
- }
-
- base.WndProc(ref m);
- }
-
- private enum ArgumentAction
- {
- Open,
- OpenUntitled,
- Print,
- NoOp
- }
-
- private bool SplitMessage(string message, out ArgumentAction action, out string actionParm)
- {
- if (message.Length == 0)
- {
- action = ArgumentAction.NoOp;
- actionParm = null;
- return false;
- }
-
- const string printPrefix = "print:";
-
- if (message.IndexOf(printPrefix) == 0)
- {
- action = ArgumentAction.Print;
- actionParm = message.Substring(printPrefix.Length);
- return true;
- }
-
- const string untitledPrefix = "untitled:";
-
- if (message.IndexOf(untitledPrefix) == 0)
- {
- action = ArgumentAction.OpenUntitled;
- actionParm = message.Substring(untitledPrefix.Length);
- return true;
- }
-
- action = ArgumentAction.Open;
- actionParm = message;
- return true;
- }
-
- private bool ProcessMessage(string message)
- {
- if (IsDisposed)
- {
- return false;
- }
-
- ArgumentAction action;
- string actionParm;
- bool result;
-
- result = SplitMessage(message, out action, out actionParm);
-
- if (!result)
- {
- return true;
- }
-
- switch (action)
- {
- case ArgumentAction.NoOp:
- result = true;
- break;
-
- case ArgumentAction.Open:
- Activate();
-
- if (IsCurrentModalForm && Enabled)
- {
- result = this.appWorkspace.OpenFileInNewWorkspace(actionParm);
- }
-
- break;
-
- case ArgumentAction.OpenUntitled:
- Activate();
-
- if (!string.IsNullOrEmpty(actionParm) && IsCurrentModalForm && Enabled)
- {
- result = this.appWorkspace.OpenFileInNewWorkspace(actionParm, false);
-
- if (result)
- {
- this.appWorkspace.ActiveDocumentWorkspace.SetDocumentSaveOptions(null, null, null);
- this.appWorkspace.ActiveDocumentWorkspace.Document.Dirty = true;
- }
- }
-
- break;
-
- case ArgumentAction.Print:
- Activate();
-
- if (!string.IsNullOrEmpty(actionParm) && IsCurrentModalForm && Enabled)
- {
- result = this.appWorkspace.OpenFileInNewWorkspace(actionParm);
-
- if (result)
- {
- DocumentWorkspace dw = this.appWorkspace.ActiveDocumentWorkspace;
- PrintAction pa = new PrintAction();
- dw.PerformAction(pa);
- CloseWorkspaceAction cwa = new CloseWorkspaceAction(dw);
- this.appWorkspace.PerformAction(cwa);
-
- if (this.appWorkspace.DocumentWorkspaces.Length == 0)
- {
- Startup.CloseApplication();
- }
- }
- }
- break;
-
- default:
- throw new InvalidEnumArgumentException();
- }
-
- return result;
- }
-
- private void ProcessQueuedInstanceMessages()
- {
- if (IsDisposed)
- {
- return;
- }
-
- if (this.splashForm != null)
- {
- this.splashForm.Close();
- this.splashForm.Dispose();
- this.splashForm = null;
- }
-
- if (IsHandleCreated &&
- !PdnInfo.IsExpired &&
- this.singleInstanceManager != null)
- {
- string[] messages1 = this.singleInstanceManager.GetPendingInstanceMessages();
- string[] messages2 = this.queuedInstanceMessages.ToArray();
- this.queuedInstanceMessages.Clear();
-
- string[] messages = new string[messages1.Length + messages2.Length];
- for (int i = 0; i < messages1.Length; ++i)
- {
- messages[i] = messages1[i];
- }
-
- for (int i = 0; i < messages2.Length; ++i)
- {
- messages[i + messages1.Length] = messages2[i];
- }
-
- foreach (string message in messages)
- {
- bool result = ProcessMessage(message);
-
- if (!result)
- {
- break;
- }
- }
- }
- }
-
- private void Application_Idle(object sender, EventArgs e)
- {
- if (!this.IsDisposed &&
- (this.queuedInstanceMessages.Count > 0 || (this.singleInstanceManager != null && this.singleInstanceManager.AreMessagesPending)))
- {
- ProcessQueuedInstanceMessages();
- }
- }
-
- public MainForm(string[] args)
- {
- bool canSetCurrentDir = true;
-
- this.StartPosition = FormStartPosition.WindowsDefaultLocation;
-
- bool splash = false;
- List<string> fileNames = new List<string>();
-
- // Parse command line arguments
- foreach (string argument in args)
- {
- if (0 == string.Compare(argument, "/dontForceGC"))
- {
- Utility.AllowGCFullCollect = false;
- }
- else if (0 == string.Compare(argument, "/splash", true))
- {
- splash = true;
- }
- else if (0 == string.Compare(argument, "/test", true))
- {
- // This lets us use an alternate update manifest on the web server so that
- // we can test manifests on a small scale before "deploying" them to everybody
- PdnInfo.IsTestMode = true;
- }
- else if (0 == string.Compare(argument, "/profileStartupTimed", true))
- {
- // profileStartupTimed and profileStartupWorkingSet compete, which
- // ever is last in the args list wins.
- PdnInfo.StartupTest = StartupTestType.Timed;
- }
- else if (0 == string.Compare(argument, "/profileStartupWorkingSet", true))
- {
- // profileStartupTimed and profileStartupWorkingSet compete, which
- // ever is last in the args list wins.
- PdnInfo.StartupTest = StartupTestType.WorkingSet;
- }
- else if (argument.Length > 0 && argument[0] != '/')
- {
- try
- {
- string fullPath = Path.GetFullPath(argument);
- fileNames.Add(fullPath);
- }
-
- catch (Exception)
- {
- fileNames.Add(argument);
- canSetCurrentDir = false;
- }
-
- splash = true;
- }
- }
-
- if (canSetCurrentDir)
- {
- try
- {
- Environment.CurrentDirectory = PdnInfo.GetApplicationDir();
- }
-
- catch (Exception ex)
- {
- Tracing.Ping("Exception while trying to set Environment.CurrentDirectory: " + ex.ToString());
- }
- }
-
- // make splash, if warranted
- if (splash)
- {
- this.splashForm = new SplashForm();
- this.splashForm.TopMost = true;
- this.splashForm.Show();
- this.splashForm.Update();
- }
-
- InitializeComponent();
-
- this.Icon = PdnInfo.AppIcon;
-
- // Does not load window location/state
- LoadSettings();
-
- foreach (string fileName in fileNames)
- {
- this.queuedInstanceMessages.Add(fileName);
- }
-
- // no file specified? create a blank image
- if (fileNames.Count == 0)
- {
- MeasurementUnit units = Document.DefaultDpuUnit;
- double dpu = Document.GetDefaultDpu(units);
- Size newSize = this.appWorkspace.GetNewDocumentSize();
- this.appWorkspace.CreateBlankDocumentInNewWorkspace(newSize, units, dpu, true);
- this.appWorkspace.ActiveDocumentWorkspace.IncrementJustPaintWhite();
- this.appWorkspace.ActiveDocumentWorkspace.Document.Dirty = false;
- }
-
- LoadWindowState();
-
- deferredInitializationTimer.Enabled = true;
-
- Application.Idle += new EventHandler(Application_Idle);
- }
-
- protected override void OnShown(EventArgs e)
- {
- base.OnShown(e);
-
- if (PdnInfo.IsExpired)
- {
- foreach (Form form in Application.OpenForms)
- {
- form.Enabled = false;
- }
-
- TaskButton checkForUpdatesTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuHelpCheckForUpdatesIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.CheckForUpdatesTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.CheckForUpdatesTB.ExplanationText"));
-
- TaskButton goToWebSiteTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuHelpPdnWebsiteIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.GoToWebSiteTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.GoToWebSiteTB.ExplanationText"));
-
- TaskButton doNotCheckForUpdatesTB = new TaskButton(
- PdnResources.GetImageResource("Icons.CancelIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.DoNotCheckForUpdatesTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.DoNotCheckForUpdatesTB.ExplanationText"));
-
- TaskButton[] taskButtons =
- new TaskButton[]
- {
- checkForUpdatesTB,
- goToWebSiteTB,
- doNotCheckForUpdatesTB
- };
-
- TaskButton clickedTB = TaskDialog.Show(
- this,
- Icon,
- PdnInfo.GetFullAppName(),
- PdnResources.GetImageResource("Icons.WarningIcon.png").Reference,
- true,
- PdnResources.GetString("ExpiredTaskDialog.InfoText"),
- taskButtons,
- checkForUpdatesTB,
- doNotCheckForUpdatesTB,
- 450);
-
- if (clickedTB == checkForUpdatesTB)
- {
- this.appWorkspace.CheckForUpdates();
- }
- else if (clickedTB == goToWebSiteTB)
- {
- PdnInfo.LaunchWebSite(this, InvariantStrings.ExpiredPage);
- }
-
- Close();
- }
- }
-
- private void LoadWindowState()
- {
- try
- {
- FormWindowState fws = (FormWindowState)Enum.Parse(typeof(FormWindowState),
- Settings.CurrentUser.GetString(SettingNames.WindowState, WindowState.ToString()), true);
-
- // if the state was saved as 'minimized' then just ignore whatever was saved
-
- if (fws != FormWindowState.Minimized)
- {
- if (fws != FormWindowState.Maximized)
- {
- Rectangle newBounds = Rectangle.Empty;
-
- // Load the registry values into a rectangle so that we
- // can update the settings all at once, instead of one
- // at a time. This will make loading the size an all or
- // none operation, with no rollback necessary
- newBounds.Width = Settings.CurrentUser.GetInt32(SettingNames.Width, this.Width);
- newBounds.Height = Settings.CurrentUser.GetInt32(SettingNames.Height, this.Height);
-
- int left = Settings.CurrentUser.GetInt32(SettingNames.Left, this.Left);
- int top = Settings.CurrentUser.GetInt32(SettingNames.Top, this.Top);
- newBounds.Location = new Point(left, top);
-
- this.Bounds = newBounds;
- }
-
- this.WindowState = fws;
- }
- }
-
- catch
- {
- try
- {
- Settings.CurrentUser.Delete(
- new string[]
- {
- SettingNames.Width,
- SettingNames.Height,
- SettingNames.WindowState,
- SettingNames.Top,
- SettingNames.Left
- });
- }
-
- catch
- {
- // ignore errors
- }
- }
- }
-
- private void LoadSettings()
- {
- try
- {
- PdnBaseForm.EnableOpacity = Settings.CurrentUser.GetBoolean(SettingNames.TranslucentWindows, true);
- }
-
- catch (Exception ex)
- {
- Tracing.Ping("Exception in MainForm.LoadSettings:" + ex.ToString());
-
- try
- {
- Settings.CurrentUser.Delete(
- new string[]
- {
- SettingNames.TranslucentWindows
- });
- }
-
- catch
- {
- }
- }
- }
-
- private void SaveSettings()
- {
- Settings.CurrentUser.SetInt32(SettingNames.Width, this.Width);
- Settings.CurrentUser.SetInt32(SettingNames.Height, this.Height);
- Settings.CurrentUser.SetInt32(SettingNames.Top, this.Top);
- Settings.CurrentUser.SetInt32(SettingNames.Left, this.Left);
- Settings.CurrentUser.SetString(SettingNames.WindowState, this.WindowState.ToString());
-
- Settings.CurrentUser.SetBoolean(SettingNames.TranslucentWindows, PdnBaseForm.EnableOpacity);
-
- if (this.WindowState != FormWindowState.Minimized)
- {
- Settings.CurrentUser.SetBoolean(SettingNames.ToolsFormVisible, this.appWorkspace.Widgets.ToolsForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.ColorsFormVisible, this.appWorkspace.Widgets.ColorsForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.HistoryFormVisible, this.appWorkspace.Widgets.HistoryForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.LayersFormVisible, this.appWorkspace.Widgets.LayerForm.Visible);
- }
-
- SnapManager.Save(Settings.CurrentUser);
- this.appWorkspace.SaveSettings();
- }
-
-
- protected override void OnQueryEndSession(CancelEventArgs e)
- {
- if (IsCurrentModalForm)
- {
- OnClosing(e);
- }
- else
- {
- foreach (Form form in Application.OpenForms)
- {
- PdnBaseForm asPDF = form as PdnBaseForm;
-
- if (asPDF != null)
- {
- asPDF.Flash();
- }
- }
-
- e.Cancel = true;
- }
-
- base.OnQueryEndSession(e);
- }
-
- protected override void OnClosing(CancelEventArgs e)
- {
- if (!e.Cancel)
- {
- if (this.appWorkspace != null)
- {
- CloseAllWorkspacesAction cawa = new CloseAllWorkspacesAction();
- this.appWorkspace.PerformAction(cawa);
- e.Cancel = cawa.Cancelled;
- }
- }
-
- if (!e.Cancel)
- {
- SaveSettings();
-
- if (this.floaters != null)
- {
- foreach (Form hideMe in this.floaters)
- {
- hideMe.Hide();
- }
- }
-
- this.Hide();
-
- if (this.queuedInstanceMessages != null)
- {
- this.queuedInstanceMessages.Clear();
- }
-
- SingleInstanceManager sim2 = this.singleInstanceManager;
- SingleInstanceManager = null;
-
- if (sim2 != null)
- {
- sim2.Dispose();
- sim2 = null;
- }
- }
-
- base.OnClosing(e);
- }
-
- protected override void OnClosed(EventArgs e)
- {
- if (this.appWorkspace.ActiveDocumentWorkspace != null)
- {
- appWorkspace.ActiveDocumentWorkspace.SetTool(null);
- }
-
- base.OnClosed(e);
- }
-
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (this.singleInstanceManager != null)
- {
- SingleInstanceManager sim2 = this.singleInstanceManager;
- SingleInstanceManager = null;
- sim2.Dispose();
- sim2 = null;
- }
-
- if (this.floaterOpacityTimer != null)
- {
- this.floaterOpacityTimer.Tick -= new System.EventHandler(this.FloaterOpacityTimer_Tick);
- this.floaterOpacityTimer.Dispose();
- this.floaterOpacityTimer = null;
- }
-
- if (this.components != null)
- {
- this.components.Dispose();
- this.components = null;
- }
- }
-
- try
- {
- base.Dispose(disposing);
- }
-
- catch (RankException)
- {
- // System.Windows.Forms.PropertyStore
- // Discard error - bug #2746
- }
- }
-
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- this.defaultButton = new System.Windows.Forms.Button();
- this.appWorkspace = new PaintDotNet.AppWorkspace();
- this.floaterOpacityTimer = new System.Windows.Forms.Timer(this.components);
- this.deferredInitializationTimer = new System.Windows.Forms.Timer(this.components);
- this.SuspendLayout();
- //
- // appWorkspace
- //
- this.appWorkspace.Dock = System.Windows.Forms.DockStyle.Fill;
- this.appWorkspace.Location = new System.Drawing.Point(0, 0);
- this.appWorkspace.Name = "appWorkspace";
- this.appWorkspace.Size = new System.Drawing.Size(752, 648);
- this.appWorkspace.TabIndex = 2;
- this.appWorkspace.ActiveDocumentWorkspaceChanging += new EventHandler(AppWorkspace_ActiveDocumentWorkspaceChanging);
- this.appWorkspace.ActiveDocumentWorkspaceChanged += new EventHandler(AppWorkspace_ActiveDocumentWorkspaceChanged);
- //
- // floaterOpacityTimer
- //
- this.floaterOpacityTimer.Enabled = false;
- this.floaterOpacityTimer.Interval = 25;
- this.floaterOpacityTimer.Tick += new System.EventHandler(this.FloaterOpacityTimer_Tick);
- //
- // deferredInitializationTimer
- //
- this.deferredInitializationTimer.Interval = 250;
- this.deferredInitializationTimer.Tick += new EventHandler(DeferredInitialization);
- //
- // defaultButton
- //
- this.defaultButton.Size = new System.Drawing.Size(1, 1);
- this.defaultButton.Text = "";
- this.defaultButton.Location = new Point(-100, -100);
- this.defaultButton.TabStop = false;
- this.defaultButton.Click += new EventHandler(DefaultButton_Click);
- //
- // MainForm
- //
-
- try
- {
- this.AllowDrop = true;
- }
-
- catch (InvalidOperationException)
- {
- // Discard error. See bug #2605.
- }
-
- this.AutoScaleDimensions = new SizeF(96F, 96F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
- this.ClientSize = new System.Drawing.Size(950, 738);
- this.Controls.Add(this.appWorkspace);
- this.Controls.Add(this.defaultButton);
- this.AcceptButton = this.defaultButton;
- this.Name = "MainForm";
- this.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultLocation;
- this.ForceActiveTitleBar = true;
- this.KeyPreview = true;
- this.Controls.SetChildIndex(this.appWorkspace, 0);
- this.ResumeLayout(false);
- this.PerformLayout();
- }
-
- private void AppWorkspace_ActiveDocumentWorkspaceChanging(object sender, EventArgs e)
- {
- if (this.appWorkspace.ActiveDocumentWorkspace != null)
- {
- this.appWorkspace.ActiveDocumentWorkspace.ScaleFactorChanged -= DocumentWorkspace_ScaleFactorChanged;
- this.appWorkspace.ActiveDocumentWorkspace.DocumentChanged -= DocumentWorkspace_DocumentChanged;
- this.appWorkspace.ActiveDocumentWorkspace.SaveOptionsChanged -= DocumentWorkspace_SaveOptionsChanged;
- }
- }
-
- private void AppWorkspace_ActiveDocumentWorkspaceChanged(object sender, EventArgs e)
- {
- if (this.appWorkspace.ActiveDocumentWorkspace != null)
- {
- this.appWorkspace.ActiveDocumentWorkspace.ScaleFactorChanged += DocumentWorkspace_ScaleFactorChanged;
- this.appWorkspace.ActiveDocumentWorkspace.DocumentChanged += DocumentWorkspace_DocumentChanged;
- this.appWorkspace.ActiveDocumentWorkspace.SaveOptionsChanged += DocumentWorkspace_SaveOptionsChanged;
- }
-
- SetTitleText();
- }
-
- private void DocumentWorkspace_SaveOptionsChanged(object sender, EventArgs e)
- {
- SetTitleText();
- }
-
- private Keys CharToKeys(char c)
- {
- Keys keys = Keys.None;
- c = Char.ToLower(c);
-
- if (c >= 'a' && c <= 'z')
- {
- keys = (Keys)((int)Keys.A + (int)c - (int)'a');
- }
-
- return keys;
- }
-
- private Keys GetMenuCmdKey(string text)
- {
- Keys keys = Keys.None;
-
- for (int i = 0; i < text.Length - 1; ++i)
- {
- if (text[i] == '&')
- {
- keys = Keys.Alt | CharToKeys(text[i + 1]);
- break;
- }
- }
-
- return keys;
- }
-
- protected override void OnLoad(EventArgs e)
- {
- EnsureFormIsOnScreen();
-
- if (killAfterInit)
- {
- Application.Exit();
- }
-
- this.floaters = new FloatingToolForm[] {
- appWorkspace.Widgets.ToolsForm,
- appWorkspace.Widgets.ColorsForm,
- appWorkspace.Widgets.HistoryForm,
- appWorkspace.Widgets.LayerForm
- };
-
- foreach (FloatingToolForm ftf in floaters)
- {
- ftf.Closing += this.HideInsteadOfCloseHandler;
- }
-
- PositionFloatingForms();
-
- base.OnLoad(e);
-
- switch (PdnInfo.StartupTest)
- {
- case StartupTestType.Timed:
- Application.DoEvents();
- Application.Exit();
- break;
-
- case StartupTestType.WorkingSet:
- const int waitPeriodForVadumpSnapshot = 20000;
- Application.DoEvents();
- Thread.Sleep(waitPeriodForVadumpSnapshot);
- Application.Exit();
- break;
- }
- }
-
- private void PositionFloatingForms()
- {
- this.appWorkspace.ResetFloatingForms();
-
- try
- {
- SnapManager.Load(Settings.CurrentUser);
- }
-
- catch
- {
- this.appWorkspace.ResetFloatingForms();
- }
-
- foreach (FloatingToolForm ftf in floaters)
- {
- this.AddOwnedForm(ftf);
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.ToolsFormVisible, true))
- {
- this.appWorkspace.Widgets.ToolsForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.ColorsFormVisible, true))
- {
- this.appWorkspace.Widgets.ColorsForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.HistoryFormVisible, true))
- {
- this.appWorkspace.Widgets.HistoryForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.LayersFormVisible, true))
- {
- this.appWorkspace.Widgets.LayerForm.Show();
- }
-
- // If the floating form is off screen somehow, reset it
- // We've been getting a lot of reports where people say their Colors window has disappeared
- Screen[] allScreens = Screen.AllScreens;
-
- foreach (FloatingToolForm ftf in this.floaters)
- {
- if (!ftf.Visible)
- {
- continue;
- }
-
- bool reset = false;
-
- try
- {
- bool foundAScreen = false;
-
- foreach (Screen screen in allScreens)
- {
- Rectangle intersect = Rectangle.Intersect(screen.Bounds, ftf.Bounds);
-
- if (intersect.Width > 0 && intersect.Height > 0)
- {
- foundAScreen = true;
- break;
- }
- }
-
- if (!foundAScreen)
- {
- reset = true;
- }
- }
-
- catch (Exception)
- {
- reset = true;
- }
-
- if (reset)
- {
- this.appWorkspace.ResetFloatingForm(ftf);
- }
- }
-
- this.floaterOpacityTimer.Enabled = true;
- }
-
- protected override void OnResize(EventArgs e)
- {
- if (floaterOpacityTimer != null)
- {
- if (WindowState == FormWindowState.Minimized)
- {
- if (this.floaterOpacityTimer.Enabled)
- {
- this.floaterOpacityTimer.Enabled = false;
- }
- }
- else
- {
- if (!this.floaterOpacityTimer.Enabled)
- {
- this.floaterOpacityTimer.Enabled = true;
- }
-
- this.FloaterOpacityTimer_Tick(this, EventArgs.Empty);
- }
- }
-
- base.OnResize (e);
- }
-
- private void DocumentWorkspace_DocumentChanged(object sender, System.EventArgs e)
- {
- SetTitleText();
- OnResize(EventArgs.Empty);
- }
-
- private void SetTitleText()
- {
- if (this.appWorkspace == null)
- {
- return;
- }
-
- if (this.appWorkspace.ActiveDocumentWorkspace == null)
- {
- this.Text = PdnInfo.GetAppName();
- }
- else
- {
- string appTitle = PdnInfo.GetAppName();
- string ratio = string.Empty;
- string title = string.Empty;
- string friendlyName = this.appWorkspace.ActiveDocumentWorkspace.GetFriendlyName();
- string text;
-
- if (this.WindowState != FormWindowState.Minimized)
- {
- string format = PdnResources.GetString("MainForm.Title.Format.Normal");
- text = string.Format(format, friendlyName, appWorkspace.ActiveDocumentWorkspace.ScaleFactor, appTitle);
- }
- else
- {
- string format = PdnResources.GetString("MainForm.Title.Format.Minimized");
- text = string.Format(format, friendlyName, appTitle);
- }
-
- if (appWorkspace.ActiveDocumentWorkspace.Document != null)
- {
- title = text;
- }
-
- this.Text = title;
- }
- }
-
- // For the menus where we dynamically enable menu items (e.g. Copy only enabled when there's a selection),
- // we have to make sure to re-enable all the items when the menu goes way.
- // This is important for cases where, for example: Edit menu is opened, "Deselect" is disabled because
- // there is no selection. User then clicks on Select All. The menu then goes away. However, since Deselect
- // was disabled, the Ctrl+D shortcut will not be honored even though there is a selection.
- // So the disabling of menu items should only be temporary for the duration of the menu's visibility.
- private void OnMenuDropDownClosed(object sender, System.EventArgs e)
- {
- ToolStripMenuItem menu = (ToolStripMenuItem)sender;
-
- foreach (ToolStripItem tsi in menu.DropDownItems)
- {
- tsi.Enabled = true;
- }
- }
-
- private void HideInsteadOfCloseHandler(object sender, CancelEventArgs e)
- {
- e.Cancel = true;
- ((Form)sender).Hide();
- }
-
- // TODO: refactor into FloatingToolForm class somehow
- private void FloaterOpacityTimer_Tick(object sender, System.EventArgs e)
- {
- if (this.WindowState == FormWindowState.Minimized ||
- this.floaters == null ||
- !PdnBaseForm.EnableOpacity ||
- this.appWorkspace.ActiveDocumentWorkspace == null)
- {
- return;
- }
-
- // Here's the behavior we want for our floaters:
- // 1. If the mouse is within a floaters rectangle, it should transition to fully opaque
- // 2. If the mouse is outside the floater's rectangle, it should transition to partially
- // opaque
- // 3. However, if the floater is outside where the document is visible on screen, it
- // should always be fully opaque.
- Rectangle screenDocRect;
-
- try
- {
- screenDocRect = this.appWorkspace.ActiveDocumentWorkspace.VisibleDocumentBounds;
- }
-
- catch (ObjectDisposedException)
- {
- return; // do nothing, we are probably in the process of shutting down the app
- }
-
- for (int i = 0; i < floaters.Length; ++i)
- {
- FloatingToolForm ftf = floaters[i];
-
- Rectangle intersect = Rectangle.Intersect(screenDocRect, ftf.Bounds);
- double opacity = -1.0;
-
- try
- {
- if (intersect.Width == 0 ||
- intersect.Height == 0 ||
- (ftf.Bounds.Contains(Control.MousePosition) &&
- !appWorkspace.ActiveDocumentWorkspace.IsMouseCaptured()) ||
- Utility.DoesControlHaveMouseCaptured(ftf))
- {
- opacity = Math.Min(1.0, ftf.Opacity + 0.125);
- }
- else
- {
- opacity = Math.Max(0.75, ftf.Opacity - 0.0625);
- }
-
- if (opacity != ftf.Opacity)
- {
- ftf.Opacity = opacity;
- }
- }
-
- catch (System.ComponentModel.Win32Exception)
- {
- // We just eat the exception. Chris Strahl was having some problem where opacity was 0.7
- // and we were trying to set it to 0.7 and it said "the parameter is incorrect"
- // ... which is stupid. Bad NVIDIA drivers for his GeForce Go?
- }
- }
- }
-
- protected override void OnDragEnter(DragEventArgs drgevent)
- {
- if (Enabled && drgevent.Data.GetDataPresent(DataFormats.FileDrop))
- {
- string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
-
- foreach (string file in files)
- {
- try
- {
- FileAttributes fa = File.GetAttributes(file);
-
- if ((fa & FileAttributes.Directory) == 0)
- {
- drgevent.Effect = DragDropEffects.Copy;
- }
- }
-
- catch
- {
- }
- }
- }
-
- base.OnDragEnter(drgevent);
- }
-
- private string[] PruneDirectories(string[] fileNames)
- {
- List<string> result = new List<string>();
-
- foreach (string fileName in fileNames)
- {
- try
- {
- FileAttributes fa = File.GetAttributes(fileName);
-
- if ((fa & FileAttributes.Directory) == 0)
- {
- result.Add(fileName);
- }
- }
-
- catch
- {
- }
- }
-
- return result.ToArray();
- }
-
- protected override void OnDragDrop(DragEventArgs drgevent)
- {
- Activate();
-
- if (!IsCurrentModalForm || !Enabled)
- {
- // do nothing
- }
- else if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
- {
- string[] allFiles = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
-
- if (allFiles == null)
- {
- return;
- }
-
- string[] files = PruneDirectories(allFiles);
-
- bool importAsLayers = true;
-
- if (files.Length == 0)
- {
- return;
- }
- else
- {
- Icon formIcon = Utility.ImageToIcon(PdnResources.GetImageResource("Icons.DragDrop.OpenOrImport.FormIcon.png").Reference);
- string title = PdnResources.GetString("DragDrop.OpenOrImport.Title");
- string infoText = PdnResources.GetString("DragDrop.OpenOrImport.InfoText");
-
- TaskButton openTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuFileOpenIcon.png").Reference,
- PdnResources.GetString("DragDrop.OpenOrImport.OpenButton.ActionText"),
- PdnResources.GetString("DragDrop.OpenOrImport.OpenButton.ExplanationText"));
-
- string importLayersExplanation;
- if (this.appWorkspace.DocumentWorkspaces.Length == 0)
- {
- importLayersExplanation = PdnResources.GetString("DragDrop.OpenOrImport.ImportLayers.ExplanationText.NoImagesYet");
- }
- else
- {
- importLayersExplanation = PdnResources.GetString("DragDrop.OpenOrImport.ImportLayers.ExplanationText");
- }
-
- TaskButton importLayersTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuLayersImportFromFileIcon.png").Reference,
- PdnResources.GetString("DragDrop.OpenOrImport.ImportLayers.ActionText"),
- importLayersExplanation);
-
- TaskButton clickedTB = TaskDialog.Show(
- this,
- formIcon,
- title,
- null,
- false,
- infoText,
- new TaskButton[] { openTB, importLayersTB, TaskButton.Cancel },
- null,
- TaskButton.Cancel);
-
- if (clickedTB == openTB)
- {
- importAsLayers = false;
- }
- else if (clickedTB == importLayersTB)
- {
- importAsLayers = true;
- }
- else
- {
- return;
- }
- }
-
- if (!importAsLayers)
- {
- // open files into new tabs
- this.appWorkspace.OpenFilesInNewWorkspace(files);
- }
- else
- {
- // no image open? we will have to create one
- if (this.appWorkspace.ActiveDocumentWorkspace == null)
- {
- Size newSize = this.appWorkspace.GetNewDocumentSize();
-
- this.appWorkspace.CreateBlankDocumentInNewWorkspace(
- newSize,
- Document.DefaultDpuUnit,
- Document.GetDefaultDpu(Document.DefaultDpuUnit),
- false);
- }
-
- ImportFromFileAction action = new ImportFromFileAction();
- HistoryMemento ha = action.ImportMultipleFiles(this.appWorkspace.ActiveDocumentWorkspace, files);
-
- if (ha != null)
- {
- this.appWorkspace.ActiveDocumentWorkspace.History.PushNewMemento(ha);
- }
- }
- }
-
- base.OnDragDrop(drgevent);
- }
-
- private void DocumentWorkspace_ScaleFactorChanged(object sender, EventArgs e)
- {
- SetTitleText();
- }
-
- protected override void OnSizeChanged(EventArgs e)
- {
- base.OnSizeChanged(e);
- SetTitleText();
- }
-
- private void DeferredInitialization(object sender, EventArgs e)
- {
- this.deferredInitializationTimer.Enabled = false;
- this.deferredInitializationTimer.Tick -= new EventHandler(DeferredInitialization);
- this.deferredInitializationTimer.Dispose();
- this.deferredInitializationTimer = null;
-
- // TODO
- this.appWorkspace.ToolBar.MainMenu.PopulateEffects();
- }
-
- protected override void OnHelpRequested(HelpEventArgs hevent)
- {
- // F1 is already handled by the Menu->Help menu item. No need to process it twice.
- hevent.Handled = true;
-
- base.OnHelpRequested(hevent);
- }
-
- private void DefaultButton_Click(object sender, EventArgs e)
- {
- // Since defaultButton is the AcceptButton, hitting Enter will get 'eaten' by this button
- // So we have to give the Enter key to the Tool
- if (this.appWorkspace.ActiveDocumentWorkspace != null)
- {
- this.appWorkspace.ActiveDocumentWorkspace.Focus();
-
- if (this.appWorkspace.ActiveDocumentWorkspace.Tool != null)
- {
- this.appWorkspace.ActiveDocumentWorkspace.Tool.PerformKeyPress(new KeyPressEventArgs('\r'));
- this.appWorkspace.ActiveDocumentWorkspace.Tool.PerformKeyPress(Keys.Enter);
- }
- }
- }
-
- #if DEBUG
- static MainForm()
- {
- new Thread(FocusPrintThread).Start();
- }
-
- private static string GetControlName(Control control)
- {
- if (control == null)
- {
- return "null";
- }
-
- string name = control.Name + "(" + control.GetType().Name + ")";
-
- if (control.Parent != null)
- {
- name += " <- " + GetControlName(control.Parent);
- }
-
- return name;
- }
-
- private static void PrintFocus()
- {
- Control c = Utility.FindFocus();
- Tracing.Ping("Focused: " + GetControlName(c));
- }
-
- private static void FocusPrintThread()
- {
- Thread.CurrentThread.IsBackground = true;
-
- while (true)
- {
- try
- {
- FormCollection forms = Application.OpenForms;
- Form form;
- if (forms.Count > 0)
- {
- form = forms[0];
- form.BeginInvoke(new Procedure(PrintFocus));
- }
- }
-
- catch
- {
- }
-
- Thread.Sleep(1000);
- }
- }
- #endif
-
- }
- }