2
// MonoDevelop XML Editor
4
// Copyright (C) 2007 Matthew Ward
5
// Copyright (C) 2004-2007 MonoDevelop Team
11
using MonoDevelop.Core;
12
using MonoDevelop.Ide.Gui;
13
using MonoDevelop.Ide.Gui.Content;
14
using MonoDevelop.Ide.Gui.Search;
15
using MonoDevelop.Projects.Text;
19
namespace MonoDevelop.XmlEditor
21
public class XmlEditorViewContent : AbstractViewContent, IEditableTextBuffer, IDocumentInformation, IClipboardHandler
23
XmlEditorWindow xmlEditorWindow;
26
const string TextXmlMimeType = "text/xml";
27
const string ApplicationXmlMimeType = "application/xml";
28
string fileName = String.Empty;
29
EventHandler<PropertyChangedEventArgs> propertyChangedHandler;
30
string stylesheetFileName;
32
public XmlEditorViewContent()
34
xmlEditorWindow = new XmlEditorWindow(this);
35
view = xmlEditorWindow.View;
36
buffer = (SourceBuffer)view.Buffer;
37
buffer.Changed += BufferChanged;
39
view.SchemaCompletionDataItems = XmlSchemaManager.SchemaCompletionDataItems;
42
// Watch for changes to the source editor properties.
43
propertyChangedHandler = (EventHandler<PropertyChangedEventArgs>)DispatchService.GuiDispatch(new EventHandler<PropertyChangedEventArgs>(SourceEditorPropertyChanged));
44
TextEditorProperties.Properties.PropertyChanged += propertyChangedHandler;
46
buffer.ModifiedChanged += new EventHandler (OnModifiedChanged);
47
XmlEditorAddInOptions.PropertyChanged += new EventHandler<PropertyChangedEventArgs>(XmlEditorPropertyChanged);
49
XmlSchemaManager.UserSchemaAdded += new EventHandler(UserSchemaAdded);
50
XmlSchemaManager.UserSchemaRemoved += new EventHandler(UserSchemaRemoved);
52
xmlEditorWindow.ShowAll();
55
public static bool IsMimeTypeHandled(string mimeType)
57
Console.WriteLine("mimeType: " + mimeType);
58
if (mimeType != null) {
59
if (mimeType == TextXmlMimeType || mimeType == ApplicationXmlMimeType) {
67
/// Determines whether the file can be displayed by
70
public static bool IsFileNameHandled(string fileName)
72
if (fileName == null) {
76
string vfsname = fileName;
77
vfsname = vfsname.Replace ("%", "%25");
78
vfsname = vfsname.Replace ("#", "%23");
79
vfsname = vfsname.Replace ("?", "%3F");
80
string mimeType = MimeType.GetMimeTypeForUri (vfsname);
81
if (IsMimeTypeHandled(mimeType)) {
85
return XmlFileExtensions.IsXmlFileExtension(Path.GetExtension(fileName));
88
public XmlEditorView XmlEditorView {
94
public override Gtk.Widget Control {
96
return xmlEditorWindow;
100
public override bool IsDirty {
105
buffer.Modified = value;
109
public override string UntitledName {
111
return base.UntitledName;
114
base.UntitledName = value;
117
SetDefaultSchema(value);
122
public override string TabPageLabel {
128
public string FileName {
135
/// Gets or sets the stylesheet associated with this xml file.
137
public string StylesheetFileName {
139
return stylesheetFileName;
142
stylesheetFileName = value;
146
public bool IsSchema {
148
if (fileName != null) {
149
string extension = Path.GetExtension(fileName);
150
if (extension != null) {
151
return String.Compare(extension, ".xsd", true) == 0;
158
public override void Load(string fileName)
160
using (StreamReader reader = System.IO.File.OpenText(fileName)) {
161
LoadContent(reader.ReadToEnd());
163
ContentName = fileName;
164
this.fileName = fileName;
165
SetDefaultSchema(ContentName);
168
public void LoadContent(string content)
170
buffer.Text = content;
171
buffer.Modified = false;
174
public override void Dispose()
176
XmlEditorAddInOptions.PropertyChanged -= new EventHandler<PropertyChangedEventArgs>(XmlEditorPropertyChanged);
177
XmlSchemaManager.UserSchemaAdded -= new EventHandler(UserSchemaAdded);
178
XmlSchemaManager.UserSchemaRemoved -= new EventHandler(UserSchemaRemoved);
179
TextEditorProperties.Properties.PropertyChanged -= propertyChangedHandler;
180
xmlEditorWindow.Dispose();
183
public override void Save(string fileName)
185
using (TextWriter s = new StreamWriter (fileName, true)) {
188
using (TextWriter s = new StreamWriter (fileName, false)) {
189
s.Write (buffer.Text);
191
ContentName = fileName;
192
xmlEditorWindow.View.Buffer.Modified = false;
196
/// Code taken from SourceEditorDisplayBinding.
198
void SetInitialValues()
200
view.ShowSchemaAnnotation = XmlEditorAddInOptions.ShowSchemaAnnotation;
201
view.AutoCompleteElements = XmlEditorAddInOptions.AutoCompleteElements;
203
view.ModifyFont (TextEditorProperties.Font);
204
view.ShowLineNumbers = TextEditorProperties.ShowLineNumbers;
205
((SourceBuffer)view.Buffer).HighlightMatchingBrackets = TextEditorProperties.ShowMatchingBracket;
206
view.ShowRightMargin = TextEditorProperties.ShowVerticalRuler;
207
view.InsertSpacesInsteadOfTabs = TextEditorProperties.ConvertTabsToSpaces;
208
view.AutoIndent = (TextEditorProperties.IndentStyle == IndentStyle.Auto);
209
view.HighlightCurrentLine = TextEditorProperties.HighlightCurrentLine;
210
((SourceBuffer)view.Buffer).HighlightSyntax = TextEditorProperties.SyntaxHighlight;
212
if (TextEditorProperties.TabIndent > -1)
213
view.TabWidth = (uint) TextEditorProperties.TabIndent;
215
view.TabWidth = (uint) 4;
217
if (TextEditorProperties.VerticalRulerRow > -1)
218
view.RightMarginPosition = (uint) TextEditorProperties.VerticalRulerRow;
220
view.RightMarginPosition = 80;
222
UpdateStyleScheme ();
225
void OnModifiedChanged (object o, EventArgs e)
227
base.IsDirty = view.Buffer.Modified;
230
void UpdateStyleScheme ()
232
string id = TextEditorProperties.Properties.Get<string> ("GtkSourceViewStyleScheme", "classic");
233
SourceStyleScheme scheme = GtkSourceView.SourceStyleSchemeManager.Default.GetScheme (id);
235
MonoDevelop.Core.LoggingService.LogWarning ("GTKSourceView style scheme '" + id + "' is missing.");
237
((SourceBuffer)view.Buffer).StyleScheme = scheme;
240
void XmlEditorPropertyChanged(object o, PropertyChangedEventArgs e)
243
case "AutoCompleteElements":
244
view.AutoCompleteElements = XmlEditorAddInOptions.AutoCompleteElements;
246
case "ShowSchemaAnnotation":
247
view.ShowSchemaAnnotation = XmlEditorAddInOptions.ShowSchemaAnnotation;
250
string extension = Path.GetExtension(fileName).ToLower();
251
if (e.Key == extension) {
252
SetDefaultSchema(extension);
254
Console.WriteLine("XmlEditor: Unhandled property change: " + e.Key);
260
void SourceEditorPropertyChanged(object o, PropertyChangedEventArgs e)
264
view.ModifyFont(TextEditorProperties.Font);
266
case "ShowLineNumbers":
267
view.ShowLineNumbers = TextEditorProperties.ShowLineNumbers;
269
case "ConvertTabsToSpaces":
270
view.InsertSpacesInsteadOfTabs = TextEditorProperties.ConvertTabsToSpaces;
272
case "ShowBracketHighlight":
273
((SourceBuffer)view.Buffer).HighlightMatchingBrackets = TextEditorProperties.ShowMatchingBracket;
276
view.ShowRightMargin = TextEditorProperties.ShowVerticalRuler;
279
if (TextEditorProperties.VerticalRulerRow > -1)
280
view.RightMarginPosition = (uint) TextEditorProperties.VerticalRulerRow;
282
view.RightMarginPosition = 80;
285
if (TextEditorProperties.TabIndent > -1)
286
view.TabWidth = (uint) TextEditorProperties.TabIndent;
288
view.TabWidth = (uint) 4;
291
view.AutoIndent = (TextEditorProperties.IndentStyle == IndentStyle.Auto);
293
case "HighlightCurrentLine":
294
view.HighlightCurrentLine = TextEditorProperties.HighlightCurrentLine;
296
case "GtkSourceViewStyleScheme":
297
UpdateStyleScheme ();
300
MonoDevelop.Core.LoggingService.LogWarning ("XmlEditor: Unhandled source editor property change: " + e.Key);
305
#region IClipboardHandler
306
public bool EnableCut {
308
return ((IClipboardHandler)view).EnableCut;
311
public bool EnableCopy {
313
return ((IClipboardHandler)view).EnableCopy;
316
public bool EnablePaste {
318
return ((IClipboardHandler)view).EnablePaste;
321
public bool EnableDelete {
323
return ((IClipboardHandler)view).EnableDelete;
326
public bool EnableSelectAll {
328
return ((IClipboardHandler)view).EnableSelectAll;
334
((IClipboardHandler)view).Cut ();
339
((IClipboardHandler)view).Copy ();
344
((IClipboardHandler)view).Paste ();
347
public void Delete ()
349
((IClipboardHandler)view).Delete ();
352
public void SelectAll ()
354
((IClipboardHandler)view).SelectAll ();
359
/// Sets the default schema and namespace prefix that the xml editor will use.
361
void SetDefaultSchema(string fileName)
363
if (fileName == null) {
366
string extension = Path.GetExtension(fileName).ToLower();
367
view.DefaultSchemaCompletionData = XmlSchemaManager.GetSchemaCompletionData(extension);
368
view.DefaultNamespacePrefix = XmlSchemaManager.GetNamespacePrefix(extension);
372
/// Updates the default schema association since the schema
373
/// may have been added.
375
void UserSchemaAdded(object source, EventArgs e)
377
SetDefaultSchema(ContentName);
381
/// Updates the default schema association since the schema
382
/// may have been removed.
384
void UserSchemaRemoved(object source, EventArgs e)
386
SetDefaultSchema(ContentName);
389
#region IEditableTextBuffer
391
public event EventHandler<TextChangedEventArgs> TextChanged;
393
public void BeginAtomicUndo ()
395
//Buffer.BeginUserAction ();
398
public void EndAtomicUndo ()
400
//Buffer.EndUserAction ();
411
// if (needsUpdate) {
412
// cachedText = se.Buffer.Text;
418
buffer.BeginUserAction();
421
buffer.EndUserAction();
431
public bool EnableUndo {
432
get { return buffer.CanUndo; }
435
public bool EnableRedo {
436
get { return buffer.CanRedo; }
444
public string SelectedText {
446
return view.GetSelectedText();
449
int offset = view.GetLowerSelectionBounds ();
450
((IClipboardHandler)view).Delete ();
451
TextIter iter = buffer.GetIterAtOffset (offset);
452
buffer.Insert (ref iter, value);
453
buffer.PlaceCursor(iter);
454
view.ScrollMarkOnscreen (buffer.InsertMark);
458
public int GetPositionFromLineColumn (int line, int column)
460
Console.WriteLine("GetPositionFromLineColumn");
464
public void InsertText (int position, string text)
466
Console.WriteLine("InsertText");
469
public void DeleteText (int pos, int length)
471
TextIter start = buffer.GetIterAtOffset (pos);
472
TextIter end = buffer.GetIterAtOffset (pos + length);
473
buffer.Delete (ref start, ref end);
476
public int CursorPosition {
478
return buffer.GetIterAtMark(buffer.InsertMark).Offset;
481
buffer.MoveMark (buffer.InsertMark, buffer.GetIterAtOffset (value));
485
public void GetLineColumnFromPosition (int position, out int line, out int column)
487
Console.WriteLine("GetLineColumnFromPosition");
492
public void ShowPosition (int position)
494
view.ScrollToIter (buffer.GetIterAtOffset (position), 0.3, false, 0, 0);
497
public char GetCharAt (int offset)
501
TextIter iter = buffer.GetIterAtOffset (offset);
502
if (iter.Equals (TextIter.Zero))
504
if (iter.Char == null || iter.Char.Length == 0)
509
public string GetText (int startPosition, int endPosition)
511
return buffer.GetText (buffer.GetIterAtOffset (startPosition), buffer.GetIterAtOffset (endPosition), true);
514
int ITextFile.Length {
516
Console.WriteLine("ITextFile.Length");
521
public void Select (int startPosition, int endPosition)
523
buffer.MoveMark (buffer.InsertMark, buffer.GetIterAtOffset (startPosition));
524
buffer.MoveMark (buffer.SelectionBound, buffer.GetIterAtOffset (endPosition));
527
public int SelectionStartPosition {
529
TextIter p1 = buffer.GetIterAtMark (buffer.InsertMark);
530
TextIter p2 = buffer.GetIterAtMark (buffer.SelectionBound);
531
if (p1.Offset < p2.Offset) return p1.Offset;
532
else return p2.Offset;
536
public int SelectionEndPosition {
538
TextIter p1 = buffer.GetIterAtMark (buffer.InsertMark);
539
TextIter p2 = buffer.GetIterAtMark (buffer.SelectionBound);
540
if (p1.Offset > p2.Offset) return p1.Offset;
541
else return p2.Offset;
547
#region IDocumentInformation
549
string IDocumentInformation.FileName {
550
get { return ContentName != null ? ContentName : UntitledName; }
553
public ITextIterator GetTextIterator ()
555
int startOffset = buffer.GetIterAtMark (buffer.InsertMark).Offset;
556
return new SourceViewTextIterator (this, view, startOffset);
559
public string GetLineTextAtOffset (int offset)
561
TextIter resultIter = buffer.GetIterAtOffset (offset);
562
TextIter start_line = resultIter, end_line = resultIter;
563
start_line.LineOffset = 0;
564
end_line.ForwardToLineEnd ();
565
return view.GetText (start_line.Offset, end_line.Offset - start_line.Offset);
570
#region IPositionable
572
public void SetCaretTo (int line, int column)
575
TextIter itr = view.Buffer.GetIterAtLine (line - 1);
576
itr.LineOffset = column - 1;
578
view.Buffer.PlaceCursor (itr);
579
view.ScrollToMark (view.Buffer.InsertMark, 0.3, false, 0, 0);
580
GLib.Timeout.Add (20, new GLib.TimeoutHandler (changeFocus));
583
protected virtual void OnCaretPositionSet (EventArgs args)
585
if (CaretPositionSet != null)
586
CaretPositionSet (this, args);
588
public event EventHandler CaretPositionSet;
590
//This code exists to workaround a gtk+ 2.4 regression/bug
592
//The gtk+ 2.4 treeview steals focus with double clicked
594
// http://bugzilla.gnome.org/show_bug.cgi?id=138458
597
if (!view.IsRealized)
600
view.ScrollToMark (view.Buffer.InsertMark, 0.3, false, 0, 0);
601
OnCaretPositionSet (EventArgs.Empty);
607
void BufferChanged(object source, EventArgs e)
609
if (TextChanged != null) {
610
TextChanged(this, new TextChangedEventArgs(0, 0));