Automatically link from plugin list screen to plugin settings screens

If a plugin implements a screen for administrating its settings that
is available under "#/x/<plugin-name>/settings" it is automatically
linked from the plugin list screen.

This avoids that each plugin has to register an own menu entry for its
settings screen.

Change-Id: I6d76f5286c936fd412572e484ee45edeb176a98e
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 14470b0..ad07b67 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -1602,6 +1602,13 @@
 }
 ----
 
+[[settings-screen]]
+== Plugin Settings Screen
+
+If a plugin implements a screen for administrating its settings that is
+available under "#/x/<plugin-name>/settings" it is automatically linked
+from the plugin list screen.
+
 [[http]]
 == HTTP Servlets
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
index 8937bcc..3319457 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
@@ -61,6 +61,9 @@
   @Source("readOnly.png")
   public ImageResource readOnly();
 
+  @Source("gear.png")
+  public ImageResource gear();
+
   @Source("info.png")
   public ImageResource info();
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index 2f26ad9..1458976 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -110,8 +110,10 @@
   String plugins();
   String pluginEnabled();
   String pluginDisabled();
+  String pluginSettingsToolTip();
 
   String columnPluginName();
+  String columnPluginSettings();
   String columnPluginVersion();
   String columnPluginStatus();
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index f06d657..14dbab2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -89,7 +89,9 @@
 plugins = Plugins
 pluginEnabled = Enabled
 pluginDisabled = Disabled
+pluginSettingsToolTip = Plugin Settings
 columnPluginName = Plugin Name
+columnPluginSettings = Settings
 columnPluginVersion = Version
 columnPluginStatus = Status
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
index 7f85f51..e1c73fa 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
@@ -15,14 +15,17 @@
 package com.google.gerrit.client.admin;
 
 import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.api.ExtensionScreen;
 import com.google.gerrit.client.plugins.PluginInfo;
 import com.google.gerrit.client.plugins.PluginMap;
 import com.google.gerrit.client.rpc.Natives;
 import com.google.gerrit.client.rpc.ScreenLoadCallback;
 import com.google.gerrit.client.ui.FancyFlexTable;
+import com.google.gerrit.client.ui.InlineHyperlink;
 import com.google.gwt.user.client.ui.Anchor;
 import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
 import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.ImageResourceRenderer;
 import com.google.gwt.user.client.ui.Panel;
 
 public class PluginListScreen extends PluginScreen {
@@ -60,13 +63,15 @@
   private class PluginTable extends FancyFlexTable<PluginInfo> {
     PluginTable() {
       table.setText(0, 1, Util.C.columnPluginName());
-      table.setText(0, 2, Util.C.columnPluginVersion());
-      table.setText(0, 3, Util.C.columnPluginStatus());
+      table.setText(0, 2, Util.C.columnPluginSettings());
+      table.setText(0, 3, Util.C.columnPluginVersion());
+      table.setText(0, 4, Util.C.columnPluginStatus());
 
       final FlexCellFormatter fmt = table.getFlexCellFormatter();
       fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader());
       fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
       fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
+      fmt.addStyleName(0, 4, Gerrit.RESOURCES.css().dataHeader());
     }
 
     void display(final PluginMap plugins) {
@@ -86,16 +91,20 @@
       if (plugin.disabled() || plugin.indexUrl() == null) {
         table.setText(row, 1, plugin.name());
       } else {
-        table.setWidget(
-            row,
-            1,
-            new Anchor(
-                plugin.name(),
-                Gerrit.selfRedirect(plugin.indexUrl()),
-                "_blank"));
+        table.setWidget(row, 1, new Anchor(plugin.name(),
+            Gerrit.selfRedirect(plugin.indexUrl()), "_blank"));
+
+        if (new ExtensionScreen(plugin.name() + "/settings").isFound()) {
+          InlineHyperlink adminScreenLink = new InlineHyperlink();
+          adminScreenLink.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.gear()));
+          adminScreenLink.setTargetHistoryToken("/x/" + plugin.name() + "/settings");
+          adminScreenLink.setTitle(Util.C.pluginSettingsToolTip());
+          table.setWidget(row, 2, adminScreenLink);
+        }
       }
-      table.setText(row, 2, plugin.version());
-      table.setText(row, 3, plugin.disabled()
+
+      table.setText(row, 3, plugin.version());
+      table.setText(row, 4, plugin.disabled()
           ? Util.C.pluginDisabled()
           : Util.C.pluginEnabled());
 
@@ -103,6 +112,7 @@
       fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell());
       fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
       fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
+      fmt.addStyleName(row, 4, Gerrit.RESOURCES.css().dataCell());
 
       setRowItem(row, plugin);
     }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png
new file mode 100644
index 0000000..2f84e47
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png
Binary files differ