/src/MainForm.cs
C# | 1262 lines | 982 code | 206 blank | 74 comment | 171 complexity | e3364e7e27af285f1e3690207e118f87 MD5 | raw file
- /////////////////////////////////////////////////////////////////////////////////
- // 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 System.Linq;
- using PaintDotNet.Actions;
- using PaintDotNet.Base;
- using PaintDotNet.SystemLayer;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.IO;
- 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 IContainer components;
- private const bool KillAfterInit = false;
- private SplashForm _splashForm;
- private SingleInstanceManager _singleInstanceManager;
- private readonly List<string> _queuedInstanceMessages = new List<string>();
-
- public SingleInstanceManager SingleInstanceManager
- {
- get
- {
- return _singleInstanceManager;
- }
-
- set
- {
- if (_singleInstanceManager != null)
- {
- _singleInstanceManager.InstanceMessageReceived -= SingleInstanceManagerInstanceMessageReceived;
- _singleInstanceManager.SetWindow(null);
- }
-
- _singleInstanceManager = value;
-
- if (_singleInstanceManager == null) return;
- _singleInstanceManager.SetWindow(this);
- _singleInstanceManager.InstanceMessageReceived += SingleInstanceManagerInstanceMessageReceived;
- }
- }
-
- private void SingleInstanceManagerInstanceMessageReceived(object sender, EventArgs e)
- {
- BeginInvoke(new Procedure(ProcessQueuedInstanceMessages), null);
- }
-
- public MainForm()
- : this(new string[0])
- {
- }
-
- protected override void WndProc(ref Message m)
- {
- if (_singleInstanceManager != null)
- {
- _singleInstanceManager.FilterMessage(ref m);
- }
-
- base.WndProc(ref m);
- }
-
- private enum ArgumentAction
- {
- Open,
- OpenUntitled,
- Print,
- NoOp
- }
-
- private static 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 = 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 = _appWorkspace.OpenFileInNewWorkspace(actionParm);
- }
-
- break;
-
- case ArgumentAction.OpenUntitled:
- Activate();
-
- if (!string.IsNullOrEmpty(actionParm) && IsCurrentModalForm && Enabled)
- {
- result = _appWorkspace.OpenFileInNewWorkspace(actionParm, false);
-
- if (result)
- {
- _appWorkspace.ActiveDocumentWorkspace.SetDocumentSaveOptions(null, null, null);
- _appWorkspace.ActiveDocumentWorkspace.Document.Dirty = true;
- }
- }
-
- break;
-
- case ArgumentAction.Print:
- Activate();
-
- if (!string.IsNullOrEmpty(actionParm) && IsCurrentModalForm && Enabled)
- {
- result = _appWorkspace.OpenFileInNewWorkspace(actionParm);
-
- if (result)
- {
- DocumentWorkspace dw = _appWorkspace.ActiveDocumentWorkspace;
- var pa = new PrintAction();
- dw.PerformAction(pa);
- var cwa = new CloseWorkspaceAction(dw);
- _appWorkspace.PerformAction(cwa);
-
- if (_appWorkspace.DocumentWorkspaces.Length == 0)
- {
- Startup.CloseApplication();
- }
- }
- }
- break;
-
- default:
- throw new InvalidEnumArgumentException();
- }
-
- return result;
- }
-
- private void ProcessQueuedInstanceMessages()
- {
- if (IsDisposed)
- {
- return;
- }
-
- if (_splashForm != null)
- {
- _splashForm.Close();
- _splashForm.Dispose();
- _splashForm = null;
- }
-
- if (!IsHandleCreated || PdnInfo.IsExpired || _singleInstanceManager == null) return;
- string[] messages1 = _singleInstanceManager.GetPendingInstanceMessages();
- string[] messages2 = _queuedInstanceMessages.ToArray();
- _queuedInstanceMessages.Clear();
-
- var 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 (bool result in messages.Select(message => ProcessMessage(message)).Where(result => !result))
- {
- break;
- }
- }
-
- private void ApplicationIdle(object sender, EventArgs e)
- {
- if (!IsDisposed &&
- (_queuedInstanceMessages.Count > 0 || (_singleInstanceManager != null && _singleInstanceManager.AreMessagesPending)))
- {
- ProcessQueuedInstanceMessages();
- }
- }
-
- public MainForm(IEnumerable<string> args)
- {
- bool canSetCurrentDir = true;
-
- StartPosition = FormStartPosition.WindowsDefaultLocation;
-
- bool splash = false;
- var 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)
- {
- _splashForm = new SplashForm {TopMost = true};
- _splashForm.Show();
- _splashForm.Update();
- }
-
- InitializeComponent();
-
- Icon = PdnInfo.AppIcon;
-
- // Does not load window location/state
- LoadSettings();
-
- foreach (string fileName in fileNames)
- {
- _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 = _appWorkspace.GetNewDocumentSize();
- _appWorkspace.CreateBlankDocumentInNewWorkspace(newSize, units, dpu, true);
- _appWorkspace.ActiveDocumentWorkspace.IncrementJustPaintWhite();
- _appWorkspace.ActiveDocumentWorkspace.Document.Dirty = false;
- }
-
- LoadWindowState();
-
- _deferredInitializationTimer.Enabled = true;
-
- Application.Idle += ApplicationIdle;
- }
-
- protected override void OnShown(EventArgs e)
- {
- base.OnShown(e);
-
- if (!PdnInfo.IsExpired) return;
- foreach (Form form in Application.OpenForms)
- {
- form.Enabled = false;
- }
-
- var checkForUpdatesTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuHelpCheckForUpdatesIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.CheckForUpdatesTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.CheckForUpdatesTB.ExplanationText"));
-
- var goToWebSiteTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuHelpPdnWebsiteIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.GoToWebSiteTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.GoToWebSiteTB.ExplanationText"));
-
- var doNotCheckForUpdatesTB = new TaskButton(
- PdnResources.GetImageResource("Icons.CancelIcon.png").Reference,
- PdnResources.GetString("ExpiredTaskDialog.DoNotCheckForUpdatesTB.ActionText"),
- PdnResources.GetString("ExpiredTaskDialog.DoNotCheckForUpdatesTB.ExplanationText"));
-
- var taskButtons =
- new[]
- {
- 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)
- {
- _appWorkspace.CheckForUpdates();
- }
- else if (clickedTB == goToWebSiteTB)
- {
- PdnInfo.LaunchWebSite(this, InvariantStrings.ExpiredPage);
- }
-
- Close();
- }
-
- private void LoadWindowState()
- {
- try
- {
- var 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, Width);
- newBounds.Height = Settings.CurrentUser.GetInt32(SettingNames.Height, Height);
-
- int left = Settings.CurrentUser.GetInt32(SettingNames.Left, Left);
- int top = Settings.CurrentUser.GetInt32(SettingNames.Top, Top);
- newBounds.Location = new Point(left, top);
-
- Bounds = newBounds;
- }
-
- WindowState = fws;
- }
- }
-
- catch
- {
- try
- {
- Settings.CurrentUser.Delete(
- new[]
- {
- SettingNames.Width,
- SettingNames.Height,
- SettingNames.WindowState,
- SettingNames.Top,
- SettingNames.Left
- });
- }
-
- catch
- {
- // ignore errors
- }
- }
- }
-
- private static void LoadSettings()
- {
- try
- {
- EnableOpacity = Settings.CurrentUser.GetBoolean(SettingNames.TranslucentWindows, true);
- }
-
- catch (Exception ex)
- {
- Tracing.Ping("Exception in MainForm.LoadSettings:" + ex.ToString());
-
- try
- {
- Settings.CurrentUser.Delete(
- new[]
- {
- SettingNames.TranslucentWindows
- });
- }
-
- catch
- {
- }
- }
- }
-
- private void SaveSettings()
- {
- Settings.CurrentUser.SetInt32(SettingNames.Width, Width);
- Settings.CurrentUser.SetInt32(SettingNames.Height, Height);
- Settings.CurrentUser.SetInt32(SettingNames.Top, Top);
- Settings.CurrentUser.SetInt32(SettingNames.Left, Left);
- Settings.CurrentUser.SetString(SettingNames.WindowState, WindowState.ToString());
-
- Settings.CurrentUser.SetBoolean(SettingNames.TranslucentWindows, EnableOpacity);
-
- if (WindowState != FormWindowState.Minimized)
- {
- Settings.CurrentUser.SetBoolean(SettingNames.ToolsFormVisible, _appWorkspace.Widgets.ToolsForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.ColorsFormVisible, _appWorkspace.Widgets.ColorsForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.HistoryFormVisible, _appWorkspace.Widgets.HistoryForm.Visible);
- Settings.CurrentUser.SetBoolean(SettingNames.LayersFormVisible, _appWorkspace.Widgets.LayerForm.Visible);
- }
-
- SnapManager.Save(Settings.CurrentUser);
- _appWorkspace.SaveSettings();
- }
-
-
- protected override void OnQueryEndSession(CancelEventArgs e)
- {
- if (IsCurrentModalForm)
- {
- OnClosing(e);
- }
- else
- {
- foreach (var asPDF in Application.OpenForms.OfType<PdnBaseForm>())
- {
- asPDF.Flash();
- }
-
- e.Cancel = true;
- }
-
- base.OnQueryEndSession(e);
- }
-
- protected override void OnClosing(CancelEventArgs e)
- {
- if (!e.Cancel)
- {
- if (_appWorkspace != null)
- {
- var cawa = new CloseAllWorkspacesAction();
- _appWorkspace.PerformAction(cawa);
- e.Cancel = cawa.Cancelled;
- }
- }
-
- if (!e.Cancel)
- {
- SaveSettings();
-
- if (_floaters != null)
- {
- foreach (FloatingToolForm hideMe in _floaters)
- {
- hideMe.Hide();
- }
- }
-
- Hide();
-
- if (_queuedInstanceMessages != null)
- {
- _queuedInstanceMessages.Clear();
- }
-
- SingleInstanceManager sim2 = _singleInstanceManager;
- SingleInstanceManager = null;
-
- if (sim2 != null)
- {
- sim2.Dispose();
- sim2 = null;
- }
- }
-
- base.OnClosing(e);
- }
-
- protected override void OnClosed(EventArgs e)
- {
- if (_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 (_singleInstanceManager != null)
- {
- SingleInstanceManager sim2 = _singleInstanceManager;
- SingleInstanceManager = null;
- sim2.Dispose();
- sim2 = null;
- }
-
- if (_floaterOpacityTimer != null)
- {
- _floaterOpacityTimer.Tick -= FloaterOpacityTimerTick;
- _floaterOpacityTimer.Dispose();
- _floaterOpacityTimer = null;
- }
-
- if (components != null)
- {
- components.Dispose();
- 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()
- {
- components = new Container();
- _defaultButton = new Button();
- _appWorkspace = new AppWorkspace();
- _floaterOpacityTimer = new System.Windows.Forms.Timer(components);
- _deferredInitializationTimer = new System.Windows.Forms.Timer(components);
- SuspendLayout();
- //
- // appWorkspace
- //
- _appWorkspace.Dock = DockStyle.Fill;
- _appWorkspace.Location = new Point(0, 0);
- _appWorkspace.Name = "_appWorkspace";
- _appWorkspace.Size = new Size(752, 648);
- _appWorkspace.TabIndex = 2;
- _appWorkspace.ActiveDocumentWorkspaceChanging += AppWorkspaceActiveDocumentWorkspaceChanging;
- _appWorkspace.ActiveDocumentWorkspaceChanged += AppWorkspaceActiveDocumentWorkspaceChanged;
- //
- // floaterOpacityTimer
- //
- _floaterOpacityTimer.Enabled = false;
- _floaterOpacityTimer.Interval = 25;
- _floaterOpacityTimer.Tick += FloaterOpacityTimerTick;
- //
- // deferredInitializationTimer
- //
- _deferredInitializationTimer.Interval = 250;
- _deferredInitializationTimer.Tick += DeferredInitialization;
- //
- // defaultButton
- //
- _defaultButton.Size = new Size(1, 1);
- _defaultButton.Text = "";
- _defaultButton.Location = new Point(-100, -100);
- _defaultButton.TabStop = false;
- _defaultButton.Click += DefaultButtonClick;
- //
- // MainForm
- //
-
- try
- {
- AllowDrop = true;
- }
-
- catch (InvalidOperationException)
- {
- // Discard error. See bug #2605.
- }
-
- AutoScaleDimensions = new SizeF(96F, 96F);
- AutoScaleMode = AutoScaleMode.Dpi;
- ClientSize = new Size(950, 738);
- Controls.Add(_appWorkspace);
- Controls.Add(_defaultButton);
- AcceptButton = _defaultButton;
- Name = "MainForm";
- StartPosition = FormStartPosition.WindowsDefaultLocation;
- ForceActiveTitleBar = true;
- KeyPreview = true;
- Controls.SetChildIndex(_appWorkspace, 0);
- ResumeLayout(false);
- PerformLayout();
- }
-
- private void AppWorkspaceActiveDocumentWorkspaceChanging(object sender, EventArgs e)
- {
- if (_appWorkspace.ActiveDocumentWorkspace == null) return;
- _appWorkspace.ActiveDocumentWorkspace.ScaleFactorChanged -= DocumentWorkspaceScaleFactorChanged;
- _appWorkspace.ActiveDocumentWorkspace.DocumentChanged -= DocumentWorkspaceDocumentChanged;
- _appWorkspace.ActiveDocumentWorkspace.SaveOptionsChanged -= DocumentWorkspaceSaveOptionsChanged;
- }
-
- private void AppWorkspaceActiveDocumentWorkspaceChanged(object sender, EventArgs e)
- {
- if (_appWorkspace.ActiveDocumentWorkspace != null)
- {
- _appWorkspace.ActiveDocumentWorkspace.ScaleFactorChanged += DocumentWorkspaceScaleFactorChanged;
- _appWorkspace.ActiveDocumentWorkspace.DocumentChanged += DocumentWorkspaceDocumentChanged;
- _appWorkspace.ActiveDocumentWorkspace.SaveOptionsChanged += DocumentWorkspaceSaveOptionsChanged;
- }
-
- SetTitleText();
- }
-
- private void DocumentWorkspaceSaveOptionsChanged(object sender, EventArgs e)
- {
- SetTitleText();
- }
-
- private static Keys CharToKeys(char c)
- {
- Keys keys = Keys.None;
- c = Char.ToLower(c);
-
- if (c >= 'a' && c <= 'z')
- {
- keys = (Keys)((int)Keys.A + c - 'a');
- }
-
- return keys;
- }
-
- private Keys GetMenuCmdKey(string text)
- {
- Keys keys = Keys.None;
-
- for (int i = 0; i < text.Length - 1; ++i)
- {
- if (text[i] != '&') continue;
- keys = Keys.Alt | CharToKeys(text[i + 1]);
- break;
- }
-
- return keys;
- }
-
- protected override void OnLoad(EventArgs e)
- {
- EnsureFormIsOnScreen();
-
- _floaters = new FloatingToolForm[] {
- _appWorkspace.Widgets.ToolsForm,
- _appWorkspace.Widgets.ColorsForm,
- _appWorkspace.Widgets.HistoryForm,
- _appWorkspace.Widgets.LayerForm
- };
-
- foreach (FloatingToolForm ftf in _floaters)
- {
- ftf.Closing += 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()
- {
- _appWorkspace.ResetFloatingForms();
-
- try
- {
- SnapManager.Load(Settings.CurrentUser);
- }
-
- catch
- {
- _appWorkspace.ResetFloatingForms();
- }
-
- foreach (FloatingToolForm ftf in _floaters)
- {
- AddOwnedForm(ftf);
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.ToolsFormVisible, true))
- {
- _appWorkspace.Widgets.ToolsForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.ColorsFormVisible, true))
- {
- _appWorkspace.Widgets.ColorsForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.HistoryFormVisible, true))
- {
- _appWorkspace.Widgets.HistoryForm.Show();
- }
-
- if (Settings.CurrentUser.GetBoolean(SettingNames.LayersFormVisible, true))
- {
- _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 _floaters)
- {
- if (!ftf.Visible)
- {
- continue;
- }
-
- bool reset = false;
-
- try
- {
- bool foundAScreen = allScreens.Select(screen => Rectangle.Intersect(screen.Bounds, ftf.Bounds)).Any(intersect => intersect.Width > 0 && intersect.Height > 0);
-
- if (!foundAScreen)
- {
- reset = true;
- }
- }
-
- catch (Exception)
- {
- reset = true;
- }
-
- if (reset)
- {
- _appWorkspace.ResetFloatingForm(ftf);
- }
- }
-
- _floaterOpacityTimer.Enabled = true;
- }
-
- protected override void OnResize(EventArgs e)
- {
- if (_floaterOpacityTimer != null)
- {
- if (WindowState == FormWindowState.Minimized)
- {
- if (_floaterOpacityTimer.Enabled)
- {
- _floaterOpacityTimer.Enabled = false;
- }
- }
- else
- {
- if (!_floaterOpacityTimer.Enabled)
- {
- _floaterOpacityTimer.Enabled = true;
- }
-
- FloaterOpacityTimerTick(this, EventArgs.Empty);
- }
- }
-
- base.OnResize (e);
- }
-
- private void DocumentWorkspaceDocumentChanged(object sender, EventArgs e)
- {
- SetTitleText();
- OnResize(EventArgs.Empty);
- }
-
- private void SetTitleText()
- {
- if (_appWorkspace == null)
- {
- return;
- }
-
- if (_appWorkspace.ActiveDocumentWorkspace == null)
- {
- Text = PdnInfo.GetAppName();
- }
- else
- {
- string appTitle = PdnInfo.GetAppName();
- string ratio = string.Empty;
- string title = string.Empty;
- string friendlyName = _appWorkspace.ActiveDocumentWorkspace.GetFriendlyName();
- string text;
-
- if (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;
- }
-
- 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, EventArgs e)
- {
- var menu = (ToolStripMenuItem)sender;
-
- foreach (ToolStripItem tsi in menu.DropDownItems)
- {
- tsi.Enabled = true;
- }
- }
-
- private static void HideInsteadOfCloseHandler(object sender, CancelEventArgs e)
- {
- e.Cancel = true;
- ((Form)sender).Hide();
- }
-
- // TODO: refactor into FloatingToolForm class somehow
- private void FloaterOpacityTimerTick(object sender, EventArgs e)
- {
- if (WindowState == FormWindowState.Minimized ||
- _floaters == null ||
- !EnableOpacity ||
- _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 = _appWorkspace.ActiveDocumentWorkspace.VisibleDocumentBounds;
- }
-
- catch (ObjectDisposedException)
- {
- return; // do nothing, we are probably in the process of shutting down the app
- }
-
- foreach (FloatingToolForm ftf in _floaters)
- {
- Rectangle intersect = Rectangle.Intersect(screenDocRect, ftf.Bounds);
-
- try
- {
- double opacity;
- if (intersect.Width == 0 ||
- intersect.Height == 0 ||
- (ftf.Bounds.Contains(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 (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))
- {
- var 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 static string[] PruneDirectories(IEnumerable<string> fileNames)
- {
- var 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))
- {
- var allFiles = (string[])drgevent.Data.GetData(DataFormats.FileDrop);
-
- if (allFiles == null)
- {
- return;
- }
-
- string[] files = PruneDirectories(allFiles);
-
- bool importAsLayers = true;
-
- if (files.Length == 0)
- {
- return;
- }
- 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");
-
- var openTB = new TaskButton(
- PdnResources.GetImageResource("Icons.MenuFileOpenIcon.png").Reference,
- PdnResources.GetString("DragDrop.OpenOrImport.OpenButton.ActionText"),
- PdnResources.GetString("DragDrop.OpenOrImport.OpenButton.ExplanationText"));
-
- string importLayersExplanation = PdnResources.GetString(_appWorkspace.DocumentWorkspaces.Length == 0 ? "DragDrop.OpenOrImport.ImportLayers.ExplanationText.NoImagesYet" : "DragDrop.OpenOrImport.ImportLayers.ExplanationText");
-
- var 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[] { openTB, importLayersTB, TaskButton.Cancel },
- null,
- TaskButton.Cancel);
-
- if (clickedTB == openTB)
- {
- importAsLayers = false;
- }
- else if (clickedTB == importLayersTB)
- {
- }
- else
- {
- return;
- }
-
- if (!importAsLayers)
- {
- // open files into new tabs
- _appWorkspace.OpenFilesInNewWorkspace(files);
- }
- else
- {
- // no image open? we will have to create one
- if (_appWorkspace.ActiveDocumentWorkspace == null)
- {
- Size newSize = _appWorkspace.GetNewDocumentSize();
-
- _appWorkspace.CreateBlankDocumentInNewWorkspace(
- newSize,
- Document.DefaultDpuUnit,
- Document.GetDefaultDpu(Document.DefaultDpuUnit),
- false);
- }
-
- var action = new ImportFromFileAction();
- HistoryMemento ha = action.ImportMultipleFiles(_appWorkspace.ActiveDocumentWorkspace, files);
-
- if (ha != null)
- {
- _appWorkspace.ActiveDocumentWorkspace.History.PushNewMemento(ha);
- }
- }
- }
-
- base.OnDragDrop(drgevent);
- }
-
- private void DocumentWorkspaceScaleFactorChanged(object sender, EventArgs e)
- {
- SetTitleText();
- }
-
- protected override void OnSizeChanged(EventArgs e)
- {
- base.OnSizeChanged(e);
- SetTitleText();
- }
-
- private void DeferredInitialization(object sender, EventArgs e)
- {
- _deferredInitializationTimer.Enabled = false;
- _deferredInitializationTimer.Tick -= DeferredInitialization;
- _deferredInitializationTimer.Dispose();
- _deferredInitializationTimer = null;
-
- // TODO
- _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 DefaultButtonClick(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 (_appWorkspace.ActiveDocumentWorkspace == null) return;
- _appWorkspace.ActiveDocumentWorkspace.Focus();
-
- if (_appWorkspace.ActiveDocumentWorkspace.Tool == null) return;
- _appWorkspace.ActiveDocumentWorkspace.Tool.PerformKeyPress(new KeyPressEventArgs('\r'));
- _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
-
- }
- }