blob: 344104dd68d43df385a4f9b427ab5bd04e87184f [file] [log] [blame]
// Copyright (C) 2011 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.admin;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.ProjectAccess;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.ValueAwareEditor;
import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ValueListBox;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AccessSectionEditor extends Composite implements
Editor<AccessSection>, ValueAwareEditor<AccessSection> {
interface Binder extends UiBinder<HTMLPanel, AccessSectionEditor> {
}
private static final Binder uiBinder = GWT.create(Binder.class);
@UiField
ValueEditor<String> name;
@UiField
FlowPanel permissionContainer;
ListEditor<Permission, PermissionEditor> permissions;
@UiField
DivElement addContainer;
@UiField(provided = true)
@Editor.Ignore
ValueListBox<String> permissionSelector;
@UiField
SpanElement deletedName;
@UiField
Anchor deleteSection;
@UiField
DivElement normal;
@UiField
DivElement deleted;
@UiField
SpanElement sectionType;
@UiField
SpanElement sectionName;
private final ProjectAccess projectAccess;
private AccessSection value;
private boolean editing;
private boolean readOnly;
private boolean isDeleted;
public AccessSectionEditor(ProjectAccess access) {
projectAccess = access;
permissionSelector =
new ValueListBox<String>(PermissionNameRenderer.INSTANCE);
permissionSelector.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
if (!Util.C.addPermission().equals(event.getValue())) {
onAddPermission(event.getValue());
}
}
});
initWidget(uiBinder.createAndBindUi(this));
permissions = ListEditor.of(new PermissionEditorSource());
}
@UiHandler("deleteSection")
void onDeleteHover(MouseOverEvent event) {
normal.addClassName(AdminResources.I.css().deleteSectionHover());
}
@UiHandler("deleteSection")
void onDeleteNonHover(MouseOutEvent event) {
normal.removeClassName(AdminResources.I.css().deleteSectionHover());
}
@UiHandler("deleteSection")
void onDeleteSection(ClickEvent event) {
isDeleted = true;
if (name.isVisible()
&& RefConfigSection.isValid(name.getValue())) {
deletedName.setInnerText(Util.M.deletedReference(name.getValue()));
} else {
String name = Util.C.sectionNames().get(value.getName());
if (name == null) {
name = value.getName();
}
deletedName.setInnerText(Util.M.deletedSection(name));
}
normal.getStyle().setDisplay(Display.NONE);
deleted.getStyle().setDisplay(Display.BLOCK);
}
@UiHandler("undoDelete")
void onUndoDelete(ClickEvent event) {
isDeleted = false;
deleted.getStyle().setDisplay(Display.NONE);
normal.getStyle().setDisplay(Display.BLOCK);
}
void onAddPermission(String varName) {
int idx = permissions.getList().size();
Permission p = value.getPermission(varName, true);
permissions.getList().add(p);
PermissionEditor e = permissions.getEditors().get(idx);
e.beginAddRule();
rebuildPermissionSelector();
}
void editRefPattern() {
name.edit();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
name.setFocus(true);
}});
}
void enableEditing() {
readOnly = false;
addContainer.getStyle().setDisplay(Display.BLOCK);
rebuildPermissionSelector();
}
boolean isDeleted() {
return isDeleted;
}
@Override
public void setValue(AccessSection value) {
Collections.sort(value.getPermissions());
this.value = value;
this.readOnly = !editing || !(projectAccess.isOwnerOf(value) || projectAccess.canUpload());
name.setEnabled(!readOnly);
deleteSection.setVisible(!readOnly);
if (RefConfigSection.isValid(value.getName())) {
name.setVisible(true);
name.setIgnoreEditorValue(false);
sectionType.setInnerText(Util.C.sectionTypeReference());
} else {
name.setVisible(false);
name.setIgnoreEditorValue(true);
String name = Util.C.sectionNames().get(value.getName());
if (name != null) {
sectionType.setInnerText(name);
sectionName.getStyle().setDisplay(Display.NONE);
} else {
sectionType.setInnerText(Util.C.sectionTypeSection());
sectionName.setInnerText(value.getName());
sectionName.getStyle().clearDisplay();
}
}
if (readOnly) {
addContainer.getStyle().setDisplay(Display.NONE);
} else {
enableEditing();
}
}
void setEditing(final boolean editing) {
this.editing = editing;
}
private void rebuildPermissionSelector() {
List<String> perms = new ArrayList<String>();
if (AccessSection.GLOBAL_CAPABILITIES.equals(value.getName())) {
for (String varName : Util.C.capabilityNames().keySet()) {
addPermission(varName, perms);
}
} else if (RefConfigSection.isValid(value.getName())) {
for (LabelType t : projectAccess.getLabelTypes().getLabelTypes()) {
addPermission(Permission.LABEL + t.getName(), perms);
}
for (String varName : Util.C.permissionNames().keySet()) {
addPermission(varName, perms);
}
}
if (perms.isEmpty()) {
addContainer.getStyle().setDisplay(Display.NONE);
} else {
addContainer.getStyle().setDisplay(Display.BLOCK);
perms.add(0, Util.C.addPermission());
permissionSelector.setValue(Util.C.addPermission());
permissionSelector.setAcceptableValues(perms);
}
}
private void addPermission(final String permissionName,
final List<String> permissionList) {
if (value.getPermission(permissionName) != null) {
return;
}
if (Gerrit.getConfig().getWildProject()
.equals(projectAccess.getProjectName())
&& !Permission.canBeOnAllProjects(value.getName(), permissionName)) {
return;
}
permissionList.add(permissionName);
}
@Override
public void flush() {
List<Permission> src = permissions.getList();
List<Permission> keep = new ArrayList<Permission>(src.size());
for (int i = 0; i < src.size(); i++) {
PermissionEditor e = (PermissionEditor) permissionContainer.getWidget(i);
if (!e.isDeleted()) {
keep.add(src.get(i));
}
}
value.setPermissions(keep);
}
@Override
public void onPropertyChange(String... paths) {
}
@Override
public void setDelegate(EditorDelegate<AccessSection> delegate) {
}
private class PermissionEditorSource extends EditorSource<PermissionEditor> {
@Override
public PermissionEditor create(int index) {
PermissionEditor subEditor =
new PermissionEditor(projectAccess.getProjectName(), readOnly, value,
projectAccess.getLabelTypes());
permissionContainer.insert(subEditor, index);
return subEditor;
}
@Override
public void dispose(PermissionEditor subEditor) {
subEditor.removeFromParent();
}
@Override
public void setIndex(PermissionEditor subEditor, int index) {
permissionContainer.insert(subEditor, index);
}
}
}