Skip to content

Commit d2cd037

Browse files
committed
Added "Yes to all" option to file change dialog...
1 parent d3a87b6 commit d2cd037

8 files changed

Lines changed: 254 additions & 1 deletion

File tree

‎FlashDevelop/Managers/FilePollManager.cs‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace FlashDevelop.Managers
1313
class FilePollManager
1414
{
1515
private static Timer FilePollTimer;
16+
private static Boolean YesToAll = false;
1617

1718
/// <summary>
1819
/// Initialize the file change polling
@@ -46,13 +47,24 @@ private static void CheckFileChange(ITabbedDocument document)
4647
if (Globals.Settings.AutoReloadModifiedFiles) casted.Reload(false);
4748
else
4849
{
50+
if (YesToAll)
51+
{
52+
casted.Reload(false);
53+
return;
54+
}
4955
String dlgTitle = TextHelper.GetString("Title.InfoDialog");
5056
String dlgMessage = TextHelper.GetString("Info.FileIsModifiedOutside");
5157
String formatted = String.Format(dlgMessage, "\n", casted.FileName);
52-
if (MessageBox.Show(Globals.MainForm, formatted, " " + dlgTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
58+
MessageBoxManager.Cancel = TextHelper.GetString("Label.YesToAll");
59+
MessageBoxManager.Register(); // Use custom labels...
60+
DialogResult result = MessageBox.Show(Globals.MainForm, formatted, " " + dlgTitle, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
61+
if (result == DialogResult.Yes) casted.Reload(false);
62+
else if (result == DialogResult.Cancel)
5363
{
5464
casted.Reload(false);
65+
YesToAll = true;
5566
}
67+
MessageBoxManager.Unregister();
5668
}
5769
}
5870
}
@@ -73,6 +85,7 @@ private static void FilePollTimerTick(Object sender, EventArgs e)
7385
if (document != current) CheckFileChange(document);
7486
}
7587
FilePollTimer.Enabled = true;
88+
YesToAll = false;
7689
}
7790
catch { /* No errors shown here.. */ }
7891
}

‎PluginCore/PluginCore.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
<Compile Include="PluginCore\Controls\Common.cs">
302302
<SubType>Component</SubType>
303303
</Compile>
304+
<Compile Include="PluginCore\Controls\MessageBoxManager.cs" />
304305
<Compile Include="PluginCore\Controls\ShellContextMenu.cs" />
305306
<Compile Include="PluginCore\Controls\SmartForm.cs">
306307
<SubType>Form</SubType>
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#pragma warning disable 0618
2+
using System;
3+
using System.Text;
4+
using System.Runtime.InteropServices;
5+
using System.Security.Permissions;
6+
7+
[assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
8+
namespace System.Windows.Forms
9+
{
10+
public class MessageBoxManager
11+
{
12+
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
13+
private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam);
14+
15+
private const int WH_CALLWNDPROCRET = 12;
16+
private const int WM_DESTROY = 0x0002;
17+
private const int WM_INITDIALOG = 0x0110;
18+
private const int WM_TIMER = 0x0113;
19+
private const int WM_USER = 0x400;
20+
private const int DM_GETDEFID = WM_USER + 0;
21+
22+
private const int MBOK = 1;
23+
private const int MBCancel = 2;
24+
private const int MBAbort = 3;
25+
private const int MBRetry = 4;
26+
private const int MBIgnore = 5;
27+
private const int MBYes = 6;
28+
private const int MBNo = 7;
29+
30+
31+
[DllImport("user32.dll")]
32+
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
33+
34+
[DllImport("user32.dll")]
35+
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
36+
37+
[DllImport("user32.dll")]
38+
private static extern int UnhookWindowsHookEx(IntPtr idHook);
39+
40+
[DllImport("user32.dll")]
41+
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
42+
43+
[DllImport("user32.dll", EntryPoint = "GetWindowTextLengthW", CharSet = CharSet.Unicode)]
44+
private static extern int GetWindowTextLength(IntPtr hWnd);
45+
46+
[DllImport("user32.dll", EntryPoint = "GetWindowTextW", CharSet = CharSet.Unicode)]
47+
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength);
48+
49+
[DllImport("user32.dll")]
50+
private static extern int EndDialog(IntPtr hDlg, IntPtr nResult);
51+
52+
[DllImport("user32.dll")]
53+
private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);
54+
55+
[DllImport("user32.dll", EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
56+
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
57+
58+
[DllImport("user32.dll")]
59+
private static extern int GetDlgCtrlID(IntPtr hwndCtl);
60+
61+
[DllImport("user32.dll")]
62+
private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
63+
64+
[DllImport("user32.dll", EntryPoint = "SetWindowTextW", CharSet = CharSet.Unicode)]
65+
private static extern bool SetWindowText(IntPtr hWnd, string lpString);
66+
67+
68+
[StructLayout(LayoutKind.Sequential)]
69+
public struct CWPRETSTRUCT
70+
{
71+
public IntPtr lResult;
72+
public IntPtr lParam;
73+
public IntPtr wParam;
74+
public uint message;
75+
public IntPtr hwnd;
76+
};
77+
78+
private static HookProc hookProc;
79+
private static EnumChildProc enumProc;
80+
[ThreadStatic]
81+
private static IntPtr hHook;
82+
[ThreadStatic]
83+
private static int nButton;
84+
85+
/// <summary>
86+
/// OK text
87+
/// </summary>
88+
public static string OK = "&OK";
89+
/// <summary>
90+
/// Cancel text
91+
/// </summary>
92+
public static string Cancel = "&Cancel";
93+
/// <summary>
94+
/// Abort text
95+
/// </summary>
96+
public static string Abort = "&Abort";
97+
/// <summary>
98+
/// Retry text
99+
/// </summary>
100+
public static string Retry = "&Retry";
101+
/// <summary>
102+
/// Ignore text
103+
/// </summary>
104+
public static string Ignore = "&Ignore";
105+
/// <summary>
106+
/// Yes text
107+
/// </summary>
108+
public static string Yes = "&Yes";
109+
/// <summary>
110+
/// No text
111+
/// </summary>
112+
public static string No = "&No";
113+
114+
static MessageBoxManager()
115+
{
116+
hookProc = new HookProc(MessageBoxHookProc);
117+
enumProc = new EnumChildProc(MessageBoxEnumProc);
118+
hHook = IntPtr.Zero;
119+
}
120+
121+
/// <summary>
122+
/// Enables MessageBoxManager functionality
123+
/// </summary>
124+
/// <remarks>
125+
/// MessageBoxManager functionality is enabled on current thread only.
126+
/// Each thread that needs MessageBoxManager functionality has to call this method.
127+
/// </remarks>
128+
public static void Register()
129+
{
130+
if (hHook != IntPtr.Zero)
131+
throw new NotSupportedException("One hook per thread allowed.");
132+
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
133+
}
134+
135+
/// <summary>
136+
/// Disables MessageBoxManager functionality
137+
/// </summary>
138+
/// <remarks>
139+
/// Disables MessageBoxManager functionality on current thread only.
140+
/// </remarks>
141+
public static void Unregister()
142+
{
143+
if (hHook != IntPtr.Zero)
144+
{
145+
UnhookWindowsHookEx(hHook);
146+
hHook = IntPtr.Zero;
147+
}
148+
}
149+
150+
private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam)
151+
{
152+
if (nCode < 0)
153+
return CallNextHookEx(hHook, nCode, wParam, lParam);
154+
155+
CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT));
156+
IntPtr hook = hHook;
157+
158+
if (msg.message == WM_INITDIALOG)
159+
{
160+
int nLength = GetWindowTextLength(msg.hwnd);
161+
StringBuilder className = new StringBuilder(10);
162+
GetClassName(msg.hwnd, className, className.Capacity);
163+
if (className.ToString() == "#32770")
164+
{
165+
nButton = 0;
166+
EnumChildWindows(msg.hwnd, enumProc, IntPtr.Zero);
167+
if (nButton == 1)
168+
{
169+
IntPtr hButton = GetDlgItem(msg.hwnd, MBCancel);
170+
if (hButton != IntPtr.Zero)
171+
SetWindowText(hButton, OK);
172+
}
173+
}
174+
}
175+
176+
return CallNextHookEx(hook, nCode, wParam, lParam);
177+
}
178+
179+
private static bool MessageBoxEnumProc(IntPtr hWnd, IntPtr lParam)
180+
{
181+
StringBuilder className = new StringBuilder(10);
182+
GetClassName(hWnd, className, className.Capacity);
183+
if (className.ToString() == "Button")
184+
{
185+
int ctlId = GetDlgCtrlID(hWnd);
186+
switch (ctlId)
187+
{
188+
case MBOK:
189+
SetWindowText(hWnd, OK);
190+
break;
191+
case MBCancel:
192+
SetWindowText(hWnd, Cancel);
193+
break;
194+
case MBAbort:
195+
SetWindowText(hWnd, Abort);
196+
break;
197+
case MBRetry:
198+
SetWindowText(hWnd, Retry);
199+
break;
200+
case MBIgnore:
201+
SetWindowText(hWnd, Ignore);
202+
break;
203+
case MBYes:
204+
SetWindowText(hWnd, Yes);
205+
break;
206+
case MBNo:
207+
SetWindowText(hWnd, No);
208+
break;
209+
210+
}
211+
nButton++;
212+
}
213+
214+
return true;
215+
}
216+
217+
218+
}
219+
}

‎PluginCore/PluginCore/Resources/de_DE.resX‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5010,4 +5010,8 @@ Eigene Sprachumgebungen müssen eine Erweiterung der Standard-Sprachumgebung sei
50105010
<value>Webserver...</value>
50115011
<comment>Added after 4.4.2</comment>
50125012
</data>
5013+
<data name="FlashDevelop.Label.YesToAll" xml:space="preserve">
5014+
<value>Yes to &amp;all</value>
5015+
<comment>Added after 4.4.3</comment>
5016+
</data>
50135017
</root>

‎PluginCore/PluginCore/Resources/en_US.resX‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5016,4 +5016,8 @@ Custom locales must be an extension of a default locale, e.g. en-US.</value>
50165016
<value>Webserver...</value>
50175017
<comment>Added after 4.4.2</comment>
50185018
</data>
5019+
<data name="FlashDevelop.Label.YesToAll" xml:space="preserve">
5020+
<value>Yes to &amp;all</value>
5021+
<comment>Added after 4.4.3</comment>
5022+
</data>
50195023
</root>

‎PluginCore/PluginCore/Resources/eu_ES.resX‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5003,4 +5003,8 @@ Lokalizazio pertsonalizatuek lehenetsiaren luzapen bat izan behar dute, adb. en-
50035003
<value>Web zerbitzaria...</value>
50045004
<comment>Added after 4.4.2</comment>
50055005
</data>
5006+
<data name="FlashDevelop.Label.YesToAll" xml:space="preserve">
5007+
<value>Yes to &amp;all</value>
5008+
<comment>Added after 4.4.3</comment>
5009+
</data>
50065010
</root>

‎PluginCore/PluginCore/Resources/ja_JP.resX‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5068,4 +5068,8 @@ UseData:"</value>
50685068
<value>ウェブサーバー...</value>
50695069
<comment>Added after 4.4.2</comment>
50705070
</data>
5071+
<data name="FlashDevelop.Label.YesToAll" xml:space="preserve">
5072+
<value>Yes to &amp;all</value>
5073+
<comment>Added after 4.4.3</comment>
5074+
</data>
50715075
</root>

‎PluginCore/PluginCore/Resources/zh_CN.resx‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5016,4 +5016,8 @@
50165016
<value>Web服务器...</value>
50175017
<comment>Added after 4.4.2</comment>
50185018
</data>
5019+
<data name="FlashDevelop.Label.YesToAll" xml:space="preserve">
5020+
<value>Yes to &amp;all</value>
5021+
<comment>Added after 4.4.3</comment>
5022+
</data>
50195023
</root>

0 commit comments

Comments
 (0)