Index: /main/trunk/greenstone3/web/WEB-INF/classes/interface_default.properties
===================================================================
--- /main/trunk/greenstone3/web/WEB-INF/classes/interface_default.properties	(revision 27014)
+++ /main/trunk/greenstone3/web/WEB-INF/classes/interface_default.properties	(revision 27015)
@@ -12,4 +12,5 @@
 page_icon_image=interfaces/__INTERFACE_NAME__/images/itext.gif
 trash_full_image=interfaces/__INTERFACE_NAME__/images/trash-full.png
+trash_empty_image=interfaces/__INTERFACE_NAME__/images/trash-empty.png
 blank_image=interfaces/__INTERFACE_NAME__/images/blankImage.png
 next_image=interfaces/__INTERFACE_NAME__/images/next.png
Index: /main/trunk/greenstone3/web/interfaces/default/js/debug_scripts.js
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/js/debug_scripts.js	(revision 27014)
+++ /main/trunk/greenstone3/web/interfaces/default/js/debug_scripts.js	(revision 27015)
@@ -38,5 +38,5 @@
 	var _styleFunctions = new Array();
 	
-	var partialPageReload = function()
+	var partialPageReload = function(callback)
 	{
 		$.ajax(document.URL)
@@ -70,4 +70,9 @@
 			alert("There was an error reloading the page, please reload manually.");
 		});
+		
+		if(callback)
+		{
+			callback();
+		}
 	}
 	
@@ -166,4 +171,5 @@
 				if(_isVisualEditor)
 				{
+					_vEditor.savePendingEdits();
 					xmlString = new XMLSerializer().serializeToString(_vEditor.getXML());
 				}
@@ -190,6 +196,6 @@
 				if(_currentMatch && _currentMatch.length > 0){parameters["s1.match"] = _currentMatch;}
 
-				_saveButton.button("option", "label", "Saving...");
 				_saveButton.button("option", "disabled", true);
+				$.blockUI({message:'<div class="ui-state-active">Saving, please wait...</div>'});
 
 				$.post(url, parameters)
@@ -199,15 +205,14 @@
 					.success(function()
 					{
-						alert("The template has been saved successfully.");
+						partialPageReload(function(){$.unblockUI();});
 					})
 					.error(function()
 					{
+						$.unblockUI();
 						alert("Error reloading collection.");
 					})
 					.complete(function()
 					{
-						_saveButton.button("option", "label", "Save changes");
 						_saveButton.button("option", "disabled", false);
-						partialPageReload();
 					});
 				})
@@ -227,4 +232,5 @@
 				if(_isVisualEditor)
 				{
+					_vEditor.savePendingEdits();
 					_vEditor.getMainDiv().hide();
 					var containerNode = _vEditor.getXML().firstChild;
Index: /main/trunk/greenstone3/web/interfaces/default/js/visual-xml-editor.js
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/js/visual-xml-editor.js	(revision 27014)
+++ /main/trunk/greenstone3/web/interfaces/default/js/visual-xml-editor.js	(revision 27015)
@@ -6,4 +6,6 @@
 function visualXMLEditor(xmlString)
 {
+	var thisEditor = this;
+
 	var _globalID = 0;
 
@@ -27,4 +29,6 @@
 	var _origDDPosition;
 	
+	var _editingNodes = new Array();
+	
 	var _overList = new Array();
 	_overList.freeSpaces = new Array();
@@ -82,4 +86,16 @@
 				}
 				resizeAll();
+
+				//Check if we need to change the recycle bin icon
+				var found = false;
+				for(var i = 0; i < _transactions.length; i++)
+				{
+					if(_transactions[i].type == "remMvElem"){found = true; break;}
+				}
+
+				if(!found)
+				{
+					$("#veTrash").children("img").attr("src", gs.imageURLs.trashEmpty);
+				}
 			}
 			//Undo an added attribute
@@ -162,5 +178,7 @@
 	var placeTrashBin = function()
 	{
-		var bin = $("<div id=\"veTrash\">Recycle Bin</div>");
+		var binImage = $("<img src=\"" + gs.imageURLs.trashEmpty + "\"/>");
+		var bin = $("<div id=\"veTrash\">");
+		bin.append(binImage);
 		bin.addClass("ui-state-default");
 		bin.addClass("ui-corner-all");
@@ -183,5 +201,5 @@
 		var elemList = 
 		{
-			html:["a", "br", "div", "li", "link", "script", "span", "table", "td", "tr", "ul"],
+			html:["a", "br", "div", "li", "link", "p", "script", "span", "table", "td", "tr", "ul"],
 			xsl:
 			[
@@ -343,4 +361,13 @@
 	}
 	
+	this.savePendingEdits = function()
+	{
+		while(_editingNodes && _editingNodes.length > 0)
+		{
+			var attr = _editingNodes.pop();
+			attr.saveEdits();
+		}
+	}
+	
 	var addToOverList = function(veElement)
 	{
@@ -475,5 +502,74 @@
 		_mainDiv.append($("<div>", {"style":"clear:both;"}));		
 	}
-
+	
+	// *********************************************************************** //
+	// Visual Editor Text                                                      //
+	// This inner class represents a single xml text node in the visual editor //
+	// *********************************************************************** //
+
+	var VEText = function(node)
+	{
+		var _thisNode = this;
+		var _xmlNode = node;
+	
+		var _textEditor = $("<div>");
+		var textTitle = $("<div>Text:</div>");
+		var _nodeText = $("<div>");
+		_nodeText.text(_xmlNode.nodeValue);
+
+		_textEditor.append(textTitle);
+		_textEditor.append(_nodeText);
+		
+		var editButton = $("<button>edit text</button>");
+		editButton.click(function()
+		{
+			if(editButton.text() == "edit text")
+			{
+				_thisNode.editMode();
+			}
+			else
+			{
+				_thisNode.saveEdits();
+			}
+		});
+		_textEditor.append(editButton);
+		
+		this.editMode = function()
+		{
+			_editingNodes.push(_thisNode);
+			_nodeText.data("prevTextValue", _nodeText.text());
+			var textArea = $("<textarea>");
+			textArea.val(_nodeText.text());
+			_nodeText.text("");
+			_nodeText.append(textArea);
+			editButton.text("done");
+		}
+
+		this.saveEdits = function()
+		{
+			for(var i = 0; i < _editingNodes.length; i++)
+			{
+				if(_editingNodes[i] == _thisNode)
+				{
+					_editingNodes.splice(i, 1);
+					break;
+				}
+			}
+		
+			_transactions.push({type:"editText", elem:_xmlNode, vElem: _nodeText, value:_nodeText.data("prevTextValue")});
+			var textArea = _nodeText.find("textarea");
+			var newValue = textArea.val();
+			_xmlNode.nodeValue = newValue;
+			_nodeText.empty();
+			_nodeText.text(newValue);
+			editButton.text("edit text");
+		}
+
+		this.getDiv = function()
+		{
+			return _textEditor;
+		}
+	}
+	
 	// *********************************************************************** //
 	// Visual Editor Attribute                                                 //
@@ -502,8 +598,9 @@
 			_value = attrElem.value;
 		}
-		
 		var _xmlElem = xmlElem;
 		var _row;
 
+		var _thisAttr = this;
+		
 		this.getName = function()
 		{
@@ -534,53 +631,8 @@
 			var cell = $("<td>", {"class":"veEditCell"});
 			var link = $("<a href=\"javascript:;\">edit</a>");
+			
 			link.click(function()
 			{
-				var nameCell = _row.children("td").eq(0);
-				var valueCell = _row.children("td").eq(1);
-				if(link.text() == "edit")
-				{
-					link.text("done");
-
-					var nameInput = $("<input type=\"text\">");
-					nameInput.width(nameCell.width() - 5);
-					nameInput.val(_name);
-
-					var valueInput = $("<input type=\"text\">");
-					valueInput.width(valueCell.width() - 5);
-					valueInput.val(_value);
-
-					nameCell.text("");
-					valueCell.text("");
-
-					nameCell.append(nameInput);
-					valueCell.append(valueInput);
-				}
-				else
-				{
-					link.text("edit");
-
-					var nameInput = nameCell.children("input");
-					var valueInput = valueCell.children("input");
-
-					var name = nameInput.val();
-					var value = valueInput.val();
-
-					nameCell.empty();
-					nameCell.text(name);
-
-					valueCell.empty();
-					valueCell.text(value);
-
-					if(nameCell.data("prevName") != "")
-					{
-						_xmlElem.removeAttribute(_name);
-					}
-					_xmlElem.setAttribute(name, value);
-					
-					_transactions.push({type:"editAttr", elem:_xmlElem, row:_row, newName:name, name:_name, value:_value});
-					
-					_name = name;
-					_value = value;
-				}
+				_thisAttr.editMode();
 			});
 			cell.append(link);
@@ -621,4 +673,85 @@
 
 			return tableRow;
+		}
+		
+		this.editMode = function()
+		{
+			_editingNodes.push(_thisAttr);
+		
+			var nameCell = _row.children("td").eq(0);
+			var valueCell = _row.children("td").eq(1);
+			var editLink = _row.children("td").eq(2).find("a");
+
+			editLink.text("done");
+			editLink.off("click");
+			editLink.click(function()
+			{
+				_thisAttr.saveEdits();
+			});
+
+			var nameInput = $("<input type=\"text\">");
+			nameInput.width(nameCell.width() - 5);
+			nameInput.val(_name);
+
+			var valueInput = $("<input type=\"text\">");
+			valueInput.width(valueCell.width() - 5);
+			valueInput.val(_value);
+
+			nameCell.text("");
+			valueCell.text("");
+
+			nameCell.append(nameInput);
+			valueCell.append(valueInput);
+
+			nameInput.focus();
+		}
+		
+		this.saveEdits = function()
+		{
+			for(var i = 0; i < _editingNodes.length; i++)
+			{
+				if(_editingNodes[i] == _thisAttr)
+				{
+					_editingNodes.splice(i, 1);
+					break;
+				}
+			}
+
+			var nameCell = _row.children("td").eq(0);
+			var valueCell = _row.children("td").eq(1);
+			var editLink = _row.children("td").eq(2).find("a");
+		
+			editLink.text("edit");
+			editLink.off("click");
+			editLink.click(function()
+			{
+				_thisAttr.editMode();
+			});
+
+			var nameInput = nameCell.children("input");
+			var valueInput = valueCell.children("input");
+			
+			nameInput.blur();
+			valueInput.blur();
+
+			var name = nameInput.val();
+			var value = valueInput.val();
+			
+			nameCell.empty();
+			nameCell.text(name);
+
+			valueCell.empty();
+			valueCell.text(value);
+			
+			if(nameCell.data("prevName") != "")
+			{
+				_xmlElem.removeAttribute(_name);
+			}
+			_xmlElem.setAttribute(name, value);
+			
+			_transactions.push({type:"editAttr", elem:_xmlElem, row:_row, newName:name, name:_name, value:_value});
+			
+			_name = name;
+			_value = value;
 		}
 	}
@@ -858,4 +991,5 @@
 		this.populateInformationDiv = function()
 		{
+			thisEditor.savePendingEdits();
 			_infoDiv.empty();
 
@@ -894,4 +1028,5 @@
 					var row = newAtt.getAsTableRow();
 					attributeTable.append(row);
+					newAtt.editMode();
 					_transactions.push({type:"addAttr", row:row})
 				});
@@ -901,50 +1036,7 @@
 			if(_xmlNode.nodeType == 3)
 			{
-				var textEditor = $("<div>");
-				var textTitle = $("<div>Text:</div>");
-				var nodeText = $("<div>");
-				nodeText.text(_xmlNode.nodeValue);
-
-				textEditor.append(textTitle);
-				textEditor.append(nodeText);
-
-				_infoDiv.append(textEditor);
-				
-				var editButton = $("<button>edit text</button>");
-				editButton.click(function()
-				{
-					if(editButton.text() == "edit text")
-					{
-						nodeText.data("prevTextValue", nodeText.text());
-						var textArea = $("<textarea>");
-						textArea.val(nodeText.text());
-						nodeText.text("");
-						nodeText.append(textArea);
-						editButton.text("done");
-					}
-					else
-					{
-						_transactions.push({type:"editText", elem:_xmlNode, vElem: nodeText, value:nodeText.data("prevTextValue")});
-						var textArea = nodeText.find("textarea");
-						var newValue = textArea.val();
-						_xmlNode.nodeValue = newValue;
-						nodeText.empty();
-						nodeText.text(newValue);
-						editButton.text("edit text");
-					}
-				});
-				
-				textEditor.append(editButton);
-			}
-			
-			_infoDiv.append($("<br>"));
-			_infoDiv.append($("<br>"));
-			
-			var removeButton = $("<button>Delete this element</button>");
-			_infoDiv.append(removeButton);
-			removeButton.click(function()
-			{
-				_div.data("parentVEElement").remove();
-			});
+				var textNode = new VEText(_xmlNode);
+				_infoDiv.append(textNode.getDiv());
+			}
 		}
 		
@@ -962,4 +1054,6 @@
 				divParent.first().trigger("click");
 			}
+			
+			$("#veTrash").children("img").attr("src", gs.imageURLs.trashFull);
 		}
 
Index: /main/trunk/greenstone3/web/interfaces/default/style/core.css
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/style/core.css	(revision 27014)
+++ /main/trunk/greenstone3/web/interfaces/default/style/core.css	(revision 27015)
@@ -1034,6 +1034,4 @@
 	right:0px;
 	bottom:0px;
-	width:5%;
-	height:20%;
 	text-align:center;
 }
