#region Disclaimer / License // Copyright (C) 2013, Jackie Ng // http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com // // Original code from SharpDevelop 3.2.1 licensed under the same terms (LGPL 2.1) // Copyright 2002-2010 by // // AlphaSierraPapa, Christoph Wille // Vordernberger Strasse 27/8 // A-8700 Leoben // Austria // // email: office@alphasierrapapa.com // court of jurisdiction: Landesgericht Leoben // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion Disclaimer / License using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Gui.CompletionWindow; using System; using System.Windows.Forms; namespace Maestro.Editors.Generic.XmlEditor.AutoCompletion { /// /// Provides the autocomplete (intellisense) data for an /// xml document that specifies a known schema. /// internal class XmlCompletionDataProvider : ICompletionDataProvider { private XmlSchemaCompletionDataCollection schemaCompletionDataItems; private XmlSchemaCompletionData defaultSchemaCompletionData; private string defaultNamespacePrefix = String.Empty; public XmlCompletionDataProvider(XmlSchemaCompletionDataCollection schemaCompletionDataItems, XmlSchemaCompletionData defaultSchemaCompletionData, string defaultNamespacePrefix) { this.schemaCompletionDataItems = schemaCompletionDataItems; this.defaultSchemaCompletionData = defaultSchemaCompletionData; this.defaultNamespacePrefix = defaultNamespacePrefix; DefaultIndex = 0; } private static ImageList smImageList; public ImageList ImageList { get { if (smImageList == null) { smImageList = new ImageList(); smImageList.Images.Add(Properties.Resources.document_code); } return smImageList; } } /// /// Overrides the default behaviour and allows special xml /// characters such as '.' and ':' to be used as completion data. /// public CompletionDataProviderKeyResult ProcessKey(char key) { if (key == '\r' || key == '\t') { return CompletionDataProviderKeyResult.InsertionKey; } return CompletionDataProviderKeyResult.NormalKey; } public ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped) { this.PreSelection = null; string text = String.Concat(textArea.Document.GetText(0, textArea.Caret.Offset), charTyped); switch (charTyped) { case '=': // Namespace intellisense. if (XmlParser.IsNamespaceDeclaration(text, text.Length)) { return schemaCompletionDataItems.GetNamespaceCompletionData(); } break; case '<': // Child element intellisense. XmlElementPath parentPath = XmlParser.GetParentElementPath(text); if (parentPath.Elements.Count > 0) { return GetChildElementCompletionData(parentPath); } else if (defaultSchemaCompletionData != null) { return defaultSchemaCompletionData.GetElementCompletionData(defaultNamespacePrefix); } break; case ' ': // Attribute intellisense. if (!XmlParser.IsInsideAttributeValue(text, text.Length)) { XmlElementPath path = XmlParser.GetActiveElementStartPath(text, text.Length); if (path.Elements.Count > 0) { return GetAttributeCompletionData(path); } } break; default: // Attribute value intellisense. if (XmlParser.IsAttributeValueChar(charTyped)) { string attributeName = XmlParser.GetAttributeName(text, text.Length); if (attributeName.Length > 0) { XmlElementPath elementPath = XmlParser.GetActiveElementStartPath(text, text.Length); if (elementPath.Elements.Count > 0) { this.PreSelection = charTyped.ToString(); return GetAttributeValueCompletionData(elementPath, attributeName); } } } break; } return null; } /// /// Finds the schema given the xml element path. /// public XmlSchemaCompletionData FindSchema(XmlElementPath path) { if (path.Elements.Count > 0) { string namespaceUri = path.Elements[0].Namespace; if (namespaceUri.Length > 0) { return schemaCompletionDataItems[namespaceUri]; } else if (defaultSchemaCompletionData != null) { // Use the default schema namespace if none // specified in a xml element path, otherwise // we will not find any attribute or element matches // later. foreach (QualifiedName name in path.Elements) { if (name.Namespace.Length == 0) { name.Namespace = defaultSchemaCompletionData.NamespaceUri; } } return defaultSchemaCompletionData; } } return null; } /// /// Finds the schema given a namespace URI. /// public XmlSchemaCompletionData FindSchema(string namespaceUri) { return schemaCompletionDataItems[namespaceUri]; } /// /// Gets the schema completion data that was created from the specified /// schema filename. /// public XmlSchemaCompletionData FindSchemaFromFileName(string fileName) { return schemaCompletionDataItems.GetSchemaFromFileName(fileName); } private ICompletionData[] GetChildElementCompletionData(XmlElementPath path) { ICompletionData[] completionData = null; XmlSchemaCompletionData schema = FindSchema(path); if (schema != null) { completionData = schema.GetChildElementCompletionData(path); } return completionData; } private ICompletionData[] GetAttributeCompletionData(XmlElementPath path) { ICompletionData[] completionData = null; XmlSchemaCompletionData schema = FindSchema(path); if (schema != null) { completionData = schema.GetAttributeCompletionData(path); } return completionData; } private ICompletionData[] GetAttributeValueCompletionData(XmlElementPath path, string name) { ICompletionData[] completionData = null; XmlSchemaCompletionData schema = FindSchema(path); if (schema != null) { completionData = schema.GetAttributeValueCompletionData(path, name); } return completionData; } public string PreSelection { get; private set; } public int DefaultIndex { get; } public bool InsertSpace { get; set; } public bool InsertAction(ICompletionData data, ICSharpCode.TextEditor.TextArea textArea, int insertionOffset, char key) { if (InsertSpace) { textArea.Document.Insert(insertionOffset++, " "); } textArea.Caret.Position = textArea.Document.OffsetToPosition(insertionOffset); return data.InsertAction(textArea, key); } } }