Package com.urswolfer.intellij.plugin.gerrit.ui

Source Code of com.urswolfer.intellij.plugin.gerrit.ui.GerritChangeListPanel$GerritChangeColumnStarredInfo

/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2013 Urs Wolfer
*
* 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.urswolfer.intellij.plugin.gerrit.ui;

import com.google.common.collect.Lists;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.LabelInfo;
import com.google.inject.Inject;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.table.TableView;
import com.intellij.util.Consumer;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.intellij.util.ui.UIUtil;
import com.urswolfer.intellij.plugin.gerrit.SelectedRevisions;
import com.urswolfer.intellij.plugin.gerrit.rest.LoadChangesProxy;
import com.urswolfer.intellij.plugin.gerrit.util.GerritDataKeys;
import icons.Git4ideaIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.List;
import java.util.Map;

import static com.intellij.icons.AllIcons.Actions.*;

/**
* A table with the list of changes.
* Parts based on git4idea.ui.GitCommitListPanel
*
* @author Kirill Likhodedov
* @author Urs Wolfer
*/
public class GerritChangeListPanel extends JPanel implements TypeSafeDataProvider, Consumer<LoadChangesProxy> {
    private final SelectedRevisions selectedRevisions;
    private final GerritSelectRevisionInfoColumn selectRevisionInfoColumn;

    private final List<ChangeInfo> changes;
    private final TableView<ChangeInfo> table;
    private GerritToolWindow gerritToolWindow;
    private LoadChangesProxy loadChangesProxy = null;

    private volatile boolean loadingMoreChanges = false;
    private final JScrollPane scrollPane;

    @Inject
    public GerritChangeListPanel(SelectedRevisions selectedRevisions,
                                 GerritSelectRevisionInfoColumn selectRevisionInfoColumn) {
        this.selectedRevisions = selectedRevisions;
        this.selectRevisionInfoColumn = selectRevisionInfoColumn;
        this.changes = Lists.newArrayList();

        this.table = new TableView<ChangeInfo>();
        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        PopupHandler.installPopupHandler(table, "Gerrit.ListPopup", ActionPlaces.UNKNOWN);

        updateModel(changes);
        table.setStriped(true);

        setLayout(new BorderLayout());
        scrollPane = ScrollPaneFactory.createScrollPane(table);
        scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                if (!loadingMoreChanges && loadChangesProxy != null) {
                    loadingMoreChanges = true;
                    try {
                        int lowerEnd = e.getAdjustable().getVisibleAmount() + e.getAdjustable().getValue();
                        if (lowerEnd == e.getAdjustable().getMaximum()) {
                            loadChangesProxy.getNextPage(new Consumer<List<ChangeInfo>>() {
                                @Override
                                public void consume(List<ChangeInfo> changeInfos) {
                                    addChanges(changeInfos);
                                }
                            });
                        }
                    } finally {
                        loadingMoreChanges = false;
                    }
                }
            }
        });
        add(scrollPane);
    }

    @Override
    public void consume(LoadChangesProxy proxy) {
        loadChangesProxy = proxy;
        proxy.getNextPage(new Consumer<List<ChangeInfo>>() {
            @Override
            public void consume(List<ChangeInfo> changeInfos) {
                setChanges(changeInfos);
            }
        });
    }

    /**
     * Adds a listener that would be called once user selects a change in the table.
     */
    public void addListSelectionListener(final @NotNull Consumer<ChangeInfo> listener) {
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(final ListSelectionEvent e) {
                ListSelectionModel lsm = (ListSelectionModel) e.getSource();
                int i = lsm.getMaxSelectionIndex();
                if (i >= 0 && !e.getValueIsAdjusting()) {
                    listener.consume(changes.get(i));
                }
            }
        });
    }

    /**
     * Registers the diff action which will be called when the diff shortcut is pressed in the table.
     */
    public void registerDiffAction(@NotNull AnAction diffAction) {
        diffAction.registerCustomShortcutSet(CommonShortcuts.getDiff(), table);
    }

    // Make changes available for diff action
    @Override
    public void calcData(DataKey key, DataSink sink) {
        sink.put(GerritDataKeys.TOOL_WINDOW, gerritToolWindow);

        if (VcsDataKeys.CHANGES.equals(key)) {
            int[] rows = table.getSelectedRows();
            if (rows.length != 1) return;
            int row = rows[0];

            // TODO impl ?
//            ChangeInfo change = changes.get(row);
            // suppressing: inherited API
            //noinspection unchecked
//            sink.put(key, ArrayUtil.toObjectArray(change.getChanges(), Change.class));
        }
    }

    @NotNull
    public JComponent getPreferredFocusComponent() {
        return table;
    }

    public TableView<ChangeInfo> getTable() {
        return table;
    }

    public void clearSelection() {
        table.clearSelection();
    }

    public void setChanges(@NotNull List<ChangeInfo> changes) {
        this.changes.clear();
        this.changes.addAll(changes);
        initModel();
        table.repaint();
        selectedRevisions.clear();
    }

    public void addChanges(@NotNull List<ChangeInfo> changes) {
        this.changes.addAll(changes);
        // did not find another way to update the scrollbar after adding more changes...
        scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getValue() - 1);
    }

    public void registerChangeListPanel(GerritToolWindow gerritToolWindow) {
        this.gerritToolWindow = gerritToolWindow;
    }

    private void initModel() {
        table.setModelAndUpdateColumns(new ListTableModel<ChangeInfo>(generateColumnsInfo(changes), changes, 0));
    }

    private void updateModel(List<ChangeInfo> changes) {
        table.getListTableModel().addRows(changes);
    }

    @NotNull
    private ColumnInfo[] generateColumnsInfo(@NotNull List<ChangeInfo> changes) {
        ItemAndWidth hash = new ItemAndWidth("", 0);
        ItemAndWidth author = new ItemAndWidth("", 0);
        ItemAndWidth project = new ItemAndWidth("", 0);
        ItemAndWidth branch = new ItemAndWidth("", 0);
        ItemAndWidth time = new ItemAndWidth("", 0);
        for (ChangeInfo change : changes) {
            hash = getMax(hash, getHash(change));
            author = getMax(author, getOwner(change));
            project = getMax(project, getProject(change));
            branch = getMax(branch, getBranch(change));
            time = getMax(time, getTime(change));
        }

        return new ColumnInfo[]{
                new GerritChangeColumnStarredInfo(),
                new GerritChangeColumnInfo("ID", hash.item) {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return getHash(change);
                    }
                },
                selectRevisionInfoColumn,
                new ColumnInfo<ChangeInfo, String>("Subject") {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return change.subject;
                    }
                },
                new GerritChangeColumnInfo("Owner", author.item) {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return getOwner(change);
                    }
                },
                new GerritChangeColumnInfo("Project", project.item) {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return getProject(change);
                    }
                },
                new GerritChangeColumnInfo("Branch", branch.item) {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return getBranch(change);
                    }
                },
                new GerritChangeColumnInfo("Updated", time.item) {
                    @Override
                    public String valueOf(ChangeInfo change) {
                        return getTime(change);
                    }
                },
                new GerritChangeColumnIconLabelInfo("CR") {
                    @Override
                    public LabelInfo getLabelInfo(ChangeInfo change) {
                        return getCodeReview(change);
                    }
                },
                new GerritChangeColumnIconLabelInfo("V") {
                    @Override
                    public LabelInfo getLabelInfo(ChangeInfo change) {
                        return getVerified(change);
                    }
                }
        };
    }

    private ItemAndWidth getMax(ItemAndWidth current, String candidate) {
        if (candidate == null) {
            return current;
        }
        int width = table.getFontMetrics(table.getFont()).stringWidth(candidate);
        if (width > current.width) {
            return new ItemAndWidth(candidate, width);
        }
        return current;
    }

    private static class ItemAndWidth {
        private final String item;
        private final int width;

        private ItemAndWidth(String item, int width) {
            this.item = item;
            this.width = width;
        }
    }

    private static String getHash(ChangeInfo change) {
        return change.changeId.substring(0, 9);
    }

    private static String getOwner(ChangeInfo change) {
        return change.owner.name;
    }

    private static String getProject(ChangeInfo change) {
        return change.project;
    }

    private static String getBranch(ChangeInfo change) {
        return change.branch;
    }

    private static String getTime(ChangeInfo change) {
        return DateFormatUtil.formatPrettyDateTime(change.updated);
    }

    private static LabelInfo getCodeReview(ChangeInfo change) {
        return getLabel(change, "Code-Review");
    }

    private static LabelInfo getVerified(ChangeInfo change) {
        return getLabel(change, "Verified");
    }

    private static LabelInfo getLabel(ChangeInfo change, String labelName) {
        Map<String,LabelInfo> labels = change.labels;
        if (labels != null) {
            return labels.get(labelName);
        } else {
            return null;
        }
    }

    private abstract static class GerritChangeColumnInfo extends ColumnInfo<ChangeInfo, String> {

        @NotNull
        private final String maxString;

        public GerritChangeColumnInfo(@NotNull String name, @NotNull String maxString) {
            super(name);
            this.maxString = maxString;
        }

        @Override
        public String getMaxStringValue() {
            return maxString;
        }

        @Override
        public int getAdditionalWidth() {
            return UIUtil.DEFAULT_HGAP;
        }
    }

    private abstract static class GerritChangeColumnIconLabelInfo extends ColumnInfo<ChangeInfo, LabelInfo> {

        public GerritChangeColumnIconLabelInfo(String name) {
            super(name);
        }

        @Nullable
        @Override
        public LabelInfo valueOf(ChangeInfo changeInfo) {
            return null;
        }

        public abstract LabelInfo getLabelInfo(ChangeInfo change);

        @Nullable
        @Override
        public TableCellRenderer getRenderer(final ChangeInfo changeInfo) {
            return new DefaultTableCellRenderer() {
                @Override
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                    LabelInfo labelInfo = getLabelInfo(changeInfo);
                    label.setIcon(getIconForLabel(labelInfo));
                    label.setToolTipText(getToolTipForLabel(labelInfo));
                    label.setHorizontalAlignment(CENTER);
                    label.setVerticalAlignment(CENTER);
                    return label;
                }
            };
        }

        @Override
        public int getWidth(JTable table) {
            return Checked.getIconWidth() + 20;
        }

        private static Icon getIconForLabel(LabelInfo labelInfo) {
            if (labelInfo != null) {
                if (labelInfo.approved != null) {
                    return Checked;
                }
                if (labelInfo.recommended != null) {
                    return MoveUp;
                }
                if (labelInfo.disliked != null) {
                    return MoveDown;
                }
                if (labelInfo.rejected != null) {
                    return Cancel;
                }
            }
            return null;
        }

        private static String getToolTipForLabel(LabelInfo labelInfo) {
            if (labelInfo != null) {
                if (labelInfo.approved != null) {
                    return labelInfo.approved.name;
                }
                if (labelInfo.recommended != null) {
                    return labelInfo.recommended.name;
                }
                if (labelInfo.disliked != null) {
                    return labelInfo.disliked.name;
                }
                if (labelInfo.rejected != null) {
                    return labelInfo.rejected.name;
                }
            }
            return null;
        }
    }

    private static class GerritChangeColumnStarredInfo extends ColumnInfo<ChangeInfo, Boolean> {

        public GerritChangeColumnStarredInfo() {
            super("");
        }

        @Nullable
        @Override
        public Boolean valueOf(ChangeInfo changeInfo) {
            return null;
        }

        @Nullable
        @Override
        public TableCellRenderer getRenderer(final ChangeInfo changeInfo) {
            return new DefaultTableCellRenderer() {
                @Override
                public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                    if (changeInfo.starred != null && changeInfo.starred) {
                        label.setIcon(Git4ideaIcons.Star);
                    }
                    label.setHorizontalAlignment(CENTER);
                    label.setVerticalAlignment(CENTER);
                    return label;
                }
            };
        }

        @Override
        public int getWidth(JTable table) {
            return Git4ideaIcons.Star.getIconWidth();
        }
    }
}
TOP

Related Classes of com.urswolfer.intellij.plugin.gerrit.ui.GerritChangeListPanel$GerritChangeColumnStarredInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.