diff options
author | Martin Fick <mfick@codeaurora.org> | 2010-08-26 16:47:41 -0600 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2010-10-14 21:14:42 -0700 |
commit | 1d9a6526baad7b45cb4a211d65c3f02ff05c86a6 (patch) | |
tree | f3cb1b603fdc045c1b8a138131fa4cd610db4baf | |
parent | d2605edacf7c1f5bbb7c25d065a0753e8e933d9c (diff) |
Add ProjectsList popup under Settings > Watched Projects
Add a browse button which opens a popup panel containing the
list of projects and their descriptions to the Settings >
Watched Projects screen. Selecting a project from the list
(single clicking it) adds it to the add project text field,
and opening a project from the list (double clicking it) adds
it straight to the watched list.
Bug: issue 204
Change-Id: Ifb24da3ba870b8d4fee09a0d8b7a1960b4ea6c98
5 files changed, 321 insertions, 4 deletions
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java index ff704eeb6c..c9b8a03f0b 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java @@ -83,6 +83,14 @@ public interface AccountConstants extends Constants { String buttonWatchProject(); String defaultProjectName(); String defaultFilter(); + String buttonBrowseProjects(); + String projects(); + String projectsClose(); + String projectName(); + String projectDescription(); + String projectListOpen(); + String projectListPrev(); + String projectListNext(); String watchedProjectName(); String watchedProjectFilter(); String watchedProjectColumnEmailNotifications(); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties index 756e60d5be..9706d35db6 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties @@ -64,6 +64,14 @@ sshJavaAppletNotAvailable = Open Key Unavailable: Java not enabled buttonWatchProject = Watch defaultProjectName = Project Name defaultFilter = branch:name, or other search expression +projects = All Watchable Projects +projectsClose = Close +buttonBrowseProjects = Browse +projectName = Project Name +projectDescription = Project Description +projectListOpen = Select project +projectListPrev = Previous project +projectListNext = Next project watchedProjectName = Project Name watchedProjectFilter = Only If watchedProjectColumnEmailNotifications = Email Notifications diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java index 5457efe5d6..aaf4234831 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyWatchedProjectsScreen.java @@ -21,37 +21,64 @@ import com.google.gerrit.client.ui.HintTextBox; import com.google.gerrit.client.ui.ProjectNameSuggestOracle; import com.google.gerrit.client.ui.RPCSuggestOracle; import com.google.gerrit.common.data.AccountProjectWatchInfo; +import com.google.gerrit.reviewdb.Project; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; +import com.google.gwt.event.logical.shared.ResizeEvent; +import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Grid; -import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.HTMLTable.CellFormatter; +import com.google.gwt.user.client.ui.PopupPanel; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; +import com.google.gwtexpui.globalkey.client.GlobalKey; +import com.google.gwtexpui.globalkey.client.HidePopupPanelCommand; +import com.google.gwtexpui.user.client.PluginSafeDialogBox; import java.util.List; -public class MyWatchedProjectsScreen extends SettingsScreen { +public class MyWatchedProjectsScreen extends SettingsScreen implements + ResizeHandler { private Button addNew; private HintTextBox nameBox; private SuggestBox nameTxt; private HintTextBox filterTxt; private MyWatchesTable watchesTab; + private Button browse; + private PluginSafeDialogBox popup; + private Button close; + private ProjectsTable projectsTab; private Button delSel; + + private PopupPanel.PositionCallback popupPosition; + private HandlerRegistration regWindowResize; + + private int preferredPopupWidth = -1; + private boolean submitOnSelection; + private boolean firstPopupLoad = true; + private boolean popingUp; + + private ScrollPanel sp; @Override protected void onInitUI() { super.onInitUI(); - createWidgets(); + + /* top table */ + final Grid grid = new Grid(2, 2); grid.setStyleName(Gerrit.RESOURCES.css().infoBlock()); grid.setText(0, 0, Util.C.watchedProjectName()); @@ -71,10 +98,67 @@ public class MyWatchedProjectsScreen extends SettingsScreen { fp.setStyleName(Gerrit.RESOURCES.css().addWatchPanel()); fp.add(grid); fp.add(addNew); + fp.add(browse); add(fp); + + /* bottom table */ + add(watchesTab); add(delSel); + + + /* popup */ + + final FlowPanel pfp = new FlowPanel(); + sp = new ScrollPanel(projectsTab); + pfp.add(sp); + pfp.add(close); + popup.setWidget(pfp); + + popupPosition = new PopupPanel.PositionCallback() { + public void setPosition(int offsetWidth, int offsetHeight) { + if (preferredPopupWidth == -1) { + preferredPopupWidth = offsetWidth; + } + + int top = grid.getAbsoluteTop() - 50; // under page header + + // Try to place it to the right of everything else, but not + // right justified + int left = 5 + Math.max( + grid.getAbsoluteLeft() + grid.getOffsetWidth(), + watchesTab.getAbsoluteLeft() + watchesTab.getOffsetWidth() ); + + if (top + offsetHeight > Window.getClientHeight()) { + top = Window.getClientHeight() - offsetHeight; + } + if (left + offsetWidth > Window.getClientWidth()) { + left = Window.getClientWidth() - offsetWidth; + } + + if (top < 0) { + sp.setHeight((sp.getOffsetHeight() + top) + "px"); + top = 0; + } + if (left < 0) { + sp.setWidth((sp.getOffsetWidth() + left) + "px"); + left = 0; + } + + popup.setPopupPosition(left, top); + } + }; + } + + @Override + public void onResize(final ResizeEvent event) { + sp.setSize("100%","100%"); + + // For some reason keeping track of preferredWidth keeps the width better, + // but using 100% for height works better. + popup.setHeight("100%"); + popupPosition.setPosition(preferredPopupWidth, popup.getOffsetHeight()); } protected void createWidgets() { @@ -126,6 +210,45 @@ public class MyWatchedProjectsScreen extends SettingsScreen { } }); + projectsTab = new ProjectsTable() { + @Override + protected void movePointerTo(final int row, final boolean scroll) { + super.movePointerTo(row, scroll); + + // prevent user input from being overwritten by simply poping up + if (! popingUp || "".equals(nameBox.getText()) ) { + nameBox.setText(getRowItem(row).getName()); + } + } + + @Override + protected void onOpenRow(final int row) { + super.onOpenRow(row); + nameBox.setText(getRowItem(row).getName()); + doAddNew(); + } + }; + + close = new Button(Util.C.projectsClose()); + close.addClickHandler(new ClickHandler() { + @Override + public void onClick(final ClickEvent event) { + closePopup(); + } + }); + + popup = new PluginSafeDialogBox(); + popup.setModal(false); + popup.setText(Util.C.projects()); + + browse = new Button(Util.C.buttonBrowseProjects()); + browse.addClickHandler(new ClickHandler() { + @Override + public void onClick(final ClickEvent event) { + displayPopup(); + } + }); + watchesTab = new MyWatchesTable(); delSel = new Button(Util.C.buttonDeleteSshKey()); @@ -143,7 +266,42 @@ public class MyWatchedProjectsScreen extends SettingsScreen { populateWatches(); } - void doAddNew() { + @Override + protected void onUnload() { + super.onUnload(); + closePopup(); + } + + protected void displayPopup() { + popingUp = true; + if (firstPopupLoad) { // For sizing/positioning, delay display until loaded + populateProjects(); + } else { + popup.setPopupPositionAndShow(popupPosition); + + GlobalKey.dialog(popup); + GlobalKey.addApplication(popup, new HidePopupPanelCommand(0, + KeyCodes.KEY_ESCAPE, popup)); + projectsTab.setRegisterKeys(true); + + projectsTab.finishDisplay(); + + if (regWindowResize == null) { + regWindowResize = Window.addResizeHandler(this); + } + + popingUp = false; + } + } + protected void closePopup() { + popup.hide(); + if (regWindowResize != null) { + regWindowResize.removeHandler(); + regWindowResize = null; + } + } + + protected void doAddNew() { final String projectName = nameTxt.getText(); if ("".equals(projectName)) { return; @@ -190,4 +348,18 @@ public class MyWatchedProjectsScreen extends SettingsScreen { } }); } + + protected void populateProjects() { + Util.PROJECT_SVC.visibleProjects( + new GerritCallback<List<Project>>() { + @Override + public void onSuccess(final List<Project> result) { + projectsTab.display(result); + if (firstPopupLoad) { // Display was delayed until table was loaded + firstPopupLoad = false; + displayPopup(); + } + } + }); + } } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ProjectsTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ProjectsTable.java new file mode 100644 index 0000000000..9c854ea227 --- /dev/null +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ProjectsTable.java @@ -0,0 +1,123 @@ +// Copyright (C) 2010 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.account; + +import com.google.gerrit.client.Gerrit; +import com.google.gerrit.client.ui.NavigationTable; +import com.google.gerrit.common.PageLinks; +import com.google.gerrit.reviewdb.Project; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter; + +import java.util.List; + +public class ProjectsTable extends NavigationTable<Project> { + + public ProjectsTable() { + setSavePointerId(PageLinks.SETTINGS_PROJECTS); + keysNavigation.add(new PrevKeyCommand(0, 'k', Util.C.projectListPrev())); + keysNavigation.add(new NextKeyCommand(0, 'j', Util.C.projectListNext())); + keysNavigation.add(new OpenKeyCommand(0, KeyCodes.KEY_ENTER, + Util.C.projectListOpen())); + + table.setText(0, 1, Util.C.projectName()); + table.setText(0, 2, Util.C.projectDescription()); + + final FlexCellFormatter fmt = table.getFlexCellFormatter(); + fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader()); + fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader()); + } + + protected MyFlexTable createFlexTable() { + MyFlexTable table = new MyFlexTable() { + @Override + public void onBrowserEvent(final Event event) { + switch (DOM.eventGetType(event)) { + case Event.ONCLICK: { + // Find out which cell was actually clicked. + final Element td = getEventTargetCell(event); + if (td == null) { + break; + } + final int row = rowOf(td); + if (getRowItem(row) != null) { + ProjectsTable.this.movePointerTo(row); + return; + } + break; + } + case Event.ONDBLCLICK: { + // Find out which cell was actually clicked. + Element td = getEventTargetCell(event); + if (td == null) { + return; + } + onOpenRow(rowOf(td)); + return; + } + } + super.onBrowserEvent(event); + } + }; + + table.sinkEvents(Event.ONDBLCLICK | Event.ONCLICK); + return table; + } + + @Override + protected Object getRowItemKey(final Project item) { + return item.getNameKey(); + } + + @Override + protected void onOpenRow(final int row) { + if (row > 0) { + movePointerTo(row); + } + } + + protected void display(final List<Project> projects) { + while (1 < table.getRowCount()) + table.removeRow(table.getRowCount() - 1); + + for (final Project k : projects) + insert(table.getRowCount(), k); + + finishDisplay(); + } + + protected void insert(final int row, final Project k) { + table.insertRow(row); + + applyDataRowStyle(row); + + final FlexCellFormatter fmt = table.getFlexCellFormatter(); + fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell()); + fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().cPROJECT()); + fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell()); + + populate(row, k); + } + + protected void populate(final int row, final Project k) { + table.setText(row, 1, k.getName()); + table.setText(row, 2, k.getDescription()); + + setRowItem(row, k); + } +} diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Util.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Util.java index 5ed79e6716..59e439d57c 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Util.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/Util.java @@ -16,6 +16,8 @@ package com.google.gerrit.client.account; import com.google.gerrit.common.data.AccountSecurity; import com.google.gerrit.common.data.AccountService; +import com.google.gerrit.common.data.ProjectAdminService; +import com.google.gerrit.reviewdb.Project; import com.google.gwt.core.client.GWT; import com.google.gwtjsonrpc.client.JsonUtil; @@ -24,6 +26,7 @@ public class Util { public static final AccountMessages M = GWT.create(AccountMessages.class); public static final AccountService ACCOUNT_SVC; public static final AccountSecurity ACCOUNT_SEC; + public static final ProjectAdminService PROJECT_SVC; static { ACCOUNT_SVC = GWT.create(AccountService.class); @@ -31,5 +34,8 @@ public class Util { ACCOUNT_SEC = GWT.create(AccountSecurity.class); JsonUtil.bind(ACCOUNT_SEC, "rpc/AccountSecurity"); + + PROJECT_SVC = GWT.create(ProjectAdminService.class); + JsonUtil.bind(PROJECT_SVC, "rpc/ProjectAdminService"); } } |