Hi,

> "Restore" is less frightening than "Delete", but it works better for
> "changes" than for "additions" so I feel the
> The dialog helps filter unintended or not ready contributions (either
> "changes" and "additions"). I the dialog you'd need to have a way to
> "Restore/Delete" unintended contributions and other to "Select" those
> to be uploaded, as they may yeld different sets.
> 
> This dialog, or some other derived from it, may help also in
> navigating through the "pending" contributions (the ones not yet ready
> to be uploaded) as the work on them may span many sessions inside the
> documentation browser.
> 

I've added to the patch the dialog thing, to see an screenshot look
here: 
http://msopena.blogspot.com/2005/08/contributor-experiencetm-revisited.html

There is the possibility to:
- open selected contribution
- restore/delete selected contribution
- upload only the marked ones

Of course that only works with contributions writen after the patch.
The old ones are automatically sent in the first upload being made (at
least the program shows at the root page how many of those
contributions are left, as well as new contributions with a link).

I've tried several times the upload process and everything seems ok
(sorry if I have sent several mini-contributions to the docs).

Ok to commit?

Mario
Index: docbrowser/GeckoHtmlRender.cs
===================================================================
--- docbrowser/GeckoHtmlRender.cs	(revision 48726)
+++ docbrowser/GeckoHtmlRender.cs	(working copy)
@@ -48,7 +48,6 @@
 	protected void OnOpenUri (object o, OpenUriArgs args)
 	{
 		url = CheckUrl (args.AURI);
-		System.Console.WriteLine ("Abriendo:{0}:{1}:", url, args.AURI);
 		if (UrlClicked != null)
 			UrlClicked (this, new EventArgs());
 		args.RetVal = true; //this prevents Gecko to continue processing
Index: docbrowser/ChangeLog
===================================================================
--- docbrowser/ChangeLog	(revision 48726)
+++ docbrowser/ChangeLog	(working copy)
@@ -1,3 +1,16 @@
+2005-08-22 Mario Sopena Novales <[EMAIL PROTECTED]>
+	* browser.cs:
+		- Update the treeview everytime we change the tab
+		- Added a new CurrentNode property to Tabs
+		- Added a new class Contributions (Contributions window)
+		- update the save process to include the new NodeUrl property
+		- update the serial of not uploaded changes after a successful upload
+		- dont set the browser mode to viewer every time a row is activated
+	* browser.glade: 
+		- Change the "upload contributions" menu to "Contributions"
+		- Add the Contributions window
+	* GeckoHtmlRender.cs: cleaned
+	
 2005-08-17 Mario Sopena Novales <[EMAIL PROTECTED]>
 	* browser.cs: Added Menu Items for changing the font size when using 
 	gecko. Also added a Reload function.
Index: docbrowser/browser.cs
===================================================================
--- docbrowser/browser.cs	(revision 48726)
+++ docbrowser/browser.cs	(working copy)
@@ -307,6 +307,9 @@
 		} else {
 			paste1.Sensitive = true;
 		}
+		
+		if (tree_browser.SelectedNode != CurrentTab.CurrentNode)
+			tree_browser.ShowNode (CurrentTab.CurrentNode);
 	}
 	//
 	// Reload current page
@@ -451,6 +454,7 @@
 	public void Render (string text, Node matched_node, string url)
 	{
 		CurrentUrl = url;
+		CurrentTab.CurrentNode = matched_node;
 		CurrentTab.html.Render(text);
 		if (matched_node != null) {
 			if (tree_browser.SelectedNode != matched_node)
@@ -740,7 +744,124 @@
 		About.Show (this);
 	}
 
-	void OnUpload (object sender, EventArgs a)
+	void OnContrib (object sender, EventArgs a) 
+	{
+		Contributions.Show (this);
+	}
+
+	class Contributions {
+		[Glade.Widget] Window contribs;
+		[Glade.Widget] TreeView contrib_tree;
+		[Glade.Widget] Button contrib_open;
+		[Glade.Widget] Button contrib_restore;
+		ListStore contrib_store;
+
+		static Contributions ContribBox;
+		Browser parent;
+		GlobalChangeset chgs;
+
+		Contributions (Browser parent)
+		{
+			Glade.XML ui = new Glade.XML (null, "browser.glade", "contribs", null);
+			ui.Autoconnect (this);
+			this.parent = parent;
+			contribs.TransientFor = parent.window1;
+
+			contrib_store = new ListStore (typeof (bool), typeof (string), typeof (Change));
+
+			chgs = EditingUtils.changes;
+			contrib_tree.Selection.Changed += new EventHandler (OnSelectionChg);
+
+			contrib_tree.Model = contrib_store;
+			
+			// columns
+			CellRendererToggle toggle_cell = new CellRendererToggle ();
+			toggle_cell.Toggled += new ToggledHandler (OnToggleCell);
+			contrib_tree.AppendColumn ("upload", toggle_cell, "active", 0);
+			contrib_tree.AppendColumn ("node_url", new CellRendererText (), "text", 1);
+		}
+		static public void Show (Browser parent)
+		{
+			if (ContribBox == null)
+				ContribBox = new Contributions (parent);
+
+			ContribBox.Load ();
+			ContribBox.contribs.ShowAll ();
+
+		}
+		void Load ()
+		{
+			contrib_store.Clear ();
+			foreach (DocSetChangeset dscs in chgs.DocSetChangesets) 
+				foreach (FileChangeset fcs in dscs.FileChangesets) 
+					foreach (Change c in fcs.Changes)  {
+						if (c.NodeUrl == null)
+							continue;
+						if (c.Serial == SettingsHandler.Settings.SerialNumber)
+							contrib_store.AppendValues (c.Upload, c.NodeUrl, c);
+					}
+		}
+			
+		//
+		// Event handlers
+		//
+		public void OnToggleCell (object sender, ToggledArgs args)
+		{
+			TreeIter iter;
+			bool ok = contrib_store.GetIterFromString (out iter, args.Path);
+			if (!ok)
+				return;
+			//obtain the change, toggle and save it
+			Change c = contrib_store.GetValue (iter, 2) as Change;
+			c.Upload = !c.Upload;
+
+			chgs.Save ();
+			Load ();
+		}
+		void OnSelectionChg (object sender, EventArgs a)
+		{
+			contrib_open.Sensitive = true;
+			contrib_restore.Sensitive = true;
+		}
+		public void OpenContrib (object sender, EventArgs a)
+		{
+			TreeIter iter;
+			TreeModel model;
+			bool selected = contrib_tree.Selection.GetSelected (out model, out iter);
+			if (!selected)
+				return;
+			Change c = contrib_store.GetValue (iter, 2) as Change;
+			parent.LoadUrl (c.NodeUrl);
+		}
+		public void DeleteContrib (object sender, EventArgs a)
+		{
+			TreeIter iter;
+			TreeModel model;
+			bool selected = contrib_tree.Selection.GetSelected (out model, out iter);
+			if (!selected)
+				return;
+			
+			Change del = contrib_store.GetValue (iter, 2) as Change;
+			chgs.DelChange (del);
+			//reload the tree
+			Load ();
+			//reload the browser
+			parent.Reload ();
+		}
+		public void OnUpload (object sender, EventArgs a)
+		{
+			contribs.Hide ();
+			parent.OnUpload ();
+		}
+		public void CloseContrib (object sender, EventArgs a)
+		{
+			contribs.Hide ();
+			ContribBox = null;	
+		}
+			
+		
+	}
+	void OnUpload ()
 	{
 		string key = SettingsHandler.Settings.Key;
 		if (key == null || key == "")
@@ -839,6 +960,14 @@
 			case State.Done:
 				status.Text = "All contributions uploaded";
 				cancel.Label = "Close";
+				//update serial of not uploaded changes
+				foreach (DocSetChangeset dscs in EditingUtils.changes.DocSetChangesets) 
+					foreach (FileChangeset fcs in dscs.FileChangesets) 
+						foreach (Change c in fcs.Changes) 
+							if (c.NodeUrl != null && !c.Upload)
+								c.Serial = serial;
+
+				EditingUtils.changes.Save ();
 				SettingsHandler.Settings.SerialNumber = serial;
 				SettingsHandler.Save ();
 				return;
@@ -1550,7 +1679,7 @@
 	void RowActivated  (object sender, EventArgs a)
 	{
 
-		browser.CurrentTab.SetMode (Mode.Viewer);
+		//browser.CurrentTab.SetMode (Mode.Viewer);
 
 		if (IgnoreRowActivated)
 			return;
@@ -1896,6 +2025,7 @@
 		set { titleLabel.Text = value; }
 	}
 	
+	public Node CurrentNode;
 	public System.Xml.XmlNode edit_node;
 	public string edit_url;
 	
@@ -1903,6 +2033,7 @@
 	{
 
 		browser = br;
+		CurrentNode = br.help_tree;
 		ShowTabs = false;
 		ShowBorder = false;
 		TabBorder = 0;
@@ -2127,7 +2258,7 @@
 			browser.statusbar.Push (browser.context_id, e.Message);
 			return;
 		}
-		EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node);
+		EditingUtils.SaveChange (edit_url, browser.help_tree, edit_node, EcmaHelpSource.GetNiceUrl (browser.CurrentTab.CurrentNode));
 		SetMode (Mode.Viewer);
 		history.ActivateCurrent ();
 	}
Index: docbrowser/browser.glade
===================================================================
--- docbrowser/browser.glade	(revision 48726)
+++ docbrowser/browser.glade	(working copy)
@@ -85,9 +85,9 @@
 		  <child>
 		    <widget class="GtkMenuItem" id="contributor_settings1">
 		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Upload Contributions</property>
+		      <property name="label" translatable="yes">Contrib_utions</property>
 		      <property name="use_underline">True</property>
-		      <signal name="activate" handler="OnUpload" last_modification_time="Wed, 08 Oct 2003 02:53:43 GMT"/>
+		      <signal name="activate" handler="OnContrib"  last_modification_time="Tue, 23 Aug 2005 15:01:59 GMT"/>
 		      <accelerator key="U" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 		    </widget>
 		  </child>
@@ -3142,4 +3142,266 @@
   </child>
 </widget>
 
+<widget class="GtkWindow" id="contribs">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Contributions</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">True</property>
+  <property name="default_width">475</property>
+  <property name="default_height">275</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <signal name="delete_event" handler="CloseContrib" last_modification_time="Tue, 23 Aug 2005 13:37:54 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="vbox31">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+	<widget class="GtkLabel" id="label67">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">The selected items will be uploaded</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0.3</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">6</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHSeparator" id="hseparator6">
+	  <property name="visible">True</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox34">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="scrolledwindow6">
+	      <property name="border_width">3</property>
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="contrib_tree">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">True</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVButtonBox" id="vbuttonbox2">
+	      <property name="border_width">4</property>
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_START</property>
+	      <property name="spacing">3</property>
+
+	      <child>
+		<widget class="GtkButton" id="contrib_open">
+		  <property name="visible">True</property>
+		  <property name="sensitive">False</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-open</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="OpenContrib" last_modification_time="Tue, 23 Aug 2005 13:37:01 GMT"/>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="contrib_restore">
+		  <property name="visible">True</property>
+		  <property name="sensitive">False</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-undelete</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="DeleteContrib" last_modification_time="Tue, 23 Aug 2005 13:36:50 GMT"/>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	      <property name="pack_type">GTK_PACK_END</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHSeparator" id="hseparator5">
+	  <property name="visible">True</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHButtonBox" id="hbuttonbox3">
+	  <property name="border_width">7</property>
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkButton" id="button32">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <signal name="clicked" handler="CloseContrib" last_modification_time="Tue, 23 Aug 2005 13:37:28 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="contrib_upload">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <signal name="clicked" handler="OnUpload" last_modification_time="Tue, 23 Aug 2005 15:01:59 GMT"/>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment1">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">0</property>
+		  <property name="yscale">0</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox35">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">2</property>
+
+		      <child>
+			<widget class="GtkImage" id="image133">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-connect</property>
+			  <property name="icon_size">4</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label66">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">_Upload</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>
Index: browser/editing.cs
===================================================================
--- browser/editing.cs	(revision 48386)
+++ browser/editing.cs	(working copy)
@@ -80,7 +80,7 @@
 				
 		}
 		
-		public static void SaveChange (string url, RootTree tree, XmlNode node)
+		public static void SaveChange (string url, RootTree tree, XmlNode node, string node_url)
 		{
 			string [] uSplit = ParseEditUrl (url);
 		
@@ -91,7 +91,7 @@
 				int prov = int.Parse (uSplit [0].Substring("monodoc://".Length));
 				HelpSource hs = tree.GetHelpSourceFromId (prov);
 				
-				changes.AddChange (hs.Name, hs.GetRealPath (id), xp, node);
+				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);
 			
@@ -265,11 +265,12 @@
 			}
 		}
 
-		Change NewChange (string xpath, XmlNode new_node)
+		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;
@@ -277,10 +278,10 @@
 			return new_change;
 		}
 		
-		public void AddChange (string doc_set, string real_file, string xpath, XmlNode new_node)
+		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);
+			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");
@@ -324,6 +325,20 @@
 			new_dcs.FileChangesets.Add (new_file_change_set);
 			DocSetChangesets.Add (new_dcs);
 		}
+		public void DelChange (Change del) {
+			for (int i = 0; i < DocSetChangesets.Count; i++) {
+				DocSetChangeset dscs = DocSetChangesets [i] as DocSetChangeset;
+				for (int j = 0; j < dscs.FileChangesets.Count; j++) {
+					FileChangeset fcs = dscs.FileChangesets [j] as FileChangeset;
+					fcs.Changes.Remove (del);
+					if (fcs.Changes.Count == 0)
+						dscs.FileChangesets.Remove (fcs);
+				}
+				if (dscs.FileChangesets.Count == 0)
+					DocSetChangesets.Remove (dscs);
+			}
+			Save ();
+		}
 
 		public GlobalChangeset GetFrom (int starting_serial_id)
 		{
@@ -378,6 +393,9 @@
 			foreach (Change c in Changes){
 				if (c.Serial < starting_serial_id)
 					continue;
+				if (c.NodeUrl != null) //this prevents old contrib from not being uploaded
+					if (!c.Upload)
+						continue;
 				if (fcs == null){
 					fcs = new FileChangeset ();
 					fcs.RealFile = RealFile;
@@ -391,6 +409,8 @@
 	public class Change {
 		[XmlAttribute] public string XPath;
 		[XmlAttribute] public int FromVersion = RootTree.MonodocVersion;
+		[XmlAttribute] public string NodeUrl;
+		[XmlAttribute] public bool Upload;
 		
 		public XmlNode NewNode;
 
@@ -412,6 +432,7 @@
 			applied = value;
 		}
 	}
+	
 #endregion
 	
 	public class EditMerger {
Index: browser/provider.cs
===================================================================
--- browser/provider.cs	(revision 48618)
+++ browser/provider.cs	(working copy)
@@ -1086,6 +1086,7 @@
 		return (HelpSource) help_sources [id];
 	}
 	
+	string home_cache;
 	/// <summary>
 	///    Allows every HelpSource to try to provide the content for this
 	///    URL.
@@ -1095,12 +1096,82 @@
 		lastHelpSourceTime = DateTime.MinValue;
 		if (url == "root:") {
 			match_node = this;
-			StringBuilder sb = new StringBuilder ("<table bgcolor=\"#b0c4de\" width=\"100%\" cellpadding=\"5\"><tr><td><h3>Mono Documentation Library</h3></td></tr></table>");
+
+			// look whether there are contribs
+			GlobalChangeset chgs = EditingUtils.changes;
+			StringBuilder con = new StringBuilder ();
+			
+			//add links to the contrib
+			int oldContrib = 0, contribs = 0;
+			con.Append ("<ul>");
+			foreach (DocSetChangeset dscs in chgs.DocSetChangesets) 
+				foreach (FileChangeset fcs in dscs.FileChangesets) 
+					foreach (Change c in fcs.Changes) {
+						if (c.NodeUrl == null) {
+							if (c.Serial == SettingsHandler.Settings.SerialNumber)
+								oldContrib++;
+						} else if (c.Serial == SettingsHandler.Settings.SerialNumber) {
+							contribs++;
+							con.Append (String.Format ("<li><a href=\"{0}\">{0}</a></li>", c.NodeUrl));
+						}
+					}
 			
-			foreach (Node n in Nodes)
-				sb.AppendFormat ("<a href='{0}'>{1}</a><br/>", n.Element, n.Caption);
+			string contrib = (oldContrib + contribs) == 1?"There is {0} contribution":"There are {0} contributions";
+			con.Insert (0, String.Format (contrib, oldContrib + contribs) + " for uploading <i>(File--&gt; Contributions--&gt; Upload)</i>", 1);
+			con.Append ("</ul>");
+			if (oldContrib == 1)
+				con.Append ("<i>You have 1 contribution that is not listed below and will be send the next time you upload contributions. Only contributions made from now on will be listed.</i>");
+			else if (oldContrib > 1)
+				con.Append ("<i>You have " + oldContrib + "contributions that are not listed below and will be send the next time you upload contributions. Only contributions made from now on will be listed.</i>");
+
+			//start the rendering
+			if (!HelpSource.use_css) {
+				StringBuilder sb = new StringBuilder ("<table bgcolor=\"#b0c4de\" width=\"100%\" cellpadding=\"5\"><tr><td><h3>Mono Documentation Library</h3></td></tr></table>");
 			
-			return sb.ToString ();	
+				foreach (Node n in Nodes)
+					sb.AppendFormat ("<a href='{0}'>{1}</a><br/>", n.Element, n.Caption);
+			
+				//contributions
+				sb.Append ("<br><table bgcolor=\"#fff3f3\" width=\"100%\" cellpadding=\"5\"><tr><td>");
+				sb.Append ("<h5>Contributions</h5><br>");
+				if ((oldContrib + contribs) == 0) {
+					sb.Append ("<p><b>You don't have any contribution yet.</b></p>");
+					sb.Append ("<p>The Documentation of the libraries is not complete and your contributions would be greatly apreciated. The procedure is easy, browse to the part of the documentation you want to contribute and click on the <font color=\"blue\">[Edit]</font> link to start writing the documentation.</p>");
+					sb.Append ("<p>When you are happy with your changes, use the menu File--&gt; Contributions--&gt; Upload to upload your contributions to our server.</p></div>");
+				} else {
+					sb.Append (con.ToString ());
+				}
+				sb.Append ("</td></tr></table>");
+				return sb.ToString ();	
+			} else {
+				if (home_cache == null) {
+					System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly (typeof (HelpSource));
+					Stream hp_stream = assembly.GetManifestResourceStream ("home.html");
+					home_cache = (new StreamReader (hp_stream)).ReadToEnd ();
+				}
+				StringBuilder sb = new StringBuilder (home_cache);
+				// adjust fonts
+				sb.Replace ("@@FONT_FAMILY@@", SettingsHandler.Settings.preferred_font_family);
+				sb.Replace ("@@FONT_SIZE@@", SettingsHandler.Settings.preferred_font_size.ToString());
+				//contributions
+				if ((oldContrib + contribs) == 0) {
+					sb.Replace ("@@CONTRIB_DISP@@", "display: none;");
+				} else {
+					sb.Replace ("@@NO_CONTRIB_DISP@@", "display: none;");
+					sb.Replace ("@@CONTRIBS@@", con.ToString ());
+				}
+					
+				// load the url of nodes
+				String add_str;
+				StringBuilder urls = new StringBuilder ();
+				foreach (Node n in Nodes) {
+					add_str = String.Format ("<li><a href=\"{0}\">{1}</a></li>", n.Element, n.Caption);
+					urls.Append (add_str);
+				}
+				sb.Replace ("@@API_DOCS@@", urls.ToString ());
+						
+				return sb.ToString ();
+			}
 		} 
 		
 		if (url.StartsWith ("root:")) {
Index: browser/ChangeLog
===================================================================
--- browser/ChangeLog	(revision 48618)
+++ browser/ChangeLog	(working copy)
@@ -1,3 +1,15 @@
+2005-08-22 Mario Sopena Novales <[EMAIL PROTECTED]>
+	* editing.cs: 
+		- Add a new Attribute NodeUrl to Change
+		- Add a new Attribute Upload to Change
+		- Add a new method DelChange to remove changes
+		- The GetFrom method of FileChangeset returns only the uploadable
+		changes (and all the old contribtuions)
+	* provider.cs: Render root with Css (use home.html as template) and contribution links
+	* home.html: added. Template for the root page
+	* ecma-provider.cs: new method GetNiceUrl to obtain "T:System.Object" urls
+	* Makefile.am: added the home.html file to the build process
+
 2005-08-17 Mario Sopena Novales <[EMAIL PROTECTED]>
 	* provider.cs: The preferred_font_family and the preferred_font_size
 	are now handled by the settings object
Index: browser/home.html
===================================================================
--- browser/home.html	(revision 0)
+++ browser/home.html	(revision 0)
@@ -0,0 +1,77 @@
+<head>
+<style type="text/css">
+/* GENERAL */
+
+body, table {
+	font-family: @@FONT_FAMILY@@, sans-serif;
+	font-size: @@FONT_SIZE@@%;
+}
+
+#title {
+	width: 94%;
+	margin-left: 1%;
+	padding: 2%;
+	border: 2px solid black;
+	background: #b0c4de;
+	font-size: 140%;
+	font-weight: bold;
+	font-variant: small-caps;
+	text-align: center;
+	}
+
+/* ECMA BLOCK */
+#docs {
+	margin-bottom: 1em;
+}
+
+/* CONTRIBUTIONS */
+#contrib {
+	margin-top: 2em;
+	width: 98%;
+	margin-left: 1%;
+	color: black;
+	background: #fff3f3;
+	border: 1px solid #ffc9c9;
+	}
+#contribTitle {
+	text-align: left;
+	font-weight: bold;
+	padding: .4em;
+	font-size: 110%;
+}
+#contrib #content {
+	padding: .4em;
+}
+#some-contrib {
+	@@CONTRIB_DISP@@
+}
+#no-contrib {
+	@@NO_CONTRIB_DISP@@
+}
+#contrib p {
+	text-indent: 1em;
+	text-align: justify;
+	}
+</style>
+</head>
+
+<div id="title">Mono Documentation Library</div>
+
+<div id="docs">
+	<ul>
+	    @@API_DOCS@@
+	</ul>
+</div>
+
+<div id="contrib">
+	<div id="contribTitle">Contributions</div>
+	<div id="content">
+		<div id="some-contrib">
+			@@CONTRIBS@@
+		</div>
+		<div id="no-contrib">
+			<p><b>You don't have any contribution yet.</b></p>
+			<p>The Documentation of the libraries is not complete and your contributions would be greatly apreciated. The procedure is easy, browse to the part of the documentation you want to contribute and click on the <font color="blue">[Edit]</font> link to start writing the documentation.</p>
+			<p>When you are happy with your changes, use the menu File--&gt; Contributions--&gt; Upload to upload your contributions to our server.</p></div>
+	</div>
+</div>
Index: browser/ecma-provider.cs
===================================================================
--- browser/ecma-provider.cs	(revision 48386)
+++ browser/ecma-provider.cs	(working copy)
@@ -1332,6 +1332,54 @@
 	}
 	
 	//
+	// Obtain an URL of the type T:System.Object from the node
+	// 
+	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.URL.IndexOf ('/');
+			return node.URL[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.URL.IndexOf ('/');
+			return node.URL[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.URL.IndexOf ('/');
+			return node.URL[idx+1] + ":" + full + "." + node.Caption;
+		}
+		return "";
+
+	}
+				
+	//
 	// Populates the index.
 	//
 	public override void PopulateIndex (IndexMaker index_maker)
Index: browser/Makefile.am
===================================================================
--- browser/Makefile.am	(revision 48386)
+++ browser/Makefile.am	(working copy)
@@ -50,7 +50,8 @@
 	ecmaspec-html.xsl mod.cs		\
 	AssemblyInfo.cs.in $(cs2ecma_sources) \
 	ecmaspec-html-css.xsl ecmaspec.css \
-	base.css mono-ecma-css.xsl mono-ecma.css
+	base.css mono-ecma-css.xsl mono-ecma.css \
+	home.html
 
 monodoc_FILES = assembler.exe normalize.exe validate.exe cs2ecma.exe
 
@@ -72,8 +73,8 @@
 mono.pub: $(top_srcdir)/mono.pub
 	cp $(top_srcdir)/mono.pub .
 
-monodoc.dll: $(monodoc_sources) mono-ecma.xsl mono.pub ecmaspec-html-css.xsl ecmaspec.css base.css mono-ecma-css.xsl mono-ecma.css
-	$(CSC) -debug -out:monodoc.dll -target:library /resource:$(srcdir)/mono-ecma.xsl,mono-ecma.xsl /resource:$(srcdir)/ecmaspec-html.xsl,ecmaspec-html.xsl /resource:$(srcdir)/ecmaspec-html-css.xsl,ecmaspec-html-css.xsl /resource:$(srcdir)/base.css,base.css /resource:$(srcdir)/ecmaspec.css,ecmaspec.css /resource:$(srcdir)/mono-ecma-css.xsl,mono-ecma-css.xsl /resource:$(srcdir)/mono-ecma.css,mono-ecma.css $(monodoc_sources) -r:ICSharpCode.SharpZipLib.dll -r:System.Web -r:System.Web.Services
+monodoc.dll: $(monodoc_sources) mono-ecma.xsl mono.pub ecmaspec-html-css.xsl ecmaspec.css base.css mono-ecma-css.xsl mono-ecma.css home.html
+	$(CSC) -debug -out:monodoc.dll -target:library /resource:$(srcdir)/mono-ecma.xsl,mono-ecma.xsl /resource:$(srcdir)/ecmaspec-html.xsl,ecmaspec-html.xsl /resource:$(srcdir)/ecmaspec-html-css.xsl,ecmaspec-html-css.xsl /resource:$(srcdir)/base.css,base.css /resource:$(srcdir)/ecmaspec.css,ecmaspec.css /resource:$(srcdir)/mono-ecma-css.xsl,mono-ecma-css.xsl /resource:$(srcdir)/mono-ecma.css,mono-ecma.css /resource:$(srcdir)/home.html,home.html $(monodoc_sources) -r:ICSharpCode.SharpZipLib.dll -r:System.Web -r:System.Web.Services
 
 monodoc.dll.config: $(srcdir)/monodoc.dll.config.in Makefile
 	if sed 's,@''monodoc_refdir@,$(monodoc_refdir),' $(srcdir)/monodoc.dll.config.in > [EMAIL PROTECTED]; then mv [EMAIL PROTECTED] $@; else rm -f [EMAIL PROTECTED] ; exit 1; fi
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to