~ubuntu-branches/ubuntu/saucy/monodevelop/saucy-proposed

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-09-10 16:54:48 UTC
  • mfrom: (19.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100910165448-0rybfk25zd4o9431
Tags: 2.4+dfsg-2
* debian/patches/inject_Mono.Debugger.Soft_source.patch,
  debian/patches/use_system_Mono.Debugger.Soft.patch,
  debian/control:
  + Build against system Soft Debugger, since we now have a new
    enough Mono to match MonoDevelop's required API

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// RootWorkspace.cs
 
2
//
 
3
// Author:
 
4
//   Lluis Sanchez Gual <lluis@novell.com>
 
5
//
 
6
// Copyright (c) 2008 Novell, Inc (http://www.novell.com)
 
7
//
 
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
9
// of this software and associated documentation files (the "Software"), to deal
 
10
// in the Software without restriction, including without limitation the rights
 
11
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
12
// copies of the Software, and to permit persons to whom the Software is
 
13
// furnished to do so, subject to the following conditions:
 
14
//
 
15
// The above copyright notice and this permission notice shall be included in
 
16
// all copies or substantial portions of the Software.
 
17
//
 
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
24
// THE SOFTWARE.
 
25
//
 
26
//
 
27
 
 
28
using System;
 
29
using System.IO;
 
30
using System.Collections;
 
31
using System.Collections.Generic;
 
32
using System.Collections.ObjectModel;
 
33
using System.Xml;
 
34
using MonoDevelop.Projects;
 
35
using MonoDevelop.Core;
 
36
using MonoDevelop.Core.Assemblies;
 
37
using MonoDevelop.Core.Serialization;
 
38
using MonoDevelop.Projects.CodeGeneration;
 
39
using MonoDevelop.Ide.Gui.Dialogs;
 
40
using MonoDevelop.Ide.Gui.Content;
 
41
using System.Runtime.CompilerServices;
 
42
using MonoDevelop.Core.Instrumentation;
 
43
using MonoDevelop.Ide.Gui;
 
44
using MonoDevelop.Ide.Projects;
 
45
 
 
46
namespace MonoDevelop.Ide
 
47
{
 
48
        public class RootWorkspace: IBuildTarget, IWorkspaceObject
 
49
        {
 
50
                WorkspaceItemCollection items;
 
51
//              IParserDatabase parserDatabase;
 
52
                string activeConfiguration;
 
53
                bool useDefaultRuntime;
 
54
                
 
55
                ProjectFileEventHandler fileAddedToProjectHandler;
 
56
                ProjectFileEventHandler fileRemovedFromProjectHandler;
 
57
                ProjectFileRenamedEventHandler fileRenamedInProjectHandler;
 
58
                ProjectFileEventHandler fileChangedInProjectHandler;
 
59
                ProjectFileEventHandler filePropertyChangedInProjectHandler;
 
60
                ProjectReferenceEventHandler referenceAddedToProjectHandler;
 
61
                ProjectReferenceEventHandler referenceRemovedFromProjectHandler;
 
62
                SolutionItemChangeEventHandler itemAddedToSolutionHandler;
 
63
                SolutionItemChangeEventHandler itemRemovedFromSolutionHandler;
 
64
                EventHandler<WorkspaceItemChangeEventArgs> descendantItemAddedHandler;
 
65
                EventHandler<WorkspaceItemChangeEventArgs> descendantItemRemovedHandler;
 
66
                EventHandler configurationsChanged;
 
67
                
 
68
                internal RootWorkspace ()
 
69
                {
 
70
                        fileAddedToProjectHandler = (ProjectFileEventHandler) DispatchService.GuiDispatch (new ProjectFileEventHandler (NotifyFileAddedToProject));
 
71
                        fileRemovedFromProjectHandler = (ProjectFileEventHandler) DispatchService.GuiDispatch (new ProjectFileEventHandler (NotifyFileRemovedFromProject));
 
72
                        fileRenamedInProjectHandler = (ProjectFileRenamedEventHandler) DispatchService.GuiDispatch (new ProjectFileRenamedEventHandler (NotifyFileRenamedInProject));
 
73
                        fileChangedInProjectHandler = (ProjectFileEventHandler) DispatchService.GuiDispatch (new ProjectFileEventHandler (NotifyFileChangedInProject));
 
74
                        filePropertyChangedInProjectHandler = (ProjectFileEventHandler) DispatchService.GuiDispatch (new ProjectFileEventHandler (NotifyFilePropertyChangedInProject));
 
75
                        referenceAddedToProjectHandler = (ProjectReferenceEventHandler) DispatchService.GuiDispatch (new ProjectReferenceEventHandler (NotifyReferenceAddedToProject));
 
76
                        referenceRemovedFromProjectHandler = (ProjectReferenceEventHandler) DispatchService.GuiDispatch (new ProjectReferenceEventHandler (NotifyReferenceRemovedFromProject));
 
77
                
 
78
                        itemAddedToSolutionHandler = (SolutionItemChangeEventHandler) DispatchService.GuiDispatch (new SolutionItemChangeEventHandler (NotifyItemAddedToSolution));
 
79
                        itemRemovedFromSolutionHandler = (SolutionItemChangeEventHandler) DispatchService.GuiDispatch (new SolutionItemChangeEventHandler (NotifyItemRemovedFromSolution));
 
80
                        
 
81
                        descendantItemAddedHandler = (EventHandler<WorkspaceItemChangeEventArgs>) DispatchService.GuiDispatch (new EventHandler<WorkspaceItemChangeEventArgs> (NotifyDescendantItemAdded));
 
82
                        descendantItemRemovedHandler = (EventHandler<WorkspaceItemChangeEventArgs>) DispatchService.GuiDispatch (new EventHandler<WorkspaceItemChangeEventArgs> (NotifyDescendantItemRemoved));
 
83
                        configurationsChanged = (EventHandler) DispatchService.GuiDispatch (new EventHandler (NotifyConfigurationsChanged));
 
84
                        
 
85
                        FileService.FileRemoved += (EventHandler<FileEventArgs>) DispatchService.GuiDispatch (new EventHandler<FileEventArgs> (CheckFileRemove));
 
86
                        FileService.FileRenamed += (EventHandler<FileCopyEventArgs>) DispatchService.GuiDispatch (new EventHandler<FileCopyEventArgs> (CheckFileRename));
 
87
                        
 
88
                        // Set the initial active runtime
 
89
                        UseDefaultRuntime = true;
 
90
                        IdeApp.Preferences.DefaultTargetRuntimeChanged += delegate {
 
91
                                // If the default runtime changes and current active is default, update it
 
92
                                if (UseDefaultRuntime) {
 
93
                                        Runtime.SystemAssemblyService.DefaultRuntime = IdeApp.Preferences.DefaultTargetRuntime;
 
94
                                        useDefaultRuntime = true;
 
95
                                }
 
96
                        };
 
97
                        
 
98
                        //FIXME: disabled OnRunProjectChecks timeout because it churns disk, wastes power on laptop. Need better solution.
 
99
                        //GLib.Timeout.Add (2000, OnRunProjectChecks);
 
100
                }
 
101
                
 
102
                public WorkspaceItemCollection Items {
 
103
                        get {
 
104
                                if (items == null)
 
105
                                        items = new RootWorkspaceItemCollection (this);
 
106
                                return items; 
 
107
                        }
 
108
                }
 
109
                /*
 
110
                public IParserDatabase ParserDatabase {
 
111
                        get { 
 
112
                                if (parserDatabase == null) {
 
113
                                        parserDatabase = Services.ParserService.CreateParserDatabase ();
 
114
                                        parserDatabase.TrackFileChanges = true;
 
115
                                        parserDatabase.ParseProgressMonitorFactory = new ParseProgressMonitorFactory (); 
 
116
                                }
 
117
                                return parserDatabase; 
 
118
                        }
 
119
                }*/
 
120
                
 
121
                public string ActiveConfigurationId {
 
122
                        get {
 
123
                                return activeConfiguration;
 
124
                        }
 
125
                        set {
 
126
                                if (activeConfiguration != value) {
 
127
                                        activeConfiguration = value;
 
128
                                        if (ActiveConfigurationChanged != null)
 
129
                                                ActiveConfigurationChanged (this, EventArgs.Empty);
 
130
                                }
 
131
                        }
 
132
                }
 
133
                
 
134
                public ConfigurationSelector ActiveConfiguration {
 
135
                        get { return new SolutionConfigurationSelector (activeConfiguration); }
 
136
                }
 
137
                
 
138
                public TargetRuntime ActiveRuntime {
 
139
                        get {
 
140
                                return Runtime.SystemAssemblyService.DefaultRuntime;
 
141
                        }
 
142
                        set {
 
143
                                useDefaultRuntime = false;
 
144
                                Runtime.SystemAssemblyService.DefaultRuntime = value;
 
145
                        }
 
146
                }
 
147
                
 
148
                public bool UseDefaultRuntime {
 
149
                        get { return useDefaultRuntime; }
 
150
                        set {
 
151
                                if (useDefaultRuntime != value) {
 
152
                                        useDefaultRuntime = value;
 
153
                                        if (value)
 
154
                                                Runtime.SystemAssemblyService.DefaultRuntime = IdeApp.Preferences.DefaultTargetRuntime;
 
155
                                }
 
156
                        }
 
157
                }
 
158
                
 
159
                public bool IsOpen {
 
160
                        get { return Items.Count > 0; }
 
161
                }
 
162
                
 
163
                public CodeRefactorer GetCodeRefactorer (Solution solution) 
 
164
                {
 
165
                        CodeRefactorer refactorer = new CodeRefactorer (solution);
 
166
                        refactorer.TextFileProvider = new OpenDocumentFileProvider ();
 
167
                        return refactorer;
 
168
                }
 
169
 
 
170
                IDictionary IExtendedDataItem.ExtendedProperties {
 
171
                        get {
 
172
                                throw new NotSupportedException ("Root namespace can't have extended properties.");
 
173
                        }
 
174
                }
 
175
 
 
176
                string IWorkspaceObject.Name {
 
177
                        get {
 
178
                                return "MonoDevelop Workspace";
 
179
                        }
 
180
                        set {
 
181
                                throw new NotSupportedException ("Can't change the name of the root workspace.");
 
182
                        }
 
183
                }
 
184
 
 
185
                public FilePath BaseDirectory {
 
186
                        get {
 
187
                                return IdeApp.ProjectOperations.ProjectsDefaultPath;
 
188
                        }
 
189
                }
 
190
                
 
191
                FilePath IWorkspaceObject.BaseDirectory {
 
192
                        get {
 
193
                                return BaseDirectory;
 
194
                        }
 
195
                        set {
 
196
                                throw new NotSupportedException ();
 
197
                        }
 
198
                }
 
199
                
 
200
                FilePath IWorkspaceObject.ItemDirectory {
 
201
                        get {
 
202
                                return BaseDirectory;
 
203
                        }
 
204
                }
 
205
                
 
206
                public AuthorInformation GetAuthorInformation  (SolutionItem item)
 
207
                {
 
208
                        if (item != null)
 
209
                                return GetAuthorInformation (item.ParentSolution);
 
210
                        return AuthorInformation.Default;
 
211
                }
 
212
                
 
213
                public AuthorInformation GetAuthorInformation (Solution solution)
 
214
                {
 
215
                        if (solution == null)
 
216
                                return AuthorInformation.Default;
 
217
                        AuthorInformation info = solution.UserProperties.GetValue<AuthorInformation> ("AuthorInfo");
 
218
                        return info ?? AuthorInformation.Default;
 
219
                }
 
220
                
 
221
#region Model queries
 
222
                
 
223
                public SolutionEntityItem FindSolutionItem (string fileName)
 
224
                {
 
225
                        foreach (WorkspaceItem it in Items) {
 
226
                                SolutionEntityItem si = it.FindSolutionItem (fileName);
 
227
                                if (si != null)
 
228
                                        return si;
 
229
                        }
 
230
                        return null;
 
231
                }
 
232
                
 
233
                public ReadOnlyCollection<SolutionItem> GetAllSolutionItems ()
 
234
                {
 
235
                        return GetAllSolutionItems<SolutionItem> ();
 
236
                }
 
237
                
 
238
                public virtual ReadOnlyCollection<T> GetAllSolutionItems<T> () where T: SolutionItem
 
239
                {
 
240
                        List<T> list = new List<T> ();
 
241
                        foreach (WorkspaceItem it in Items) {
 
242
                                list.AddRange (it.GetAllSolutionItems<T> ());
 
243
                        }
 
244
                        return list.AsReadOnly ();
 
245
                }
 
246
                
 
247
                public ReadOnlyCollection<Project> GetAllProjects ()
 
248
                {
 
249
                        return GetAllSolutionItems<Project> ();
 
250
                }
 
251
                
 
252
                public ReadOnlyCollection<Solution> GetAllSolutions ()
 
253
                {
 
254
                        return GetAllItems<Solution> ();
 
255
                }
 
256
                        
 
257
                public ReadOnlyCollection<T> GetAllItems<T> () where T:WorkspaceItem
 
258
                {
 
259
                        List<T> list = new List<T> ();
 
260
                        foreach (WorkspaceItem it in Items)
 
261
                                GetAllItems<T> (list, it);
 
262
                        return list.AsReadOnly ();
 
263
                }
 
264
                
 
265
                void GetAllItems<T> (List<T> list, WorkspaceItem item) where T: WorkspaceItem
 
266
                {
 
267
                        if (item is T)
 
268
                                list.Add ((T) item);
 
269
                        
 
270
                        if (item is Workspace) {
 
271
                                foreach (WorkspaceItem citem in ((Workspace)item).Items)
 
272
                                        GetAllItems<T> (list, citem);
 
273
                        }
 
274
                }
 
275
 
 
276
                public Project GetProjectContainingFile (string fileName)
 
277
                {
 
278
                        foreach (WorkspaceItem it in Items) {
 
279
                                Project p = it.GetProjectContainingFile (fileName);
 
280
                                if (p != null)
 
281
                                        return p;
 
282
                        }
 
283
                        return null;
 
284
                }
 
285
                
 
286
#endregion
 
287
                
 
288
#region Build and run operations
 
289
                
 
290
                public void Save ()
 
291
                {
 
292
                        IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true);
 
293
                        try {
 
294
                                Save (monitor);
 
295
                                monitor.ReportSuccess (GettextCatalog.GetString ("Workspace saved."));
 
296
                        } catch (Exception ex) {
 
297
                                monitor.ReportError (GettextCatalog.GetString ("Save failed."), ex);
 
298
                        } finally {
 
299
                                monitor.Dispose ();
 
300
                        }
 
301
                }
 
302
                
 
303
                public IAsyncOperation Build ()
 
304
                {
 
305
                        return IdeApp.ProjectOperations.Build (this);
 
306
                }
 
307
 
 
308
                public void Clean ()
 
309
                {
 
310
                        IdeApp.ProjectOperations.Clean (this);
 
311
                }
 
312
 
 
313
                public IAsyncOperation Execute ()
 
314
                {
 
315
                        if (IdeApp.ProjectOperations.CurrentSelectedSolution != null)
 
316
                                return IdeApp.ProjectOperations.Execute (IdeApp.ProjectOperations.CurrentSelectedSolution);
 
317
                        else {
 
318
                                MessageService.ShowError (GettextCatalog.GetString ("No solution has been selected"), GettextCatalog.GetString ("The solution to be executed must be selected in the solution pad."));
 
319
                                return null;
 
320
                        }
 
321
                }
 
322
 
 
323
                public bool CanExecute ()
 
324
                {
 
325
                        if (IdeApp.ProjectOperations.CurrentSelectedSolution != null)
 
326
                                return IdeApp.ProjectOperations.CanExecute (IdeApp.ProjectOperations.CurrentSelectedSolution);
 
327
                        else {
 
328
                                return false;
 
329
                        }
 
330
                }
 
331
 
 
332
                bool IBuildTarget.CanExecute (ExecutionContext context, ConfigurationSelector configuration)
 
333
                {
 
334
                        if (IdeApp.ProjectOperations.CurrentSelectedSolution != null)
 
335
                                return IdeApp.ProjectOperations.CurrentSelectedSolution.CanExecute (context, configuration);
 
336
                        else {
 
337
                                return false;
 
338
                        }
 
339
                }
 
340
                
 
341
                public void Dispose ()
 
342
                {
 
343
                }
 
344
 
 
345
                public void Save (IProgressMonitor monitor)
 
346
                {
 
347
                        monitor.BeginTask (GettextCatalog.GetString ("Saving Workspace..."), Items.Count);
 
348
                        foreach (WorkspaceItem it in Items) {
 
349
                                it.Save (monitor);
 
350
                                monitor.Step (1);
 
351
                        }
 
352
                        monitor.EndTask ();
 
353
                }
 
354
                
 
355
                BuildResult IBuildTarget.RunTarget (IProgressMonitor monitor, string target, ConfigurationSelector configuration)
 
356
                {
 
357
                        BuildResult result = null;
 
358
                        foreach (WorkspaceItem it in Items) {
 
359
                                BuildResult res = it.RunTarget (monitor, target, configuration);
 
360
                                if (res != null) {
 
361
                                        if (result == null)
 
362
                                                result = new BuildResult ();
 
363
                                        result.Append (res);
 
364
                                }
 
365
                        }
 
366
                        return result;
 
367
                }
 
368
 
 
369
                public void Execute (MonoDevelop.Core.IProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
 
370
                {
 
371
                        Solution sol = IdeApp.ProjectOperations.CurrentSelectedSolution;
 
372
                        if (sol == null) {
 
373
                                ReadOnlyCollection<Solution> sols = GetAllSolutions ();
 
374
                                if (sols.Count > 0)
 
375
                                        sol = sols [0];
 
376
                        }
 
377
                        if (sol != null)
 
378
                                sol.Execute (monitor, context, configuration);
 
379
                        else
 
380
                                throw new UserException (GettextCatalog.GetString ("No solution has been selected."));
 
381
                }
 
382
                
 
383
                public bool NeedsBuilding ()
 
384
                {
 
385
                        return NeedsBuilding (IdeApp.Workspace.ActiveConfiguration) || IsDirtyFileInCombine;
 
386
                }
 
387
 
 
388
                public bool NeedsBuilding (ConfigurationSelector configuration)
 
389
                {
 
390
                        foreach (WorkspaceItem it in Items) {
 
391
                                if (it.NeedsBuilding (configuration))
 
392
                                        return true;
 
393
                        }
 
394
                        return false;
 
395
                }
 
396
 
 
397
                public void SetNeedsBuilding (bool needsBuilding, ConfigurationSelector configuration)
 
398
                {
 
399
                        foreach (WorkspaceItem it in Items)
 
400
                                it.SetNeedsBuilding (needsBuilding, configuration);
 
401
                }
 
402
 
 
403
                bool IsDirtyFileInCombine {
 
404
                        get {
 
405
                                foreach (Project projectEntry in GetAllProjects()) {
 
406
                                        foreach (ProjectFile fInfo in projectEntry.Files) {
 
407
                                                foreach (Document doc in IdeApp.Workbench.Documents) {
 
408
                                                        if (doc.IsDirty && doc.FileName == fInfo.FilePath) {
 
409
                                                                return true;
 
410
                                                        }
 
411
                                                }
 
412
                                        }
 
413
                                }
 
414
                                return false;
 
415
                        }
 
416
                }
 
417
                
 
418
                public ReadOnlyCollection<string> GetConfigurations ()
 
419
                {
 
420
                        List<string> configs = new List<string> ();
 
421
                        foreach (WorkspaceItem it in Items) {
 
422
                                foreach (string conf in it.GetConfigurations ()) {
 
423
                                        if (!configs.Contains (conf))
 
424
                                                configs.Add (conf);
 
425
                                }
 
426
                        }
 
427
                        return configs.AsReadOnly ();
 
428
                }
 
429
#endregion
 
430
                
 
431
#region Opening and closing
 
432
 
 
433
                public void SavePreferences ()
 
434
                {
 
435
                        foreach (WorkspaceItem it in Items)
 
436
                                SavePreferences (it);
 
437
                }
 
438
                
 
439
                public bool Close ()
 
440
                {
 
441
                        return Close (true);
 
442
                }
 
443
 
 
444
                public bool Close (bool saveWorkspacePreferencies)
 
445
                {
 
446
                        return Close (saveWorkspacePreferencies, true);
 
447
                }
 
448
                
 
449
                internal bool Close (bool saveWorkspacePreferencies, bool closeProjectFiles)
 
450
                {
 
451
                        if (Items.Count > 0) {
 
452
                                
 
453
                                // Request permission for unloading the items
 
454
                                foreach (WorkspaceItem it in new List<WorkspaceItem> (Items)) {
 
455
                                        if (!RequestItemUnload (it))
 
456
                                                return false;
 
457
                                }
 
458
                                
 
459
                                if (saveWorkspacePreferencies)
 
460
                                        SavePreferences ();
 
461
 
 
462
                                if (closeProjectFiles) {
 
463
                                        Document[] docs = new Document[IdeApp.Workbench.Documents.Count];
 
464
                                        IdeApp.Workbench.Documents.CopyTo (docs, 0);
 
465
                                        foreach (Document doc in docs) {
 
466
                                                if (doc.HasProject) {
 
467
                                                        if (!doc.Close ())
 
468
                                                                return false;
 
469
                                                }
 
470
                                        }
 
471
                                }
 
472
                                
 
473
                                foreach (WorkspaceItem it in new List<WorkspaceItem> (Items)) {
 
474
                                        try {
 
475
                                                Items.Remove (it);
 
476
                                                it.Dispose ();
 
477
                                        } catch (Exception ex) {
 
478
                                                MessageService.ShowException (ex, GettextCatalog.GetString ("Could not close solution '{0}'.", it.Name));
 
479
                                        }
 
480
                                }
 
481
                        }
 
482
                        return true;
 
483
                }
 
484
                
 
485
                public void CloseWorkspaceItem (WorkspaceItem item)
 
486
                {
 
487
                        if (!Items.Contains (item))
 
488
                                throw new InvalidOperationException ("Only top level items can be closed.");
 
489
                        
 
490
                        if (RequestItemUnload (item))
 
491
                                Items.Remove (item);
 
492
                }
 
493
                
 
494
                public bool RequestItemUnload (IBuildTarget item)
 
495
                {
 
496
                        if (ItemUnloading != null) {
 
497
                                try {
 
498
                                        ItemUnloadingEventArgs args = new ItemUnloadingEventArgs (item);
 
499
                                        ItemUnloading (this, args);
 
500
                                        return !args.Cancel;
 
501
                                } catch (Exception ex) {
 
502
                                        LoggingService.LogError ("Exception in ItemUnloading.", ex);
 
503
                                }
 
504
                        }
 
505
                        return true;
 
506
                }
 
507
                
 
508
                public IAsyncOperation OpenWorkspaceItem (string filename)
 
509
                {
 
510
                        return OpenWorkspaceItem (filename, true);
 
511
                }
 
512
                
 
513
                public IAsyncOperation OpenWorkspaceItem (string filename, bool closeCurrent)
 
514
                {
 
515
                        return OpenWorkspaceItem (filename, closeCurrent, true);
 
516
                }
 
517
                
 
518
                public IAsyncOperation OpenWorkspaceItem (string filename, bool closeCurrent, bool loadPreferences)
 
519
                {
 
520
                        if (closeCurrent) {
 
521
                                if (!Close ())
 
522
                                        return MonoDevelop.Core.ProgressMonitoring.NullAsyncOperation.Failure;
 
523
                        }
 
524
 
 
525
                        if (filename.StartsWith ("file://"))
 
526
                                filename = new Uri(filename).LocalPath;
 
527
 
 
528
                        IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetLoadProgressMonitor (true);
 
529
                        
 
530
                        DispatchService.BackgroundDispatch (delegate {
 
531
                                BackgroundLoadWorkspace (monitor, filename, loadPreferences);
 
532
                        });
 
533
                        return monitor.AsyncOperation;
 
534
                }
 
535
                
 
536
                void ReattachDocumentProjects (IEnumerable<string> closedDocs)
 
537
                {
 
538
                        foreach (Document doc in IdeApp.Workbench.Documents) {
 
539
                                if (doc.Project == null && doc.IsFile) {
 
540
                                        Project p = GetProjectContainingFile (doc.FileName);
 
541
                                        if (p != null)
 
542
                                                doc.SetProject (p);
 
543
                                }
 
544
                        }
 
545
                        if (closedDocs != null) {
 
546
                                foreach (string doc in closedDocs) {
 
547
                                        IdeApp.Workbench.OpenDocument (doc, false);
 
548
                                }
 
549
                        }
 
550
                }
 
551
                
 
552
                void BackgroundLoadWorkspace (IProgressMonitor monitor, string filename, bool loadPreferences)
 
553
                {
 
554
                        WorkspaceItem item = null;
 
555
                        ITimeTracker timer = Counters.OpenWorkspaceItemTimer.BeginTiming ();
 
556
                        
 
557
                        try {
 
558
                                if (!File.Exists (filename)) {
 
559
                                        monitor.ReportError (GettextCatalog.GetString ("File not found: {0}", filename), null);
 
560
                                        monitor.Dispose ();
 
561
                                        return;
 
562
                                }
 
563
                                
 
564
                                if (!Services.ProjectService.IsWorkspaceItemFile (filename)) {
 
565
                                        if (!Services.ProjectService.IsSolutionItemFile (filename)) {
 
566
                                                monitor.ReportError (GettextCatalog.GetString ("File is not a project or solution: {0}", filename), null);
 
567
                                                monitor.Dispose ();
 
568
                                                return;
 
569
                                        }
 
570
                                        
 
571
                                        // It is a project, not a solution. Try to create a dummy solution and add the project to it
 
572
                                        
 
573
                                        timer.Trace ("Getting wrapper solution");
 
574
                                        item = IdeApp.Services.ProjectService.GetWrapperSolution (monitor, filename);
 
575
                                }
 
576
                                
 
577
                                if (item == null) {
 
578
                                        timer.Trace ("Reading item");
 
579
                                        item = Services.ProjectService.ReadWorkspaceItem (monitor, filename);
 
580
                                        if (monitor.IsCancelRequested) {
 
581
                                                monitor.Dispose ();
 
582
                                                return;
 
583
                                        }
 
584
                                }
 
585
 
 
586
                                timer.Trace ("Registering to recent list");
 
587
                                IdeApp.Workbench.RecentOpen.AddLastProject (item.FileName, item.Name);
 
588
                                
 
589
                                timer.Trace ("Adding to items list");
 
590
                                Items.Add (item);
 
591
                                
 
592
                                timer.Trace ("Searching for new files");
 
593
                                SearchForNewFiles ();
 
594
 
 
595
                        } catch (Exception ex) {
 
596
                                monitor.ReportError ("Load operation failed.", ex);
 
597
                                
 
598
                                // Don't use 'finally' to dispose the monitor, since it has to be disposed later
 
599
                                monitor.Dispose ();
 
600
                                timer.End ();
 
601
                                return;
 
602
                        }
 
603
                        
 
604
                        Gtk.Application.Invoke (delegate {
 
605
                                using (monitor) {
 
606
                                        try {
 
607
                                                if (Items.Count == 1 && loadPreferences) {
 
608
                                                        timer.Trace ("Restoring workspace preferences");
 
609
                                                        RestoreWorkspacePreferences (item);
 
610
                                                }
 
611
                                                timer.Trace ("Reattaching documents");
 
612
                                                ReattachDocumentProjects (null);
 
613
                                                monitor.ReportSuccess (GettextCatalog.GetString ("Solution loaded."));
 
614
                                        } finally {
 
615
                                                timer.End ();
 
616
                                        }
 
617
                                }
 
618
                        });
 
619
                }
 
620
                
 
621
                void SearchForNewFiles ()
 
622
                {
 
623
                        foreach (Project p in GetAllProjects()) {
 
624
                                if (p.NewFileSearch != NewFileSearch.None)
 
625
                                        SearchNewFiles (p);
 
626
                        }
 
627
                }
 
628
 
 
629
                
 
630
                void SearchNewFiles (Project project)
 
631
                {
 
632
                        List<string> newFiles   = new List<string> ();
 
633
                        string[] collection = Directory.GetFiles (project.BaseDirectory, "*", SearchOption.AllDirectories);
 
634
                        
 
635
                        HashSet<string> projectFiles = new HashSet<string> ();
 
636
                        foreach (string file in project.GetItemFiles (true))
 
637
                                projectFiles.Add (file);
 
638
 
 
639
                        foreach (string sfile in collection) {
 
640
                                if (projectFiles.Contains (Path.GetFullPath (sfile)))
 
641
                                        continue;
 
642
                                if (IdeApp.Services.ProjectService.IsSolutionItemFile (sfile) || IdeApp.Services.ProjectService.IsWorkspaceItemFile (sfile))
 
643
                                        continue;
 
644
                                string extension = Path.GetExtension(sfile).ToUpper();
 
645
                                string file = Path.GetFileName (sfile);
 
646
 
 
647
                                if (extension != ".SCC" &&  // source safe control files -- Svante Lidmans
 
648
                                        extension != ".DLL" &&
 
649
                                        extension != ".PDB" &&
 
650
                                        extension != ".EXE" &&
 
651
                                        extension != ".CMBX" &&
 
652
                                        extension != ".PRJX" &&
 
653
                                        extension != ".SWP" &&
 
654
                                        extension != ".MDSX" &&
 
655
                                        extension != ".MDS" &&
 
656
                                        extension != ".MDP" && 
 
657
                                        extension != ".PIDB" &&
 
658
                                        extension != ".PIDB-JOURNAL" &&
 
659
                                        !file.EndsWith ("make.sh") &&
 
660
                                        !file.EndsWith ("~") &&
 
661
                                        !file.StartsWith (".") &&
 
662
                                        !(Path.GetDirectoryName(sfile).IndexOf("CVS") != -1) &&
 
663
                                        !(Path.GetDirectoryName(sfile).IndexOf(".svn") != -1) &&
 
664
                                        !(Path.GetDirectoryName(sfile).IndexOf(Path.DirectorySeparatorChar + "bin" + Path.DirectorySeparatorChar) != -1) &&
 
665
                                        !file.StartsWith ("Makefile") &&
 
666
                                        !Path.GetDirectoryName(file).EndsWith("ProjectDocumentation")) {
 
667
 
 
668
                                        newFiles.Add(sfile);
 
669
                                }
 
670
                        }
 
671
                        
 
672
                        if (newFiles.Count > 0) {
 
673
                                if (project.NewFileSearch == NewFileSearch.OnLoadAutoInsert) {
 
674
                                        foreach (string file in newFiles) {
 
675
                                                project.AddFile (file);
 
676
                                        }               
 
677
                                } else {
 
678
                                        DispatchService.GuiDispatch (
 
679
                                                delegate (object state) {
 
680
                                                        NewFilesMessage message = (NewFilesMessage) state;
 
681
                                                        var includeNewFilesDialog = new IncludeNewFilesDialog (message.Project);
 
682
                                                        includeNewFilesDialog.AddFiles (message.NewFiles);
 
683
                                                        MessageService.ShowCustomDialog (includeNewFilesDialog, IdeApp.Workbench.RootWindow);
 
684
                                                },
 
685
                                                new NewFilesMessage (project, newFiles)
 
686
                                        );
 
687
                                }
 
688
                        }
 
689
                }
 
690
                
 
691
                private class NewFilesMessage
 
692
                {
 
693
                        public Project Project;
 
694
                        public List<string> NewFiles;
 
695
                        public NewFilesMessage (Project p, List<string> newFiles)
 
696
                        {
 
697
                                this.Project = p;
 
698
                                this.NewFiles = newFiles;
 
699
                        }
 
700
                }
 
701
                
 
702
                void RestoreWorkspacePreferences (WorkspaceItem item)
 
703
                {
 
704
                        // Restore local configuration data
 
705
                        
 
706
                        try {
 
707
                                WorkspaceUserData data = item.UserProperties.GetValue<WorkspaceUserData> ("MonoDevelop.Ide.Workspace");
 
708
                                if (data != null) {
 
709
                                        ActiveConfigurationId = data.ActiveConfiguration;
 
710
                                        if (string.IsNullOrEmpty (data.ActiveRuntime))
 
711
                                                UseDefaultRuntime = true;
 
712
                                        else {
 
713
                                                TargetRuntime tr = Runtime.SystemAssemblyService.GetTargetRuntime (data.ActiveRuntime);
 
714
                                                if (tr != null)
 
715
                                                        ActiveRuntime = tr;
 
716
                                                else
 
717
                                                        UseDefaultRuntime = true;
 
718
                                        }
 
719
                                }
 
720
                        }
 
721
                        catch (Exception ex) {
 
722
                                LoggingService.LogError ("Exception while loading user solution preferences.", ex);
 
723
                        }
 
724
                        
 
725
                        // Allow add-ins to restore preferences
 
726
                        
 
727
                        if (LoadingUserPreferences != null) {
 
728
                                UserPreferencesEventArgs args = new UserPreferencesEventArgs (item, item.UserProperties);
 
729
                                try {
 
730
                                        LoadingUserPreferences (this, args);
 
731
                                } catch (Exception ex) {
 
732
                                        LoggingService.LogError ("Exception in LoadingUserPreferences.", ex);
 
733
                                }
 
734
                        }
 
735
                }
 
736
                
 
737
                public void SavePreferences (WorkspaceItem item)
 
738
                {
 
739
                        // Local configuration info
 
740
                        
 
741
                        WorkspaceUserData data = new WorkspaceUserData ();
 
742
                        data.ActiveConfiguration = ActiveConfigurationId;
 
743
                        data.ActiveRuntime = UseDefaultRuntime ? null : ActiveRuntime.Id;
 
744
                        item.UserProperties.SetValue ("MonoDevelop.Ide.Workspace", data);
 
745
                        
 
746
                        // Allow add-ins to fill-up data
 
747
                        
 
748
                        if (StoringUserPreferences != null) {
 
749
                                UserPreferencesEventArgs args = new UserPreferencesEventArgs (item, item.UserProperties);
 
750
                                try {
 
751
                                        StoringUserPreferences (this, args);
 
752
                                } catch (Exception ex) {
 
753
                                        LoggingService.LogError ("Exception in UserPreferencesRequested.", ex);
 
754
                                }
 
755
                        }
 
756
                        
 
757
                        // Save the file
 
758
                        
 
759
                        item.SaveUserProperties ();
 
760
                }
 
761
                
 
762
                bool OnRunProjectChecks ()
 
763
                {
 
764
                        // If any project has been modified, reload it
 
765
                        foreach (WorkspaceItem it in new List<WorkspaceItem> (Items))
 
766
                                OnCheckWorkspaceItem (it);
 
767
                        return true;
 
768
                }
 
769
                
 
770
                void OnCheckWorkspaceItem (WorkspaceItem item)
 
771
                {
 
772
                        if (item.NeedsReload) {
 
773
                                IEnumerable<string> closedDocs;
 
774
                                if (AllowReload (item.GetAllProjects (), out closedDocs)) {
 
775
                                        if (item.ParentWorkspace == null) {
 
776
                                                string file = item.FileName;
 
777
                                                SavePreferences ();
 
778
                                                CloseWorkspaceItem (item);
 
779
                                                OpenWorkspaceItem (file, false);
 
780
                                        }
 
781
                                        else {
 
782
                                                using (IProgressMonitor m = IdeApp.Workbench.ProgressMonitors.GetSaveProgressMonitor (true)) {
 
783
                                                        item.ParentWorkspace.ReloadItem (m, item);
 
784
                                                        ReattachDocumentProjects (closedDocs);
 
785
                                                }
 
786
                                        }
 
787
 
 
788
                                        return;
 
789
                                } else
 
790
                                        item.NeedsReload = false;
 
791
                        }
 
792
 
 
793
                        if (item is Workspace) {
 
794
                                Workspace ws = (Workspace) item;
 
795
                                List<WorkspaceItem> items = new List<WorkspaceItem> (ws.Items);
 
796
                                foreach (WorkspaceItem it in items)
 
797
                                        OnCheckWorkspaceItem (it);
 
798
                        }
 
799
                        else if (item is Solution) {
 
800
                                Solution sol = (Solution) item;
 
801
                                OnCheckProject (sol.RootFolder);
 
802
                        }
 
803
                }
 
804
                
 
805
                void OnCheckProject (SolutionItem entry)
 
806
                {
 
807
                        if (entry.NeedsReload) {
 
808
                                IEnumerable projects = null;
 
809
                                if (entry is Project) {
 
810
                                        projects = new Project [] { (Project) entry };
 
811
                                } else if (entry is SolutionFolder) {
 
812
                                        projects = ((SolutionFolder)entry).GetAllProjects ();
 
813
                                }
 
814
                                
 
815
                                IEnumerable<string> closedDocs;
 
816
                                
 
817
                                if (AllowReload (projects, out closedDocs)) {
 
818
                                        using (IProgressMonitor m = IdeApp.Workbench.ProgressMonitors.GetLoadProgressMonitor (true)) {
 
819
                                                // Root folders never need to reload
 
820
                                                entry.ParentFolder.ReloadItem (m, entry);
 
821
                                                ReattachDocumentProjects (closedDocs);
 
822
                                        }
 
823
                                        return;
 
824
                                } else
 
825
                                        entry.NeedsReload = false;
 
826
                        }
 
827
                        
 
828
                        if (entry is SolutionFolder) {
 
829
                                ArrayList ens = new ArrayList ();
 
830
                                foreach (SolutionItem ce in ((SolutionFolder)entry).Items)
 
831
                                        ens.Add (ce);
 
832
                                foreach (SolutionItem ce in ens)
 
833
                                        OnCheckProject (ce);
 
834
                        }
 
835
                }
 
836
                
 
837
//              bool AllowReload (IEnumerable projects)
 
838
//              {
 
839
//                      IEnumerable<string> closedDocs;
 
840
//                      return AllowReload (projects, out closedDocs);
 
841
//              }
 
842
                
 
843
                bool AllowReload (IEnumerable projects, out IEnumerable<string> closedDocs)
 
844
                {
 
845
                        closedDocs = null;
 
846
                        
 
847
                        if (projects == null)
 
848
                                return true;
 
849
                        
 
850
                        List<Document> docs = new List<Document> ();
 
851
                        foreach (Project p in projects) {
 
852
                                docs.AddRange (GetOpenDocuments (p, false));
 
853
                        }
 
854
                        
 
855
                        if (docs.Count == 0)
 
856
                                return true;
 
857
                        
 
858
                        // Find a common project reload capability
 
859
                        
 
860
                        bool hasUnsaved = false;
 
861
                        bool hasNoFiles = false;
 
862
                        ProjectReloadCapability prc = ProjectReloadCapability.Full;
 
863
                        foreach (Document doc in docs) {
 
864
                                if (doc.IsDirty)
 
865
                                        hasUnsaved = true;
 
866
                                if (!doc.IsFile)
 
867
                                        hasNoFiles = true;
 
868
                                ISupportsProjectReload pr = doc.GetContent<ISupportsProjectReload> ();
 
869
                                if (pr != null) {
 
870
                                        ProjectReloadCapability c = pr.ProjectReloadCapability;
 
871
                                        if ((int) c < (int) prc)
 
872
                                                prc = c;
 
873
                                }
 
874
                                else
 
875
                                        prc = ProjectReloadCapability.None;
 
876
                        }
 
877
 
 
878
                        string msg = null;
 
879
                        
 
880
                        switch (prc) {
 
881
                                case ProjectReloadCapability.None:
 
882
                                        if (hasNoFiles && hasUnsaved)
 
883
                                                msg = GettextCatalog.GetString ("WARNING: Some documents may need to be closed, and unsaved data will be lost. You will be asked to save the unsaved documents.");
 
884
                                        else if (hasNoFiles)
 
885
                                                msg = GettextCatalog.GetString ("WARNING: Some documents may need to be reloaded or closed, and unsaved data will be lost. You will be asked to save the unsaved documents.");
 
886
                                        else if (hasUnsaved)
 
887
                                                msg = GettextCatalog.GetString ("WARNING: Some files may need to be reloaded, and unsaved data will be lost. You will be asked to save the unsaved files.");
 
888
                                        else
 
889
                                                goto case ProjectReloadCapability.UnsavedData;
 
890
                                        break;
 
891
                                        
 
892
                                case ProjectReloadCapability.UnsavedData:
 
893
                                        msg = GettextCatalog.GetString ("Some files may need to be reloaded, and editing status for those files (such as the undo queue) will be lost.");
 
894
                                        break;
 
895
                        }
 
896
                        if (msg != null) {
 
897
                                if (!MessageService.Confirm (GettextCatalog.GetString ("The project '{0}' has been modified by an external application. Do you want to reload it?", docs[0].Project.Name), msg, AlertButton.Reload))
 
898
                                        return false;
 
899
                        }
 
900
                        
 
901
                        List<string> closed = new List<string> ();
 
902
                        
 
903
                        foreach (Document doc in docs) {
 
904
                                if (doc.IsDirty)
 
905
                                        hasUnsaved = true;
 
906
                                ISupportsProjectReload pr = doc.GetContent<ISupportsProjectReload> ();
 
907
                                if (pr != null)
 
908
                                        doc.SetProject (null);
 
909
                                else {
 
910
                                        FilePath file = doc.IsFile ? doc.FileName : FilePath.Null;
 
911
                                        EventHandler saved = delegate {
 
912
                                                if (doc.IsFile)
 
913
                                                        file = doc.FileName;
 
914
                                        };
 
915
                                        doc.Saved += saved;
 
916
                                        try {
 
917
                                                if (!doc.Close ())
 
918
                                                        return false;
 
919
                                                else if (!file.IsNullOrEmpty && File.Exists (file))
 
920
                                                        closed.Add (file);
 
921
                                        } finally {
 
922
                                                doc.Saved -= saved;
 
923
                                        }
 
924
                                }
 
925
                        }
 
926
                        closedDocs = closed;
 
927
 
 
928
                        return true;
 
929
                }
 
930
                
 
931
                internal List<Document> GetOpenDocuments (Project project, bool modifiedOnly)
 
932
                {
 
933
                        List<Document> docs = new List<Document> ();
 
934
                        foreach (Document doc in IdeApp.Workbench.Documents) {
 
935
                                if (doc.Project == project && (!modifiedOnly || doc.IsDirty)) {
 
936
                                        docs.Add (doc);
 
937
                                }
 
938
                        }
 
939
                        return docs;
 
940
                }
 
941
                
 
942
                
 
943
#endregion
 
944
                
 
945
#region Event handling
 
946
                
 
947
                internal void NotifyItemAdded (WorkspaceItem item)
 
948
                {
 
949
                        if (DispatchService.IsGuiThread)
 
950
                                NotifyItemAddedGui (item);
 
951
                        else
 
952
                                Gtk.Application.Invoke (delegate {
 
953
                                        NotifyItemAddedGui (item);
 
954
                                });
 
955
                }
 
956
                
 
957
                void NotifyItemAddedGui (WorkspaceItem item)
 
958
                {
 
959
                        try {
 
960
//                              Mono.Profiler.RuntimeControls.EnableProfiler ();
 
961
                                MonoDevelop.Projects.Dom.Parser.ProjectDomService.Load (item);
 
962
//                              Mono.Profiler.RuntimeControls.DisableProfiler ();
 
963
//                              Console.WriteLine ("PARSE LOAD: " + (DateTime.Now - t).TotalMilliseconds);
 
964
                        } catch (Exception ex) {
 
965
                                LoggingService.LogError ("Could not load parser database.", ex);
 
966
                        }
 
967
 
 
968
                        Workspace ws = item as Workspace;
 
969
                        if (ws != null) {
 
970
                                ws.DescendantItemAdded += descendantItemAddedHandler;
 
971
                                ws.DescendantItemRemoved += descendantItemRemovedHandler;
 
972
                        }
 
973
                        item.ConfigurationsChanged += configurationsChanged;
 
974
                        
 
975
                        WorkspaceItemEventArgs args = new WorkspaceItemEventArgs (item);
 
976
                        NotifyDescendantItemAdded (this, args);
 
977
                        NotifyConfigurationsChanged (null, args);
 
978
                        
 
979
                        if (WorkspaceItemOpened != null)
 
980
                                WorkspaceItemOpened (this, args);
 
981
                        if (Items.Count == 1) {
 
982
                                IdeApp.Workbench.CurrentLayout = "Solution";
 
983
                                if (FirstWorkspaceItemOpened != null)
 
984
                                        FirstWorkspaceItemOpened (this, args);
 
985
                        }
 
986
                }
 
987
                
 
988
                internal void NotifyItemRemoved (WorkspaceItem item)
 
989
                {
 
990
                        if (DispatchService.IsGuiThread)
 
991
                                NotifyItemRemovedGui (item);
 
992
                        else
 
993
                                Gtk.Application.Invoke (delegate {
 
994
                                        NotifyItemRemovedGui (item);
 
995
                                });
 
996
                }
 
997
                
 
998
                internal void NotifyItemRemovedGui (WorkspaceItem item)
 
999
                {
 
1000
                        Workspace ws = item as Workspace;
 
1001
                        if (ws != null) {
 
1002
                                ws.DescendantItemAdded -= descendantItemAddedHandler;
 
1003
                                ws.DescendantItemRemoved -= descendantItemRemovedHandler;
 
1004
                        }
 
1005
                        item.ConfigurationsChanged -= configurationsChanged;
 
1006
                        
 
1007
                        if (Items.Count == 0) {
 
1008
                                IdeApp.Workbench.CurrentLayout = "Default";
 
1009
                                if (LastWorkspaceItemClosed != null)
 
1010
                                        LastWorkspaceItemClosed (this, EventArgs.Empty);
 
1011
                        }
 
1012
                        
 
1013
                        WorkspaceItemEventArgs args = new WorkspaceItemEventArgs (item);
 
1014
                        NotifyConfigurationsChanged (null, args);
 
1015
                        
 
1016
                        if (WorkspaceItemClosed != null)
 
1017
                                WorkspaceItemClosed (this, args);
 
1018
                        
 
1019
                        MonoDevelop.Projects.Dom.Parser.ProjectDomService.Unload (item);
 
1020
//                      ParserDatabase.Unload (item);
 
1021
                        
 
1022
                        NotifyDescendantItemRemoved (this, args);
 
1023
                }
 
1024
                
 
1025
                void SubscribeSolution (Solution sol)
 
1026
                {
 
1027
                        sol.FileAddedToProject += fileAddedToProjectHandler;
 
1028
                        sol.FileRemovedFromProject += fileRemovedFromProjectHandler;
 
1029
                        sol.FileRenamedInProject += fileRenamedInProjectHandler;
 
1030
                        sol.FileChangedInProject += fileChangedInProjectHandler;
 
1031
                        sol.FilePropertyChangedInProject += filePropertyChangedInProjectHandler;
 
1032
                        sol.ReferenceAddedToProject += referenceAddedToProjectHandler;
 
1033
                        sol.ReferenceRemovedFromProject += referenceRemovedFromProjectHandler;
 
1034
                        sol.SolutionItemAdded += itemAddedToSolutionHandler;
 
1035
                        sol.SolutionItemRemoved += itemRemovedFromSolutionHandler;
 
1036
                }
 
1037
                
 
1038
                void UnsubscribeSolution (Solution solution)
 
1039
                {
 
1040
                        solution.FileAddedToProject -= fileAddedToProjectHandler;
 
1041
                        solution.FileRemovedFromProject -= fileRemovedFromProjectHandler;
 
1042
                        solution.FileRenamedInProject -= fileRenamedInProjectHandler;
 
1043
                        solution.FileChangedInProject -= fileChangedInProjectHandler;
 
1044
                        solution.FilePropertyChangedInProject -= filePropertyChangedInProjectHandler;
 
1045
                        solution.ReferenceAddedToProject -= referenceAddedToProjectHandler;
 
1046
                        solution.ReferenceRemovedFromProject -= referenceRemovedFromProjectHandler;
 
1047
                        solution.SolutionItemAdded -= itemAddedToSolutionHandler;
 
1048
                        solution.SolutionItemRemoved -= itemRemovedFromSolutionHandler;
 
1049
                }
 
1050
                
 
1051
                void NotifyConfigurationsChanged (object s, EventArgs a)
 
1052
                {
 
1053
                        if (ConfigurationsChanged != null)
 
1054
                                ConfigurationsChanged (this, a);
 
1055
                }
 
1056
                
 
1057
                void NotifyFileRemovedFromProject (object sender, ProjectFileEventArgs e)
 
1058
                {
 
1059
                        if (FileRemovedFromProject != null) {
 
1060
                                FileRemovedFromProject(this, e);
 
1061
                        }
 
1062
                }
 
1063
                
 
1064
                void NotifyFileAddedToProject (object sender, ProjectFileEventArgs e)
 
1065
                {
 
1066
                        if (FileAddedToProject != null) {
 
1067
                                FileAddedToProject (this, e);
 
1068
                        }
 
1069
                }
 
1070
 
 
1071
                internal void NotifyFileRenamedInProject (object sender, ProjectFileRenamedEventArgs e)
 
1072
                {
 
1073
                        if (FileRenamedInProject != null) {
 
1074
                                FileRenamedInProject (this, e);
 
1075
                        }
 
1076
                }               
 
1077
                
 
1078
                internal void NotifyFileChangedInProject (object sender, ProjectFileEventArgs e)
 
1079
                {
 
1080
                        if (FileChangedInProject != null) {
 
1081
                                FileChangedInProject (this, e);
 
1082
                        }
 
1083
                }               
 
1084
                
 
1085
                internal void NotifyFilePropertyChangedInProject (object sender, ProjectFileEventArgs e)
 
1086
                {
 
1087
                        if (FilePropertyChangedInProject != null) {
 
1088
                                FilePropertyChangedInProject (this, e);
 
1089
                        }
 
1090
                }               
 
1091
                
 
1092
                internal void NotifyReferenceAddedToProject (object sender, ProjectReferenceEventArgs e)
 
1093
                {
 
1094
                        if (ReferenceAddedToProject != null) {
 
1095
                                ReferenceAddedToProject (this, e);
 
1096
                        }
 
1097
                }
 
1098
                
 
1099
                internal void NotifyReferenceRemovedFromProject (object sender, ProjectReferenceEventArgs e)
 
1100
                {
 
1101
                        if (ReferenceRemovedFromProject != null) {
 
1102
                                ReferenceRemovedFromProject (this, e);
 
1103
                        }
 
1104
                }
 
1105
                
 
1106
                void NotifyItemAddedToSolution (object sender, SolutionItemEventArgs args)
 
1107
                {
 
1108
                        // Delay the notification of this event to ensure that the new project is properly
 
1109
                        // registered in the parser database when it is fired
 
1110
                        
 
1111
                        Gtk.Application.Invoke (delegate {
 
1112
                                if (ItemAddedToSolution != null)
 
1113
                                        ItemAddedToSolution (sender, args);
 
1114
                        });
 
1115
                }
 
1116
                
 
1117
                void NotifyItemRemovedFromSolution (object sender, SolutionItemEventArgs args)
 
1118
                {
 
1119
                        NotifyItemRemovedFromSolutionRec (sender, args.SolutionItem, args.Solution);
 
1120
                }
 
1121
                
 
1122
                void NotifyItemRemovedFromSolutionRec (object sender, SolutionItem e, Solution sol)
 
1123
                {
 
1124
                        if (e == IdeApp.ProjectOperations.CurrentSelectedSolutionItem)
 
1125
                                IdeApp.ProjectOperations.CurrentSelectedSolutionItem = null;
 
1126
                                
 
1127
                        if (e is SolutionFolder) {
 
1128
                                foreach (SolutionItem ce in ((SolutionFolder)e).Items)
 
1129
                                        NotifyItemRemovedFromSolutionRec (sender, ce, sol);
 
1130
                        }
 
1131
                        if (ItemRemovedFromSolution != null)
 
1132
                                ItemRemovedFromSolution (sender, new SolutionItemEventArgs (e, sol));
 
1133
                }
 
1134
                
 
1135
                void NotifyDescendantItemAdded (object s, WorkspaceItemEventArgs args)
 
1136
                {
 
1137
                        // If a top level item has been moved to a child item, remove it from
 
1138
                        // the top
 
1139
                        if (s != this && Items.Contains (args.Item))
 
1140
                                Items.Remove (args.Item);
 
1141
                        foreach (WorkspaceItem item in args.Item.GetAllItems ()) {
 
1142
                                if (item is Solution)
 
1143
                                        SubscribeSolution ((Solution)item);
 
1144
                                OnItemLoaded (item);
 
1145
                        }
 
1146
                }
 
1147
                
 
1148
                void NotifyDescendantItemRemoved (object s, WorkspaceItemEventArgs args)
 
1149
                {
 
1150
                        foreach (WorkspaceItem item in args.Item.GetAllItems ()) {
 
1151
                                OnItemUnloaded (item);
 
1152
                                if (item is Solution)
 
1153
                                        UnsubscribeSolution ((Solution)item);
 
1154
                        }
 
1155
                }
 
1156
                
 
1157
                void OnItemLoaded (WorkspaceItem item)
 
1158
                {
 
1159
                        try {
 
1160
                                if (WorkspaceItemLoaded != null)
 
1161
                                        WorkspaceItemLoaded (this, new WorkspaceItemEventArgs (item));
 
1162
                                if (item is Solution && SolutionLoaded != null)
 
1163
                                        SolutionLoaded (this, new SolutionEventArgs ((Solution)item));
 
1164
                        } catch (Exception ex) {
 
1165
                                LoggingService.LogError ("Error in SolutionOpened event.", ex);
 
1166
                        }
 
1167
                }
 
1168
                
 
1169
                void OnItemUnloaded (WorkspaceItem item)
 
1170
                {
 
1171
                        try {
 
1172
                                if (WorkspaceItemUnloaded != null)
 
1173
                                        WorkspaceItemUnloaded (this, new WorkspaceItemEventArgs (item));
 
1174
                                if (item is Solution && SolutionUnloaded != null)
 
1175
                                        SolutionUnloaded (this, new SolutionEventArgs ((Solution)item));
 
1176
                        } catch (Exception ex) {
 
1177
                                LoggingService.LogError ("Error in SolutionClosed event.", ex);
 
1178
                        }
 
1179
                }
 
1180
 
 
1181
                void CheckFileRemove(object sender, FileEventArgs e)
 
1182
                {
 
1183
                        foreach (Solution sol in GetAllSolutions ())
 
1184
                                sol.RootFolder.RemoveFileFromProjects (e.FileName);
 
1185
                }
 
1186
                
 
1187
                void CheckFileRename(object sender, FileCopyEventArgs e)
 
1188
                {
 
1189
                        foreach (Solution sol in GetAllSolutions ())
 
1190
                                sol.RootFolder.RenameFileInProjects (e.SourceFile, e.TargetFile);
 
1191
                }
 
1192
                
 
1193
#endregion
 
1194
 
 
1195
#region Event declaration
 
1196
                
 
1197
                public event ProjectFileEventHandler FileRemovedFromProject;
 
1198
                public event ProjectFileEventHandler FileAddedToProject;
 
1199
                public event ProjectFileEventHandler FileChangedInProject;
 
1200
                public event ProjectFileEventHandler FilePropertyChangedInProject;
 
1201
                public event ProjectFileRenamedEventHandler FileRenamedInProject;
 
1202
                
 
1203
                public event EventHandler<SolutionEventArgs> SolutionLoaded;
 
1204
                public event EventHandler<SolutionEventArgs> SolutionUnloaded;
 
1205
                public event EventHandler<WorkspaceItemEventArgs> FirstWorkspaceItemOpened;
 
1206
                public event EventHandler LastWorkspaceItemClosed;
 
1207
                public event EventHandler<WorkspaceItemEventArgs> WorkspaceItemLoaded;
 
1208
                public event EventHandler<WorkspaceItemEventArgs> WorkspaceItemUnloaded;
 
1209
                public event EventHandler<WorkspaceItemEventArgs> WorkspaceItemOpened;
 
1210
                public event EventHandler<WorkspaceItemEventArgs> WorkspaceItemClosed;
 
1211
                public event EventHandler<UserPreferencesEventArgs> StoringUserPreferences;
 
1212
                public event EventHandler<UserPreferencesEventArgs> LoadingUserPreferences;
 
1213
                public event EventHandler<ItemUnloadingEventArgs> ItemUnloading;
 
1214
                
 
1215
                public event EventHandler<SolutionEventArgs> CurrentSelectedSolutionChanged;
 
1216
                
 
1217
                public event ProjectReferenceEventHandler ReferenceAddedToProject;
 
1218
                public event ProjectReferenceEventHandler ReferenceRemovedFromProject;
 
1219
                
 
1220
                // Fired just before an entry is added to a combine
 
1221
                public event SolutionItemEventHandler ItemAddedToSolution;
 
1222
                public event SolutionItemEventHandler ItemRemovedFromSolution;
 
1223
 
 
1224
                public event EventHandler ActiveConfigurationChanged;
 
1225
                public event EventHandler ConfigurationsChanged;
 
1226
                
 
1227
                public event EventHandler RuntimesChanged {
 
1228
                        add { Runtime.SystemAssemblyService.RuntimesChanged += value; }
 
1229
                        remove { Runtime.SystemAssemblyService.RuntimesChanged -= value; }
 
1230
                }
 
1231
                
 
1232
                public event EventHandler ActiveRuntimeChanged {
 
1233
                        add { Runtime.SystemAssemblyService.DefaultRuntimeChanged += value; }
 
1234
                        remove { Runtime.SystemAssemblyService.DefaultRuntimeChanged -= value; }
 
1235
                }
 
1236
#endregion
 
1237
        }
 
1238
        
 
1239
        class RootWorkspaceItemCollection: WorkspaceItemCollection
 
1240
        {
 
1241
                RootWorkspace parent;
 
1242
                
 
1243
                public RootWorkspaceItemCollection (RootWorkspace parent)
 
1244
                {
 
1245
                        this.parent = parent;
 
1246
                }
 
1247
                
 
1248
                protected override void ClearItems ()
 
1249
                {
 
1250
                        if (parent != null) {
 
1251
                                List<WorkspaceItem> items = new List<WorkspaceItem> (this);
 
1252
                                foreach (WorkspaceItem it in items)
 
1253
                                        parent.NotifyItemRemoved (it);
 
1254
                        }
 
1255
                        else
 
1256
                                base.ClearItems ();
 
1257
                }
 
1258
                
 
1259
                protected override void InsertItem (int index, WorkspaceItem item)
 
1260
                {
 
1261
                        base.InsertItem (index, item);
 
1262
                        if (parent != null)
 
1263
                                parent.NotifyItemAdded (item);
 
1264
                }
 
1265
                
 
1266
                protected override void RemoveItem (int index)
 
1267
                {
 
1268
                        WorkspaceItem item = this [index];
 
1269
                        base.RemoveItem (index);
 
1270
                        if (parent != null)
 
1271
                                parent.NotifyItemRemoved (item);
 
1272
                }
 
1273
                
 
1274
                protected override void SetItem (int index, WorkspaceItem item)
 
1275
                {
 
1276
                        WorkspaceItem oldItem = this [index];
 
1277
                        base.SetItem (index, item);
 
1278
                        if (parent != null) {
 
1279
                                parent.NotifyItemRemoved (oldItem);
 
1280
                                parent.NotifyItemAdded (item);
 
1281
                        }
 
1282
                }
 
1283
        }
 
1284
        
 
1285
        public class UserPreferencesEventArgs: WorkspaceItemEventArgs
 
1286
        {
 
1287
                PropertyBag properties;
 
1288
                
 
1289
                public PropertyBag Properties {
 
1290
                        get {
 
1291
                                return properties;
 
1292
                        }
 
1293
                }
 
1294
                
 
1295
                public UserPreferencesEventArgs (WorkspaceItem item, PropertyBag properties): base (item)
 
1296
                {
 
1297
                        this.properties = properties;
 
1298
                }
 
1299
        }
 
1300
        
 
1301
        [DataItem ("Workspace")]
 
1302
        class WorkspaceUserData
 
1303
        {
 
1304
                [ItemProperty]
 
1305
                public string ActiveConfiguration;
 
1306
                [ItemProperty]
 
1307
                public string ActiveRuntime;
 
1308
        }
 
1309
        
 
1310
        public class ItemUnloadingEventArgs: EventArgs
 
1311
        {
 
1312
                IBuildTarget item;
 
1313
                
 
1314
                public bool Cancel { get; set; }
 
1315
                
 
1316
                public IBuildTarget Item {
 
1317
                        get {
 
1318
                                return item;
 
1319
                        }
 
1320
                }
 
1321
                
 
1322
                public ItemUnloadingEventArgs (IBuildTarget item)
 
1323
                {
 
1324
                        this.item = item;
 
1325
                }
 
1326
        }
 
1327
}
 
1328
 
 
1329
namespace Mono.Profiler {
 
1330
        public class RuntimeControls {
 
1331
                
 
1332
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
 
1333
                public static extern void TakeHeapSnapshot ();
 
1334
                
 
1335
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
 
1336
                public static extern void EnableProfiler ();
 
1337
                
 
1338
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
 
1339
                public static extern void DisableProfiler ();
 
1340
        }
 
1341
}