~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.ComponentModel;
 
6
using System.Diagnostics;
 
7
using System.Windows;
 
8
using System.Windows.Forms;
 
9
using ICSharpCode.Core;
 
10
using ICSharpCode.Core.WinForms;
 
11
 
 
12
namespace ICSharpCode.SharpDevelop.Gui
 
13
{
 
14
        public static class WorkbenchSingleton
 
15
        {
 
16
                const string uiIconStyle             = "IconMenuItem.IconMenuStyle";
 
17
                const string uiLanguageProperty      = "CoreProperties.UILanguage";
 
18
                const string workbenchMemento        = "WorkbenchMemento";
 
19
                const string activeContentState      = "Workbench.ActiveContent";
 
20
                
 
21
                static IWorkbench workbench;
 
22
                
 
23
                /// <summary>
 
24
                /// Gets the main form. Returns null in unit-testing mode.
 
25
                /// </summary>
 
26
                public static IWin32Window MainWin32Window {
 
27
                        get {
 
28
                                if (workbench != null) {
 
29
                                        return workbench.MainWin32Window;
 
30
                                }
 
31
                                return null;
 
32
                        }
 
33
                }
 
34
                
 
35
                /// <summary>
 
36
                /// Gets the main window. Returns null in unit-testing mode.
 
37
                /// </summary>
 
38
                public static Window MainWindow {
 
39
                        get {
 
40
                                if (workbench != null) {
 
41
                                        return workbench.MainWindow;
 
42
                                }
 
43
                                return null;
 
44
                        }
 
45
                }
 
46
                
 
47
                /// <summary>
 
48
                /// Gets the workbench. Returns null in unit-testing mode.
 
49
                /// </summary>
 
50
                public static IWorkbench Workbench {
 
51
                        get {
 
52
                                return workbench;
 
53
                        }
 
54
                }
 
55
                
 
56
                public static IStatusBarService StatusBar {
 
57
                        get {
 
58
                                return workbench != null ? workbench.StatusBar : null;
 
59
                        }
 
60
                }
 
61
                
 
62
                public static void InitializeWorkbench(IWorkbench workbench, IWorkbenchLayout layout)
 
63
                {
 
64
                        WorkbenchSingleton.workbench = workbench;
 
65
                        
 
66
                        LanguageService.ValidateLanguage();
 
67
                        
 
68
                        DisplayBindingService.InitializeService();
 
69
                        LayoutConfiguration.LoadLayoutConfiguration();
 
70
                        FileService.InitializeService();
 
71
                        DomHostCallback.Register(); // must be called after StatusBarService.Initialize()
 
72
                        ParserService.InitializeParserService();
 
73
                        TaskService.Initialize();
 
74
                        Bookmarks.BookmarkManager.Initialize();
 
75
                        Project.CustomToolsService.Initialize();
 
76
                        Project.BuildModifiedProjectsOnlyService.Initialize();
 
77
                        
 
78
                        var messageService = Core.Services.ServiceManager.Instance.MessageService as IDialogMessageService;
 
79
                        if (messageService != null) {
 
80
                                messageService.DialogOwner = workbench.MainWin32Window;
 
81
                                Debug.Assert(messageService.DialogOwner != null);
 
82
                                messageService.DialogSynchronizeInvoke = workbench.SynchronizingObject;
 
83
                        }
 
84
                        
 
85
                        workbench.Initialize();
 
86
                        workbench.SetMemento(PropertyService.Get(workbenchMemento, new Properties()));
 
87
                        workbench.WorkbenchLayout = layout;
 
88
                        
 
89
                        ApplicationStateInfoService.RegisterStateGetter(activeContentState, delegate { return WorkbenchSingleton.Workbench.ActiveContent; });
 
90
                        
 
91
                        OnWorkbenchCreated();
 
92
                        
 
93
                        // initialize workbench-dependent services:
 
94
                        Project.ProjectService.InitializeService();
 
95
                        NavigationService.InitializeService();
 
96
                        
 
97
                        workbench.ActiveContentChanged += delegate {
 
98
                                Debug.WriteLine("ActiveContentChanged to " + workbench.ActiveContent);
 
99
                                LoggingService.Debug("ActiveContentChanged to " + workbench.ActiveContent);
 
100
                        };
 
101
                        workbench.ActiveViewContentChanged += delegate {
 
102
                                Debug.WriteLine("ActiveViewContentChanged to " + workbench.ActiveViewContent);
 
103
                                LoggingService.Debug("ActiveViewContentChanged to " + workbench.ActiveViewContent);
 
104
                        };
 
105
                        workbench.ActiveWorkbenchWindowChanged += delegate {
 
106
                                Debug.WriteLine("ActiveWorkbenchWindowChanged to " + workbench.ActiveWorkbenchWindow);
 
107
                                LoggingService.Debug("ActiveWorkbenchWindowChanged to " + workbench.ActiveWorkbenchWindow);
 
108
                        };
 
109
                }
 
110
                
 
111
                /// <summary>
 
112
                /// Runs workbench cleanup.
 
113
                /// Is called by ICSharpCode.SharpDevelop.Sda and should not be called manually!
 
114
                /// </summary>
 
115
                public static void OnWorkbenchUnloaded()
 
116
                {
 
117
                        if (!Project.ProjectService.IsClosingCanceled()) {
 
118
                                Project.ProjectService.CloseSolution();
 
119
                                NavigationService.Unload();
 
120
                                
 
121
                                ApplicationStateInfoService.UnregisterStateGetter(activeContentState);
 
122
                                
 
123
                                WorkbenchUnloaded(null, EventArgs.Empty);
 
124
                                
 
125
                                FileService.Unload();
 
126
                        }
 
127
                }
 
128
                
 
129
                #region Safe Thread Caller
 
130
                public static bool InvokeRequired {
 
131
                        get {
 
132
                                if (workbench == null)
 
133
                                        return false; // unit test mode, don't crash
 
134
                                else
 
135
                                        return workbench.SynchronizingObject.InvokeRequired;
 
136
                        }
 
137
                }
 
138
                
 
139
                /// <summary>
 
140
                /// Throws an exception if the current thread is not the main thread.
 
141
                /// For performance reasons, the thread check is only done in debug builds.
 
142
                /// </summary>
 
143
                [Conditional("DEBUG")]
 
144
                internal static void DebugAssertMainThread()
 
145
                {
 
146
                        AssertMainThread();
 
147
                }
 
148
                
 
149
                /// <summary>
 
150
                /// Throws an exception if the current thread is not the main thread.
 
151
                /// </summary>
 
152
                public static void AssertMainThread()
 
153
                {
 
154
                        if (InvokeRequired) {
 
155
                                throw new InvalidOperationException("This operation can be called on the main thread only.");
 
156
                        }
 
157
                }
 
158
                
 
159
                readonly static object[] emptyObjectArray = new object[0];
 
160
                
 
161
                /// <summary>
 
162
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
163
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
164
                /// held by this thread!
 
165
                /// </summary>
 
166
                public static R SafeThreadFunction<R>(Func<R> method)
 
167
                {
 
168
                        // InvokeRequired test is necessary so that we don't run other actions in the message queue
 
169
                        // when we're already running on the main thread (unexpected reentrancy)
 
170
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
171
                        if (si.InvokeRequired)
 
172
                                return (R)workbench.SynchronizingObject.Invoke(method, emptyObjectArray);
 
173
                        else
 
174
                                return method();
 
175
                }
 
176
                
 
177
                /// <summary>
 
178
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
179
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
180
                /// held by this thread!
 
181
                /// </summary>
 
182
                public static R SafeThreadFunction<A, R>(Func<A, R> method, A arg1)
 
183
                {
 
184
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
185
                        if (si.InvokeRequired)
 
186
                                return (R)si.Invoke(method, new object[] { arg1 });
 
187
                        else
 
188
                                return method(arg1);
 
189
                }
 
190
                
 
191
                /// <summary>
 
192
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
193
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
194
                /// held by this thread!
 
195
                /// </summary>
 
196
                public static void SafeThreadCall(Action method)
 
197
                {
 
198
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
199
                        if (si.InvokeRequired)
 
200
                                si.Invoke(method, emptyObjectArray);
 
201
                        else
 
202
                                method();
 
203
                }
 
204
                
 
205
                /// <summary>
 
206
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
207
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
208
                /// held by this thread!
 
209
                /// </summary>
 
210
                public static void SafeThreadCall<A>(Action<A> method, A arg1)
 
211
                {
 
212
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
213
                        if (si.InvokeRequired)
 
214
                                si.Invoke(method, new object[] { arg1 });
 
215
                        else
 
216
                                method(arg1);
 
217
                }
 
218
                
 
219
                /// <summary>
 
220
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
221
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
222
                /// held by this thread!
 
223
                /// </summary>
 
224
                public static void SafeThreadCall<A, B>(Action<A, B> method, A arg1, B arg2)
 
225
                {
 
226
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
227
                        if (si.InvokeRequired)
 
228
                                si.Invoke(method, new object[] { arg1, arg2 });
 
229
                        else
 
230
                                method(arg1, arg2);
 
231
                }
 
232
                
 
233
                /// <summary>
 
234
                /// Makes a call GUI threadsafe. WARNING: This method waits for the result of the
 
235
                /// operation, which can result in a dead-lock when the main thread waits for a lock
 
236
                /// held by this thread!
 
237
                /// </summary>
 
238
                public static void SafeThreadCall<A, B, C>(Action<A, B, C> method, A arg1, B arg2, C arg3)
 
239
                {
 
240
                        ISynchronizeInvoke si = workbench.SynchronizingObject;
 
241
                        if (si.InvokeRequired)
 
242
                                si.Invoke(method, new object[] { arg1, arg2, arg3 });
 
243
                        else
 
244
                                method(arg1, arg2, arg3);
 
245
                }
 
246
                
 
247
                /// <summary>
 
248
                /// Makes a call GUI threadsafe without waiting for the returned value.
 
249
                /// </summary>
 
250
                public static void SafeThreadAsyncCall(Action method)
 
251
                {
 
252
                        workbench.SynchronizingObject.BeginInvoke(method, emptyObjectArray);
 
253
                }
 
254
                
 
255
                /// <summary>
 
256
                /// Makes a call GUI threadsafe without waiting for the returned value.
 
257
                /// </summary>
 
258
                public static void SafeThreadAsyncCall<A>(Action<A> method, A arg1)
 
259
                {
 
260
                        workbench.SynchronizingObject.BeginInvoke(method, new object[] { arg1 });
 
261
                }
 
262
                
 
263
                /// <summary>
 
264
                /// Makes a call GUI threadsafe without waiting for the returned value.
 
265
                /// </summary>
 
266
                public static void SafeThreadAsyncCall<A, B>(Action<A, B> method, A arg1, B arg2)
 
267
                {
 
268
                        workbench.SynchronizingObject.BeginInvoke(method, new object[] { arg1, arg2 });
 
269
                }
 
270
                
 
271
                /// <summary>
 
272
                /// Makes a call GUI threadsafe without waiting for the returned value.
 
273
                /// </summary>
 
274
                public static void SafeThreadAsyncCall<A, B, C>(Action<A, B, C> method, A arg1, B arg2, C arg3)
 
275
                {
 
276
                        workbench.SynchronizingObject.BeginInvoke(method, new object[] { arg1, arg2, arg3 });
 
277
                }
 
278
                
 
279
                /// <summary>
 
280
                /// Calls a method on the GUI thread, but delays the call a bit.
 
281
                /// </summary>
 
282
                public static void CallLater(TimeSpan delay, Action method)
 
283
                {
 
284
                        int delayMilliseconds = (int)delay.TotalMilliseconds;
 
285
                        if (delayMilliseconds < 0)
 
286
                                throw new ArgumentOutOfRangeException("delay", delay, "Value must be positive");
 
287
                        if (method == null)
 
288
                                throw new ArgumentNullException("method");
 
289
                        SafeThreadAsyncCall(
 
290
                                delegate {
 
291
                                        Timer t = new Timer();
 
292
                                        t.Interval = Math.Max(1, delayMilliseconds);
 
293
                                        t.Tick += delegate {
 
294
                                                t.Stop();
 
295
                                                t.Dispose();
 
296
                                                method();
 
297
                                        };
 
298
                                        t.Start();
 
299
                                });
 
300
                }
 
301
                #endregion
 
302
                
 
303
                static void OnWorkbenchCreated()
 
304
                {
 
305
                        WorkbenchCreated(null, EventArgs.Empty);
 
306
                }
 
307
                
 
308
                /// <summary>
 
309
                /// Is called, when the workbench is created
 
310
                /// </summary>
 
311
                public static event EventHandler WorkbenchCreated = delegate {};
 
312
                
 
313
                /// <summary>
 
314
                /// Is called, when the workbench is unloaded
 
315
                /// </summary>
 
316
                public static event EventHandler WorkbenchUnloaded = delegate {};
 
317
        }
 
318
}