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

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.XmlEditor/MonoDevelop.XmlEditor/XmlTextEditorExtension.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
using MonoDevelop.Xml.StateEngine;
42
42
using MonoDevelop.Ide.Tasks;
43
43
using MonoDevelop.Ide;
 
44
using MonoDevelop.Ide.CodeFormatting;
44
45
 
45
46
namespace MonoDevelop.XmlEditor
46
47
{
47
 
        
48
 
        
49
48
        public class XmlTextEditorExtension : MonoDevelop.XmlEditor.Gui.BaseXmlEditorExtension
50
49
        {
51
50
                const string TextXmlMimeType = "text/xml";
72
71
                public override void Initialize ()
73
72
                {
74
73
                        base.Initialize ();
75
 
                        XmlEditorOptions.XmlSchemaAssociationChanged += HandleXmlSchemaAssociationChanged;
 
74
                        XmlEditorOptions.XmlFileAssociationChanged += HandleXmlFileAssociationChanged;
76
75
                        XmlSchemaManager.UserSchemaAdded += UserSchemaAdded;
77
76
                        XmlSchemaManager.UserSchemaRemoved += UserSchemaRemoved;
78
77
                        SetDefaultSchema (FileExtension);
88
87
                        }
89
88
                }
90
89
 
91
 
                void HandleXmlSchemaAssociationChanged (object sender, XmlSchemaAssociationChangedEventArgs e)
 
90
                void HandleXmlFileAssociationChanged (object sender, XmlFileAssociationChangedEventArgs e)
92
91
                {
93
92
                        if (e.Extension == FileExtension)
94
93
                                SetDefaultSchema (FileExtension);
99
98
                {
100
99
                        if (!disposed) {
101
100
                                disposed = false;
102
 
                                XmlEditorOptions.XmlSchemaAssociationChanged -= HandleXmlSchemaAssociationChanged;
 
101
                                XmlEditorOptions.XmlFileAssociationChanged -= HandleXmlFileAssociationChanged;
103
102
                                XmlSchemaManager.UserSchemaAdded -= UserSchemaAdded;
104
103
                                XmlSchemaManager.UserSchemaRemoved -= UserSchemaRemoved;
105
104
                                base.Dispose ();
108
107
                
109
108
                #region Code completion
110
109
                
111
 
//              IEditableTextBuffer GetBuffer ()
112
 
//              {
113
 
//                      IEditableTextBuffer buf = Document.GetContent<IEditableTextBuffer> ();
114
 
//                      System.Diagnostics.Debug.Assert (buf != null);
115
 
//                      return buf;
116
 
//              }
117
 
                
118
 
                XmlElementPath GetCurrentPath ()
 
110
                XmlElementPath GetElementPath ()
119
111
                {
120
 
                        return ConvertPath (Tracker.Engine.Nodes.OfType<XElement> ().Reverse ());
 
112
                        return ConvertPath (GetCurrentPath ());
121
113
                }
122
114
                
123
 
                static XmlElementPath ConvertPath (IEnumerable<XElement> path)
 
115
                XmlElementPath ConvertPath (IList<XObject> path)
124
116
                {
125
 
                        XmlElementPath elementPath = new XmlElementPath ();
126
 
                        var namespaces = new Dictionary<string, string> ();
127
 
                        string defaultNamespace = null;
128
 
                        foreach (XElement el in path) {
129
 
                                foreach (XAttribute att in el.Attributes) {
130
 
                                        if (att.Name.HasPrefix) {
131
 
                                                if (att.Name.Prefix == "xmlns")
132
 
                                                        namespaces [att.Name.Name] = att.Value;
133
 
                                        } else {
134
 
                                                if (att.Name.Name == "xmlns")
135
 
                                                        defaultNamespace = att.Value;
 
117
                        var elementPath = new XmlElementPath ();
 
118
                        
 
119
                        if (defaultSchemaCompletionData != null && !string.IsNullOrEmpty (defaultSchemaCompletionData.NamespaceUri))
 
120
                                elementPath.Namespaces.AddPrefix (defaultSchemaCompletionData.NamespaceUri, defaultNamespacePrefix ?? "");
 
121
                        
 
122
                        foreach (var obj in path) {
 
123
                                var el = obj as XElement;
 
124
                                if (el == null)
 
125
                                        continue;
 
126
                                foreach (var att in el.Attributes) {
 
127
                                        if (!string.IsNullOrEmpty (att.Value)) {
 
128
                                                if (att.Name.HasPrefix) {
 
129
                                                        if (att.Name.Prefix == "xmlns")
 
130
                                                                elementPath.Namespaces.AddPrefix (att.Value, att.Name.Name);
 
131
                                                } else if (att.Name.Name == "xmlns") {
 
132
                                                                elementPath.Namespaces.AddPrefix (att.Value, "");
 
133
                                                }
136
134
                                        }
137
135
                                }
138
 
                                string ns = null;
139
 
                                if (el.Name.HasPrefix)
140
 
                                        namespaces.TryGetValue (el.Name.Prefix, out ns);
141
 
                                else
142
 
                                        ns = defaultNamespace;
 
136
                                string ns = elementPath.Namespaces.GetNamespace (el.Name.HasPrefix? el.Name.Prefix : "");
143
137
                                QualifiedName qn = new QualifiedName (el.Name.Name, ns, el.Name.Prefix ?? String.Empty);
144
138
                                elementPath.Elements.Add (qn);
145
139
                        }
148
142
                
149
143
                protected override void GetElementCompletions (CompletionDataList list)
150
144
                {       
151
 
                        XmlElementPath path = GetCurrentPath ();
 
145
                        var path = GetElementPath ();
152
146
                        if (path.Elements.Count > 0) {
153
147
                                IXmlCompletionProvider schema = FindSchema (path);
154
148
                                if (schema == null)
155
149
                                        schema = inferredCompletionData;
156
150
                                if (schema != null) {
157
 
                                        CompletionData[] completionData = schema.GetChildElementCompletionData (path);
 
151
                                        var completionData = schema.GetChildElementCompletionData (path);
158
152
                                        if (completionData != null)
159
153
                                                list.AddRange (completionData);
160
154
                                }
163
157
                        } else if (inferredCompletionData != null) {
164
158
                                list.AddRange (inferredCompletionData.GetElementCompletionData ());
165
159
                        }
 
160
                        AddMiscBeginTags (list);
166
161
                }
167
162
                
168
163
                protected override CompletionDataList GetAttributeCompletions (IAttributedXObject attributedOb,
169
164
                        Dictionary<string, string> existingAtts)
170
165
                {
171
 
                        XmlElementPath path = GetCurrentPath ();
 
166
                        var path = GetElementPath ();
172
167
                        if (path.Elements.Count > 0) {
173
168
                                IXmlCompletionProvider schema = FindSchema (path);
174
169
                                if (schema == null)
175
170
                                        schema = inferredCompletionData;
176
 
                                if (schema != null) {
177
 
                                        CompletionData[] completionData = schema.GetAttributeCompletionData (path);
178
 
                                        if (completionData != null)
179
 
                                                return new CompletionDataList (completionData);
180
 
                                }
 
171
                                if (schema != null)
 
172
                                        return schema.GetAttributeCompletionData (path);
181
173
                        }
182
174
                        return null;
183
175
                }
184
176
                
185
177
                protected override CompletionDataList GetAttributeValueCompletions (IAttributedXObject attributedOb, XAttribute att)
186
178
                {
187
 
                        XmlElementPath path = GetCurrentPath ();
 
179
                        var path = GetElementPath ();
188
180
                        if (path.Elements.Count > 0) {
189
 
                                XmlSchemaCompletionData schema = FindSchema (path);
190
 
                                if (schema != null) {
191
 
                                        CompletionData[] completionData = schema.GetAttributeValueCompletionData (path, att.Name.FullName);
192
 
                                        if (completionData != null)
193
 
                                                return new CompletionDataList (completionData);
194
 
                                }
 
181
                                var schema = FindSchema (path);
 
182
                                if (schema != null)
 
183
                                        return schema.GetAttributeValueCompletionData (path, att.Name.FullName);
195
184
                        }
196
185
                        return null;
197
186
                }
253
242
                public XmlSchemaObject GetSchemaObjectSelected (XmlSchemaCompletionData currentSchemaCompletionData)
254
243
                {
255
244
                        // Find element under cursor.
256
 
                        XmlElementPath path = GetCurrentPath ();
 
245
                        XmlElementPath path = GetElementPath ();
257
246
                        
258
247
                        //attribute name under cursor, if valid
259
248
                        string attributeName = null;
273
262
                                XmlSchemaElement element = schemaCompletionData.FindElement(path);
274
263
                                schemaObject = element;
275
264
                                if (element != null) {
276
 
                                        if (attributeName.Length > 0) {
 
265
                                        if (!string.IsNullOrEmpty (attributeName)) {
277
266
                                                XmlSchemaAttribute attribute = schemaCompletionData.FindAttribute(element, attributeName);
278
267
                                                if (attribute != null) {
279
268
                                                        if (currentSchemaCompletionData != null) {
468
457
                                        return true;
469
458
                        }
470
459
                        
471
 
                        return XmlFileExtensions.IsXmlFileExtension (System.IO.Path.GetExtension (fileName));
 
460
                        return XmlFileAssociationManager.IsXmlFileExtension (System.IO.Path.GetExtension (fileName));
472
461
                }
473
462
                
474
463
                public static bool IsMimeTypeHandled (string mimeType)
486
475
                        
487
476
                        if (TextEditorProperties.IndentStyle == IndentStyle.Smart && key == Gdk.Key.Return) {
488
477
                                result = base.KeyPress (key, keyChar, modifier);
489
 
                                SmartIndentLine (Editor.CursorLine);
 
478
                                SmartIndentLine (Editor.Caret.Line);
490
479
                                return result;
491
480
                        }
492
481
                        return base.KeyPress (key, keyChar, modifier);
523
512
                        while (i > 0) {
524
513
                                char c = Editor.GetCharAt (i);
525
514
                                if (c == '\n' || c == '\r')
526
 
                                        return Editor.GetText (i + 1, indentEnd);
 
515
                                        return Editor.GetTextBetween (i + 1, indentEnd);
527
516
                                if (!char.IsWhiteSpace (c))
528
517
                                        indentEnd--;
529
518
                                i--;
547
536
                        //FIXME: implement
548
537
                }
549
538
                
550
 
                [CommandHandler (Commands.Format)]
551
 
                public void FormatCommand ()
552
 
                {
553
 
                        TaskService.Errors.Clear ();
554
 
                        
555
 
                        using (IProgressMonitor monitor = XmlEditorService.GetMonitor ()) {
556
 
                                bool selection = (Editor.SelectionEndPosition - Editor.SelectionStartPosition) > 0;
557
 
                                string xml = selection? Editor.SelectedText : Editor.Text;
558
 
                                XmlDocument doc = XmlEditorService.ValidateWellFormedness (monitor, xml, FileName);
559
 
                                if (doc == null)
560
 
                                        return;
561
 
                                
562
 
                                //if there's a line indent at the current location, prepend that to all new lines
563
 
                                string extraIndent = null;
564
 
                                if (selection)
565
 
                                        extraIndent = GetPositionIndent (Editor.SelectionStartPosition);
566
 
                                
567
 
                                string formattedXml = XmlEditorService.IndentedFormat (xml);
568
 
                                
569
 
                                //convert newlines and prepend extra indents to each line if needed
570
 
                                bool nonNativeNewline = (Editor.NewLine != Environment.NewLine);
571
 
                                bool hasExtraIndent = !string.IsNullOrEmpty (extraIndent);
572
 
                                if (hasExtraIndent || nonNativeNewline) {
573
 
                                        System.Text.StringBuilder builder = new System.Text.StringBuilder (formattedXml);
574
 
                                        
575
 
                                        if (nonNativeNewline)
576
 
                                                builder.Replace (Environment.NewLine, Editor.NewLine);
577
 
                                        
578
 
                                        if (hasExtraIndent) {
579
 
                                                builder.Replace (Editor.NewLine, Editor.NewLine + extraIndent);
580
 
                                                if (formattedXml.EndsWith (Environment.NewLine))
581
 
                                                        builder.Remove (builder.Length - 1 - extraIndent.Length, extraIndent.Length);
582
 
                                        }
583
 
                                        formattedXml = builder.ToString ();
584
 
                                }
585
 
                                
586
 
                                Editor.BeginAtomicUndo ();
587
 
                                if (selection) {
588
 
                                        Editor.SelectedText = formattedXml;
589
 
                                } else {
590
 
                                        Editor.DeleteText (0, Editor.TextLength);
591
 
                                        Editor.InsertText (0, formattedXml);
592
 
                                }
593
 
                                Editor.EndAtomicUndo ();
594
 
                        }
595
 
                }
596
 
                
597
539
                [CommandHandler (Commands.CreateSchema)]
598
540
                public void CreateSchemaCommand ()
599
541
                {
617
559
                                        }
618
560
                                }
619
561
                        } catch (Exception ex) {
620
 
                                MessageService.ShowError(ex.Message);
 
562
                                MessageService.ShowError (ex.Message);
621
563
                        }
622
564
                }
623
565
                
654
596
                                        IdeApp.Workbench.OpenDocument (
655
597
                                            schemaFileName,
656
598
                                            Math.Max (1, schemaObject.LineNumber),
657
 
                                            Math.Max (1, schemaObject.LinePosition), true);
 
599
                                            Math.Max (1, schemaObject.LinePosition));
658
600
                                }
659
601
                        } catch (Exception ex) {
660
602
                                MonoDevelop.Core.LoggingService.LogError ("Could not open document.", ex);
729
671
                        }
730
672
                }
731
673
                
 
674
                /*
 
675
                [CommandUpdateHandler (CodeFormattingCommands.FormatSelection)]
 
676
                internal void UpdateFormatSelection (CommandInfo info)
 
677
                {
 
678
                        info.Enabled = false;
 
679
                }
 
680
                
 
681
                [CommandHandler (CodeFormattingCommands.FormatSelection)]
 
682
                internal void FormatSelection (CommandInfo info)
 
683
                {
 
684
                        throw new NotImplementedException ();
 
685
                }
 
686
                */
 
687
                
 
688
                [CommandUpdateHandler (CodeFormattingCommands.FormatBuffer)]
 
689
                internal void UpdateFormatDocument (CommandInfo info)
 
690
                {
 
691
                        //we know there is an XML formatter because this addin registers it
 
692
                        info.Enabled = true;
 
693
                }
 
694
                
 
695
                //we have to implement the command here simply to force the document mimetype
 
696
                //FIXME: instead we should register the XML mimetype additions to the desktopservice
 
697
                [CommandHandler (CodeFormattingCommands.FormatBuffer)]
 
698
                internal void FormatDocument ()
 
699
                {
 
700
                        var formatter = CodeFormatterService.GetFormatter (TextXmlMimeType);
 
701
                        Editor.Document.BeginAtomicUndo ();
 
702
                        var loc = Editor.Caret.Location;
 
703
                        var text = formatter.FormatText (Document.Project != null ? Document.Project.Policies : null, Editor.Text);
 
704
                        if (text != null) {
 
705
                                Editor.Replace (0, Editor.Length, text);
 
706
                                Editor.Caret.Location = loc;
 
707
                        }
 
708
                        Editor.Document.EndAtomicUndo ();
 
709
                }
 
710
                
732
711
                string GetFileContent (string fileName)
733
712
                {
734
713
                        MonoDevelop.Projects.Text.IEditableTextFile tf =
735
 
                                MonoDevelop.DesignerSupport.OpenDocumentFileProvider.Instance.GetEditableTextFile (fileName);
736
 
                        if (tf != null)
 
714
                                MonoDevelop.Ide.TextFileProvider.Instance.GetEditableTextFile (fileName);
 
715
                        if (tf != null)
737
716
                                return tf.Text;
738
717
                        System.IO.StreamReader reader = new System.IO.StreamReader (fileName, true);
739
718
                        return reader.ReadToEnd();