~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.GtkCore/lib/stetic/libsteticui/WidgetEditSession.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// WidgetEditSession.cs
3
 
//
4
 
// Author:
5
 
//   Lluis Sanchez Gual
6
 
//
7
 
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
8
 
//
9
 
// Permission is hereby granted, free of charge, to any person obtaining
10
 
// a copy of this software and associated documentation files (the
11
 
// "Software"), to deal in the Software without restriction, including
12
 
// without limitation the rights to use, copy, modify, merge, publish,
13
 
// distribute, sublicense, and/or sell copies of the Software, and to
14
 
// permit persons to whom the Software is furnished to do so, subject to
15
 
// the following conditions:
16
 
// 
17
 
// The above copyright notice and this permission notice shall be
18
 
// included in all copies or substantial portions of the Software.
19
 
// 
20
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 
//
28
 
 
29
 
 
30
 
using System;
31
 
using System.Xml;
32
 
using System.Reflection;
33
 
using System.Collections;
34
 
using System.CodeDom;
35
 
using Mono.Unix;
36
 
 
37
 
namespace Stetic {
38
 
    
39
 
        internal class WidgetEditSession: MarshalByRefObject, IDisposable
40
 
        {
41
 
                string sourceWidget;
42
 
                Stetic.ProjectBackend sourceProject;
43
 
                
44
 
                Stetic.ProjectBackend gproject;
45
 
                Stetic.Wrapper.Container rootWidget;
46
 
                Stetic.WidgetDesignerBackend widget;
47
 
                Gtk.VBox designer;
48
 
                Gtk.Plug plug;
49
 
                bool autoCommitChanges;
50
 
                WidgetActionBar toolbar;
51
 
                WidgetDesignerFrontend frontend;
52
 
                bool allowBinding;
53
 
                bool disposed;
54
 
                
55
 
                ContainerUndoRedoManager undoManager;
56
 
                UndoQueue undoQueue;
57
 
                
58
 
                public event EventHandler ModifiedChanged;
59
 
                public event EventHandler RootWidgetChanged;
60
 
                public event Stetic.Wrapper.WidgetEventHandler SelectionChanged;
61
 
                
62
 
                public WidgetEditSession (ProjectBackend sourceProject, WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
63
 
                {
64
 
                        this.frontend = frontend;
65
 
                        this.autoCommitChanges = autoCommitChanges;
66
 
                        undoManager = new ContainerUndoRedoManager ();
67
 
                        undoQueue = new UndoQueue ();
68
 
                        undoManager.UndoQueue = undoQueue;
69
 
                        
70
 
                        sourceWidget = windowName;
71
 
                        this.sourceProject = sourceProject;
72
 
                        
73
 
                        if (!autoCommitChanges) {
74
 
                                // Reuse the action groups and icon factory of the main project
75
 
                                gproject = editingBackend;
76
 
                                
77
 
                                // Attach will prevent the destruction of the action group list by gproject
78
 
                                gproject.AttachActionGroups (sourceProject.ActionGroups);
79
 
                                
80
 
                                gproject.IconFactory = sourceProject.IconFactory;
81
 
                                gproject.FileName = sourceProject.FileName;
82
 
                                gproject.ImagesRootPath = sourceProject.ImagesRootPath;
83
 
                                gproject.ResourceProvider = sourceProject.ResourceProvider;
84
 
                                gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
85
 
                                gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
86
 
                                gproject.TargetGtkVersion = sourceProject.TargetGtkVersion;
87
 
                                sourceProject.ComponentTypesChanged += OnSourceProjectLibsChanged;
88
 
                                sourceProject.ProjectReloaded += OnSourceProjectReloaded;
89
 
                                
90
 
                                rootWidget = editingBackend.GetTopLevelWrapper (sourceWidget, false);
91
 
                                if (rootWidget == null) {
92
 
                                        // Copy the widget to edit from the source project
93
 
                                        // When saving the file, this project will be merged with the main project.
94
 
                                        sourceProject.CopyWidgetToProject (windowName, gproject, windowName);
95
 
                                        rootWidget = gproject.GetTopLevelWrapper (windowName, true);
96
 
                                }
97
 
                                
98
 
                                gproject.Modified = false;
99
 
                        }
100
 
                        else {
101
 
                                rootWidget = sourceProject.GetTopLevelWrapper (windowName, true);
102
 
                                gproject = sourceProject;
103
 
                        }
104
 
                        
105
 
                        rootWidget.Select ();
106
 
                        undoManager.RootObject = rootWidget;
107
 
                        
108
 
                        gproject.ModifiedChanged += new EventHandler (OnModifiedChanged);
109
 
                        gproject.Changed += new EventHandler (OnChanged);
110
 
                        gproject.ProjectReloaded += new EventHandler (OnProjectReloaded);
111
 
                        gproject.ProjectReloading += new EventHandler (OnProjectReloading);
112
 
//                      gproject.WidgetMemberNameChanged += new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
113
 
                }
114
 
                
115
 
                public bool AllowWidgetBinding {
116
 
                        get { return allowBinding; }
117
 
                        set {
118
 
                                allowBinding = value;
119
 
                                if (toolbar != null)
120
 
                                        toolbar.AllowWidgetBinding = allowBinding;
121
 
                        }
122
 
                }
123
 
                
124
 
                public Stetic.Wrapper.Widget GladeWidget {
125
 
                        get { return rootWidget; }
126
 
                }
127
 
                
128
 
                public Stetic.Wrapper.Container RootWidget {
129
 
                        get { return (Wrapper.Container) Component.GetSafeReference (rootWidget); }
130
 
                }
131
 
                
132
 
                public Gtk.Widget WrapperWidget {
133
 
                        get {
134
 
                                if (designer == null) {
135
 
                                        if (rootWidget == null)
136
 
                                                return widget;
137
 
                                        Gtk.Container wc = rootWidget.Wrapped as Gtk.Container;
138
 
                                        if (widget == null)
139
 
                                                widget = Stetic.UserInterface.CreateWidgetDesigner (wc, rootWidget.DesignWidth, rootWidget.DesignHeight);
140
 
                                        
141
 
                                        toolbar = new WidgetActionBar (frontend, rootWidget);
142
 
                                        toolbar.AllowWidgetBinding = allowBinding;
143
 
                                        designer = new Gtk.VBox ();
144
 
                                        designer.BorderWidth = 3;
145
 
                                        designer.PackStart (toolbar, false, false, 0);
146
 
                                        designer.PackStart (widget, true, true, 3);
147
 
                                        widget.DesignArea.SetSelection (gproject.Selection, gproject.Selection, false);
148
 
                                        widget.SelectionChanged += OnSelectionChanged;
149
 
                                
150
 
                                }
151
 
                                return designer; 
152
 
                        }
153
 
                }
154
 
                
155
 
                [NoGuiDispatch]
156
 
                public void CreateWrapperWidgetPlug (uint socketId)
157
 
                {
158
 
                        Gdk.Threads.Enter ();
159
 
                        plug = new Gtk.Plug (socketId);
160
 
                        plug.Add (WrapperWidget);
161
 
                        plug.Decorated = false;
162
 
                        plug.ShowAll ();
163
 
                        Gdk.Threads.Leave ();
164
 
                }
165
 
                
166
 
                public void DestroyWrapperWidgetPlug ()
167
 
                {
168
 
                        if (designer != null) {
169
 
                                Gtk.Plug plug = (Gtk.Plug) WrapperWidget.Parent;
170
 
                                plug.Remove (WrapperWidget);
171
 
                                plug.Destroy ();
172
 
                        }
173
 
                }
174
 
                
175
 
                public void Save ()
176
 
                {
177
 
                        if (!autoCommitChanges) {
178
 
                                gproject.CopyWidgetToProject (rootWidget.Wrapped.Name, sourceProject, sourceWidget);
179
 
                                sourceWidget = rootWidget.Wrapped.Name;
180
 
                                gproject.Modified = false;
181
 
                        }
182
 
                }
183
 
                
184
 
                public ProjectBackend EditingBackend {
185
 
                        get { return gproject; }
186
 
                }
187
 
                
188
 
                public void Dispose ()
189
 
                {
190
 
                        sourceProject.ComponentTypesChanged -= OnSourceProjectLibsChanged;
191
 
                        sourceProject.ProjectReloaded -= OnSourceProjectReloaded;
192
 
                        
193
 
                        gproject.ModifiedChanged -= new EventHandler (OnModifiedChanged);
194
 
                        gproject.Changed -= new EventHandler (OnChanged);
195
 
                        gproject.ProjectReloaded -= OnProjectReloaded;
196
 
                        gproject.ProjectReloading -= OnProjectReloading;
197
 
//                      gproject.WidgetMemberNameChanged -= new Stetic.Wrapper.WidgetNameChangedHandler (OnWidgetNameChanged);
198
 
                        
199
 
                        if (!autoCommitChanges) {
200
 
                                // Don't dispose the project here! it will be disposed by the frontend
201
 
                                if (widget != null) {
202
 
                                        widget.SelectionChanged -= OnSelectionChanged;
203
 
                                        // Don't dispose the widget. It will be disposed when destroyed together
204
 
                                        // with the container
205
 
                                        widget = null;
206
 
                                }
207
 
                        }
208
 
                        
209
 
                        if (plug != null)
210
 
                                plug.Destroy ();
211
 
                        gproject = null;
212
 
                        rootWidget = null;
213
 
                        frontend = null;
214
 
                        System.Runtime.Remoting.RemotingServices.Disconnect (this);
215
 
                        disposed = true;
216
 
                }
217
 
                
218
 
                public bool Disposed {
219
 
                        get { return disposed; }
220
 
                }
221
 
 
222
 
                public override object InitializeLifetimeService ()
223
 
                {
224
 
                        // Will be disconnected when calling Dispose
225
 
                        return null;
226
 
                }
227
 
                
228
 
                public void SetDesignerActive ()
229
 
                {
230
 
                        widget.UpdateObjectViewers ();
231
 
                }
232
 
                
233
 
                public bool Modified {
234
 
                        get { return gproject.Modified; }
235
 
                }
236
 
                
237
 
                public UndoQueue UndoQueue {
238
 
                        get { 
239
 
                                if (undoQueue != null)
240
 
                                        return undoQueue;
241
 
                                else
242
 
                                        return UndoQueue.Empty;
243
 
                        }
244
 
                }
245
 
                
246
 
                void OnModifiedChanged (object s, EventArgs a)
247
 
                {
248
 
                        if (frontend != null)
249
 
                                frontend.NotifyModifiedChanged ();
250
 
                }
251
 
                
252
 
                void OnChanged (object s, EventArgs a)
253
 
                {
254
 
                        if (frontend != null)
255
 
                                frontend.NotifyChanged ();
256
 
                }
257
 
                
258
 
                void OnSourceProjectReloaded (object s, EventArgs a)
259
 
                {
260
 
                        // Propagate gtk version change
261
 
                        if (sourceProject.TargetGtkVersion != gproject.TargetGtkVersion)
262
 
                                gproject.TargetGtkVersion = sourceProject.TargetGtkVersion;
263
 
                }
264
 
                
265
 
                void OnSourceProjectLibsChanged (object s, EventArgs a)
266
 
                {
267
 
                        // If component types have changed in the source project, they must also change
268
 
                        // in this project.
269
 
                        gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
270
 
                        gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
271
 
                        gproject.NotifyComponentTypesChanged ();
272
 
                }
273
 
                
274
 
                void OnProjectReloading (object s, EventArgs a)
275
 
                {
276
 
                        if (frontend != null)
277
 
                                frontend.NotifyRootWidgetChanging ();
278
 
                }
279
 
                
280
 
                void OnProjectReloaded (object s, EventArgs a)
281
 
                {
282
 
                        // Update the actions group list
283
 
                        if (!autoCommitChanges) {
284
 
                                gproject.AttachActionGroups (sourceProject.ActionGroups);
285
 
                                gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
286
 
                                gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
287
 
                        }
288
 
                        
289
 
                        Gtk.Widget[] tops = gproject.Toplevels;
290
 
                        if (tops.Length > 0) {
291
 
                                rootWidget = Stetic.Wrapper.Container.Lookup (tops[0]);
292
 
                                undoManager.RootObject = rootWidget;
293
 
                                if (rootWidget != null) {
294
 
                                        Gtk.Widget oldWidget = designer;
295
 
                                        if (widget != null) {
296
 
                                                widget.SelectionChanged -= OnSelectionChanged;
297
 
                                                widget = null;
298
 
                                        }
299
 
                                        OnRootWidgetChanged ();
300
 
                                        if (oldWidget != null) {
301
 
                                                // Delay the destruction of the old widget, so the designer has time to
302
 
                                                // show the new widget. This avoids flickering.
303
 
                                                GLib.Timeout.Add (500, delegate {
304
 
                                                        oldWidget.Destroy ();
305
 
                                                        return false;
306
 
                                                });
307
 
                                        }
308
 
                                                
309
 
                                        gproject.NotifyComponentTypesChanged ();
310
 
                                        return;
311
 
                                }
312
 
                        }
313
 
                        SetErrorMode ();
314
 
                }
315
 
                
316
 
                void SetErrorMode ()
317
 
                {
318
 
                        Gtk.Label lab = new Gtk.Label ();
319
 
                        lab.Markup = "<b>" + Catalog.GetString ("The form designer could not be loaded") + "</b>";
320
 
                        Gtk.EventBox box = new Gtk.EventBox ();
321
 
                        box.Add (lab);
322
 
                        
323
 
                        widget = Stetic.UserInterface.CreateWidgetDesigner (box, 100, 100);
324
 
                        rootWidget = null;
325
 
                        
326
 
                        OnRootWidgetChanged ();
327
 
                }
328
 
                
329
 
                void OnRootWidgetChanged ()
330
 
                {
331
 
                        if (designer != null) {
332
 
                                if (designer.Parent is Gtk.Plug)
333
 
                                        ((Gtk.Plug)designer.Parent).Remove (designer);
334
 
                                designer = null;
335
 
                        }
336
 
                        
337
 
                        if (plug != null) {
338
 
                                Gdk.Threads.Enter ();
339
 
                                plug.Add (WrapperWidget);
340
 
                                plug.ShowAll ();
341
 
                                Gdk.Threads.Leave ();
342
 
                        }
343
 
                        
344
 
                        if (frontend != null)
345
 
                                frontend.NotifyRootWidgetChanged ();
346
 
                        if (RootWidgetChanged != null)
347
 
                                RootWidgetChanged (this, EventArgs.Empty);
348
 
                }
349
 
                
350
 
                void OnSelectionChanged (object ob, EventArgs a)
351
 
                {
352
 
                        if (frontend != null) {
353
 
                                bool canCut, canCopy, canPaste, canDelete;
354
 
                                ObjectWrapper obj = ObjectWrapper.Lookup (widget.Selection);
355
 
                                Stetic.Wrapper.Widget wrapper = obj as Stetic.Wrapper.Widget;
356
 
                                IEditableObject editable = widget.Selection as IEditableObject;
357
 
                                if (editable == null)
358
 
                                        editable = obj as IEditableObject;
359
 
                                if (editable != null) {
360
 
                                        canCut = editable.CanCut;
361
 
                                        canCopy = editable.CanCopy;
362
 
                                        canPaste = editable.CanPaste;
363
 
                                        canDelete = editable.CanDelete;
364
 
                                }
365
 
                                else {
366
 
                                        canCut = canCopy = canPaste = canDelete = false;
367
 
                                }
368
 
                                
369
 
                                frontend.NotifySelectionChanged (Component.GetSafeReference (obj), canCut, canCopy, canPaste, canDelete);
370
 
                                if (SelectionChanged != null)
371
 
                                        SelectionChanged (this, new Stetic.Wrapper.WidgetEventArgs (wrapper));
372
 
                        }
373
 
                }
374
 
                
375
 
                public object SaveState ()
376
 
                {
377
 
                        return null;
378
 
                }
379
 
                
380
 
                public void RestoreState (object sessionData)
381
 
                {
382
 
                }
383
 
                
384
 
                internal void ClipboardCopySelection ()
385
 
                {
386
 
                        IEditableObject editable = widget.Selection as IEditableObject;
387
 
                        if (editable == null)
388
 
                                editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
389
 
                        if (editable != null)
390
 
                                editable.Copy ();
391
 
                }
392
 
                
393
 
                public void ClipboardCutSelection ()
394
 
                {
395
 
                        IEditableObject editable = widget.Selection as IEditableObject;
396
 
                        if (editable == null)
397
 
                                editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
398
 
                        if (editable != null)
399
 
                                editable.Cut ();
400
 
                }
401
 
                
402
 
                public void ClipboardPaste ()
403
 
                {
404
 
                        IEditableObject editable = widget.Selection as IEditableObject;
405
 
                        if (editable == null)
406
 
                                editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
407
 
                        if (editable != null)
408
 
                                editable.Paste ();
409
 
                }
410
 
                
411
 
                public void DeleteSelection ()
412
 
                {
413
 
                        IEditableObject editable = widget.Selection as IEditableObject;
414
 
                        if (editable == null)
415
 
                                editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
416
 
                        if (editable != null)
417
 
                                editable.Delete ();
418
 
                }
419
 
        }
420
 
}