PageRenderTime 2ms CodeModel.GetById 21ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/extras/MonoDevelop.AddinAuthoring/MonoDevelop.AddinAuthoring.NodeBuilders/ExtensionNodeNodeBuilder.cs

https://github.com/jfcantin/monodevelop
C# | 316 lines | 282 code | 8 blank | 26 comment | 1 complexity | c94a48c23ddcf56cf60b2ef9abb32a4a MD5 | raw file
  1// ExtensionPointsNodeBuilder.cs
  2//
  3// Author:
  4//   Lluis Sanchez Gual <lluis@novell.com>
  5//
  6// Copyright (c) 2007 Novell, Inc (http://www.novell.com)
  7//
  8// Permission is hereby granted, free of charge, to any person obtaining a copy
  9// of this software and associated documentation files (the "Software"), to deal
 10// in the Software without restriction, including without limitation the rights
 11// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12// copies of the Software, and to permit persons to whom the Software is
 13// furnished to do so, subject to the following conditions:
 14//
 15// The above copyright notice and this permission notice shall be included in
 16// all copies or substantial portions of the Software.
 17//
 18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24// THE SOFTWARE.
 25//
 26//
 27
 28using System;
 29using MonoDevelop.Projects;
 30using MonoDevelop.Core;
 31using MonoDevelop.Ide;
 32using MonoDevelop.Ide.Gui;
 33using MonoDevelop.Ide.Gui.Pads;
 34using MonoDevelop.Ide.Gui.Pads.ProjectPad;
 35using MonoDevelop.Components.Commands;
 36using Mono.Addins;
 37using Mono.Addins.Description;
 38using MonoDevelop.Ide.Gui.Components;
 39using Gdk;
 40 
 41using System.Text;
 42
 43namespace MonoDevelop.AddinAuthoring.NodeBuilders
 44{
 45	public class ExtensionNodeNodeBuilder: ExtensionModelTypeNodeBuilder
 46	{
 47		public override Type NodeDataType {
 48			get { return typeof(ExtensionNodeInfo); }
 49		}
 50		
 51		public override Type CommandHandlerType {
 52			get { return typeof(ExtensionNodeCommandHandler); }
 53		}
 54		
 55		public override string ContextMenuAddinPath {
 56			get { return "/MonoDevelop/AddinAuthoring/ContextMenu/ExtensionModelPad/ExtensionNode"; }
 57		}
 58		
 59		public override string GetNodeName (ITreeNavigator thisNode, object dataObject)
 60		{
 61			ExtensionNodeInfo ep = (ExtensionNodeInfo) dataObject;
 62			return ep.Node.Id;
 63		}
 64
 65		public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, ref string label, ref Pixbuf icon, ref Pixbuf closedIcon)
 66		{
 67			ExtensionNodeInfo ninfo = (ExtensionNodeInfo) dataObject;
 68			ExtensionNodeDescription node = ninfo.Node;
 69			
 70			label = GLib.Markup.EscapeText (node.NodeName);
 71			StringBuilder desc = new StringBuilder ();
 72			foreach (NodeAttribute at in node.Attributes) {
 73				if (desc.Length > 0)
 74					desc.Append ("  ");
 75				desc.Append (at.Name).Append ("=\"").Append (GLib.Markup.EscapeText (at.Value)).Append ('"');
 76			}
 77			if (desc.Length > 0)
 78				label += "(<i>" + desc + "</i>)";
 79			
 80			icon = Context.GetIcon ("md-extension-node");
 81			
 82			if (treeBuilder.Options ["ShowExistingNodes"] && !ninfo.CanModify) {
 83				Gdk.Pixbuf gicon = Context.GetComposedIcon (icon, "fade");
 84				if (gicon == null) {
 85					gicon = ImageService.MakeTransparent (icon, 0.5);
 86					Context.CacheComposedIcon (icon, "fade", gicon);
 87				}
 88				icon = gicon;
 89			}
 90		}
 91		
 92		public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject)
 93		{
 94			ExtensionNodeInfo en = (ExtensionNodeInfo) dataObject;
 95			foreach (ExtensionNodeInfo child in en.Expand ())
 96				treeBuilder.AddChild (child);
 97		}
 98
 99		public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
100		{
101			ExtensionNodeInfo en = (ExtensionNodeInfo) dataObject;
102			return en.HasChildren;
103		}
104		
105		public override int CompareObjects (ITreeNavigator thisNode, ITreeNavigator otherNode)
106		{
107			ExtensionNodeInfo n1 = thisNode.DataItem as ExtensionNodeInfo;
108			ExtensionNodeInfo n2 = otherNode.DataItem as ExtensionNodeInfo;
109			if (n1 != null && n2 != null)
110				return n1.Order.CompareTo (n2.Order);
111			else
112				return base.CompareObjects (thisNode, otherNode);
113		}
114		
115		public override void OnNodeAdded (object dataObject)
116		{
117			ExtensionNodeInfo en = (ExtensionNodeInfo) dataObject;
118			en.Changed += HandleNodeChanged;
119		}
120		
121		public override void OnNodeRemoved (object dataObject)
122		{
123			ExtensionNodeInfo en = (ExtensionNodeInfo) dataObject;
124			en.Changed -= HandleNodeChanged;
125		}
126
127		void HandleNodeChanged (object sender, EventArgs e)
128		{
129			ITreeBuilder builder = Context.GetTreeBuilder (sender);
130			if (builder != null)
131				builder.UpdateAll ();
132		}
133
134	}
135	
136	class ExtensionNodeCommandHandler: NodeCommandHandler
137	{
138		public override DragOperation CanDragNode ()
139		{
140			ExtensionNodeInfo en = (ExtensionNodeInfo) CurrentNode.DataItem;
141			if (en.CanModify)
142				return DragOperation.Copy | DragOperation.Move;
143			else
144				return DragOperation.None;
145		}
146		
147		public override bool CanDropNode (object dataObject, DragOperation operation, DropPosition pos)
148		{
149			object parent1 = CurrentNode.GetParentDataItem (typeof(Extension), false);
150			if (parent1 == null)
151				parent1 = CurrentNode.GetParentDataItem (typeof(ExtensionPoint), false);
152			
153			ITreeNavigator nav = CurrentNode.Clone ();
154			if (!nav.MoveToObject (dataObject))
155				return false;
156			object parent2 = nav.GetParentDataItem (parent1.GetType (), false);
157			if (parent2 != parent1)
158				return false;
159			
160			return true;
161		}
162		
163		public override void OnMultipleNodeDrop (object[] dataObjects, DragOperation operation, DropPosition pos)
164		{
165			DotNetProject p = (DotNetProject) CurrentNode.GetParentDataItem (typeof(Project), false);
166			AddinData adata = p.GetAddinData ();
167			
168			ExtensionNodeInfo en = (ExtensionNodeInfo) CurrentNode.DataItem;
169
170			foreach (ExtensionNodeInfo newNode in dataObjects) {
171				if (newNode.Node.Parent is ExtensionNodeDescription)
172					((ExtensionNodeDescription)newNode.Node.Parent).ChildNodes.Remove (en.Node);
173				else
174					((Extension)newNode.Node.Parent).ExtensionNodes.Remove (newNode.Node);
175				InsertNode (adata, en, pos, newNode.Node);
176				
177				// Add all other nodes after the first node
178				en = newNode;
179				pos = DropPosition.After;
180			}
181			
182			adata.CachedAddinManifest.Save ();
183			adata.NotifyChanged (false);
184		}
185
186		[CommandUpdateHandler (Commands.AddNodeAfter)]
187		public void UpdateAddNodeAfter (CommandArrayInfo cinfo)
188		{
189			foreach (ExtensionNodeType ntype in GetAllowedChildTypes ()) {
190				cinfo.Add (ntype.NodeName, ntype);
191			}
192		}
193		
194		[CommandHandler (Commands.AddNodeAfter)]
195		public void AddNodeAfter (object data)
196		{
197			DotNetProject p = (DotNetProject) CurrentNode.GetParentDataItem (typeof(Project), false);
198			AddinData adata = p.GetAddinData ();
199			
200			ExtensionNodeInfo en = (ExtensionNodeInfo) CurrentNode.DataItem;
201			ExtensionNodeType ntype = (ExtensionNodeType) data;
202			ExtensionNodeDescription newNode = new ExtensionNodeDescription (ntype.NodeName);
203			InsertNode (adata, en, DropPosition.After, newNode);
204			
205			adata.CachedAddinManifest.Save ();
206			adata.NotifyChanged (false);
207		}
208
209		
210		[CommandUpdateHandler (Commands.AddNodeBefore)]
211		public void UpdateAddNodeBefore (CommandArrayInfo cinfo)
212		{
213			foreach (ExtensionNodeType ntype in GetAllowedChildTypes ()) {
214				cinfo.Add (ntype.NodeName, ntype);
215			}
216		}
217		
218		[CommandHandler (Commands.AddNodeBefore)]
219		public void AddNodeBefore (object data)
220		{
221			DotNetProject p = (DotNetProject) CurrentNode.GetParentDataItem (typeof(Project), false);
222			AddinData adata = p.GetAddinData ();
223			
224			ExtensionNodeInfo en = (ExtensionNodeInfo) CurrentNode.DataItem;
225			ExtensionNodeType ntype = (ExtensionNodeType) data;
226			ExtensionNodeDescription newNode = new ExtensionNodeDescription (ntype.NodeName);
227			InsertNode (adata, en, DropPosition.Before, newNode);
228			
229			adata.CachedAddinManifest.Save ();
230			adata.NotifyChanged (false);
231		}
232		
233		ExtensionNodeDescription InsertNode (AddinData adata, ExtensionNodeInfo refNode, DropPosition pos, ExtensionNodeDescription newNode)
234		{
235			ExtensionNodeDescriptionCollection nodes = null;
236			newNode.InsertBefore = "";
237			newNode.InsertAfter = "";
238			
239			if (refNode.CanModify) {
240				if (pos == DropPosition.Into)
241					nodes = refNode.Node.ChildNodes;
242				else if (refNode.Node.Parent is ExtensionNodeDescription)
243					nodes = ((ExtensionNodeDescription)refNode.Node.Parent).ChildNodes;
244			} else {
245				if (pos == DropPosition.After)
246				    newNode.InsertAfter = refNode.Node.Id;
247				else if (pos == DropPosition.Before)
248					newNode.InsertBefore = refNode.Node.Id;
249			}
250			if (nodes == null) {
251				string path = refNode.Node.GetParentPath ();
252				if (pos == DropPosition.Into)
253					path += "/" + refNode.Node.Id;
254				Extension ext = adata.CachedAddinManifest.MainModule.GetExtension (path);
255				nodes = ext.ExtensionNodes;
256			}
257
258			for (int n = 0; n < nodes.Count; n++) {
259				ExtensionNodeDescription node = nodes [n];
260				if (node == refNode.Node) {
261					if (pos == DropPosition.After) n++;
262					nodes.Insert (n, newNode);
263					return newNode;
264				}
265			}
266			nodes.Add (newNode);
267			return newNode;
268		}
269		
270		ExtensionNodeTypeCollection GetAllowedChildTypes ()
271		{
272			ExtensionNodeInfo en = (ExtensionNodeInfo) CurrentNode.DataItem;
273			object parent = en.Node.Parent;
274			
275			Extension ext = parent as Extension;
276			if (ext != null)
277				return ext.GetAllowedNodeTypes ();
278			else {
279				ExtensionNodeDescription node = (ExtensionNodeDescription) parent;
280				if (node != null) {
281					ExtensionNodeType tn = node.GetNodeType ();
282					if (tn != null)
283						return tn.GetAllowedNodeTypes ();
284				}
285			}
286			return new ExtensionNodeTypeCollection ();
287		}		
288		
289		public override bool CanDeleteMultipleItems ()
290		{
291			foreach (var nav in CurrentNodes) {
292				ExtensionNodeInfo en = (ExtensionNodeInfo) nav.DataItem;
293				if (!en.CanModify)
294					return false;
295			}
296			return true;
297		}
298		
299		public override void DeleteMultipleItems ()
300		{
301			if (MessageService.Confirm (GettextCatalog.GetString ("Are you sure you want to delete the selected nodes?"), AlertButton.Delete)) {
302				foreach (var nav in CurrentNodes) {
303					ExtensionNodeInfo en = (ExtensionNodeInfo) nav.DataItem;
304					if (en.Node.Parent is Extension)
305						((Extension)en.Node.Parent).ExtensionNodes.Remove (en.Node);
306					else if (en.Node.Parent is ExtensionNodeDescription)
307						((ExtensionNodeDescription)en.Node.Parent).ChildNodes.Remove (en.Node);
308				}
309			}
310			DotNetProject p = (DotNetProject) CurrentNode.GetParentDataItem (typeof(Project), false);
311			AddinData adata = p.GetAddinData ();
312			adata.SaveAddinManifest ();
313			adata.NotifyChanged (false);
314		}
315	}
316}