2
// WidgetEditSession.cs
7
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
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:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
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.
32
using System.Reflection;
33
using System.Collections;
39
internal class WidgetEditSession: MarshalByRefObject, IDisposable
42
Stetic.ProjectBackend sourceProject;
44
Stetic.ProjectBackend gproject;
45
Stetic.Wrapper.Container rootWidget;
46
Stetic.WidgetDesignerBackend widget;
49
bool autoCommitChanges;
50
WidgetActionBar toolbar;
51
WidgetDesignerFrontend frontend;
55
ContainerUndoRedoManager undoManager;
58
public event EventHandler ModifiedChanged;
59
public event EventHandler RootWidgetChanged;
60
public event Stetic.Wrapper.WidgetEventHandler SelectionChanged;
62
public WidgetEditSession (ProjectBackend sourceProject, WidgetDesignerFrontend frontend, string windowName, Stetic.ProjectBackend editingBackend, bool autoCommitChanges)
64
this.frontend = frontend;
65
this.autoCommitChanges = autoCommitChanges;
66
undoManager = new ContainerUndoRedoManager ();
67
undoQueue = new UndoQueue ();
68
undoManager.UndoQueue = undoQueue;
70
sourceWidget = windowName;
71
this.sourceProject = sourceProject;
73
if (!autoCommitChanges) {
74
// Reuse the action groups and icon factory of the main project
75
gproject = editingBackend;
77
// Attach will prevent the destruction of the action group list by gproject
78
gproject.AttachActionGroups (sourceProject.ActionGroups);
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;
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);
98
gproject.Modified = false;
101
rootWidget = sourceProject.GetTopLevelWrapper (windowName, true);
102
gproject = sourceProject;
105
rootWidget.Select ();
106
undoManager.RootObject = rootWidget;
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);
115
public bool AllowWidgetBinding {
116
get { return allowBinding; }
118
allowBinding = value;
120
toolbar.AllowWidgetBinding = allowBinding;
124
public Stetic.Wrapper.Widget GladeWidget {
125
get { return rootWidget; }
128
public Stetic.Wrapper.Container RootWidget {
129
get { return (Wrapper.Container) Component.GetSafeReference (rootWidget); }
132
public Gtk.Widget WrapperWidget {
134
if (designer == null) {
135
if (rootWidget == null)
137
Gtk.Container wc = rootWidget.Wrapped as Gtk.Container;
139
widget = Stetic.UserInterface.CreateWidgetDesigner (wc, rootWidget.DesignWidth, rootWidget.DesignHeight);
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;
156
public void CreateWrapperWidgetPlug (uint socketId)
158
Gdk.Threads.Enter ();
159
plug = new Gtk.Plug (socketId);
160
plug.Add (WrapperWidget);
161
plug.Decorated = false;
163
Gdk.Threads.Leave ();
166
public void DestroyWrapperWidgetPlug ()
168
if (designer != null) {
169
Gtk.Plug plug = (Gtk.Plug) WrapperWidget.Parent;
170
plug.Remove (WrapperWidget);
177
if (!autoCommitChanges) {
178
gproject.CopyWidgetToProject (rootWidget.Wrapped.Name, sourceProject, sourceWidget);
179
sourceWidget = rootWidget.Wrapped.Name;
180
gproject.Modified = false;
184
public ProjectBackend EditingBackend {
185
get { return gproject; }
188
public void Dispose ()
190
sourceProject.ComponentTypesChanged -= OnSourceProjectLibsChanged;
191
sourceProject.ProjectReloaded -= OnSourceProjectReloaded;
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);
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
214
System.Runtime.Remoting.RemotingServices.Disconnect (this);
218
public bool Disposed {
219
get { return disposed; }
222
public override object InitializeLifetimeService ()
224
// Will be disconnected when calling Dispose
228
public void SetDesignerActive ()
230
widget.UpdateObjectViewers ();
233
public bool Modified {
234
get { return gproject.Modified; }
237
public UndoQueue UndoQueue {
239
if (undoQueue != null)
242
return UndoQueue.Empty;
246
void OnModifiedChanged (object s, EventArgs a)
248
if (frontend != null)
249
frontend.NotifyModifiedChanged ();
252
void OnChanged (object s, EventArgs a)
254
if (frontend != null)
255
frontend.NotifyChanged ();
258
void OnSourceProjectReloaded (object s, EventArgs a)
260
// Propagate gtk version change
261
if (sourceProject.TargetGtkVersion != gproject.TargetGtkVersion)
262
gproject.TargetGtkVersion = sourceProject.TargetGtkVersion;
265
void OnSourceProjectLibsChanged (object s, EventArgs a)
267
// If component types have changed in the source project, they must also change
269
gproject.WidgetLibraries = (ArrayList) sourceProject.WidgetLibraries.Clone ();
270
gproject.InternalWidgetLibraries = (ArrayList) sourceProject.InternalWidgetLibraries.Clone ();
271
gproject.NotifyComponentTypesChanged ();
274
void OnProjectReloading (object s, EventArgs a)
276
if (frontend != null)
277
frontend.NotifyRootWidgetChanging ();
280
void OnProjectReloaded (object s, EventArgs a)
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 ();
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;
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 ();
309
gproject.NotifyComponentTypesChanged ();
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 ();
323
widget = Stetic.UserInterface.CreateWidgetDesigner (box, 100, 100);
326
OnRootWidgetChanged ();
329
void OnRootWidgetChanged ()
331
if (designer != null) {
332
if (designer.Parent is Gtk.Plug)
333
((Gtk.Plug)designer.Parent).Remove (designer);
338
Gdk.Threads.Enter ();
339
plug.Add (WrapperWidget);
341
Gdk.Threads.Leave ();
344
if (frontend != null)
345
frontend.NotifyRootWidgetChanged ();
346
if (RootWidgetChanged != null)
347
RootWidgetChanged (this, EventArgs.Empty);
350
void OnSelectionChanged (object ob, EventArgs a)
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;
366
canCut = canCopy = canPaste = canDelete = false;
369
frontend.NotifySelectionChanged (Component.GetSafeReference (obj), canCut, canCopy, canPaste, canDelete);
370
if (SelectionChanged != null)
371
SelectionChanged (this, new Stetic.Wrapper.WidgetEventArgs (wrapper));
375
public object SaveState ()
380
public void RestoreState (object sessionData)
384
internal void ClipboardCopySelection ()
386
IEditableObject editable = widget.Selection as IEditableObject;
387
if (editable == null)
388
editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
389
if (editable != null)
393
public void ClipboardCutSelection ()
395
IEditableObject editable = widget.Selection as IEditableObject;
396
if (editable == null)
397
editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
398
if (editable != null)
402
public void ClipboardPaste ()
404
IEditableObject editable = widget.Selection as IEditableObject;
405
if (editable == null)
406
editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
407
if (editable != null)
411
public void DeleteSelection ()
413
IEditableObject editable = widget.Selection as IEditableObject;
414
if (editable == null)
415
editable = ObjectWrapper.Lookup (widget.Selection) as IEditableObject;
416
if (editable != null)