From 12adc008742fbf0fdf14cbbacdf49a20f70a42c4 Mon Sep 17 00:00:00 2001
From: Edwin Kempin <edwin.kempin@sap.com>
Date: Wed, 2 Apr 2014 16:23:52 +0200
Subject: [PATCH] Keep 'My' menu selected if a 'My' menu item opens project
 screen

If a project screen is shown the 'Projects' menu is automatically
selected. This is bad for custom 'My' menu items that link to a
project screen because in this case the user expects that the 'My'
menu stays selected.

Change-Id: I894853392bd8b0efa6ad5708c101c0be3132eda9
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
---
 .../java/com/google/gerrit/client/Gerrit.java | 60 ++++++-------------
 .../google/gerrit/client/ui/LinkMenuBar.java  |  2 +
 .../google/gerrit/client/ui/LinkMenuItem.java | 13 +++-
 .../gerrit/client/ui/ProjectLinkMenuItem.java | 47 +++++++++++++++
 4 files changed, 79 insertions(+), 43 deletions(-)
 create mode 100644 gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectLinkMenuItem.java

diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index b36bc50e92..3635a90978 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -38,8 +38,8 @@ import com.google.gerrit.client.ui.LinkMenuBar;
 import com.google.gerrit.client.ui.LinkMenuItem;
 import com.google.gerrit.client.ui.MorphingTabPanel;
 import com.google.gerrit.client.ui.PatchLink;
+import com.google.gerrit.client.ui.ProjectLinkMenuItem;
 import com.google.gerrit.client.ui.Screen;
-import com.google.gerrit.client.ui.ScreenLoadEvent;
 import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.common.data.GerritConfig;
 import com.google.gerrit.common.data.GitwebConfig;
@@ -50,7 +50,6 @@ import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountDiffPreference;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
 import com.google.gerrit.reviewdb.client.AuthType;
-import com.google.gerrit.reviewdb.client.Project;
 import com.google.gwt.aria.client.Roles;
 import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.core.client.GWT;
@@ -214,6 +213,10 @@ public class Gerrit implements EntryPoint {
     }
   }
 
+  public static void selectMenu(LinkMenuBar bar) {
+    menuLeft.selectTab(menuLeft.getWidgetIndex(bar));
+  }
+
   /**
    * Update the current history token after a screen change.
    * <p>
@@ -619,22 +622,21 @@ public class Gerrit implements EntryPoint {
     addDiffLink(diffBar, C.menuDiffPatchSets(), PatchScreen.TopView.PATCH_SETS);
     addDiffLink(diffBar, C.menuDiffFiles(), PatchScreen.TopView.FILES);
 
-    final LinkMenuBar projectsBar = new LinkMenuBar() {
-      @Override
-      public void onScreenLoad(ScreenLoadEvent event) {
-        if (event.getScreen() instanceof ProjectScreen) {
-          menuLeft.selectTab(menuLeft.getWidgetIndex(this));
-        }
-      }
-    };
+    final LinkMenuBar projectsBar = new LinkMenuBar();
     menuBars.put(GerritTopMenu.PROJECTS.menuName, projectsBar);
     addLink(projectsBar, C.menuProjectsList(), PageLinks.ADMIN_PROJECTS);
-    addProjectLink(projectsBar, C.menuProjectsInfo(), ProjectScreen.INFO);
-    addProjectLink(projectsBar, C.menuProjectsBranches(), ProjectScreen.BRANCH);
-    addProjectLink(projectsBar, C.menuProjectsAccess(), ProjectScreen.ACCESS);
+    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsInfo(), ProjectScreen.INFO));
+    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsBranches(), ProjectScreen.BRANCH));
+    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsAccess(), ProjectScreen.ACCESS));
     final LinkMenuItem dashboardsMenuItem =
-        addProjectLink(projectsBar, C.menuProjectsDashboards(),
-            ProjectScreen.DASHBOARDS);
+        new ProjectLinkMenuItem(C.menuProjectsDashboards(),
+            ProjectScreen.DASHBOARDS) {
+      protected boolean match(String token) {
+        return super.match(token) ||
+            (!getTargetHistoryToken().isEmpty() && ("/admin" + token).startsWith(getTargetHistoryToken()));
+      }
+    };
+    projectsBar.addItem(dashboardsMenuItem);
     menuLeft.add(projectsBar, C.menuProjects());
 
     if (signedIn) {
@@ -848,32 +850,6 @@ public class Gerrit implements EntryPoint {
       });
   }
 
-  private static LinkMenuItem addProjectLink(final LinkMenuBar m, final String text,
-      final String panel) {
-    LinkMenuItem i = new LinkMenuItem(text, "") {
-        @Override
-        public void onScreenLoad(ScreenLoadEvent event) {
-          Screen screen = event.getScreen();
-          Project.NameKey projectKey;
-          if (screen instanceof ProjectScreen) {
-            projectKey = ((ProjectScreen)screen).getProjectKey();
-          } else {
-            projectKey = ProjectScreen.getSavedKey();
-          }
-
-          if (projectKey != null) {
-            setVisible(true);
-            setTargetHistoryToken(Dispatcher.toProjectAdmin(projectKey, panel));
-          } else {
-            setVisible(false);
-          }
-          super.onScreenLoad(event);
-        }
-      };
-    m.addItem(i);
-    return i;
-  }
-
   private static void addDiffLink(final LinkMenuBar m, final String text,
       final PatchScreen.Type type) {
     m.addItem(new LinkMenuItem(text, "") {
@@ -906,7 +882,7 @@ public class Gerrit implements EntryPoint {
       if (item.getId() != null) {
         a.getElement().setAttribute("id", item.getId());
       }
-      m.add(a);
+      m.addItem(a);
     } else {
       Anchor atag = anchor(item.getName(), isAbsolute(item.getUrl())
           ? item.getUrl()
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
index bc88eed616..deca808e3f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
@@ -41,10 +41,12 @@ public class LinkMenuBar extends Composite implements ScreenLoadHandler {
   }
 
   public void addItem(final LinkMenuItem i) {
+    i.setMenuBar(this);
     add(i);
   }
 
   public void insertItem(final LinkMenuItem i, int beforeIndex) {
+    i.setMenuBar(this);
     insert(i, beforeIndex);
   }
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
index 20569c32ce..29c053bc6e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
@@ -19,6 +19,8 @@ import com.google.gwt.aria.client.Roles;
 import com.google.gwt.dom.client.AnchorElement;
 
 public class LinkMenuItem extends InlineHyperlink implements ScreenLoadHandler {
+  private LinkMenuBar bar;
+
   public LinkMenuItem(final String text, final String targetHistoryToken) {
     super(text, targetHistoryToken);
     setStyleName(Gerrit.RESOURCES.css().menuItem());
@@ -32,11 +34,20 @@ public class LinkMenuItem extends InlineHyperlink implements ScreenLoadHandler {
     AnchorElement.as(getElement()).blur();
   }
 
+  public void setMenuBar(LinkMenuBar bar) {
+    this.bar = bar;
+  }
+
   public void onScreenLoad(ScreenLoadEvent event) {
-    if (event.getScreen().getToken().equals(getTargetHistoryToken())){
+    if (match(event.getScreen().getToken())) {
+      Gerrit.selectMenu(bar);
       addStyleName(Gerrit.RESOURCES.css().activeRow());
     } else {
       removeStyleName(Gerrit.RESOURCES.css().activeRow());
     }
   }
+
+  protected boolean match(String token) {
+    return token.equals(getTargetHistoryToken());
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectLinkMenuItem.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectLinkMenuItem.java
new file mode 100644
index 0000000000..2917505115
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/ProjectLinkMenuItem.java
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.client.ui;
+
+import com.google.gerrit.client.Dispatcher;
+import com.google.gerrit.client.admin.ProjectScreen;
+import com.google.gerrit.reviewdb.client.Project;
+
+public class ProjectLinkMenuItem extends LinkMenuItem {
+  private final String panel;
+
+  public ProjectLinkMenuItem(String text, String panel) {
+    super(text, "");
+    this.panel = panel;
+  }
+
+  @Override
+  public void onScreenLoad(ScreenLoadEvent event) {
+    Screen screen = event.getScreen();
+    Project.NameKey projectKey;
+    if (screen instanceof ProjectScreen) {
+      projectKey = ((ProjectScreen)screen).getProjectKey();
+    } else {
+      projectKey = ProjectScreen.getSavedKey();
+    }
+
+    if (projectKey != null) {
+      setVisible(true);
+      setTargetHistoryToken(Dispatcher.toProjectAdmin(projectKey, panel));
+    } else {
+      setVisible(false);
+    }
+    super.onScreenLoad(event);
+  }
+}