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

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.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:
25
25
 
26
26
using System;
27
27
using System.IO;
28
 
using System.Collections;
29
28
using System.Collections.ObjectModel;
30
29
using System.Collections.Generic;
31
30
using System.Drawing;
32
31
using System.Diagnostics;
33
 
using System.CodeDom.Compiler;
34
 
using System.ComponentModel;
35
 
using System.Xml;
 
32
using System.Linq;
36
33
 
37
34
using MonoDevelop.Projects;
38
35
using Mono.Addins;
39
36
using MonoDevelop.Core;
40
 
using MonoDevelop.Core.Gui;
41
 
using MonoDevelop.Core.Gui.Components;
42
 
using MonoDevelop.Ide.Gui.Content;
43
 
using MonoDevelop.Core.Gui.Dialogs;
44
 
using MonoDevelop.Ide.Commands;
 
37
using MonoDevelop.Ide.Gui.Dialogs;
45
38
using MonoDevelop.Ide.Codons;
46
 
using MonoDevelop.Ide.Gui.Dialogs;
47
 
using MonoDevelop.Projects.Dom.Parser;
48
39
using MonoDevelop.Components.Commands;
 
40
using MonoDevelop.Components.Docking;
49
41
 
50
42
using GLib;
 
43
using MonoDevelop.Components.DockToolbars;
 
44
using Gtk;
 
45
using MonoDevelop.Components;
 
46
using MonoDevelop.Ide.Extensions;
51
47
 
52
48
namespace MonoDevelop.Ide.Gui
53
49
{
54
50
        /// <summary>
55
51
        /// This is the a Workspace with a multiple document interface.
56
52
        /// </summary>
57
 
        internal class DefaultWorkbench : Gtk.Window, IWorkbench
 
53
        internal class DefaultWorkbench : WorkbenchWindow
58
54
        {
59
55
                readonly static string mainMenuPath    = "/MonoDevelop/Ide/MainMenu";
60
56
                readonly static string viewContentPath = "/MonoDevelop/Ide/Pads";
61
57
                readonly static string toolbarsPath    = "/MonoDevelop/Ide/Toolbar";
 
58
                readonly static string stockLayoutsPath    = "/MonoDevelop/Ide/WorkbenchLayouts";
 
59
                
 
60
                static string configFile = System.IO.Path.Combine (PropertyService.ConfigPath, "EditingLayout2.xml");
 
61
                const string fullViewModeTag = "[FullViewMode]";
 
62
                const int MAX_LASTACTIVEWINDOWS = 10;
 
63
                
 
64
                // list of layout names for the current context, without the context prefix
 
65
                List<string> layouts = new List<string> ();
62
66
                
63
67
                List<PadCodon> padContentCollection      = new List<PadCodon> ();
64
68
                List<IViewContent> viewContentCollection = new List<IViewContent> ();
65
 
                
66
 
                bool closeAll = false;
 
69
                Dictionary<PadCodon, IPadWindow> padWindows = new Dictionary<PadCodon, IPadWindow> ();
 
70
                Dictionary<IPadWindow, PadCodon> padCodons = new Dictionary<IPadWindow, PadCodon> ();
 
71
                
 
72
                IWorkbenchWindow lastActive;
 
73
                LinkedList<IWorkbenchWindow> lastActiveWindows = new LinkedList<IWorkbenchWindow> ();
 
74
                
 
75
                bool closeAll;
 
76
                bool ignorePageSwitch;
67
77
 
68
78
                bool fullscreen;
69
79
                Rectangle normalBounds = new Rectangle(0, 0, 640, 480);
70
80
                
71
 
                private IWorkbenchLayout layout = null;
72
 
 
73
81
                internal static GType gtype;
74
82
                
75
 
                Gtk.MenuBar topMenu = null;
76
 
                private Gtk.Toolbar[] toolbars = null;
77
 
                MonoDevelopStatusBar statusBar = new MonoDevelop.Ide.MonoDevelopStatusBar ();
78
 
                
79
 
                public MonoDevelopStatusBar StatusBar {
80
 
                        get {
81
 
                                return statusBar;
82
 
                        }
83
 
                }
 
83
                Gtk.Container rootWidget;
 
84
                DockToolbarFrame toolbarFrame;
 
85
                DockFrame dock;
 
86
                SdiDragNotebook tabControl;
 
87
                Gtk.MenuBar topMenu;
 
88
                Gtk.Toolbar[] toolbars;
 
89
                MonoDevelopStatusBar statusBar;
 
90
                Gtk.VBox fullViewVBox;
 
91
                DockItem documentDockItem;
84
92
                
85
93
                enum TargetList {
86
94
                        UriList = 100
90
98
                        new Gtk.TargetEntry ("text/uri-list", 0, (uint)TargetList.UriList)
91
99
                };
92
100
                
 
101
#if DUMMY_STRINGS_FOR_TRANSLATION_DO_NOT_COMPILE
 
102
                private void DoNotCompile ()
 
103
                {
 
104
                        //The default layout, translated indirectly because it's used as an ID
 
105
                        GettextCatalog.GetString ("Default");
 
106
                }
 
107
#endif
 
108
                
 
109
                public event EventHandler ActiveWorkbenchWindowChanged;
 
110
                
 
111
                public MonoDevelopStatusBar StatusBar {
 
112
                        get {
 
113
                                if (statusBar == null)
 
114
                                        statusBar = new MonoDevelop.Ide.MonoDevelopStatusBar ();
 
115
                                return statusBar;
 
116
                        }
 
117
                }
 
118
                
93
119
                public Gtk.MenuBar TopMenu {
94
120
                        get { return topMenu; }
95
121
                }
96
122
                
 
123
                public IWorkbenchWindow ActiveWorkbenchWindow {
 
124
                        get {
 
125
                                if (tabControl == null || tabControl.CurrentPage < 0 || tabControl.CurrentPage >= tabControl.NPages)  {
 
126
                                        return null;
 
127
                                }
 
128
                                return (IWorkbenchWindow) tabControl.CurrentPageWidget;
 
129
                        }
 
130
                }
 
131
                
 
132
                public DockFrame DockFrame {
 
133
                        get { return dock; }
 
134
                }
 
135
                
97
136
                public bool FullScreen {
98
137
                        get {
99
138
                                return fullscreen;
107
146
                                }
108
147
                        }
109
148
                }
 
149
 
 
150
                public IList<string> Layouts {
 
151
                        get {
 
152
                                return layouts;
 
153
                        }
 
154
                }
110
155
                
111
 
                /*
112
 
                public string Title {
 
156
                public string CurrentLayout {
113
157
                        get {
114
 
                                return Text;
 
158
                                if (dock != null && dock.CurrentLayout != null) {
 
159
                                        string s = dock.CurrentLayout;
 
160
                                        s = s.Substring (s.IndexOf (".") + 1);
 
161
                                        if (s.EndsWith (fullViewModeTag))
 
162
                                                return s.Substring (0, s.Length - fullViewModeTag.Length);
 
163
                                        return s;
 
164
                                }
 
165
                                else
 
166
                                        return "";
115
167
                        }
116
168
                        set {
117
 
                                Text = value;
118
 
                        }
119
 
                }*/
120
 
                
121
 
                EventHandler windowChangeEventHandler;
122
 
                
123
 
                public IWorkbenchLayout WorkbenchLayout {
124
 
                        get {
125
 
                                //FIXME: i added this, we need to fix this shit
126
 
                                //                              if (layout == null) {
127
 
                                //      layout = new SdiWorkbenchLayout ();
128
 
                                //      layout.Attach(this);
129
 
                                //}
130
 
                                return layout;
131
 
                        }
132
 
                }
133
 
                
134
 
                public ReadOnlyCollection<PadCodon> PadContentCollection {
135
 
                        get {
136
 
                                Debug.Assert(padContentCollection != null);
137
 
                                return padContentCollection.AsReadOnly ();
138
 
                        }
139
 
                }
140
 
                
141
 
                public List<PadCodon> ActivePadContentCollection {
142
 
                        get {
143
 
                                if (layout == null)
144
 
                                        return new List<PadCodon> ();
145
 
                                return layout.PadContentCollection;
146
 
                        }
147
 
                }
148
 
                
149
 
                public ReadOnlyCollection<IViewContent> ViewContentCollection {
150
 
                        get {
151
 
                                Debug.Assert(viewContentCollection != null);
152
 
                                return viewContentCollection.AsReadOnly ();
 
169
                                // Leave dragging mode, to avoid problems due to widget relocating
 
170
                                tabControl.LeaveDragMode (0);
 
171
                                
 
172
                                var oldLayout = dock.CurrentLayout;
 
173
                                
 
174
                                InitializeLayout (value);
 
175
                                toolbarFrame.CurrentLayout = dock.CurrentLayout = value;
 
176
                                
 
177
                                DestroyFullViewLayouts (oldLayout);
 
178
                                
 
179
                                // persist the selected layout
 
180
                                PropertyService.Set ("MonoDevelop.Core.Gui.CurrentWorkbenchLayout", value);
 
181
                        }
 
182
                }
 
183
                
 
184
                public void DeleteLayout (string name)
 
185
                {
 
186
                        string layout = name;
 
187
                        layouts.Remove (name);
 
188
                        dock.DeleteLayout (layout);
 
189
                }
 
190
                
 
191
                public List<PadCodon> PadContentCollection {
 
192
                        get {
 
193
                                return padContentCollection;
153
194
                        }
154
195
                }
155
196
                
160
201
                        }
161
202
                }
162
203
                
163
 
                public IWorkbenchWindow ActiveWorkbenchWindow {
164
 
                        get {
165
 
                                if (layout == null) {
166
 
                                        return null;
167
 
                                }
168
 
                                return layout.ActiveWorkbenchwindow;
169
 
                        }
170
 
                }
171
 
 
172
 
                public DefaultWorkbench() : base (Gtk.WindowType.Toplevel)
 
204
                public DefaultWorkbench()
173
205
                {
174
206
                        Title = "MonoDevelop";
175
207
                        LoggingService.LogInfo ("Creating DefaultWorkbench");
176
208
                        
177
 
                        windowChangeEventHandler = new EventHandler(OnActiveWindowChanged);
178
 
 
179
209
                        WidthRequest = normalBounds.Width;
180
210
                        HeightRequest = normalBounds.Height;
181
211
 
185
215
                                Gtk.Window.DefaultIconName = "monodevelop";
186
216
                        else
187
217
                                this.IconList = new Gdk.Pixbuf[] {
188
 
                                        ImageService.GetPixbuf (Stock.MonoDevelop, Gtk.IconSize.Menu),
189
 
                                        ImageService.GetPixbuf (Stock.MonoDevelop, Gtk.IconSize.Button),
190
 
                                        ImageService.GetPixbuf (Stock.MonoDevelop, Gtk.IconSize.Dnd),
191
 
                                        ImageService.GetPixbuf (Stock.MonoDevelop, Gtk.IconSize.Dialog)
 
218
                                        ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.MonoDevelop, Gtk.IconSize.Menu),
 
219
                                        ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.MonoDevelop, Gtk.IconSize.Button),
 
220
                                        ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.MonoDevelop, Gtk.IconSize.Dnd),
 
221
                                        ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.MonoDevelop, Gtk.IconSize.Dialog)
192
222
                                };
193
223
 
194
224
                        //this.WindowPosition = Gtk.WindowPosition.None;
233
263
//                      TopMenu.Selected   += new CommandHandler(OnTopMenuSelected);
234
264
//                      TopMenu.Deselected += new CommandHandler(OnTopMenuDeselected);
235
265
                        
236
 
                        if (!DesktopService.SetGlobalMenu (MonoDevelop.Ide.Gui.IdeApp.CommandService, mainMenuPath))
 
266
                        if (!DesktopService.SetGlobalMenu (IdeApp.CommandService, mainMenuPath))
237
267
                                topMenu = IdeApp.CommandService.CreateMenuBar (mainMenuPath);
238
268
                        
239
269
                        toolbars = IdeApp.CommandService.CreateToolbarSet (toolbarsPath);
252
282
                
253
283
                void OnExtensionChanged (object s, ExtensionEventArgs args)
254
284
                {
255
 
                        bool changed = false;
256
 
                        
257
285
                        if (args.PathChanged (mainMenuPath)) {
258
 
                                if (DesktopService.SetGlobalMenu (MonoDevelop.Ide.Gui.IdeApp.CommandService, mainMenuPath))
 
286
                                if (DesktopService.SetGlobalMenu (IdeApp.CommandService, mainMenuPath))
259
287
                                        return;
260
288
                                
 
289
                                UninstallMenuBar ();
261
290
                                topMenu = IdeApp.CommandService.CreateMenuBar (mainMenuPath);
262
 
                                changed = true;
 
291
                                InstallMenuBar ();
263
292
                        }
264
293
                        
265
294
                        if (args.PathChanged (toolbarsPath)) {
266
295
                                toolbars = IdeApp.CommandService.CreateToolbarSet (toolbarsPath);
267
 
                                foreach (Gtk.Toolbar t in toolbars)
268
 
                                        t.ToolbarStyle = Gtk.ToolbarStyle.Icons;
269
 
                                changed = true;
270
 
                        }
 
296
                                string cl = toolbarFrame.CurrentLayout;
 
297
                                DockToolbarFrameStatus mem = toolbarFrame.GetStatus ();
 
298
                                toolbarFrame.ClearToolbars ();
 
299
                                foreach (DockToolbar tb in toolbars) {
 
300
                                        tb.ToolbarStyle = Gtk.ToolbarStyle.Icons;
 
301
                                        tb.ShowAll ();
 
302
                                        toolbarFrame.AddBar (tb);
 
303
                                }
 
304
                                toolbarFrame.SetStatus (mem);
 
305
                                toolbarFrame.CurrentLayout = cl;
 
306
                        }
 
307
                }
 
308
                
 
309
                void InstallMenuBar ()
 
310
                {
 
311
                        if (topMenu != null) {
 
312
                                ((VBox)rootWidget).PackStart (topMenu, false, false, 0);
 
313
                                ((Gtk.Box.BoxChild) rootWidget [topMenu]).Position = 0;
 
314
                                topMenu.ShowAll ();
 
315
                        }
 
316
                }
 
317
                                
 
318
                void UninstallMenuBar ()
 
319
                {
 
320
                        if (topMenu == null)
 
321
                                return;
271
322
                        
272
 
                        if (changed && layout != null)
273
 
                                layout.RedrawAllComponents();
 
323
                        rootWidget.Remove (topMenu);
 
324
                        topMenu = null;
274
325
                }
275
 
                                
 
326
                
276
327
                public void CloseContent (IViewContent content)
277
328
                {
278
329
                        if (viewContentCollection.Contains(content)) {
287
338
                                List<IViewContent> fullList = new List<IViewContent>(viewContentCollection);
288
339
                                foreach (IViewContent content in fullList) {
289
340
                                        IWorkbenchWindow window = content.WorkbenchWindow;
290
 
                                        window.CloseWindow(true, true, 0);
 
341
                                        if (window != null)
 
342
                                                window.CloseWindow(true, true, 0);
291
343
                                }
292
344
                        } finally {
293
345
                                closeAll = false;
294
 
                                OnActiveWindowChanged(null, null);
 
346
                                OnActiveWindowChanged (null, null);
295
347
                        }
296
348
                }
297
349
                
298
350
                public virtual void ShowView (IViewContent content, bool bringToFront)
299
351
                {
300
 
                        Debug.Assert(layout != null);
301
 
                        viewContentCollection.Add(content);
302
 
                        if (PropertyService.Get("SharpDevelop.LoadDocumentProperties", true) && content is IMementoCapable) {
 
352
                        viewContentCollection.Add (content);
 
353
                        
 
354
                        if (PropertyService.Get ("SharpDevelop.LoadDocumentProperties", true) && content is IMementoCapable) {
303
355
                                try {
304
356
                                        Properties memento = GetStoredMemento(content);
305
357
                                        if (memento != null) {
310
362
                                }
311
363
                        }
312
364
                        
313
 
                        layout.ShowView(content);
 
365
                        Gtk.Image mimeimage = null;
 
366
                        
 
367
                        if (content.StockIconId != null ) {
 
368
                                mimeimage = new Gtk.Image ((IconId) content.StockIconId, IconSize.Menu );
 
369
                        }
 
370
                        else if (content.IsUntitled && content.UntitledName == null) {
 
371
                                mimeimage = new Gtk.Image (DesktopService.GetPixbufForType ("gnome-fs-regular", Gtk.IconSize.Menu));
 
372
                        } else {
 
373
                                mimeimage = new Gtk.Image (DesktopService.GetPixbufForFile (content.ContentName ?? content.UntitledName, Gtk.IconSize.Menu));
 
374
                        }                       
 
375
 
 
376
                        TabLabel tabLabel = new TabLabel (new Label (), mimeimage != null ? mimeimage : new Gtk.Image (""));
 
377
                        tabLabel.CloseClicked += new EventHandler (closeClicked);                       
 
378
                        tabLabel.ClearFlag (WidgetFlags.CanFocus);
 
379
                        SdiWorkspaceWindow sdiWorkspaceWindow = new SdiWorkspaceWindow (this, content, tabControl, tabLabel);
 
380
                        sdiWorkspaceWindow.TitleChanged += delegate { SetWorkbenchTitle (); };
 
381
                        sdiWorkspaceWindow.Closed += CloseWindowEvent;
 
382
                        tabControl.InsertPage (sdiWorkspaceWindow, tabLabel, -1);
 
383
                        tabLabel.Show ();
314
384
                        
315
385
                        if (bringToFront)
316
386
                                content.WorkbenchWindow.SelectWindow();
320
390
                {
321
391
                        if (node is PadCodon) {
322
392
                                PadCodon pad = (PadCodon) node;
323
 
                                ShowPad (pad);
324
 
                                if (layout != null) {
325
 
                                        IPadWindow win = WorkbenchLayout.GetPadWindow (pad);
326
 
                                        if (pad.Label != null)
327
 
                                                win.Title = pad.Label;
328
 
                                        if (pad.Icon != null)
329
 
                                                win.Icon = pad.Icon;
330
 
                                }
 
393
                                RegisterPad (pad);
331
394
                        }
332
395
                        else if (node is CategoryNode) {
333
396
                                foreach (ExtensionNode cn in node.ChildNodes)
355
418
                        AddPad (content, false);
356
419
                }
357
420
                
358
 
                void AddPad (PadCodon content, bool show)
 
421
                void RegisterPad (PadCodon content)
359
422
                {
360
 
                        if (padContentCollection.Contains (content))
361
 
                                return;
362
 
 
363
423
                        if (content.HasId) {
364
424
                                ActionCommand cmd = new ActionCommand ("Pad|" + content.PadId, GettextCatalog.GetString (content.Label), null);
365
425
                                cmd.DefaultHandler = new PadActivationHandler (this, content);
368
428
                                IdeApp.CommandService.RegisterCommand (cmd);
369
429
                        }
370
430
                        padContentCollection.Add (content);
 
431
                }
 
432
                
 
433
                void AddPad (PadCodon content, bool show)
 
434
                {
 
435
                        DockItem item = GetDockItem (content);
 
436
                        if (padContentCollection.Contains (content)) {
 
437
                                if (show && item != null)
 
438
                                        item.Visible = true;
 
439
                                return;
 
440
                        }
 
441
 
 
442
                        RegisterPad (content);
371
443
                        
372
 
                        if (layout != null) {
 
444
                        if (item != null) {
373
445
                                if (show)
374
 
                                        layout.ShowPad (content);
375
 
                                else
376
 
                                        layout.AddPad (content);
 
446
                                        item.Visible = true;
 
447
                        } else {
 
448
                                AddPad (content, content.DefaultPlacement, content.DefaultStatus);
377
449
                        }
378
450
                }
379
451
                
384
456
                                if (cmd != null)
385
457
                                        IdeApp.CommandService.UnregisterCommand (cmd);
386
458
                        }
 
459
                        DockItem item = GetDockItem (codon);
387
460
                        padContentCollection.Remove (codon);
 
461
                        PadWindow win = (PadWindow) padWindows [codon];
 
462
                        win.NotifyDestroyed ();
 
463
                        if (item != null)
 
464
                                dock.RemoveItem (item);
 
465
                        padWindows.Remove (codon);
 
466
                        padCodons.Remove (win);
388
467
                        
389
 
                        if (layout != null)
390
 
                                layout.RemovePad (codon);
 
468
                        Counters.PadsLoaded--;
391
469
                }
392
470
                
393
471
                public void BringToFront (PadCodon content)
397
475
                
398
476
                public virtual void BringToFront (PadCodon content, bool giveFocus)
399
477
                {
400
 
                        if (!layout.IsVisible (content))
401
 
                                layout.ShowPad (content);
 
478
                        if (!IsVisible (content))
 
479
                                ShowPad (content);
402
480
 
403
 
                        layout.ActivatePad (content, giveFocus);
 
481
                        ActivatePad (content, giveFocus);
404
482
                }
405
483
                
406
 
                public void RedrawAllComponents()
 
484
                void SetWorkbenchTitle ()
407
485
                {
408
 
                        foreach (IViewContent content in viewContentCollection) {
409
 
                                content.RedrawContent();
410
 
                        }
411
 
                        foreach (PadCodon content in padContentCollection) {
412
 
                                if (content.Initialized) {
413
 
                                        content.PadContent.RedrawContent();
 
486
                        try {
 
487
                                IWorkbenchWindow window = ActiveWorkbenchWindow;
 
488
                                if (window != null) {
 
489
                                        if (window.ViewContent.IsUntitled) {
 
490
                                                SetDefaultTitle ();
 
491
                                        } else {
 
492
                                                string post = String.Empty;
 
493
                                                if (window.ViewContent.IsDirty) {
 
494
                                                        post = "*";
 
495
                                                }
 
496
                                                if (window.ViewContent.Project != null) {
 
497
                                                        Title = window.ViewContent.Project.Name + " - " + window.ViewContent.PathRelativeToProject + post + " - MonoDevelop";
 
498
                                                } else {
 
499
                                                        Title = window.ViewContent.ContentName + post + " - MonoDevelop";
 
500
                                                }
 
501
                                        }
 
502
                                } else {
 
503
                                        SetDefaultTitle ();
 
504
                                        if (IsInFullViewMode)
 
505
                                                this.ToggleFullViewMode ();
414
506
                                }
415
 
                        }
416
 
                        layout.RedrawAllComponents();
417
 
                        //statusBarManager.RedrawStatusbar();
 
507
                        } catch (Exception) {
 
508
                                SetDefaultTitle ();
 
509
                        }
 
510
                }
 
511
                
 
512
                void SetDefaultTitle ()
 
513
                {
 
514
                        if (IdeApp.ProjectOperations.CurrentSelectedProject != null) {
 
515
                                Title = IdeApp.ProjectOperations.CurrentSelectedProject.Name + " - MonoDevelop";
 
516
                        } else {
 
517
                                Title = "MonoDevelop";
 
518
                        }
418
519
                }
419
520
                
420
521
                public Properties GetStoredMemento(IViewContent content)
447
548
                                }
448
549
                                memento.WindowState = GdkWindow.State;
449
550
                                memento.FullScreen  = fullscreen;
450
 
                                if (layout != null)
451
 
                                        memento.LayoutMemento = (Properties)layout.Memento;
 
551
                                memento.ToolbarStatus = toolbarFrame.GetStatus ();
452
552
                                return memento.ToProperties ();
453
553
                        }
454
554
                        set {
465
565
                                        }
466
566
                                        //GdkWindow.State = memento.WindowState;
467
567
                                        FullScreen = memento.FullScreen;
468
 
        
469
 
                                        if (layout != null && memento.LayoutMemento != null)
470
 
                                                layout.Memento = memento.LayoutMemento;
 
568
                                        toolbarFrame.SetStatus (memento.ToolbarStatus);
471
569
                                }
472
570
                                Decorated = true;
473
571
                        }
476
574
                void CheckRemovedFile(object sender, FileEventArgs e)
477
575
                {
478
576
                        if (e.IsDirectory) {
479
 
                                IViewContent[] views = new IViewContent [ViewContentCollection.Count];
480
 
                                ViewContentCollection.CopyTo (views, 0);
 
577
                                IViewContent[] views = new IViewContent [viewContentCollection.Count];
 
578
                                viewContentCollection.CopyTo (views, 0);
481
579
                                foreach (IViewContent content in views) {
482
580
                                        if (content.ContentName.StartsWith(e.FileName)) {
483
581
                                                content.WorkbenchWindow.CloseWindow(true, true, 0);
484
582
                                        }
485
583
                                }
486
584
                        } else {
487
 
                                foreach (IViewContent content in ViewContentCollection) {
 
585
                                foreach (IViewContent content in viewContentCollection) {
488
586
                                        if (content.ContentName != null &&
489
587
                                            content.ContentName == e.FileName) {
490
588
                                                content.WorkbenchWindow.CloseWindow(true, true, 0);
497
595
                void CheckRenamedFile(object sender, FileCopyEventArgs e)
498
596
                {
499
597
                        if (e.IsDirectory) {
500
 
                                foreach (IViewContent content in ViewContentCollection) {
 
598
                                foreach (IViewContent content in viewContentCollection) {
501
599
                                        if (content.ContentName != null && content.ContentName.StartsWith(e.SourceFile)) {
502
600
                                                content.ContentName = e.TargetFile + content.ContentName.Substring(e.SourceFile.Length);
503
601
                                        }
504
602
                                }
505
603
                        } else {
506
 
                                foreach (IViewContent content in ViewContentCollection) {
 
604
                                foreach (IViewContent content in viewContentCollection) {
507
605
                                        if (content.ContentName != null &&
508
606
                                            content.ContentName == e.SourceFile) {
509
607
                                                content.ContentName = e.TargetFile;
522
620
                        }
523
621
                }
524
622
                
525
 
                protected /*override*/ void OnClosed(EventArgs e)
 
623
                protected void OnClosed(EventArgs e)
526
624
                {
527
 
                        layout.Detach();
 
625
                        //don't allow the "full view" layouts to persist - they are always derived from the "normal" layout
 
626
                        foreach (var fv in dock.Layouts)
 
627
                                if (fv.EndsWith (fullViewModeTag))
 
628
                                        dock.DeleteLayout (fv);
 
629
                        
 
630
                        dock.SaveLayouts (configFile);
 
631
                        UninstallMenuBar ();
 
632
                        Remove (rootWidget);
 
633
                        
528
634
                        foreach (PadCodon content in PadContentCollection) {
529
 
                                if (content.Initialized) {
 
635
                                if (content.Initialized)
530
636
                                        content.PadContent.Dispose();
531
 
                                }
532
637
                        }
533
638
                }
534
639
                
538
643
                                return false;
539
644
 
540
645
                        IdeApp.Workspace.SavePreferences ();
541
 
                        IdeApp.CommandService.Dispose ();
542
646
 
543
647
                        bool showDirtyDialog = false;
544
648
 
545
 
                        foreach (IViewContent content in ViewContentCollection)
 
649
                        foreach (IViewContent content in viewContentCollection)
546
650
                        {
547
651
                                if (content.IsDirty) {
548
652
                                        showDirtyDialog = true;
553
657
                        if (showDirtyDialog) {
554
658
                                DirtyFilesDialog dlg = new DirtyFilesDialog ();
555
659
                                dlg.Modal = true;
556
 
                                dlg.TransientFor = this;
557
 
                                int response = dlg.Run ();
558
 
                                if (response != (int)Gtk.ResponseType.Ok)
 
660
                                if (MessageService.ShowCustomDialog (dlg, this) != (int)Gtk.ResponseType.Ok)
559
661
                                        return false;
560
662
                        }
561
663
                        
 
664
                        if (!IdeApp.Workspace.Close (false, false))
 
665
                                return false;
 
666
                        
562
667
                        CloseAllViews ();
563
668
                        
564
 
                        IdeApp.Workspace.Close (false);
565
669
                        PropertyService.Set ("SharpDevelop.Workbench.WorkbenchMemento", this.Memento);
566
670
                        IdeApp.OnExited ();
567
671
                        OnClosed (null);
 
672
                        
 
673
                        IdeApp.CommandService.Dispose ();
 
674
                        
568
675
                        return true;
569
676
                }
570
677
                
571
678
                void SetProjectTitle(object sender, ProjectEventArgs e)
572
679
                {
573
 
                        layout.SetWorkbenchTitle ();
 
680
                        SetWorkbenchTitle ();
574
681
                }
575
682
                
576
 
                void OnActiveWindowChanged(object sender, EventArgs e)
 
683
                void OnActiveWindowChanged (object sender, EventArgs e)
577
684
                {
 
685
                        if (ignorePageSwitch)
 
686
                                return;
 
687
                        
 
688
                        if (lastActive == ActiveWorkbenchWindow)
 
689
                                return;
 
690
                        
 
691
                        if (lastActiveWindows.Count > MAX_LASTACTIVEWINDOWS)
 
692
                                lastActiveWindows.RemoveFirst ();
 
693
                        lastActiveWindows.AddLast (lastActive);
 
694
                        lastActive = ActiveWorkbenchWindow;
 
695
                        SetWorkbenchTitle ();
 
696
                        
578
697
                        if (!closeAll && ActiveWorkbenchWindowChanged != null) {
579
698
                                ActiveWorkbenchWindowChanged(this, e);
580
699
                        }
604
723
                        return null;
605
724
                }
606
725
                
607
 
                public void InitializeLayout (IWorkbenchLayout workbenchLayout)
 
726
                public void InitializeLayout ()
608
727
                {
 
728
                        AddinManager.AddExtensionNodeHandler (stockLayoutsPath, OnLayoutsExtensionChanged);
 
729
                        
609
730
                        ExtensionNodeList padCodons = AddinManager.GetExtensionNodes (viewContentPath);
610
 
                        
611
 
                        foreach (ExtensionNode node in padCodons)
612
 
                                ShowPadNode (node);
613
 
                        
614
 
                        layout = workbenchLayout;
615
 
                        layout.Attach(this);
616
 
                        layout.ActiveWorkbenchWindowChanged += windowChangeEventHandler;
617
 
                        
618
 
                        foreach (ExtensionNode node in padCodons)
619
 
                                ShowPadNode (node);
620
 
 
621
 
                        RedrawAllComponents ();
 
731
                        foreach (ExtensionNode node in padCodons)
 
732
                                ShowPadNode (node);
 
733
                        
 
734
                        CreateComponents ();
622
735
                        
623
736
                        // Subscribe to changes in the extension
624
737
                        initializing = true;
626
739
                        initializing = false;
627
740
                }
628
741
                
 
742
                void CreateComponents ()
 
743
                {
 
744
                        fullViewVBox = new VBox (false, 0);
 
745
                        rootWidget = fullViewVBox;
 
746
                        
 
747
                        InstallMenuBar ();
 
748
                        
 
749
                        toolbarFrame = new CommandFrame (IdeApp.CommandService);
 
750
                        fullViewVBox.PackStart (toolbarFrame, true, true, 0);
 
751
                        
 
752
                        foreach (DockToolbar t in toolbars)
 
753
                                toolbarFrame.AddBar (t);
 
754
                        
 
755
                        // Create the docking widget and add it to the window.
 
756
                        dock = new DockFrame ();
 
757
                        
 
758
                        dock.CompactGuiLevel = ((int)IdeApp.Preferences.WorkbenchCompactness) + 1;
 
759
                        IdeApp.Preferences.WorkbenchCompactnessChanged += delegate {
 
760
                                dock.CompactGuiLevel = ((int)IdeApp.Preferences.WorkbenchCompactness) + 1;
 
761
                        };
 
762
                        
 
763
                        /* Side bar is experimental. Disabled for now
 
764
                        HBox hbox = new HBox ();
 
765
                        VBox sideBox = new VBox ();
 
766
                        sideBox.PackStart (new SideBar (workbench, Orientation.Vertical), false, false, 0);
 
767
                        hbox.PackStart (sideBox, false, false, 0);
 
768
                        hbox.ShowAll ();
 
769
                        sideBox.NoShowAll = true;
 
770
                        hbox.PackStart (dock, true, true, 0);
 
771
                        DockBar bar = dock.ExtractDockBar (PositionType.Left);
 
772
                        bar.AlwaysVisible = true;
 
773
                        sideBox.PackStart (bar, true, true, 0);
 
774
                        toolbarFrame.AddContent (hbox);
 
775
                        */
 
776
 
 
777
                        toolbarFrame.AddContent (dock);
 
778
                        
 
779
                        // Create the notebook for the various documents.
 
780
                        tabControl = new SdiDragNotebook (dock.ShadedContainer);
 
781
                        tabControl.Scrollable = true;
 
782
                        tabControl.SwitchPage += OnActiveWindowChanged;
 
783
                        tabControl.PageAdded += delegate { OnActiveWindowChanged (null, null); };
 
784
                        tabControl.PageRemoved += delegate { OnActiveWindowChanged (null, null); };
 
785
                
 
786
                        tabControl.ButtonPressEvent += delegate(object sender, ButtonPressEventArgs e) {
 
787
                                int tab = tabControl.FindTabAtPosition (e.Event.XRoot, e.Event.YRoot);
 
788
                                if (tab < 0)
 
789
                                        return;
 
790
                                tabControl.CurrentPage = tab;
 
791
                                if (e.Event.Type == Gdk.EventType.TwoButtonPress)
 
792
                                        ToggleFullViewMode ();
 
793
                        };
 
794
                        
 
795
                        this.tabControl.PopupMenu += delegate {
 
796
                                ShowPopup ();
 
797
                        };
 
798
                        this.tabControl.ButtonReleaseEvent += delegate (object sender, Gtk.ButtonReleaseEventArgs e) {
 
799
                                int tab = tabControl.FindTabAtPosition (e.Event.XRoot, e.Event.YRoot);
 
800
                                if (tab < 0)
 
801
                                        return;
 
802
                                if (e.Event.Button == 3)
 
803
                                        ShowPopup ();
 
804
                        };
 
805
                        
 
806
                        tabControl.TabsReordered += new TabsReorderedHandler (OnTabsReordered);
 
807
 
 
808
                        // The main document area
 
809
                        documentDockItem = dock.AddItem ("Documents");
 
810
                        documentDockItem.Behavior = DockItemBehavior.Locked;
 
811
                        documentDockItem.Expand = true;
 
812
                        documentDockItem.DrawFrame = false;
 
813
                        documentDockItem.Label = GettextCatalog.GetString ("Documents");
 
814
                        documentDockItem.Content = tabControl;
 
815
                        
 
816
                        // Add some hiden items to be used as position reference
 
817
                        DockItem dit = dock.AddItem ("__left");
 
818
                        dit.DefaultLocation = "Documents/Left";
 
819
                        dit.Behavior = DockItemBehavior.Locked;
 
820
                        dit.DefaultVisible = false;
 
821
                        
 
822
                        dit = dock.AddItem ("__right");
 
823
                        dit.DefaultLocation = "Documents/Right";
 
824
                        dit.Behavior = DockItemBehavior.Locked;
 
825
                        dit.DefaultVisible = false;
 
826
                        
 
827
                        dit = dock.AddItem ("__top");
 
828
                        dit.DefaultLocation = "Documents/Top";
 
829
                        dit.Behavior = DockItemBehavior.Locked;
 
830
                        dit.DefaultVisible = false;
 
831
                        
 
832
                        dit = dock.AddItem ("__bottom");
 
833
                        dit.DefaultLocation = "Documents/Bottom";
 
834
                        dit.Behavior = DockItemBehavior.Locked;
 
835
                        dit.DefaultVisible = false;
 
836
 
 
837
                        Add (fullViewVBox);
 
838
                        fullViewVBox.ShowAll ();
 
839
                        
 
840
                        fullViewVBox.PackEnd (this.StatusBar, false, true, 0);
 
841
                        
 
842
                        if (MonoDevelop.Core.PropertyService.IsMac)
 
843
                                this.StatusBar.HasResizeGrip = true;
 
844
                        else {
 
845
                                if (GdkWindow != null && GdkWindow.State == Gdk.WindowState.Maximized)
 
846
                                        IdeApp.Workbench.StatusBar.HasResizeGrip = false;
 
847
                                SizeAllocated += delegate {
 
848
                                        if (GdkWindow != null)
 
849
                                                IdeApp.Workbench.StatusBar.HasResizeGrip = GdkWindow.State != Gdk.WindowState.Maximized;
 
850
                                };
 
851
                        }
 
852
 
 
853
                        // create DockItems for all the pads
 
854
                        foreach (PadCodon content in padContentCollection)
 
855
                                AddPad (content, content.DefaultPlacement, content.DefaultStatus);
 
856
                        
 
857
                        try {
 
858
                                if (System.IO.File.Exists (configFile)) {
 
859
                                        dock.LoadLayouts (configFile);
 
860
                                        foreach (string layout in dock.Layouts) {
 
861
                                                if (!layouts.Contains (layout) && !layout.EndsWith (fullViewModeTag))
 
862
                                                        layouts.Add (layout);
 
863
                                        }
 
864
                                }
 
865
                        } catch (Exception ex) {
 
866
                                LoggingService.LogError (ex.ToString ());
 
867
                        }
 
868
                }
 
869
                
 
870
                void InitializeLayout (string name)
 
871
                {
 
872
                        if (!layouts.Contains (name))
 
873
                                layouts.Add (name);
 
874
                        
 
875
                        if (dock.Layouts.Contains (name))
 
876
                                return;
 
877
                        
 
878
                        dock.CreateLayout (name, true);
 
879
                        dock.CurrentLayout = name;
 
880
                        documentDockItem.Visible = true;
 
881
                        
 
882
                        LayoutExtensionNode stockLayout = null;
 
883
                        foreach (LayoutExtensionNode node in AddinManager.GetExtensionNodes (stockLayoutsPath)) {
 
884
                                if (node.Name == name) {
 
885
                                        stockLayout = node;
 
886
                                        break;
 
887
                                }
 
888
                        }
 
889
                        
 
890
                        if (stockLayout == null)
 
891
                                return;
 
892
                        
 
893
                        HashSet<string> visible = new HashSet<string> ();
 
894
                        
 
895
                        foreach (LayoutPadExtensionNode pad in stockLayout.ChildNodes) {
 
896
                                DockItem it = dock.GetItem (pad.Id);
 
897
                                if (it != null) {
 
898
                                        it.Visible = true;
 
899
                                        string loc = pad.Placement ?? it.DefaultLocation;
 
900
                                        if (!string.IsNullOrEmpty (loc))
 
901
                                            it.SetDockLocation (ToDockLocation (loc));
 
902
                                        DockItemStatus stat = pad.StatusSet ? pad.Status : it.DefaultStatus;
 
903
                                        it.Status = stat;
 
904
                                        visible.Add (pad.Id);
 
905
                                }
 
906
                        }
 
907
                        
 
908
                        foreach (PadCodon node in padContentCollection) {
 
909
                                if (!visible.Contains (node.Id) && node.DefaultLayouts != null && (node.DefaultLayouts.Contains (stockLayout.Id) || node.DefaultLayouts.Contains ("*"))) {
 
910
                                        DockItem it = dock.GetItem (node.Id);
 
911
                                        if (it != null) {
 
912
                                                it.Visible = true;
 
913
                                                if (!string.IsNullOrEmpty (node.DefaultPlacement))
 
914
                                                        it.SetDockLocation (ToDockLocation (node.DefaultPlacement));
 
915
                                                it.Status = node.DefaultStatus;
 
916
                                                visible.Add (node.Id);
 
917
                                        }
 
918
                                }
 
919
                        }
 
920
                        
 
921
                        foreach (DockItem it in dock.GetItems ()) {
 
922
                                if (!visible.Contains (it.Id) && ((it.Behavior & DockItemBehavior.Sticky) == 0) && it != documentDockItem)
 
923
                                        it.Visible = false;
 
924
                        }
 
925
                }
 
926
                
 
927
                void ShowPopup ()
 
928
                {
 
929
                        Gtk.Menu contextMenu = IdeApp.CommandService.CreateMenu ("/MonoDevelop/Ide/ContextMenu/DocumentTab");
 
930
                        if (contextMenu != null)
 
931
                                contextMenu.Popup ();
 
932
                }
 
933
                
 
934
                void OnTabsReordered (Widget widget, int oldPlacement, int newPlacement)
 
935
                {
 
936
                        IdeApp.Workbench.ReorderDocuments (oldPlacement, newPlacement);
 
937
                }
 
938
                
629
939
                public void ResetToolbars ()
630
940
                {
631
 
                        layout.ResetToolbars ();
 
941
                        toolbarFrame.ResetToolbarPositions ();
 
942
                }
 
943
                
 
944
                bool IsInFullViewMode {
 
945
                        get {
 
946
                                return dock.CurrentLayout.EndsWith (fullViewModeTag);
 
947
                        }
 
948
                }
 
949
                
 
950
                //don't allow the "full view" layouts to persist - they are always derived from the "normal" layout
 
951
                //else they will diverge
 
952
                void DestroyFullViewLayouts (string oldLayout)
 
953
                {
 
954
                        if (oldLayout != null && oldLayout.EndsWith (fullViewModeTag)) {
 
955
                                dock.DeleteLayout (oldLayout);
 
956
                                toolbarFrame.DeleteLayout (oldLayout);
 
957
                        }
 
958
                }
 
959
                
 
960
                public void ToggleFullViewMode ()
 
961
                {
 
962
                        this.tabControl.LeaveDragMode (0);
 
963
                        
 
964
                        if (IsInFullViewMode) {
 
965
                                var oldLayout = dock.CurrentLayout;
 
966
                                toolbarFrame.CurrentLayout = dock.CurrentLayout = CurrentLayout;
 
967
                                DestroyFullViewLayouts (oldLayout);
 
968
                        } else {
 
969
                                string fullViewLayout = CurrentLayout + fullViewModeTag;
 
970
                                if (!dock.HasLayout (fullViewLayout))
 
971
                                        dock.CreateLayout (fullViewLayout, true);
 
972
                                toolbarFrame.CurrentLayout = dock.CurrentLayout = fullViewLayout;
 
973
                                foreach (DockItem it in dock.GetItems ()) {
 
974
                                        if (it.Behavior != DockItemBehavior.Locked && it.Visible)
 
975
                                                it.Status = DockItemStatus.AutoHide;
 
976
                                }
 
977
                                foreach (var tb in toolbarFrame.Toolbars)
 
978
                                        tb.Status = new DockToolbarStatus (tb.Id, false, tb.Position);
 
979
                        }
632
980
                }
633
981
 
634
982
                protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
635
983
                {
636
 
                        //FIXME: Mac-ify this. The control key use is hardcoded into DocumentSwitcher too
637
 
                        Gdk.ModifierType tabSwitchModifier = Gdk.ModifierType.ControlMask;
638
 
                        
639
984
                        // Handle Alt+1-0 keys
640
985
                        Gdk.ModifierType winSwitchModifier = PropertyService.IsMac
641
986
                                ? KeyBindingManager.SelectionModifierControl
704
1049
                        
705
1050
                        if (args.Change == ExtensionChange.Add) {
706
1051
                                ShowPadNode (args.ExtensionNode);
707
 
                                RedrawAllComponents ();
708
1052
                        }
709
1053
                        else {
710
1054
                                RemovePadNode (args.ExtensionNode);
711
1055
                        }
712
1056
                }
713
1057
                
714
 
                // Handle keyboard shortcuts
715
 
 
716
 
 
717
 
                public event EventHandler ActiveWorkbenchWindowChanged;
718
 
 
719
 
                /// Context switching specific parts
720
 
                WorkbenchContext context = WorkbenchContext.Edit;
721
 
                
722
 
                public WorkbenchContext Context {
723
 
                        get { return context; }
724
 
                        set {
725
 
                                context = value;
726
 
                                if (ContextChanged != null)
727
 
                                        ContextChanged (this, new EventArgs());
728
 
                        }
729
 
                }
730
 
 
731
 
                public event EventHandler ContextChanged;
 
1058
                void OnLayoutsExtensionChanged (object s, ExtensionNodeEventArgs args)
 
1059
                {
 
1060
                        if (args.Change == ExtensionChange.Add)
 
1061
                                layouts.Add (((LayoutExtensionNode)args.ExtensionNode).Name);
 
1062
                        else
 
1063
                                layouts.Remove (((LayoutExtensionNode)args.ExtensionNode).Name);
 
1064
                }
 
1065
                
 
1066
                #region View management
 
1067
                
 
1068
                bool SelectLastActiveWindow (IWorkbenchWindow cur)
 
1069
                {
 
1070
                        if (lastActiveWindows.Count == 0)
 
1071
                                return false;
 
1072
                        IWorkbenchWindow last = null;
 
1073
                        do {
 
1074
                                last = lastActiveWindows.Last.Value;
 
1075
                                lastActiveWindows.RemoveLast ();
 
1076
                        } while (lastActiveWindows.Count > 0 && (last == cur || last == null || (last != null && last.ViewContent == null)));
 
1077
                        if (last != null) {
 
1078
                                last.SelectWindow ();
 
1079
                                return true;
 
1080
                        }
 
1081
                        return false;
 
1082
                }
 
1083
                
 
1084
                void CloseWindowEvent (object sender, WorkbenchWindowEventArgs e)
 
1085
                {
 
1086
                        SdiWorkspaceWindow f = (SdiWorkspaceWindow) sender;
 
1087
                        
 
1088
                        // Unsubscribe events to avoid memory leaks
 
1089
                        f.TabLabel.CloseClicked -= new EventHandler (closeClicked);
 
1090
                        
 
1091
                        if (f.ViewContent != null) {
 
1092
                                CloseContent (f.ViewContent);
 
1093
                                if (e.WasActive && !SelectLastActiveWindow (f))
 
1094
                                        OnActiveWindowChanged(this, null);
 
1095
                        }
 
1096
                        lastActiveWindows.Remove (f);
 
1097
                }
 
1098
                
 
1099
                void closeClicked (object o, EventArgs e)
 
1100
                {
 
1101
                        Widget tabLabel = ((Widget)o);
 
1102
                        foreach (Widget child in tabControl.Children) {
 
1103
                                if (tabControl.GetTabLabel (child) == tabLabel) {
 
1104
                                        int pageNum = tabControl.PageNum (child);
 
1105
                                        ((SdiWorkspaceWindow)child).CloseWindow (false, false, pageNum);
 
1106
                                        break;
 
1107
                                }
 
1108
                        }
 
1109
                }
 
1110
 
 
1111
                internal void RemoveTab (int pageNum) {
 
1112
                        try {
 
1113
                                // Weird switch page events are fired when a tab is removed.
 
1114
                                // This flag avoids unneeded events.
 
1115
                                ignorePageSwitch = true;
 
1116
                                IWorkbenchWindow w = ActiveWorkbenchWindow;
 
1117
                                tabControl.RemovePage (pageNum);
 
1118
                                ignorePageSwitch = false;
 
1119
                                if (w != ActiveWorkbenchWindow)
 
1120
                                        OnActiveWindowChanged (null, null);
 
1121
                        } finally {
 
1122
                                ignorePageSwitch = false;
 
1123
                        }
 
1124
                }
 
1125
                
 
1126
                #endregion
 
1127
 
 
1128
                #region Dock Item management
 
1129
                
 
1130
                public IPadWindow GetPadWindow (PadCodon content)
 
1131
                {
 
1132
                        IPadWindow w;
 
1133
                        padWindows.TryGetValue (content, out w);
 
1134
                        return w;
 
1135
                }
 
1136
                
 
1137
                public bool IsVisible (PadCodon padContent)
 
1138
                {
 
1139
                        DockItem item = GetDockItem (padContent);
 
1140
                        if (item != null)
 
1141
                                return item.Visible;
 
1142
                        return false;
 
1143
                }
 
1144
                
 
1145
                public bool IsContentVisible (PadCodon padContent)
 
1146
                {
 
1147
                        DockItem item = GetDockItem (padContent);
 
1148
                        if (item != null)
 
1149
                                return item.ContentVisible;
 
1150
                        return false;
 
1151
                }
 
1152
                
 
1153
                public void HidePad (PadCodon padContent)
 
1154
                {
 
1155
                        DockItem item = GetDockItem (padContent);
 
1156
                        if (item != null) 
 
1157
                                item.Visible = false;
 
1158
                }
 
1159
                
 
1160
                public void ActivatePad (PadCodon padContent, bool giveFocus)
 
1161
                {
 
1162
                        DockItem item = GetDockItem (padContent);
 
1163
                        if (item != null)
 
1164
                                item.Present (giveFocus);
 
1165
                }
 
1166
                
 
1167
                public bool IsSticky (PadCodon padContent)
 
1168
                {
 
1169
                        DockItem item = GetDockItem (padContent);
 
1170
                        return item != null && (item.Behavior & DockItemBehavior.Sticky) != 0;
 
1171
                }
 
1172
 
 
1173
                public void SetSticky (PadCodon padContent, bool sticky)
 
1174
                {
 
1175
                        DockItem item = GetDockItem (padContent);
 
1176
                        if (item != null) {
 
1177
                                if (sticky)
 
1178
                                        item.Behavior |= DockItemBehavior.Sticky;
 
1179
                                else
 
1180
                                        item.Behavior &= ~DockItemBehavior.Sticky;
 
1181
                        }
 
1182
                }
 
1183
                
 
1184
                internal DockItem GetDockItem (PadCodon content)
 
1185
                {
 
1186
                        if (padContentCollection.Contains (content)) {
 
1187
                                DockItem item = dock.GetItem (content.PadId);
 
1188
                                return item;
 
1189
                        }
 
1190
                        return null;
 
1191
                }
 
1192
                
 
1193
                void CreatePadContent (bool force, PadCodon padCodon, PadWindow window, DockItem item)
 
1194
                {
 
1195
                        if (force || item.Content == null) {
 
1196
                                IPadContent newContent = padCodon.InitializePadContent (window);
 
1197
 
 
1198
                                Gtk.Widget pcontent;
 
1199
                                if (newContent is Widget) {
 
1200
                                        pcontent = newContent.Control;
 
1201
                                } else {
 
1202
                                        PadCommandRouterContainer crc = new PadCommandRouterContainer (window, newContent.Control, newContent, true);
 
1203
                                        crc.Show ();
 
1204
                                        pcontent = crc;
 
1205
                                }
 
1206
                                
 
1207
                                PadCommandRouterContainer router = new PadCommandRouterContainer (window, pcontent, toolbarFrame, false);
 
1208
                                router.Show ();
 
1209
                                item.Content = router;
 
1210
                        }
 
1211
                }
 
1212
                
 
1213
                string ToDockLocation (string loc)
 
1214
                {
 
1215
                        string location = "";
 
1216
                        foreach (string s in loc.Split (' ')) {
 
1217
                                if (string.IsNullOrEmpty (s))
 
1218
                                        continue;
 
1219
                                if (location.Length > 0)
 
1220
                                        location += ";";
 
1221
                                if (s.IndexOf ('/') == -1)
 
1222
                                        location += "__" + s.ToLower () + "/CenterBefore";
 
1223
                                else
 
1224
                                        location += s;
 
1225
                        }
 
1226
                        return location;
 
1227
                }
 
1228
                
 
1229
                void AddPad (PadCodon padCodon, string placement, DockItemStatus defaultStatus)
 
1230
                {
 
1231
                        PadWindow window = new PadWindow (this, padCodon);
 
1232
                        window.Icon = padCodon.Icon;
 
1233
                        padWindows [padCodon] = window;
 
1234
                        padCodons [window] = padCodon;
 
1235
                        
 
1236
                        window.StatusChanged += new EventHandler (UpdatePad);
 
1237
                        
 
1238
                        string location = ToDockLocation (placement);
 
1239
                        
 
1240
                        DockItem item = dock.AddItem (padCodon.PadId);
 
1241
                        item.Label = GettextCatalog.GetString (padCodon.Label);
 
1242
                        item.Icon = ImageService.GetPixbuf (padCodon.Icon, IconSize.Menu);
 
1243
                        item.DefaultLocation = location;
 
1244
                        item.DefaultVisible = false;
 
1245
                        item.DefaultStatus = defaultStatus;
 
1246
                        item.DockLabelProvider = padCodon;
 
1247
                        window.Item = item;
 
1248
                        
 
1249
                        if (padCodon.Initialized) {
 
1250
                                CreatePadContent (true, padCodon, window, item);
 
1251
                        } else {
 
1252
                                item.ContentRequired += delegate {
 
1253
                                        CreatePadContent (false, padCodon, window, item);
 
1254
                                };
 
1255
                        }
 
1256
                        
 
1257
                        item.VisibleChanged += delegate {
 
1258
                                if (item.Visible)
 
1259
                                        window.NotifyShown ();
 
1260
                                else
 
1261
                                        window.NotifyHidden ();
 
1262
                        };
 
1263
                        
 
1264
                        item.ContentVisibleChanged += delegate {
 
1265
                                if (item.ContentVisible)
 
1266
                                        window.NotifyContentShown ();
 
1267
                                else
 
1268
                                        window.NotifyContentHidden ();
 
1269
                        };
 
1270
                        
 
1271
                        if (!padContentCollection.Contains (padCodon))
 
1272
                                padContentCollection.Add (padCodon);
 
1273
                }
 
1274
                
 
1275
                void UpdatePad (object source, EventArgs args)
 
1276
                {
 
1277
                        IPadWindow window = (IPadWindow) source;
 
1278
                        if (!padCodons.ContainsKey (window)) 
 
1279
                                return;
 
1280
                        PadCodon codon = padCodons [window];
 
1281
                        DockItem item = GetDockItem (codon);
 
1282
                        if (item != null) {
 
1283
                                string windowTitle = GettextCatalog.GetString (window.Title); 
 
1284
                                if (String.IsNullOrEmpty (windowTitle)) 
 
1285
                                        windowTitle = GettextCatalog.GetString (codon.Label);
 
1286
                                if (window.IsWorking)
 
1287
                                        windowTitle = "<span foreground='blue'>" + windowTitle + "</span>";
 
1288
                                else if (window.HasErrors && !window.ContentVisible)
 
1289
                                        windowTitle = "<span foreground='red'>" + windowTitle + "</span>";
 
1290
                                else if (window.HasNewData && !window.ContentVisible)
 
1291
                                        windowTitle = "<b>" + windowTitle + "</b>";
 
1292
                                item.Label = windowTitle;
 
1293
                                item.Icon  = ImageService.GetPixbuf (window.Icon, IconSize.Menu);
 
1294
                        }
 
1295
                }
 
1296
                
 
1297
                #endregion
732
1298
        }
733
1299
 
734
1300
        class PadActivationHandler: CommandHandler
747
1313
                        wb.BringToFront (pad, true);
748
1314
                }
749
1315
        }
 
1316
 
 
1317
        class PadCommandRouterContainer: CommandRouterContainer
 
1318
        {
 
1319
                public PadCommandRouterContainer (PadWindow window, Gtk.Widget child, object target, bool continueToParent): base (child, target, continueToParent)
 
1320
                {
 
1321
                }
 
1322
        }
 
1323
        
 
1324
        // The SdiDragNotebook class allows redirecting the command route to the ViewCommandHandler
 
1325
        // object of the selected document, which implement some default commands.
 
1326
        
 
1327
        class SdiDragNotebook: DragNotebook, ICommandDelegatorRouter, IShadedWidget
 
1328
        {
 
1329
                ShadedContainer shadedContainer;
 
1330
                
 
1331
                public SdiDragNotebook (ShadedContainer shadedContainer)
 
1332
                {
 
1333
                        this.shadedContainer = shadedContainer;
 
1334
                        shadedContainer.Add (this);
 
1335
                        
 
1336
                        PageAdded += delegate {
 
1337
                                if (AreasChanged != null)
 
1338
                                        AreasChanged (this, EventArgs.Empty);
 
1339
                        };
 
1340
                        PageRemoved += delegate {
 
1341
                                if (AreasChanged != null)
 
1342
                                        AreasChanged (this, EventArgs.Empty);
 
1343
                        };
 
1344
                }
 
1345
                
 
1346
                public object GetNextCommandTarget ()
 
1347
                {
 
1348
                        return Parent;
 
1349
                }
 
1350
 
 
1351
                public object GetDelegatedCommandTarget ()
 
1352
                {
 
1353
                        SdiWorkspaceWindow win = (SdiWorkspaceWindow) CurrentPageWidget;
 
1354
                        return win != null ? win.CommandHandler : null;
 
1355
                }
 
1356
                
 
1357
                protected override bool OnExposeEvent (Gdk.EventExpose evnt)
 
1358
                {
 
1359
                        shadedContainer.DrawBackground (this);
 
1360
                        return base.OnExposeEvent (evnt);
 
1361
                }
 
1362
 
 
1363
                public event EventHandler AreasChanged;
 
1364
                
 
1365
                public IEnumerable<Gdk.Rectangle> GetShadedAreas ()
 
1366
                {
 
1367
                        Gdk.Rectangle rect = Allocation;
 
1368
                        if (CurrentPageWidget != null && CurrentPageWidget.Visible)
 
1369
                                rect.Height -= CurrentPageWidget.Allocation.Height;
 
1370
                        yield return rect;
 
1371
                }
 
1372
        }
750
1373
}
751
1374