forked from gitextensions/gitextensions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGitExtensionsFormBase.cs
171 lines (139 loc) · 5.83 KB
/
GitExtensionsFormBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
using System.Diagnostics;
using GitCommands;
using GitExtUtils.GitUI.Theming;
using GitUI;
using ResourceManager.Properties;
namespace ResourceManager
{
// NOTE do not make this class abstract as it breaks the WinForms designer in VS
/// <summary>
/// Base class for all Git Extensions forms.
/// </summary>
/// <remarks>
/// Deriving from this class requires a call to <see cref="InitializeComplete"/> at
/// the end of the constructor. Omitting this call with result in a runtime exception.
/// </remarks>
public class GitExtensionsFormBase : Form, ITranslate
{
private readonly GitExtensionsControlInitialiser _initialiser;
/// <summary>Creates a new <see cref="GitExtensionsFormBase"/> indicating position restore.</summary>
public GitExtensionsFormBase()
{
_initialiser = new GitExtensionsControlInitialiser(this);
if (IsDesignMode)
{
return;
}
ShowInTaskbar = Application.OpenForms.Count <= 0;
Icon = Resources.GitExtensionsLogoIcon;
#if !SUPPORT_THEME_HOOKS
Load += (s, e) => ((Form)s!).FixVisualStyle();
#endif
}
/// <summary>
/// Checks if the form wants to handle the key and executes that hotkey
/// (without propagating an unhandled key to the base class function as in <cref>ProcessCmdKey</cref>).
/// </summary>
public virtual bool ProcessHotkey(Keys keyData)
{
if (IsDesignMode || !HotkeysEnabled)
{
return false;
}
HotkeyCommand? hotkey = Hotkeys?.FirstOrDefault(hotkey => hotkey?.KeyData == keyData);
return hotkey is not null && ExecuteCommand(hotkey.CommandCode).Executed;
}
protected bool IsDesignMode => _initialiser.IsDesignMode;
#region Hotkeys
/// <summary>Gets or sets a value that specifies if the hotkeys are used</summary>
protected bool HotkeysEnabled { get; set; }
/// <summary>Gets or sets the hotkeys</summary>
protected IEnumerable<HotkeyCommand>? Hotkeys { get; set; }
/// <summary>Overridden: Checks if a hotkey wants to handle the key before letting the message propagate</summary>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
return ProcessHotkey(keyData) || base.ProcessCmdKey(ref msg, keyData);
}
protected Keys GetShortcutKeys(int commandCode)
{
return GetHotkeyCommand(commandCode)?.KeyData ?? Keys.None;
}
protected HotkeyCommand? GetHotkeyCommand(int commandCode)
{
return Hotkeys?.FirstOrDefault(h => h.CommandCode == commandCode);
}
/// <summary>Override this method to handle form-specific Hotkey commands.</summary>
protected virtual CommandStatus ExecuteCommand(int command)
{
return false;
}
#endregion
protected override void WndProc(ref Message m)
{
if (!IsDesignMode)
{
if (m.Msg == NativeMethods.WM_ACTIVATEAPP && m.WParam != IntPtr.Zero)
{
OnApplicationActivated();
if (WindowState == FormWindowState.Minimized && Owner is null && AppSettings.WorkaroundActivateFromMinimize)
{
// Application occasionally requires explicit "restore" in Taskbar.
// See https://github.com/gitextensions/gitextensions/pull/10119.
Trace.WriteLine("WindowState is unexpectedly Minimized in OnApplicationActivated(), restoring.");
WindowState = FormWindowState.Normal;
}
}
}
base.WndProc(ref m);
}
/// <summary>Performs post-initialisation tasks such as translation and DPI scaling.</summary>
/// <remarks>
/// <para>Subclasses must ensure this method is called in their constructor, ideally as the final statement.</para>
/// <para>Requiring this extra life-cycle event allows preparing the UI after any call to <c>InitializeComponent</c>,
/// but before it is show. Both the <see cref="Form.Load"/> and <see cref="Form.Shown"/> events occur too late for
/// operations that effect layout.</para>
/// </remarks>
protected void InitializeComplete()
{
_initialiser.InitializeComplete();
if (IsDesignMode)
{
return;
}
AutoScaleMode = AppSettings.EnableAutoScale
? AutoScaleMode.Dpi
: AutoScaleMode.None;
this.AdjustForDpiScaling();
this.EnableRemoveWordHotkey();
}
#region Translation
public virtual void AddTranslationItems(ITranslation translation)
{
TranslationUtils.AddTranslationItemsFromFields(Name, this, translation);
}
public virtual void TranslateItems(ITranslation translation)
{
TranslationUtils.TranslateItemsFromFields(Name, this, translation);
}
protected void TranslateItem(string itemName, object item)
{
var translation = Translator.GetTranslation(AppSettings.CurrentTranslation);
if (translation.Count == 0)
{
return;
}
var itemsToTranslate = new[] { (itemName, item) };
foreach (var pair in translation)
{
TranslationUtils.TranslateItemsFromList(Name, pair.Value, itemsToTranslate);
}
}
#endregion
/// <summary>
/// Notifies whenever the application becomes active.
/// </summary>
protected virtual void OnApplicationActivated()
{
}
}
}