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

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.GtkCore/libsteticui/WidgetDesigner.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
using System;
 
3
using System.Collections;
 
4
 
 
5
namespace Stetic
 
6
{
 
7
        public delegate void ComponentDropCallback ();
 
8
                
 
9
        public class WidgetDesigner: Designer
 
10
        {
 
11
                WidgetEditSession session;
 
12
                WidgetDesignerFrontend frontend;
 
13
                Component selection;
 
14
                Component rootWidget;
 
15
                
 
16
                Project project;
 
17
                Project editedProject;
 
18
                int reloadCount;
 
19
                
 
20
                string componentName;
 
21
                bool autoCommitChanges;
 
22
                bool disposed;
 
23
                
 
24
                bool canCut, canCopy, canPaste, canDelete;
 
25
                
 
26
                public event EventHandler BindField;
 
27
                public event EventHandler ModifiedChanged;
 
28
                public event EventHandler Changed;
 
29
                public event EventHandler SelectionChanged;
 
30
                public event EventHandler RootComponentChanged;
 
31
                public event ComponentSignalEventHandler SignalAdded;
 
32
                public event ComponentSignalEventHandler SignalRemoved;
 
33
                public event ComponentSignalEventHandler SignalChanged;
 
34
                public event ComponentNameEventHandler ComponentNameChanged;
 
35
                public event EventHandler ComponentTypesChanged;
 
36
                
 
37
                internal WidgetDesigner (Project project, string componentName, bool autoCommitChanges): base (project.App)
 
38
                {
 
39
                        this.componentName = componentName;
 
40
                        this.autoCommitChanges = autoCommitChanges;
 
41
                        this.project = project;
 
42
                        frontend = new WidgetDesignerFrontend (this);
 
43
                        
 
44
                        if (autoCommitChanges)
 
45
                                editedProject = project;
 
46
                        else
 
47
                                editedProject = new Project (project.App);
 
48
                        
 
49
                        editedProject.SignalAdded += OnSignalAdded;
 
50
                        editedProject.SignalRemoved += OnSignalRemoved;
 
51
                        editedProject.SignalChanged += OnSignalChanged;
 
52
                        editedProject.ComponentNameChanged += OnComponentNameChanged;
 
53
                        editedProject.ComponentTypesChanged += OnComponentTypesChanged;
 
54
                        
 
55
                        project.BackendChanged += OnProjectBackendChanged;
 
56
                        editedProject.BackendChanged += OnProjectBackendChanged;
 
57
                        
 
58
                        CreateSession ();
 
59
                }
 
60
                
 
61
                public Component RootComponent {
 
62
                        get { return rootWidget; }
 
63
                }
 
64
                
 
65
                public override ProjectItemInfo ProjectItem {
 
66
                        get { return project.GetWidget (rootWidget.Name); }
 
67
                }
 
68
                
 
69
                public ComponentType[] GetComponentTypes ()
 
70
                {
 
71
                        if (!disposed) {
 
72
                                ArrayList types = new ArrayList ();
 
73
                                types.AddRange (editedProject.GetComponentTypes ());
 
74
                                
 
75
                                // Add actions from the local action groups
 
76
                                
 
77
                                WidgetComponent c = rootWidget as WidgetComponent;
 
78
                                if (c != null) {
 
79
                                        foreach (ActionGroupComponent grp in c.GetActionGroups ()) {
 
80
                                                foreach (ActionComponent ac in grp.GetActions ())
 
81
                                                        types.Add (new ComponentType (app, ac));
 
82
                                        }
 
83
                                }
 
84
                                return (ComponentType[]) types.ToArray (typeof(ComponentType)); 
 
85
                        }
 
86
                        else
 
87
                                return new ComponentType[0];
 
88
                }
 
89
                
 
90
                public void BeginComponentDrag (ComponentType type, Gtk.Widget source, Gdk.DragContext ctx)
 
91
                {
 
92
                        Stetic.ObjectWrapper wrapper = type.Action != null ? (Stetic.ObjectWrapper) type.Action.Backend : null;
 
93
                        app.Backend.BeginComponentDrag (editedProject.ProjectBackend, type.Description, type.ClassName, wrapper, source, ctx, null);
 
94
                }
 
95
                
 
96
                public void BeginComponentDrag (string title, string className, Gtk.Widget source, Gdk.DragContext ctx, ComponentDropCallback callback)
 
97
                {
 
98
                        app.Backend.BeginComponentDrag (editedProject.ProjectBackend, title, className, null, source, ctx, callback);
 
99
                }
 
100
                
 
101
                // Creates an action group designer for the widget being edited by this widget designer
 
102
                public ActionGroupDesigner CreateActionGroupDesigner ()
 
103
                {
 
104
                        if (disposed)
 
105
                                throw new ObjectDisposedException ("WidgetDesigner");
 
106
                        return new ActionGroupDesigner (editedProject, componentName, null, this, true);
 
107
                }
 
108
                
 
109
                public bool Modified {
 
110
                        get { return session != null && session.Modified; }
 
111
                }
 
112
                
 
113
                internal override void SetActive ()
 
114
                {
 
115
                        if (!disposed)
 
116
                                project.App.SetActiveDesignSession (editedProject, session);
 
117
                }
 
118
                
 
119
                public bool AllowWidgetBinding {
 
120
                        get { return session != null && session.AllowWidgetBinding; }
 
121
                        set {
 
122
                                if (session != null)
 
123
                                        session.AllowWidgetBinding = value;
 
124
                        }
 
125
                }
 
126
                
 
127
                public ImportFileDelegate ImportFileCallback {
 
128
                        get { return editedProject.ImportFileCallback; }
 
129
                        set { editedProject.ImportFileCallback = value; }
 
130
                }
 
131
                
 
132
                void CreateSession ()
 
133
                {
 
134
                        try {
 
135
                                session = project.ProjectBackend.CreateWidgetDesignerSession (frontend, componentName, editedProject.ProjectBackend, autoCommitChanges);
 
136
                                ResetCustomWidget ();
 
137
                                rootWidget = app.GetComponent (session.RootWidget, null, null);
 
138
                        } catch (Exception ex) {
 
139
                                Console.WriteLine (ex);
 
140
                                Gtk.Label lab = new Gtk.Label ();
 
141
                                lab.Text = Mono.Unix.Catalog.GetString ("The designer could not be loaded.") + "\n\n" + ex.Message;
 
142
                                lab.Wrap = true;
 
143
                                lab.WidthRequest = 400;
 
144
                                AddCustomWidget (lab);
 
145
                                session = null;
 
146
                        }
 
147
                }
 
148
                
 
149
                protected override void OnCreatePlug (uint socketId)
 
150
                {
 
151
                        session.CreateWrapperWidgetPlug (socketId);
 
152
                }
 
153
                
 
154
                protected override void OnDestroyPlug (uint socketId)
 
155
                {
 
156
                        session.DestroyWrapperWidgetPlug ();
 
157
                }
 
158
                
 
159
                protected override Gtk.Widget OnCreateWidget ()
 
160
                {
 
161
                        return session.WrapperWidget;
 
162
                }
 
163
                
 
164
                public Component Selection {
 
165
                        get {
 
166
                                return selection;
 
167
                        }
 
168
                }
 
169
                
 
170
                public void CopySelection ()
 
171
                {
 
172
                        if (session != null)
 
173
                                session.ClipboardCopySelection ();
 
174
                }
 
175
                
 
176
                public void CutSelection ()
 
177
                {
 
178
                        if (session != null)
 
179
                                session.ClipboardCutSelection ();
 
180
                }
 
181
                
 
182
                public void PasteToSelection ()
 
183
                {
 
184
                        if (session != null)
 
185
                                session.ClipboardPaste ();
 
186
                }
 
187
                
 
188
                public void DeleteSelection ()
 
189
                {
 
190
                        if (session != null)
 
191
                                session.DeleteSelection ();
 
192
                }
 
193
                
 
194
                public bool CanDeleteSelection {
 
195
                        get { return canDelete; }
 
196
                }
 
197
                
 
198
                public bool CanCutSelection {
 
199
                        get { return canCut; }
 
200
                }
 
201
                
 
202
                public bool CanCopySelection {
 
203
                        get { return canCopy; }
 
204
                }
 
205
                
 
206
                public bool CanPasteToSelection {
 
207
                        get { return canPaste; }
 
208
                }
 
209
                
 
210
                public UndoQueue UndoQueue {
 
211
                        get {
 
212
                                if (session != null)
 
213
                                        return session.UndoQueue;
 
214
                                else
 
215
                                        return UndoQueue.Empty;
 
216
                        }
 
217
                }
 
218
                
 
219
                public override void Dispose ()
 
220
                {
 
221
                        if (disposed)
 
222
                                return;
 
223
                        
 
224
                        if (project.App.ActiveProject == editedProject)
 
225
                                project.App.ActiveProject = null;
 
226
                        
 
227
                        disposed = true;
 
228
                        frontend.disposed = true;
 
229
                        editedProject.SignalAdded -= OnSignalAdded;
 
230
                        editedProject.SignalRemoved -= OnSignalRemoved;
 
231
                        editedProject.SignalChanged -= OnSignalChanged;
 
232
                        editedProject.ComponentNameChanged -= OnComponentNameChanged;
 
233
                        editedProject.BackendChanged -= OnProjectBackendChanged;
 
234
                        editedProject.ComponentTypesChanged -= OnComponentTypesChanged;
 
235
                        project.BackendChanged -= OnProjectBackendChanged;
 
236
                        
 
237
                        if (session != null) {
 
238
                                session.Dispose ();
 
239
                                session = null;
 
240
                        }
 
241
                                
 
242
                        if (!autoCommitChanges)
 
243
                                editedProject.Dispose ();
 
244
                                
 
245
                        System.Runtime.Remoting.RemotingServices.Disconnect (frontend);
 
246
                        frontend = null;
 
247
                        rootWidget = null;
 
248
                        selection = null;
 
249
                        base.Dispose ();
 
250
                }
 
251
                
 
252
                public void Save ()
 
253
                {
 
254
                        if (session != null)
 
255
                                session.Save ();
 
256
                }
 
257
                
 
258
                void OnComponentNameChanged (object s, ComponentNameEventArgs args)
 
259
                {
 
260
                        if (!disposed && ComponentNameChanged != null)
 
261
                                ComponentNameChanged (this, args);
 
262
                }
 
263
                
 
264
                internal void NotifyRootWidgetChanging ()
 
265
                {
 
266
                        PrepareUpdateWidget ();
 
267
                }
 
268
                
 
269
                internal void NotifyRootWidgetChanged ()
 
270
                {
 
271
                        object rw = session.RootWidget;
 
272
                        if (rw != null)
 
273
                                rootWidget = app.GetComponent (session.RootWidget, null, null);
 
274
                        else
 
275
                                rootWidget = null;
 
276
 
 
277
                        UpdateWidget ();
 
278
                        if (RootComponentChanged != null)
 
279
                                RootComponentChanged (this, EventArgs.Empty);
 
280
                }
 
281
                
 
282
                internal override void OnBackendChanging ()
 
283
                {
 
284
                        reloadCount = 0;
 
285
                        base.OnBackendChanging ();
 
286
                }
 
287
                
 
288
                internal override void OnBackendChanged (ApplicationBackend oldBackend)
 
289
                {
 
290
                        // Can't do anything until the projects are reloaded
 
291
                        // This is checked in OnProjectBackendChanged.
 
292
                }
 
293
                
 
294
                void OnProjectBackendChanged (ApplicationBackend oldBackend)
 
295
                {
 
296
                        if (++reloadCount == 2) {
 
297
                                object sessionData = null;
 
298
                                
 
299
                                if (oldBackend != null && !autoCommitChanges) {
 
300
                                        sessionData = session.SaveState ();
 
301
                                        session.DestroyWrapperWidgetPlug ();
 
302
                                }
 
303
 
 
304
                                // Don't dispose the session here, since it will dispose
 
305
                                // the underlying project, and we can't do it because
 
306
                                // it may need to process the OnBackendChanging event
 
307
                                // as well.
 
308
                        
 
309
                                CreateSession ();
 
310
                                
 
311
                                if (sessionData != null && session != null)
 
312
                                        session.RestoreState (sessionData);
 
313
 
 
314
                                base.OnBackendChanged (oldBackend);
 
315
                                NotifyRootWidgetChanged ();
 
316
                        }
 
317
                }
 
318
                
 
319
                void OnComponentTypesChanged (object s, EventArgs a)
 
320
                {
 
321
                        if (ComponentTypesChanged != null)
 
322
                                ComponentTypesChanged (this, a);
 
323
                }
 
324
                
 
325
                void OnSignalAdded (object sender, Stetic.ComponentSignalEventArgs args)
 
326
                {
 
327
                        if (SignalAdded != null)
 
328
                                SignalAdded (this, args);
 
329
                }
 
330
 
 
331
                void OnSignalRemoved (object sender, Stetic.ComponentSignalEventArgs args)
 
332
                {
 
333
                        if (SignalRemoved != null)
 
334
                                SignalRemoved (this, args);
 
335
                }
 
336
 
 
337
                void OnSignalChanged (object sender, Stetic.ComponentSignalEventArgs args)
 
338
                {
 
339
                        if (SignalChanged != null)
 
340
                                SignalChanged (this, args);
 
341
                }
 
342
                
 
343
                internal void NotifyBindField ()
 
344
                {
 
345
                        if (BindField != null)
 
346
                                BindField (this, EventArgs.Empty);
 
347
                }
 
348
                
 
349
                internal void NotifyModifiedChanged ()
 
350
                {
 
351
                        if (ModifiedChanged != null)
 
352
                                ModifiedChanged (this, EventArgs.Empty);
 
353
                }
 
354
                
 
355
                internal void NotifyChanged ()
 
356
                {
 
357
                        if (Changed != null)
 
358
                                Changed (this, EventArgs.Empty);
 
359
                }
 
360
                
 
361
                internal void NotifySelectionChanged (object ob, bool canCut, bool canCopy, bool canPaste, bool canDelete)
 
362
                {
 
363
                        this.canCut = canCut;
 
364
                        this.canCopy = canCopy;
 
365
                        this.canPaste = canPaste;
 
366
                        this.canDelete = canDelete;
 
367
                        
 
368
                        if (ob != null)
 
369
                                selection = app.GetComponent (ob, null, null);
 
370
                        else
 
371
                                selection = null;
 
372
 
 
373
                        if (SelectionChanged != null)
 
374
                                SelectionChanged (this, EventArgs.Empty);
 
375
                }
 
376
        }
 
377
        
 
378
        internal class WidgetDesignerFrontend: MarshalByRefObject
 
379
        {
 
380
                WidgetDesigner designer;
 
381
                internal bool disposed;
 
382
                
 
383
                public WidgetDesignerFrontend (WidgetDesigner designer)
 
384
                {
 
385
                        this.designer = designer;
 
386
                }
 
387
                
 
388
                public void NotifyBindField ()
 
389
                {
 
390
                        GuiDispatch.InvokeSync (
 
391
                                delegate { if (!disposed) designer.NotifyBindField (); }
 
392
                        );
 
393
                }
 
394
                
 
395
                public void NotifyModifiedChanged ()
 
396
                {
 
397
                        GuiDispatch.InvokeSync (
 
398
                                delegate { if (!disposed) designer.NotifyModifiedChanged (); }
 
399
                        );
 
400
                }
 
401
                
 
402
                public void NotifyChanged ()
 
403
                {
 
404
                        GuiDispatch.InvokeSync (
 
405
                                delegate { if (!disposed) designer.NotifyChanged (); }
 
406
                        );
 
407
                }
 
408
                
 
409
                internal void NotifySelectionChanged (object ob, bool canCut, bool canCopy, bool canPaste, bool canDelete)
 
410
                {
 
411
                        GuiDispatch.InvokeSync (
 
412
                                delegate { if (!disposed) designer.NotifySelectionChanged (ob, canCut, canCopy, canPaste, canDelete); }
 
413
                        );
 
414
                }
 
415
 
 
416
                public void NotifyRootWidgetChanged ()
 
417
                {
 
418
                        GuiDispatch.InvokeSync (
 
419
                                delegate { if (!disposed) designer.NotifyRootWidgetChanged (); }
 
420
                        );
 
421
                }
 
422
 
 
423
                public void NotifyRootWidgetChanging ()
 
424
                {
 
425
                        GuiDispatch.InvokeSync (
 
426
                                delegate { if (!disposed) designer.NotifyRootWidgetChanging (); }
 
427
                        );
 
428
                }
 
429
                
 
430
                public override object InitializeLifetimeService ()
 
431
                {
 
432
                        // Will be disconnected when calling Dispose
 
433
                        return null;
 
434
                }
 
435
        }
 
436
}