com.google.gerrit.client.changes.ChangeTable2.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gerrit.client.changes.ChangeTable2.java

Source

// Copyright (C) 2008 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.changes;

import static com.google.gerrit.client.FormatUtil.relativeFormat;
import static com.google.gerrit.client.FormatUtil.shortFormat;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.ui.AccountLinkPanel;
import com.google.gerrit.client.ui.BranchLink;
import com.google.gerrit.client.ui.ChangeLink;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.NeedsSignInKeyCommand;
import com.google.gerrit.client.ui.ProjectLink;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ChangeTable2 extends NavigationTable<ChangeInfo> {
    private static final int C_STAR = 1;
    private static final int C_SUBJECT = 2;
    private static final int C_STATUS = 3;
    private static final int C_OWNER = 4;
    private static final int C_PROJECT = 5;
    private static final int C_BRANCH = 6;
    private static final int C_LAST_UPDATE = 7;
    private static final int BASE_COLUMNS = 8;

    private final List<Section> sections;
    private int columns;
    private List<String> labelNames;

    public ChangeTable2() {
        super(Util.C.changeItemHelp());
        columns = BASE_COLUMNS;
        labelNames = Collections.emptyList();

        if (Gerrit.isSignedIn()) {
            keysAction.add(new StarKeyCommand(0, 's', Util.C.changeTableStar()));
        }

        sections = new ArrayList<Section>();
        table.setText(0, C_STAR, "");
        table.setText(0, C_SUBJECT, Util.C.changeTableColumnSubject());
        table.setText(0, C_STATUS, Util.C.changeTableColumnStatus());
        table.setText(0, C_OWNER, Util.C.changeTableColumnOwner());
        table.setText(0, C_PROJECT, Util.C.changeTableColumnProject());
        table.setText(0, C_BRANCH, Util.C.changeTableColumnBranch());
        table.setText(0, C_LAST_UPDATE, Util.C.changeTableColumnLastUpdate());

        final FlexCellFormatter fmt = table.getFlexCellFormatter();
        fmt.addStyleName(0, C_STAR, Gerrit.RESOURCES.css().iconHeader());
        for (int i = C_SUBJECT; i < columns; i++) {
            fmt.addStyleName(0, i, Gerrit.RESOURCES.css().dataHeader());
        }

        table.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(final ClickEvent event) {
                final Cell cell = table.getCellForEvent(event);
                if (cell == null) {
                    return;
                }
                if (cell.getCellIndex() == C_STAR) {
                    // Don't do anything (handled by star itself).
                } else if (cell.getCellIndex() == C_STATUS) {
                    // Don't do anything.
                } else if (cell.getCellIndex() == C_OWNER) {
                    // Don't do anything.
                } else if (getRowItem(cell.getRowIndex()) != null) {
                    movePointerTo(cell.getRowIndex());
                }
            }
        });
    }

    @Override
    protected Object getRowItemKey(final ChangeInfo item) {
        return item.legacy_id();
    }

    @Override
    protected void onOpenRow(final int row) {
        final ChangeInfo c = getRowItem(row);
        final Change.Id id = c.legacy_id();
        Gerrit.display(PageLinks.toChange(id), new ChangeScreen(id));
    }

    private void insertNoneRow(final int row) {
        insertRow(row);
        table.setText(row, 0, Util.C.changeTableNone());
        final FlexCellFormatter fmt = table.getFlexCellFormatter();
        fmt.setColSpan(row, 0, columns);
        fmt.setStyleName(row, 0, Gerrit.RESOURCES.css().emptySection());
    }

    private void insertChangeRow(final int row) {
        insertRow(row);
        applyDataRowStyle(row);
    }

    @Override
    protected void applyDataRowStyle(final int row) {
        super.applyDataRowStyle(row);
        final CellFormatter fmt = table.getCellFormatter();
        fmt.addStyleName(row, C_STAR, Gerrit.RESOURCES.css().iconCell());
        for (int i = C_SUBJECT; i < columns; i++) {
            fmt.addStyleName(row, i, Gerrit.RESOURCES.css().dataCell());
        }
        fmt.addStyleName(row, C_SUBJECT, Gerrit.RESOURCES.css().cSUBJECT());
        fmt.addStyleName(row, C_OWNER, Gerrit.RESOURCES.css().cOWNER());
        fmt.addStyleName(row, C_LAST_UPDATE, Gerrit.RESOURCES.css().cLastUpdate());
        for (int i = BASE_COLUMNS; i < columns; i++) {
            fmt.addStyleName(row, i, Gerrit.RESOURCES.css().cAPPROVAL());
        }
    }

    public void updateColumnsForLabels(ChangeList... lists) {
        labelNames = new ArrayList<String>();
        for (ChangeList list : lists) {
            for (int i = 0; i < list.length(); i++) {
                for (String name : list.get(i).labels()) {
                    if (!labelNames.contains(name)) {
                        labelNames.add(name);
                    }
                }
            }
        }
        Collections.sort(labelNames);

        if (BASE_COLUMNS + labelNames.size() < columns) {
            int n = columns - (BASE_COLUMNS + labelNames.size());
            for (int row = 0; row < table.getRowCount(); row++) {
                table.removeCells(row, columns, n);
            }
        }
        columns = BASE_COLUMNS + labelNames.size();

        FlexCellFormatter fmt = table.getFlexCellFormatter();
        for (int i = 0; i < labelNames.size(); i++) {
            String name = labelNames.get(i);
            int col = BASE_COLUMNS + i;

            StringBuilder abbrev = new StringBuilder();
            for (String t : name.split("-")) {
                abbrev.append(t.substring(0, 1).toUpperCase());
            }
            table.setText(0, col, abbrev.toString());
            table.getCellFormatter().getElement(0, col).setTitle(name);
            fmt.addStyleName(0, col, Gerrit.RESOURCES.css().dataHeader());
        }

        for (Section s : sections) {
            if (s.titleRow >= 0) {
                fmt.setColSpan(s.titleRow, 0, columns);
            }
        }
    }

    private void populateChangeRow(final int row, final ChangeInfo c, boolean highlightUnreviewed) {
        if (Gerrit.isSignedIn()) {
            table.setWidget(row, C_STAR, StarredChanges.createIcon(c.legacy_id(), c.starred()));
        }

        String subject = Util.cropSubject(c.subject());
        table.setWidget(row, C_SUBJECT, new TableChangeLink(subject, c));

        Change.Status status = c.status();
        if (status != Change.Status.NEW) {
            table.setText(row, C_STATUS, Util.toLongString(status));
        }

        if (c.owner() != null) {
            table.setWidget(row, C_OWNER, new AccountLinkPanel(c.owner(), status));
        } else {
            table.setText(row, C_OWNER, "");
        }

        table.setWidget(row, C_PROJECT, new ProjectLink(c.project_name_key(), c.status()));
        table.setWidget(row, C_BRANCH, new BranchLink(c.project_name_key(), c.status(), c.branch(), c.topic()));
        if (Gerrit.isSignedIn() && Gerrit.getUserAccount().getGeneralPreferences().isRelativeDateInChangeTable()) {
            table.setText(row, C_LAST_UPDATE, relativeFormat(c.updated()));
        } else {
            table.setText(row, C_LAST_UPDATE, shortFormat(c.updated()));
        }

        boolean displayName = Gerrit.isSignedIn()
                && Gerrit.getUserAccount().getGeneralPreferences().isShowUsernameInReviewCategory();

        CellFormatter fmt = table.getCellFormatter();
        for (int idx = 0; idx < labelNames.size(); idx++) {
            String name = labelNames.get(idx);
            int col = BASE_COLUMNS + idx;

            LabelInfo label = c.label(name);
            if (label == null) {
                table.clearCell(row, col);
                continue;
            }

            String user;
            if (label.rejected() != null) {
                user = label.rejected().name();
                if (displayName && user != null) {
                    FlowPanel panel = new FlowPanel();
                    panel.add(new Image(Gerrit.RESOURCES.redNot()));
                    panel.add(new InlineLabel(user));
                    table.setWidget(row, col, panel);
                } else {
                    table.setWidget(row, col, new Image(Gerrit.RESOURCES.redNot()));
                }
            } else if (label.approved() != null) {
                user = label.approved().name();
                if (displayName && user != null) {
                    FlowPanel panel = new FlowPanel();
                    panel.add(new Image(Gerrit.RESOURCES.greenCheck()));
                    panel.add(new InlineLabel(user));
                    table.setWidget(row, col, panel);
                } else {
                    table.setWidget(row, col, new Image(Gerrit.RESOURCES.greenCheck()));
                }
            } else if (label.disliked() != null) {
                user = label.disliked().name();
                String vstr = String.valueOf(label._value());
                if (displayName && user != null) {
                    vstr = vstr + " " + user;
                }
                fmt.addStyleName(row, col, Gerrit.RESOURCES.css().negscore());
                table.setText(row, col, vstr);
            } else if (label.recommended() != null) {
                user = label.recommended().name();
                String vstr = "+" + label._value();
                if (displayName && user != null) {
                    vstr = vstr + " " + user;
                }
                fmt.addStyleName(row, col, Gerrit.RESOURCES.css().posscore());
                table.setText(row, col, vstr);
            } else {
                table.clearCell(row, col);
                continue;
            }
            fmt.addStyleName(row, col, Gerrit.RESOURCES.css().singleLine());

            if (!displayName && user != null) {
                // Some web browsers ignore the embedded newline; some like it;
                // so we include a space before the newline to accommodate both.
                fmt.getElement(row, col).setTitle(name + " \nby " + user);
            }
        }

        boolean needHighlight = false;
        if (highlightUnreviewed && !c.reviewed()) {
            needHighlight = true;
        }
        final Element tr = DOM.getParent(fmt.getElement(row, 0));
        UIObject.setStyleName(tr, Gerrit.RESOURCES.css().needsReview(), needHighlight);

        setRowItem(row, c);
    }

    public void addSection(final Section s) {
        assert s.parent == null;

        s.parent = this;
        s.titleRow = table.getRowCount();
        if (s.displayTitle()) {
            final FlexCellFormatter fmt = table.getFlexCellFormatter();
            fmt.setColSpan(s.titleRow, 0, columns);
            fmt.addStyleName(s.titleRow, 0, Gerrit.RESOURCES.css().sectionHeader());
        } else {
            s.titleRow = -1;
        }

        s.dataBegin = table.getRowCount();
        insertNoneRow(s.dataBegin);
        sections.add(s);
    }

    private int insertRow(final int beforeRow) {
        for (final Section s : sections) {
            if (beforeRow <= s.titleRow) {
                s.titleRow++;
            }
            if (beforeRow < s.dataBegin) {
                s.dataBegin++;
            }
        }
        return table.insertRow(beforeRow);
    }

    private void removeRow(final int row) {
        for (final Section s : sections) {
            if (row < s.titleRow) {
                s.titleRow--;
            }
            if (row < s.dataBegin) {
                s.dataBegin--;
            }
        }
        table.removeRow(row);
    }

    public class StarKeyCommand extends NeedsSignInKeyCommand {
        public StarKeyCommand(int mask, char key, String help) {
            super(mask, key, help);
        }

        @Override
        public void onKeyPress(final KeyPressEvent event) {
            int row = getCurrentRow();
            ChangeInfo c = getRowItem(row);
            if (c != null && Gerrit.isSignedIn()) {
                ((StarredChanges.Icon) table.getWidget(row, C_STAR)).toggleStar();
            }
        }
    }

    private final class TableChangeLink extends ChangeLink {
        private TableChangeLink(final String text, final ChangeInfo c) {
            super(text, c.legacy_id());
        }

        @Override
        public void go() {
            movePointerTo(cid);
            super.go();
        }
    }

    public static class Section {
        ChangeTable2 parent;
        String titleText;
        Widget titleWidget;
        int titleRow = -1;
        int dataBegin;
        int rows;
        private boolean highlightUnreviewed;

        public void setHighlightUnreviewed(boolean value) {
            this.highlightUnreviewed = value;
        }

        public void setTitleText(final String text) {
            titleText = text;
            titleWidget = null;
            if (titleRow >= 0) {
                parent.table.setText(titleRow, 0, titleText);
            }
        }

        public void setTitleWidget(final Widget title) {
            titleWidget = title;
            titleText = null;
            if (titleRow >= 0) {
                parent.table.setWidget(titleRow, 0, title);
            }
        }

        public boolean displayTitle() {
            if (titleText != null) {
                setTitleText(titleText);
                return true;
            } else if (titleWidget != null) {
                setTitleWidget(titleWidget);
                return true;
            }
            return false;
        }

        public void display(ChangeList changeList) {
            final int sz = changeList != null ? changeList.length() : 0;
            final boolean hadData = rows > 0;

            if (hadData) {
                while (sz < rows) {
                    parent.removeRow(dataBegin);
                    rows--;
                }
            } else {
                parent.removeRow(dataBegin);
            }

            if (sz == 0) {
                parent.insertNoneRow(dataBegin);
                return;
            }

            while (rows < sz) {
                parent.insertChangeRow(dataBegin + rows);
                rows++;
            }
            for (int i = 0; i < sz; i++) {
                parent.populateChangeRow(dataBegin + i, changeList.get(i), highlightUnreviewed);
            }
        }
    }
}