FELIX-569 Apply FELIX-569-fmeschbe-3.patch based on config-treetable.patch by Valentin Valchev (thanks)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@924175 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
index d67158d..f28fc1d 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
@@ -400,8 +400,7 @@
                 String name;
                 if (ocd != null)
                 {
-                    name = ocd.getName() + " (";
-                    name += pid + ")";
+                    name = ocd.getName();
                 }
                 else
                 {
@@ -479,8 +478,7 @@
                 final ObjectClassDefinition ocd = this.getObjectClassDefinition( refs[i].getBundle(), pid, locale );
                 if ( ocd != null )
                 {
-                    name = ocd.getName() + " (";
-                    name += pid + ")";
+                    name = ocd.getName();
                 }
                 else
                 {
@@ -520,8 +518,7 @@
             props.put( type, pid );
             if ( filter == null || filter.match( props ) )
             {
-                final String name = ocd.getName() + " (" + pid + ")";
-                pidMap.put( pid, name );
+                pidMap.put( pid, ocd.getName() );
             }
         }
 
diff --git a/webconsole/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties b/webconsole/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties
index d9c96b7..d9d2b86 100644
--- a/webconsole/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties
+++ b/webconsole/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties
@@ -182,6 +182,9 @@
 config.configurations.title=Конфигурации
 config.create.tip=Създаване на нова factory конфигурация
 config.edit.tip=Редактиране на стойностите на конфигурацията
+config.title.actions=Действия
+config.title.bundle=Бъндъл
+config.title.name=Име
 
 # License plugin
 license.pluginTitle=Лицензи
diff --git a/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties b/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
index 69169ca..1e2e4fd 100644
--- a/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
+++ b/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -182,6 +182,9 @@
 config.configurations.title=Configurations
 config.create.tip=Create new factory configuration
 config.edit.tip=Edit the configuration values
+config.title.actions=Actions
+config.title.bundle=Bundle
+config.title.name=Name
 
 # License plugin
 license.pluginTitle=Licenses
diff --git a/webconsole/src/main/resources/res/ui/config.css b/webconsole/src/main/resources/res/ui/config.css
index 55e62f7..13cc0db 100644
--- a/webconsole/src/main/resources/res/ui/config.css
+++ b/webconsole/src/main/resources/res/ui/config.css
@@ -30,5 +30,7 @@
 .multiselect { display: block }
 .col_Actions { width: 6em !important }
 .pointer { cursor: pointer }
+.subpid   { display:inline-block; margin-left: 1em }
+tr.fpid   td   { font-style:italic }
 #editor, div.ui-dialog-buttonpane button { font-size: 50% }
 #factoryTableCaption { margin-top: 1.5em }
diff --git a/webconsole/src/main/resources/res/ui/config.js b/webconsole/src/main/resources/res/ui/config.js
index c282eb8..6eeeb2b 100644
--- a/webconsole/src/main/resources/res/ui/config.js
+++ b/webconsole/src/main/resources/res/ui/config.js
@@ -23,7 +23,6 @@
 var configRow = false;
 
 // factories table list
-var factoryTable = false;
 var factoryBody  = false;
 var factoryRow = false;
 
@@ -426,11 +425,20 @@
 
 function addConfig(conf) {
 	var tr = configRow.clone().appendTo(configBody);
-	tr.find('td:eq(1)').text(conf.fpid ? conf.fpid : '-'); // fpid
-	tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
+
+	// rendering name - indented if factory pid is set
+	var nms = tr.find('td:eq(0) span')
+	if (conf.fpid) { 
+		nms.after(conf.id); 
+		tr.attr('fpid', conf.name);
+	} else {
+		nms.addClass('ui-helper-hidden').parent().text(conf.name);
+	}
+
+	tr.find('td:eq(0)').click(function() { // name & edit
 		configure(conf.id);
 	});
-	tr.find('td:eq(2)').html(conf.bundle ? '<a href="' + pluginRoot + '/../bundles/' + conf.bundle + '">' + conf.bundle_name + '</a>' : '-'); // binding
+	tr.find('td:eq(1)').html(conf.bundle ? '<a href="' + pluginRoot + '/../bundles/' + conf.bundle + '">' + conf.bundle_name + '</a>' : '-'); // binding
 	
 	// buttons
 	tr.find('li:eq(0)').click(function() { // edit
@@ -453,8 +461,8 @@
 }
 
 function addFactoryConfig(conf) {
-	var tr = factoryRow.clone().appendTo(factoryBody);
-	tr.find('td:eq(1)').text(conf.id); // fpid
+	var tr = factoryRow.clone().appendTo(configTable).attr('fpid', conf.name);
+	//tr.find('td:eq(1)').text(conf.id); // fpid
 	tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
 		configure(conf.id, true);
 	});
@@ -464,22 +472,33 @@
 	});
 }
 
+function treetableExtraction(node) {
+	var td = $(node);
+	var text = td.text();
+	if (!text) return text;
+
+	// current sort order
+	var desc = $(this)[0].sortList[0][1];
+
+	var row = td.parent();
+	var fpid = row.attr('fpid');
+	
+	// factory row
+	if ( row.hasClass('fpid') && fpid) return fpid + (desc==0?1:0) + text;
+
+	// bundle or name row
+	if ( fpid ) return fpid + desc + text;
+
+	return mixedLinksExtraction(node);
+};
+
 $(document).ready(function() {
 	configContent = $('#configContent');
 	// config table list
-	configTable   = configContent.find('table:eq(0)').tablesorter({
-		headers: { 3: { sorter: false } },
-		textExtraction:mixedLinksExtraction
-	});
+	configTable   = $('#configTable');
 	configBody    = configTable.find('tbody');
-	configRow     = configBody.find('tr').clone();
-
-	// factories table list
-	factoryTable  = configContent.find('table:eq(1)').tablesorter({
-		headers: { 2: { sorter: false } }
-	});
-	factoryBody   = factoryTable.find('tbody');
-	factoryRow    = factoryBody.find('tr').clone();
+	configRow     = configBody.find('tr:eq(0)').clone();
+	factoryRow    = configBody.find('tr:eq(1)').clone();
 
 	// setup button - cannot inline in dialog option because of i18n
 	var _buttons = {};
@@ -506,16 +525,36 @@
 	// display the configuration data
 	$(".statline").html(configData.status ? i18n.stat_ok : i18n.stat_missing);
 	if (configData.status) {
-		configBody.empty(); factoryBody.empty();
+		configBody.empty();
+		var factories = {};
 
-		for(var i in configData.pids) addConfig(configData.pids[i]);
-		for(var i in configData.fpids) addFactoryConfig(configData.fpids[i]);
-		initStaticWidgets(configContent);
+		for(var i in configData.pids) {
+			var c = configData.pids[i];
+			if (c.fpid) {
+				if (!factories[c.fpid]) factories[c.fpid] = new Array();
+				factories[c.fpid].push(c);
+			} else {
+				addConfig(c);
+			}
+		}
+		for(var i in configData.fpids) {
+			addFactoryConfig(configData.fpids[i]);
 
-		// initial sorting orger by name
-		var sorting = [[0,0]]; 
-		configTable.trigger('sorton', [sorting]);
-		factoryTable.trigger('sorton', [sorting]);
+			var confs = factories[ configData.fpids[i].id ];
+			if (confs) for (var j in confs) {
+				addConfig(confs[j]);
+			}
+		}
+		initStaticWidgets(configTable);
+
+		// init tablesorte
+		configTable.tablesorter({
+			headers: { 2: { sorter: false }  },
+			sortList: [[0,1]],
+			textExtraction: treetableExtraction
+		}).bind('sortStart', function() { // clear cache, otherwse extraction will not work
+			var table = $(this).trigger('update'); 
+		}).find('th:eq(0)').click();
 	} else {
 		configContent.addClass('ui-helper-hidden');
 	}
diff --git a/webconsole/src/main/resources/templates/config.html b/webconsole/src/main/resources/templates/config.html
index 4a3d7f1..a013e33 100644
--- a/webconsole/src/main/resources/templates/config.html
+++ b/webconsole/src/main/resources/templates/config.html
@@ -36,19 +36,17 @@
 	<div id="fPidsSelect" class="ui-widget-header ui-corner-top buttonGroup">
 		${config.configurations.title}
 	</div>
-	<table class="tablesorter nicetable noauto">
+	<table id="configTable" class="tablesorter nicetable noauto">
 		<thead>
 			<tr>
-				<th class="col_Name">Name</th>
-				<th class="col_FPID">Factory PID</th>
-				<th class="col_Binding">Bundle</th>
-				<th class="col_Actions" style="width: 7em">Actions</th>
+				<th class="col_Name">${config.title.name}</th>
+				<th class="col_Binding">${config.title.bundle}</th>
+				<th class="col_Actions">${config.title.actions}</th>
 			</tr>
 		</thead>
 		<tbody>
 			<tr>
-				<td class="pointer">&nbsp;</td>
-				<td>&nbsp;</td>
+				<td class="pointer"><span class="ui-icon ui-icon-triangle-1-e subpid">&nbsp;</span></td>
 				<td>&nbsp;</td>
 				<td>
 					<ul class="icons">
@@ -58,24 +56,9 @@
 					</ul>
 				</td>
 			</tr>
-		</tbody>
-	</table>
-
-	<div id="factoryTableCaption" class="ui-widget-header ui-corner-top buttonGroup">
-		${config.factories.title}
-	</div>
-	<table class="tablesorter nicetable noauto">
-		<thead>
-			<tr>
-				<th class="col_Name">Name</th>
-				<th class="col_FPID">Factory PID</th>
-				<th class="col_Actions" style="width: 7em">Actions</th>
-			</tr>
-		</thead>
-		<tbody>
-			<tr>
+			<tr class="fpid">
 				<td class="pointer">&nbsp;</td>
-				<td>&nbsp;</td>
+				<td>-</td>
 				<td>
 					<ul class="icons">
 						<li class="dynhover" title="${config.create.tip}"><span class="ui-icon ui-icon-plusthick">&nbsp;</span></li>