5
using System.Collections;
6
using System.Collections.Generic;
7
using System.Collections.Specialized;
11
public class Project: MarshalByRefObject
14
ProjectBackend backend;
16
IResourceProvider resourceProvider;
18
string tmpProjectFile;
20
List<WidgetInfo> widgets = new List<WidgetInfo> ();
21
List<ActionGroupInfo> groups = new List<ActionGroupInfo> ();
23
ImportFileDelegate importFileDelegate;
25
public event WidgetInfoEventHandler WidgetAdded;
26
public event WidgetInfoEventHandler WidgetRemoved;
27
public event ComponentNameEventHandler ComponentNameChanged;
28
public event EventHandler ComponentTypesChanged;
30
public event EventHandler ActionGroupsChanged;
31
public event EventHandler ModifiedChanged;
32
public event EventHandler Changed;
36
internal event BackendChangingHandler BackendChanging;
37
internal event BackendChangedHandler BackendChanged;
38
internal event ComponentSignalEventHandler SignalAdded;
39
internal event ComponentSignalEventHandler SignalRemoved;
40
internal event ComponentSignalEventHandler SignalChanged;
42
public event EventHandler ProjectReloading;
43
public event EventHandler ProjectReloaded;
45
internal Project (Application app): this (app, null)
49
internal Project (Application app, ProjectBackend backend)
52
if (backend != null) {
53
this.backend = backend;
54
backend.SetFrontend (this);
57
app.BackendChanging += OnBackendChanging;
58
app.BackendChanged += OnBackendChanged;
61
internal ProjectBackend ProjectBackend {
63
if (backend == null) {
64
backend = app.Backend.CreateProject ();
65
backend.SetFrontend (this);
66
if (resourceProvider != null)
67
backend.ResourceProvider = resourceProvider;
69
backend.Load (fileName);
75
internal bool IsBackendLoaded {
76
get { return backend != null; }
79
internal Application App {
83
public void Dispose ()
85
app.BackendChanging -= OnBackendChanging;
86
app.BackendChanged -= OnBackendChanged;
88
if (tmpProjectFile != null && File.Exists (tmpProjectFile)) {
89
File.Delete (tmpProjectFile);
90
tmpProjectFile = null;
94
app.DisposeProject (this);
95
System.Runtime.Remoting.RemotingServices.Disconnect (this);
96
app.UpdateWidgetLibraries (false, false);
99
public override object InitializeLifetimeService ()
101
// Will be disconnected when calling Dispose
105
public string FileName {
106
get { return fileName; }
109
public IResourceProvider ResourceProvider {
110
get { return resourceProvider; }
112
resourceProvider = value;
114
backend.ResourceProvider = value;
118
public Stetic.ProjectIconFactory IconFactory {
119
get { return ProjectBackend.IconFactory; }
120
set { backend.IconFactory = value; }
123
public ImportFileDelegate ImportFileCallback {
124
get { return importFileDelegate; }
125
set { importFileDelegate = value; }
128
public bool CanGenerateCode {
129
get { return ProjectBackend.CanGenerateCode; }
132
public Component Selection {
133
get { return selection; }
136
public string ImagesRootPath {
137
get { return ProjectBackend.ImagesRootPath; }
138
set { ProjectBackend.ImagesRootPath = value; }
141
public string TargetGtkVersion {
142
get { return ProjectBackend.TargetGtkVersion; }
143
set { ProjectBackend.TargetGtkVersion = value; }
152
public void Load (string fileName)
154
this.fileName = fileName;
156
backend.Load (fileName);
158
using (StreamReader sr = new StreamReader (fileName)) {
159
XmlTextReader reader = new XmlTextReader (sr);
161
reader.MoveToContent ();
162
if (reader.IsEmptyElement)
165
reader.ReadStartElement ("stetic-interface");
166
if (reader.IsEmptyElement)
168
while (reader.NodeType != XmlNodeType.EndElement) {
169
if (reader.NodeType == XmlNodeType.Element) {
170
if (reader.LocalName == "widget")
172
else if (reader.LocalName == "action-group")
173
ReadActionGroup (reader);
180
reader.MoveToContent ();
185
void ReadWidget (XmlTextReader reader)
187
WidgetInfo w = new WidgetInfo (this, reader.GetAttribute ("id"), reader.GetAttribute ("class"));
189
if (reader.IsEmptyElement) {
193
reader.ReadStartElement ();
194
reader.MoveToContent ();
195
while (reader.NodeType != XmlNodeType.EndElement) {
196
if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "action-group") {
197
w.AddGroup (reader.GetAttribute ("name"));
200
reader.MoveToContent ();
202
reader.ReadEndElement ();
205
void ReadActionGroup (XmlTextReader reader)
207
groups.Add (new ActionGroupInfo (this, reader.GetAttribute ("name")));
211
public void Save (string fileName)
213
this.fileName = fileName;
215
backend.Save (fileName);
218
public void ImportGlade (string fileName)
220
ProjectBackend.ImportGlade (fileName);
223
public void ExportGlade (string fileName)
225
ProjectBackend.ExportGlade (fileName);
228
public bool Modified {
231
return backend.Modified;
237
backend.Modified = value;
243
public IEnumerable<WidgetInfo> Widgets {
244
get { return widgets; }
247
public IEnumerable<ActionGroupInfo> ActionGroups {
248
get { return groups; }
251
public WidgetInfo GetWidget (string name)
253
foreach (WidgetInfo w in widgets)
259
public ActionGroupInfo GetActionGroup (string name)
261
foreach (ActionGroupInfo w in groups)
267
public WidgetDesigner CreateWidgetDesigner (WidgetInfo widgetInfo, bool autoCommitChanges)
269
return new WidgetDesigner (this, widgetInfo.Name, autoCommitChanges);
272
public ActionGroupDesigner CreateActionGroupDesigner (ActionGroupInfo actionGroup, bool autoCommitChanges)
274
return new ActionGroupDesigner (this, null, actionGroup.Name, null, autoCommitChanges);
277
public WidgetInfo AddNewComponent (ComponentType type, string name)
279
object ob = ProjectBackend.AddNewWidget (type.Name, name);
280
WidgetComponent wc = (WidgetComponent) App.GetComponent (ob, null, null);
281
WidgetInfo wi = GetWidget (wc.Name);
283
wi = new WidgetInfo (this, wc);
289
public WidgetInfo AddNewComponent (XmlElement template)
291
object ob = ProjectBackend.AddNewWidgetFromTemplate (template.OuterXml);
292
WidgetComponent wc = (WidgetComponent) App.GetComponent (ob, null, null);
293
WidgetInfo wi = GetWidget (wc.Name);
295
wi = new WidgetInfo (this, wc);
301
public ComponentType[] GetComponentTypes ()
303
ArrayList types = new ArrayList ();
305
ArrayList typeNames = ProjectBackend.GetComponentTypes ();
306
for (int n=0; n<typeNames.Count; n++)
307
types.Add (app.GetComponentType ((string) typeNames [n]));
309
// Global action groups
310
foreach (ActionGroupComponent grp in GetActionGroups ()) {
311
foreach (ActionComponent ac in grp.GetActions ())
312
types.Add (new ComponentType (app, ac));
315
return (ComponentType[]) types.ToArray (typeof(ComponentType));
318
// Returns a list of all support widget types (including base classes)
319
public string[] GetWidgetTypes ()
321
return ProjectBackend.GetWidgetTypes ();
324
public void RemoveComponent (WidgetInfo component)
326
ProjectBackend.RemoveWidget (component.Name);
329
public WidgetComponent GetComponent (string name)
331
object ob = ProjectBackend.GetTopLevelWrapper (name, false);
333
return (WidgetComponent) App.GetComponent (ob, name, null);
338
public ActionGroupComponent AddNewActionGroup (string id)
340
object ob = ProjectBackend.AddNewActionGroup (id);
341
ActionGroupComponent ac = (ActionGroupComponent) App.GetComponent (ob, id, null);
343
// Don't wait for the group added event to come to update the groups list since
344
// it may be too late.
345
ActionGroupInfo gi = GetActionGroup (ac.Name);
347
gi = new ActionGroupInfo (this, ac.Name);
353
public ActionGroupComponent AddNewActionGroup (XmlElement template)
355
object ob = ProjectBackend.AddNewActionGroupFromTemplate (template.OuterXml);
356
ActionGroupComponent ac = (ActionGroupComponent) App.GetComponent (ob, null, null);
358
// Don't wait for the group added event to come to update the groups list since
359
// it may be too late.
360
ActionGroupInfo gi = GetActionGroup (ac.Name);
362
gi = new ActionGroupInfo (this, ac.Name);
368
public void RemoveActionGroup (ActionGroupInfo group)
370
ActionGroupComponent ac = (ActionGroupComponent) group.Component;
371
ProjectBackend.RemoveActionGroup ((Stetic.Wrapper.ActionGroup) ac.Backend);
374
internal ActionGroupComponent[] GetActionGroups ()
376
Wrapper.ActionGroup[] acs = ProjectBackend.GetActionGroups ();
378
ArrayList comps = new ArrayList (acs.Length);
379
for (int n=0; n<acs.Length; n++) {
380
ActionGroupComponent ag = (ActionGroupComponent) App.GetComponent (acs[n], null, null);
385
return (ActionGroupComponent[]) comps.ToArray (typeof(ActionGroupComponent));
388
public void AddWidgetLibrary (string assemblyPath)
390
AddWidgetLibrary (assemblyPath, false);
393
public void AddWidgetLibrary (string assemblyPath, bool isInternal)
395
reloadRequested = false;
396
ProjectBackend.AddWidgetLibrary (assemblyPath);
397
app.UpdateWidgetLibraries (false, false);
398
if (!reloadRequested)
399
ProjectBackend.Reload ();
402
public void RemoveWidgetLibrary (string assemblyPath)
404
reloadRequested = false;
405
ProjectBackend.RemoveWidgetLibrary (assemblyPath);
406
app.UpdateWidgetLibraries (false, false);
407
if (!reloadRequested)
408
ProjectBackend.Reload ();
411
public string[] WidgetLibraries {
413
return (string[]) ProjectBackend.WidgetLibraries.ToArray (typeof(string));
417
public void SetWidgetLibraries (string[] libraries, string[] internalLibraries)
419
reloadRequested = false;
421
ArrayList libs = new ArrayList ();
422
libs.AddRange (libraries);
423
libs.AddRange (internalLibraries);
424
ProjectBackend.WidgetLibraries = libs;
426
libs = new ArrayList ();
427
libs.AddRange (internalLibraries);
428
ProjectBackend.InternalWidgetLibraries = libs;
430
app.UpdateWidgetLibraries (false, false);
431
if (!reloadRequested)
432
ProjectBackend.Reload ();
435
/* public bool CanCopySelection {
436
get { return Selection != null ? Selection.CanCopy : false; }
439
public bool CanCutSelection {
440
get { return Selection != null ? Selection.CanCut : false; }
443
public bool CanPasteToSelection {
444
get { return Selection != null ? Selection.CanPaste : false; }
447
public void CopySelection ()
449
if (Selection != null)
450
backend.ClipboardCopySelection ();
453
public void CutSelection ()
455
if (Selection != null)
456
backend.ClipboardCutSelection ();
459
public void PasteToSelection ()
461
if (Selection != null)
462
backend.ClipboardPaste ();
465
public void DeleteSelection ()
467
backend.DeleteSelection ();
471
public void EditIcons ()
473
ProjectBackend.EditIcons ();
476
internal void NotifyWidgetAdded (object obj, string name, string typeName)
478
GuiDispatch.InvokeSync (
480
Component c = App.GetComponent (obj, name, typeName);
482
WidgetInfo wi = GetWidget (c.Name);
484
wi = new WidgetInfo (this, c);
487
if (WidgetAdded != null)
488
WidgetAdded (this, new WidgetInfoEventArgs (this, wi));
494
internal void NotifyWidgetRemoved (string name)
496
GuiDispatch.InvokeSync (
498
WidgetInfo wi = GetWidget (name);
501
if (WidgetRemoved != null)
502
WidgetRemoved (this, new WidgetInfoEventArgs (this, wi));
508
internal void NotifyModifiedChanged ()
510
GuiDispatch.InvokeSync (
512
if (ModifiedChanged != null)
513
ModifiedChanged (this, EventArgs.Empty);
518
internal void NotifyChanged ()
520
GuiDispatch.InvokeSync (
523
Changed (this, EventArgs.Empty);
526
foreach (ProjectItemInfo it in widgets)
528
foreach (ProjectItemInfo it in groups)
534
internal void NotifyWidgetNameChanged (object obj, string oldName, string newName, bool isRoot)
536
WidgetComponent c = obj != null ? (WidgetComponent) App.GetComponent (obj, null, null) : null;
538
c.UpdateName (newName);
541
WidgetInfo wi = GetWidget (oldName);
543
wi.NotifyNameChanged (newName);
546
GuiDispatch.InvokeSync (
549
if (ComponentNameChanged != null)
550
ComponentNameChanged (this, new ComponentNameEventArgs (this, c, oldName));
556
internal void NotifyActionGroupAdded (string group)
558
GuiDispatch.InvokeSync (delegate {
559
ActionGroupInfo gi = GetActionGroup (group);
561
gi = new ActionGroupInfo (this, group);
564
if (ActionGroupsChanged != null)
565
ActionGroupsChanged (this, EventArgs.Empty);
569
internal void NotifyActionGroupRemoved (string group)
571
GuiDispatch.InvokeSync (delegate {
572
ActionGroupInfo gi = GetActionGroup (group);
575
if (ActionGroupsChanged != null)
576
ActionGroupsChanged (this, EventArgs.Empty);
581
internal void NotifySignalAdded (object obj, string name, Signal signal)
583
GuiDispatch.InvokeSync (delegate {
584
if (SignalAdded != null) {
585
Component c = App.GetComponent (obj, name, null);
587
SignalAdded (this, new ComponentSignalEventArgs (this, c, null, signal));
592
internal void NotifySignalRemoved (object obj, string name, Signal signal)
594
GuiDispatch.InvokeSync (delegate {
595
if (SignalRemoved != null) {
596
Component c = App.GetComponent (obj, name, null);
598
SignalRemoved (this, new ComponentSignalEventArgs (this, c, null, signal));
603
internal void NotifySignalChanged (object obj, string name, Signal oldSignal, Signal signal)
605
GuiDispatch.InvokeSync (delegate {
606
if (SignalChanged != null) {
607
Component c = App.GetComponent (obj, name, null);
609
SignalChanged (this, new ComponentSignalEventArgs (this, c, oldSignal, signal));
614
internal void NotifyProjectReloaded ()
616
GuiDispatch.InvokeSync (delegate {
617
if (ProjectReloaded != null)
618
ProjectReloaded (this, EventArgs.Empty);
622
internal void NotifyProjectReloading ()
624
GuiDispatch.InvokeSync (delegate {
625
if (ProjectReloading != null)
626
ProjectReloading (this, EventArgs.Empty);
630
internal void NotifyComponentTypesChanged ()
632
GuiDispatch.InvokeSync (delegate {
633
if (ComponentTypesChanged != null)
634
ComponentTypesChanged (this, EventArgs.Empty);
638
internal string ImportFile (string filePath)
640
if (importFileDelegate != null) {
642
GuiDispatch.InvokeSync (delegate {
643
res = importFileDelegate (filePath);
651
internal void NotifyUpdateLibraries ()
653
app.UpdateWidgetLibraries (false, false);
656
void OnBackendChanging ()
660
if (BackendChanging != null)
664
void OnBackendChanged (ApplicationBackend oldBackend)
666
if (oldBackend != null) {
667
tmpProjectFile = Path.GetTempFileName ();
668
backend.Save (tmpProjectFile);
671
backend = app.Backend.CreateProject ();
672
backend.SetFrontend (this);
674
if (tmpProjectFile != null && File.Exists (tmpProjectFile)) {
675
backend.Load (tmpProjectFile, fileName);
676
File.Delete (tmpProjectFile);
677
tmpProjectFile = null;
678
} else if (fileName != null) {
679
backend.Load (fileName);
682
if (resourceProvider != null)
683
backend.ResourceProvider = resourceProvider;
685
if (BackendChanged != null)
686
BackendChanged (oldBackend);
688
if (ProjectReloaded != null)
689
ProjectReloaded (this, EventArgs.Empty);
693
public abstract class ProjectItemInfo
696
protected Project project;
698
public event EventHandler Changed;
700
internal ProjectItemInfo (Project project, string name)
703
this.project = project;
708
set { Component.Name = value; name = value; }
711
internal void NotifyNameChanged (string name)
717
internal void NotifyChanged ()
720
Changed (this, EventArgs.Empty);
723
public abstract Component Component { get; }
726
public class WidgetInfo: ProjectItemInfo
729
List<ActionGroupInfo> groups;
731
internal WidgetInfo (Project project, string name, string type): base (project, name)
736
internal WidgetInfo (Project project, Component c): base (project, c.Name)
741
public IEnumerable<ActionGroupInfo> ActionGroups {
746
return new ActionGroupInfo [0];
754
public bool IsWindow {
755
get { return type == "Gtk.Dialog" || type == "Gtk.Window"; }
758
public override Component Component {
759
get { return project.GetComponent (Name); }
762
internal void AddGroup (string group)
765
groups = new List<ActionGroupInfo> ();
766
groups.Add (new ActionGroupInfo (project, group, Name));
770
public class ActionGroupInfo: ProjectItemInfo
774
internal ActionGroupInfo (Project project, string name): base (project, name)
778
internal ActionGroupInfo (Project project, string name, string widgetName): base (project, name)
780
this.widgetName = widgetName;
783
public override Component Component {
785
ActionGroupComponent[] ags;
786
if (widgetName != null) {
787
WidgetComponent c = project.GetComponent (widgetName) as WidgetComponent;
790
ags = c.GetActionGroups ();
793
ags = project.GetActionGroups ();
795
foreach (ActionGroupComponent ag in ags)
803
public delegate string ImportFileDelegate (string fileName);