Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémie Laval <jeremie.laval@gmail.com>2013-06-26 00:09:19 +0400
committerJérémie Laval <jeremie.laval@gmail.com>2013-06-26 00:09:32 +0400
commit812b381989f90b7c15754628b113fe4e4d20bd06 (patch)
tree835176cdd5a04ffc6739a6429acad109425eee80
parent19e095b1103891462343565aff9b187f88bf3947 (diff)
[docbrowser] Make it compile again with Mono 3.0
-rw-r--r--docbrowser/Makefile.am3
-rw-r--r--docbrowser/browser.cs74
-rw-r--r--docbrowser/editing.cs519
3 files changed, 581 insertions, 15 deletions
diff --git a/docbrowser/Makefile.am b/docbrowser/Makefile.am
index a1a26265..065c430f 100644
--- a/docbrowser/Makefile.am
+++ b/docbrowser/Makefile.am
@@ -40,6 +40,7 @@ browser_sources = \
$(srcdir)/list.cs \
$(srcdir)/elabel.cs \
$(srcdir)/history.cs \
+ $(srcdir)/editing.cs \
$(srcdir)/Contributions.cs \
$(srcdir)/XmlNodeWriter.cs \
$(srcdir)/IHtmlRender.cs \
@@ -67,7 +68,7 @@ admin_sources = \
$(srcdir)/admin.cs \
$(srcdir)/Contributions.cs
-browser_assemblies = $(GTK_SHARP_LIBS) $(MONODOC_LIBS) $(GNOME_SHARP_LIBS) -r:System.Web.Services
+browser_assemblies = $(GTK_SHARP_LIBS) $(MONODOC_LIBS) $(GNOME_SHARP_LIBS) -r:System.Web.Services -r:System.Web
# we insert gtkhtml libs if we have them for printing
geckorender_assemblies = $(GTK_SHARP_LIBS) $(GTKHTML_SHARP_LIBS) $(GECKO_SHARP_LIBS) $(GNOME_SHARP_LIBS) $(MONODOC_LIBS) -r:browser.exe
gtkhtmlrender_assemblies = $(GTK_SHARP_LIBS) $(GTKHTML_SHARP_LIBS) $(GNOME_SHARP_LIBS) $(MONODOC_LIBS) -r:browser.exe
diff --git a/docbrowser/browser.cs b/docbrowser/browser.cs
index 2984bc78..6f706207 100644
--- a/docbrowser/browser.cs
+++ b/docbrowser/browser.cs
@@ -60,7 +60,7 @@ class Driver {
v => sources.Add (v) },
{ "edit=",
"Edit mdoc(5) XML documentation found within {PATH}.",
- v => RootTree.UncompiledHelpSources.Add (v) },
+ v => RootTree.AddUncompiledSource (v) },
{ "engine=",
"Specify which HTML rendering {ENGINE} to use:\n" +
" " + string.Join ("\n ", engines) + "\n" +
@@ -132,7 +132,7 @@ class Driver {
return r;
}
- if (mergeConfigFile != null) {
+ /*if (mergeConfigFile != null) {
ArrayList targetDirs = new ArrayList ();
for (int i = 0; i < topics.Count; i++)
@@ -145,7 +145,7 @@ class Driver {
e.Merge ();
return 0;
- }
+ }*/
if (r != 0 || !show_gui)
return r;
@@ -257,6 +257,7 @@ public class Browser {
TreeView search_tree;
TreeStore search_store;
SearchableIndex search_index;
+ ArrayList searchResults = new ArrayList (20);
string highlight_text;
[Glade.Widget] VBox search_vbox;
ProgressPanel ppanel;
@@ -578,6 +579,7 @@ public class Browser {
Result r = search_index.Search (term);
if (r == null)
return; //There was a problem with the index
+ searchResults.Add (r);
//insert the results in the tree
TreeIter iter;
@@ -622,7 +624,7 @@ public class Browser {
return;
int i_0 = p.Indices [0];
int i_1 = p.Indices [1];
- Result res = (Result) search_index.Results [i_0];
+ Result res = (Result) searchResults [i_0];
TreeIter parent;
model.IterParent (out parent, iter);
string term = (string) search_store.GetValue (parent, 0);
@@ -648,21 +650,21 @@ public class Browser {
void TextLarger (object obj, EventArgs args)
{
SettingsHandler.Settings.preferred_font_size += 10;
- HelpSource.CssCode = null;
+ //HelpSource.CssCode = null;
Reload ();
SettingsHandler.Save ();
}
void TextSmaller (object obj, EventArgs args)
{
SettingsHandler.Settings.preferred_font_size -= 10;
- HelpSource.CssCode = null;
+ //HelpSource.CssCode = null;
Reload ();
SettingsHandler.Save ();
}
void TextNormal (object obj, EventArgs args)
{
SettingsHandler.Settings.preferred_font_size = 100;
- HelpSource.CssCode = null;
+ //HelpSource.CssCode = null;
Reload ();
SettingsHandler.Save ();
}
@@ -794,8 +796,8 @@ public class Browser {
//
string tabTitle;
tabTitle = matched_node.Caption; //Normal title
- string[] parts = matched_node.URL.Split('/', '#');
- if(matched_node.URL != null && matched_node.URL.StartsWith("ecma:")) {
+ string[] parts = matched_node.PublicUrl.Split('/', '#');
+ if(matched_node.PublicUrl != null && matched_node.PublicUrl.StartsWith("ecma:")) {
if(parts.Length == 3 && parts[2] != String.Empty) { //List of Members, properties, events, ...
tabTitle = parts[1] + ": " + matched_node.Caption;
} else if(parts.Length >= 4) { //Showing a concrete Member, property, ...
@@ -1701,7 +1703,7 @@ ExtLoop:
void OnOkClicked (object sender, EventArgs a)
{
- CommentService service = new CommentService();
+ //CommentService service = new CommentService();
// todo
newcomment.Hide ();
}
@@ -2020,7 +2022,7 @@ public class TreeBrowser {
if (tree_view.Selection.GetSelected (out model, out iter)){
Node n = (Node) iter_to_node [iter];
- string url = n.URL;
+ string url = n.PublicUrl;
Node match;
string s;
@@ -2048,7 +2050,7 @@ public class TreeBrowser {
return;
}
- ((Browser)browser).Render ("<h1>Unhandled URL</h1>" + "<p>Functionality to view the resource <i>" + n.URL + "</i> is not available on your system or has not yet been implemented.</p>", null, url);
+ ((Browser)browser).Render ("<h1>Unhandled URL</h1>" + "<p>Functionality to view the resource <i>" + n.PublicUrl + "</i> is not available on your system or has not yet been implemented.</p>", null, url);
}
}
}
@@ -2712,7 +2714,7 @@ public class Tab : Notebook {
string [] uSplit = EditingUtils.ParseEditUrl (edit_url);
if (uSplit[0].StartsWith ("monodoc:"))
- EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, EcmaHelpSource.GetNiceUrl (browser.CurrentTab.CurrentNode));
+ EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, GetNiceUrl (browser.CurrentTab.CurrentNode));
else if (uSplit[0].StartsWith ("file:"))
EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, String.Empty);
else
@@ -2721,6 +2723,49 @@ public class Tab : Notebook {
history.ActivateCurrent ();
}
+ public static string GetNiceUrl (Node node) {
+ if (node.Element.StartsWith("N:"))
+ return node.Element;
+ string name, full;
+ int bk_pos = node.Caption.IndexOf (' ');
+ // node from an overview
+ if (bk_pos != -1) {
+ name = node.Caption.Substring (0, bk_pos);
+ full = node.Parent.Caption + "." + name.Replace ('.', '+');
+ return "T:" + full;
+ }
+ // node that lists constructors, methods, fields, ...
+ if ((node.Caption == "Constructors") || (node.Caption == "Fields") || (node.Caption == "Events")
+ || (node.Caption == "Members") || (node.Caption == "Properties") || (node.Caption == "Methods")
+ || (node.Caption == "Operators")) {
+ bk_pos = node.Parent.Caption.IndexOf (' ');
+ name = node.Parent.Caption.Substring (0, bk_pos);
+ full = node.Parent.Parent.Caption + "." + name.Replace ('.', '+');
+ return "T:" + full + "/" + node.Element;
+ }
+ int pr_pos = node.Caption.IndexOf ('(');
+ // node from a constructor
+ if (node.Parent.Element == "C") {
+ name = node.Parent.Parent.Parent.Caption;
+ int idx = node.PublicUrl.IndexOf ('/');
+ return node.PublicUrl[idx+1] + ":" + name + "." + node.Caption.Replace ('.', '+');
+ // node from a method with one signature, field, property, operator
+ } else if (pr_pos == -1) {
+ bk_pos = node.Parent.Parent.Caption.IndexOf (' ');
+ name = node.Parent.Parent.Caption.Substring (0, bk_pos);
+ full = node.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+');
+ int idx = node.PublicUrl.IndexOf ('/');
+ return node.PublicUrl[idx+1] + ":" + full + "." + node.Caption;
+ // node from a method with several signatures
+ } else {
+ bk_pos = node.Parent.Parent.Parent.Caption.IndexOf (' ');
+ name = node.Parent.Parent.Parent.Caption.Substring (0, bk_pos);
+ full = node.Parent.Parent.Parent.Parent.Caption + "." + name.Replace ('.', '+');
+ int idx = node.PublicUrl.IndexOf ('/');
+ return node.PublicUrl[idx+1] + ":" + full + "." + node.Caption;
+ }
+ }
+
void OnCancelEdits (object sender, EventArgs a)
{
SetMode (Mode.Viewer);
@@ -2747,6 +2792,7 @@ public class Tab : Notebook {
StringWriter sw = new StringWriter ();
XmlWriter w = new XmlTextWriter (sw);
+ var converter = new Monodoc.Generators.Html.Ecma2Html ();
try {
edit_node.InnerXml = text_editor.Buffer.Text;
@@ -2760,7 +2806,7 @@ public class Tab : Notebook {
}
browser.statusbar.Pop (browser.context_id);
browser.statusbar.Push (browser.context_id, "XML OK");
- string s = HelpSource.BuildHtml (EcmaHelpSource.css_ecma_code, sw.ToString ());
+ string s = converter.Export (sw.ToString (), new Dictionary<string, string> ());
html_preview.Render(s);
return false;
diff --git a/docbrowser/editing.cs b/docbrowser/editing.cs
new file mode 100644
index 00000000..d7c1e327
--- /dev/null
+++ b/docbrowser/editing.cs
@@ -0,0 +1,519 @@
+//
+// editing.cs
+//
+// Author:
+// Ben Maurer (bmaurer@users.sourceforge.net)
+//
+// (C) 2003 Ben Maurer
+//
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Xml.XPath;
+using System.Web;
+
+namespace Monodoc {
+ public class EditingUtils {
+
+ public static string FormatEditUri (string document_identifier, string xpath)
+ {
+ return String.Format ("edit:{0}@{1}", HttpUtility.UrlEncode (document_identifier),
+ HttpUtility.UrlEncode (xpath));
+ }
+
+ public static string GetXPath (XPathNavigator n)
+ {
+ switch (n.NodeType) {
+ case XPathNodeType.Root: return "/";
+ case XPathNodeType.Attribute: {
+ string ret = "@" + n.Name;
+ n.MoveToParent ();
+ string s = GetXPath (n);
+ return s + (s == "/" ? "" : "/") + ret;
+ }
+
+ case XPathNodeType.Element: {
+ string ret = n.Name;
+ int i = 1;
+ while (n.MoveToPrevious ()) {
+ if (n.NodeType == XPathNodeType.Element && n.Name == ret)
+ i++;
+ }
+ ret += "[" + i + "]";
+ if (n.MoveToParent ()) {
+ string s = GetXPath (n);
+ return s + (s == "/" ? "" : "/") + ret;
+ }
+ }
+ break;
+ }
+ throw new Exception ("node type not supported for editing");
+
+ }
+
+ public static XmlNode GetNodeFromUrl (string url, RootTree tree)
+ {
+ Console.WriteLine ("Url is: {0}", url);
+ string [] uSplit = ParseEditUrl (url);
+ Console.WriteLine ("Results are: {0}\n{1}\n{2}", uSplit [0], uSplit [1], uSplit [2]);
+
+ string xp = uSplit [2];
+ string id = uSplit [1];
+
+ XmlDocument d;
+
+ if (uSplit[0].StartsWith("monodoc:///")) {
+ int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
+ d = tree.GetHelpSourceFromId (prov).GetHelpXmlWithChanges (id);
+ } else if (uSplit[0].StartsWith("file:")) {
+ d = new XmlDocument();
+ d.PreserveWhitespace = true;
+ d.Load(uSplit[0].Substring(5));
+ } else {
+ throw new NotImplementedException("Don't know how to load " + url);
+ }
+
+ return d.SelectSingleNode (xp);
+
+ }
+
+ public static void SaveChange (string url, RootTree tree, XmlNode node, string node_url)
+ {
+ /*string [] uSplit = ParseEditUrl (url);
+
+ string xp = uSplit [2];
+ string id = uSplit [1];
+
+ if (uSplit[0].StartsWith("monodoc:///")) {
+ int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
+ HelpSource hs = tree.GetHelpSourceFromId (prov);
+
+ changes.AddChange (hs.Name, hs.GetRealPath (id), xp, node, node_url);
+ changes.Save ();
+ } else if (uSplit[0].StartsWith("file:")) {
+ uSplit[0] = uSplit[0].Substring(5);
+
+ XmlDocument d = new XmlDocument();
+ d.PreserveWhitespace = true;
+ d.Load(uSplit[0]);
+
+ XmlNode original = d.SelectSingleNode(xp);
+ original.ParentNode.ReplaceChild(d.ImportNode(node, true), original);
+
+ d.Save(uSplit[0]);
+ } else {
+ throw new NotImplementedException("Don't know how to save to " + url);
+ }*/
+ }
+
+ public static void RemoveChange (string url, RootTree tree)
+ {
+ /*string [] uSplit = ParseEditUrl (url);
+
+ string xp = uSplit [2];
+ string id = uSplit [1];
+
+ if (uSplit[0].StartsWith("monodoc:///")) {
+ int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
+ HelpSource hs = tree.GetHelpSourceFromId (prov);
+
+ changes.RemoveChange (hs.Name, hs.GetRealPath (id), xp);
+ changes.Save ();
+ } else if (uSplit[0].StartsWith("file:")) {
+ //TODO: Not implemented
+ }*/
+ }
+
+ public static void RenderEditPreview (string url, RootTree tree, XmlNode new_node, XmlWriter w)
+ {
+ string [] uSplit = ParseEditUrl (url);
+
+ if (uSplit[0].StartsWith("monodoc:///")) {
+ int prov = int.Parse (uSplit [0].Substring("monodoc:///".Length));
+ HelpSource hs = tree.GetHelpSourceFromId (prov);
+ hs.RenderPreviewDocs (new_node, w);
+ } else {
+ foreach (HelpSource hs in tree.HelpSources) {
+ if (hs is Monodoc.Providers.EcmaUncompiledHelpSource) {
+ // It doesn't matter which EcmaHelpSource is chosen.
+ hs.RenderPreviewDocs (new_node, w);
+ break;
+ }
+ }
+ }
+ }
+
+ public static string [] ParseEditUrl (string url)
+ {
+ if (!url.StartsWith ("edit:"))
+ throw new Exception ("wtf");
+
+ string [] parts = url.Split ('@');
+ if (parts.Length != 2)
+ throw new Exception (String.Format ("invalid editing url {0}", parts.Length));
+
+ string xp = HttpUtility.UrlDecode (parts [1]);
+ parts = HttpUtility.UrlDecode (parts [0]).Substring ("edit:".Length).Split ('@');
+ if (parts.Length == 1) {
+ string p = parts[0];
+ parts = new string[2];
+ parts[0] = p;
+ parts[1] = "";
+ }
+
+ return new string [] {parts [0], parts [1], xp};
+ }
+
+ public static void AccountForChanges (XmlDocument d, string doc_set, string real_file)
+ {
+ try {
+ FileChangeset fcs = changes.GetChangeset (doc_set, real_file);
+ if (fcs == null)
+ return;
+
+ foreach (Change c in fcs.Changes) {
+ // Filter out old changes
+ if (c.FromVersion != RootTree.MonodocVersion)
+ continue;
+
+ XmlNode old = d.SelectSingleNode (c.XPath);
+ if (old != null)
+ old.ParentNode.ReplaceChild (d.ImportNode (c.NewNode, true), old);
+ }
+ } catch {
+ return;
+ }
+ }
+
+ public static GlobalChangeset changes = GlobalChangeset.Load ();
+
+ static public GlobalChangeset GetChangesFrom (int starting_serial_id)
+ {
+ return changes.GetFrom (starting_serial_id);
+ }
+ }
+
+#region Data Model
+ public class GlobalChangeset {
+
+ public static XmlSerializer serializer = new XmlSerializer (typeof (GlobalChangeset));
+ static string changeset_file = Path.Combine (SettingsHandler.Path, "changeset.xml");
+ static string changeset_backup_file = Path.Combine (SettingsHandler.Path, "changeset.xml~");
+
+ public static GlobalChangeset Load ()
+ {
+ try {
+ if (File.Exists (changeset_file))
+ return LoadFromFile (changeset_file);
+ } catch {}
+
+ return new GlobalChangeset ();
+ }
+
+ public static GlobalChangeset LoadFromFile (string fileName)
+ {
+ using (Stream s = File.OpenRead (fileName)) {
+ return (GlobalChangeset) serializer.Deserialize (s);
+ }
+ }
+
+ public void Save ()
+ {
+ SettingsHandler.EnsureSettingsDirectory ();
+
+ try {
+ if (File.Exists(changeset_file)) // create backup copy
+ File.Copy (changeset_file, changeset_backup_file, true);
+
+ using (FileStream fs = File.Create (changeset_file)){
+ serializer.Serialize (fs, this);
+ }
+ } catch (Exception e) {
+ Console.WriteLine ("Error while saving changes. " + e);
+ if (File.Exists(changeset_backup_file)) // if saving fails then use backup if we have one
+ File.Copy (changeset_backup_file, changeset_file, true);
+ else
+ File.Delete (changeset_file); // if no backup, delete invalid changeset
+ }
+ }
+
+ static void VerifyDirectoryExists (DirectoryInfo d) {
+ if (d.Exists)
+ return;
+
+ VerifyDirectoryExists (d.Parent);
+ d.Create ();
+ }
+
+ [XmlElement ("DocSetChangeset", typeof (DocSetChangeset))]
+ public ArrayList DocSetChangesets = new ArrayList ();
+
+ public FileChangeset GetChangeset (string doc_set, string real_file)
+ {
+ foreach (DocSetChangeset dscs in DocSetChangesets) {
+ if (dscs.DocSet != doc_set)
+ continue;
+
+ foreach (FileChangeset fcs in dscs.FileChangesets) {
+ if (fcs.RealFile == real_file)
+ return fcs;
+ }
+ }
+
+ return null;
+ }
+
+ public int Count {
+ get {
+ int count = 0;
+
+ foreach (DocSetChangeset dscs in DocSetChangesets){
+ foreach (FileChangeset fcs in dscs.FileChangesets){
+ count += fcs.Changes.Count;
+ }
+ }
+
+ return count;
+ }
+ }
+
+ Change NewChange (string xpath, XmlNode new_node, string node_url)
+ {
+ Change new_change = new Change ();
+ new_change.XPath = xpath;
+ new_change.NewNode = new_node;
+ new_change.NodeUrl = node_url;
+
+ Console.WriteLine ("New serial:" + SettingsHandler.Settings.SerialNumber);
+ new_change.Serial = SettingsHandler.Settings.SerialNumber;
+
+ return new_change;
+ }
+
+ public void AddChange (string doc_set, string real_file, string xpath, XmlNode new_node, string node_url)
+ {
+ FileChangeset new_file_change_set;
+ Change new_change = NewChange (xpath, new_node, node_url);
+
+ if (real_file == null)
+ throw new Exception ("Could not find real_file. Please talk to Miguel or Ben about this");
+
+ foreach (DocSetChangeset dscs in DocSetChangesets) {
+ if (dscs.DocSet != doc_set)
+ continue;
+
+ foreach (FileChangeset fcs in dscs.FileChangesets) {
+ if (fcs.RealFile != real_file)
+ continue;
+
+ foreach (Change c in fcs.Changes) {
+ if (c.XPath == xpath) {
+ c.NewNode = new_node;
+ c.Serial = SettingsHandler.Settings.SerialNumber;
+ return;
+ }
+ }
+
+ fcs.Changes.Add (new_change);
+ return;
+
+ }
+
+ new_file_change_set = new FileChangeset ();
+ new_file_change_set.RealFile = real_file;
+ new_file_change_set.Changes.Add (new_change);
+ dscs.FileChangesets.Add (new_file_change_set);
+ return;
+
+ }
+
+ DocSetChangeset new_dcs = new DocSetChangeset ();
+ new_dcs.DocSet = doc_set;
+
+ new_file_change_set = new FileChangeset ();
+ new_file_change_set.RealFile = real_file;
+
+ new_file_change_set.Changes.Add (new_change);
+ new_dcs.FileChangesets.Add (new_file_change_set);
+ DocSetChangesets.Add (new_dcs);
+ }
+
+ public void RemoveChange (string doc_set, string real_file, string xpath)
+ {
+ if (real_file == null)
+ throw new Exception ("Could not find real_file. Please talk to Miguel or Ben about this");
+
+ for (int i = 0; i < DocSetChangesets.Count; i++) {
+ DocSetChangeset dscs = DocSetChangesets [i] as DocSetChangeset;
+ if (dscs.DocSet != doc_set)
+ continue;
+
+ for (int j = 0; j < dscs.FileChangesets.Count; j++) {
+ FileChangeset fcs = dscs.FileChangesets [j] as FileChangeset;
+ if (fcs.RealFile != real_file)
+ continue;
+
+ for (int k = 0; k < fcs.Changes.Count; k++) {
+ Change c = fcs.Changes [k] as Change;
+ if (c.XPath == xpath) {
+ fcs.Changes.Remove (c);
+ break;
+ }
+ }
+ if (fcs.Changes.Count == 0)
+ dscs.FileChangesets.Remove (fcs);
+ }
+
+ if (dscs.FileChangesets.Count == 0)
+ DocSetChangesets.Remove (dscs);
+ }
+ }
+
+ public GlobalChangeset GetFrom (int starting_serial_id)
+ {
+ GlobalChangeset s = null;
+
+ foreach (DocSetChangeset dscs in DocSetChangesets){
+ object o = dscs.GetFrom (starting_serial_id);
+ if (o == null)
+ continue;
+ if (s == null)
+ s = new GlobalChangeset ();
+ s.DocSetChangesets.Add (o);
+ }
+ return s;
+ }
+ }
+
+ public class DocSetChangeset {
+ [XmlAttribute] public string DocSet;
+
+ [XmlElement ("FileChangeset", typeof (FileChangeset))]
+ public ArrayList FileChangesets = new ArrayList ();
+
+ public DocSetChangeset GetFrom (int starting_serial_id)
+ {
+ DocSetChangeset dsc = null;
+
+ foreach (FileChangeset fcs in FileChangesets){
+ object o = fcs.GetFrom (starting_serial_id);
+ if (o == null)
+ continue;
+ if (dsc == null){
+ dsc = new DocSetChangeset ();
+ dsc.DocSet = DocSet;
+ }
+ dsc.FileChangesets.Add (o);
+ }
+ return dsc;
+ }
+ }
+
+ public class FileChangeset {
+ [XmlAttribute] public string RealFile;
+
+ [XmlElement ("Change", typeof (Change))]
+ public ArrayList Changes = new ArrayList ();
+
+ public FileChangeset GetFrom (int starting_serial_id)
+ {
+ FileChangeset fcs = null;
+
+ foreach (Change c in Changes){
+ if (c.Serial < starting_serial_id)
+ continue;
+ if (fcs == null){
+ fcs = new FileChangeset ();
+ fcs.RealFile = RealFile;
+ }
+ fcs.Changes.Add (c);
+ }
+ return fcs;
+ }
+ }
+
+ public class Change {
+ [XmlAttribute] public string XPath;
+ [XmlAttribute] public int FromVersion = RootTree.MonodocVersion;
+ [XmlAttribute] public string NodeUrl;
+
+ public XmlNode NewNode;
+
+ public int Serial;
+
+ bool applied = false;
+
+ //
+ // These are not a property, because we dont want them serialized;
+ // Only used by the Admin Client.
+ //
+ public bool Applied ()
+ {
+ return applied;
+ }
+
+ public void SetApplied (bool value)
+ {
+ applied = value;
+ }
+ }
+#endregion
+
+ public class EditMerger {
+ GlobalChangeset changeset;
+ ArrayList targetDirs;
+
+ public EditMerger (GlobalChangeset changeset, ArrayList targetDirs)
+ {
+ this.changeset = changeset;
+ this.targetDirs = targetDirs;
+ }
+
+ public void Merge ()
+ {
+ foreach (DocSetChangeset dsc in changeset.DocSetChangesets) {
+ bool merged = false;
+ foreach (string path in targetDirs) {
+ if (File.Exists (Path.Combine (path, dsc.DocSet + ".source"))) {
+ Merge (dsc, path);
+ merged = true;
+ break;
+ }
+ }
+ if (!merged) Console.WriteLine ("Could not merge docset {0}", dsc.DocSet);
+ }
+ }
+
+ void Merge (DocSetChangeset dsc, string path)
+ {
+ Console.WriteLine ("Merging changes in {0} ({1})", dsc.DocSet, path);
+
+ foreach (FileChangeset fcs in dsc.FileChangesets) {
+ if (File.Exists (Path.Combine (path, fcs.RealFile)))
+ Merge (fcs, path);
+ else
+ Console.WriteLine ("\tCould not find file {0}", Path.Combine (path, fcs.RealFile));
+ }
+ }
+
+ void Merge (FileChangeset fcs, string path)
+ {
+ XmlDocument d = new XmlDocument ();
+ d.Load (Path.Combine (path, fcs.RealFile));
+
+ foreach (Change c in fcs.Changes) {
+ XmlNode old = d.SelectSingleNode (c.XPath);
+ if (old != null)
+ old.ParentNode.ReplaceChild (d.ImportNode (c.NewNode, true), old);
+ }
+
+ d.Save (Path.Combine (path, fcs.RealFile));
+ }
+ }
+}
+