org.rstudio.studio.client.workbench.BrowseAddinsDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.rstudio.studio.client.workbench.BrowseAddinsDialog.java

Source

/*
 * ShowAddinsDialog.java
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.studio.client.workbench;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.cellview.client.TextHeader;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;

import org.rstudio.core.client.ListUtil;
import org.rstudio.core.client.StringUtil;
import org.rstudio.core.client.ListUtil.FilterPredicate;
import org.rstudio.core.client.js.JsUtil;
import org.rstudio.core.client.theme.RStudioDataGridResources;
import org.rstudio.core.client.theme.RStudioDataGridStyle;
import org.rstudio.core.client.widget.FilterWidget;
import org.rstudio.core.client.widget.ModalDialog;
import org.rstudio.core.client.widget.ModifyKeyboardShortcutsWidget;
import org.rstudio.core.client.widget.OperationWithInput;
import org.rstudio.core.client.widget.ThemedButton;
import org.rstudio.studio.client.RStudioGinjector;
import org.rstudio.studio.client.common.HelpLink;
import org.rstudio.studio.client.workbench.addins.Addins.AddinExecutor;
import org.rstudio.studio.client.workbench.addins.Addins.RAddin;
import org.rstudio.studio.client.workbench.addins.Addins.RAddins;
import org.rstudio.studio.client.workbench.addins.AddinsCommandManager;

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

public class BrowseAddinsDialog extends ModalDialog<Command> {
    public BrowseAddinsDialog(OperationWithInput<Command> operation) {
        super("Addins", operation);
        RStudioGinjector.INSTANCE.injectMembers(this);

        setOkButtonCaption("Execute");

        filterWidget_ = new FilterWidget() {
            @Override
            public void filter(String query) {
                BrowseAddinsDialog.this.filter(query);
            }
        };
        filterWidget_.getElement().getStyle().setFloat(Style.Float.LEFT);

        helpLink_ = new HelpLink("Using RStudio Addins", "rstudio_addins", false);
        helpLink_.getElement().getStyle().setFloat(Style.Float.RIGHT);

        keyProvider_ = new ProvidesKey<RAddin>() {
            @Override
            public Object getKey(RAddin addin) {
                return addin.hashCode();
            }
        };

        table_ = new DataGrid<RAddin>(1000, RES, keyProvider_);
        table_.setWidth("500px");
        table_.setHeight("400px");

        selectionModel_ = new SingleSelectionModel<RAddin>();
        selectionModel_.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                selection_ = selectionModel_.getSelectedObject();
            }
        });

        table_.setSelectionModel(selectionModel_);
        table_.setEmptyTableWidget(emptyTableLabel("Loading addins..."));

        addColumns();

        dataProvider_ = new ListDataProvider<RAddin>();
        dataProvider_.addDataDisplay(table_);

        originalData_ = new ArrayList<RAddin>();

        // sync to current addins
        addins_ = addinsCommandManager_.getRAddins();
        List<RAddin> data = new ArrayList<RAddin>();
        for (String key : JsUtil.asIterable(addins_.keys()))
            data.add(addins_.get(key));
        dataProvider_.setList(data);
        originalData_ = data;
        table_.setEmptyTableWidget(emptyTableLabel("No addins available"));

        addLeftWidget(new ThemedButton("Keyboard Shortcuts...", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                ModifyKeyboardShortcutsWidget widget = new ModifyKeyboardShortcutsWidget("addin");
                widget.showModal();
            }
        }));

        FlowPanel headerPanel = new FlowPanel();
        headerPanel.add(filterWidget_);
        headerPanel.add(helpLink_);

        container_ = new VerticalPanel();
        container_.add(headerPanel);
        container_.add(new VerticalSeparator("4px"));
        container_.add(table_);
    }

    private static class VerticalSeparator extends Composite {
        public VerticalSeparator(String size) {
            FlowPanel panel = new FlowPanel();
            panel.setHeight(size);
            initWidget(panel);
        }
    }

    @Inject
    private void initialize(AddinsCommandManager addinsCommandManager) {
        addinsCommandManager_ = addinsCommandManager;
    }

    private void addColumns() {
        // Package ----
        pkgColumn_ = new TextColumn<RAddin>() {
            @Override
            public String getValue(RAddin addin) {
                return addin.getPackage();
            }
        };
        pkgColumn_.setSortable(true);
        table_.addColumn(pkgColumn_, new TextHeader("Package"));
        table_.setColumnWidth(pkgColumn_, "120px");

        // Name ----
        nameColumn_ = new TextColumn<RAddin>() {
            @Override
            public String getValue(RAddin addin) {
                return StringUtil.truncate(addin.getName(), 120, "...");
            }
        };
        nameColumn_.setSortable(true);
        table_.addColumn(nameColumn_, new TextHeader("Name"));
        table_.setColumnWidth(nameColumn_, "120px");

        // Description ----
        descColumn_ = new TextColumn<RAddin>() {
            @Override
            public String getValue(RAddin addin) {
                return addin.getDescription();
            }
        };
        descColumn_.setSortable(true);
        table_.addColumn(descColumn_, new TextHeader("Description"));

        table_.addColumnSortHandler(new ColumnSortEvent.Handler() {
            @Override
            public void onColumnSort(ColumnSortEvent event) {
                int index = -1;
                if (event.getColumn().equals(pkgColumn_))
                    index = 0;
                else if (event.getColumn().equals(nameColumn_))
                    index = 1;
                else if (event.getColumn().equals(descColumn_))
                    index = 2;

                if (index == -1)
                    return;

                sort(index, event.isSortAscending());
            }
        });
    }

    private void sort(final int index, final boolean forward) {
        Collections.sort(dataProvider_.getList(), new Comparator<RAddin>() {
            @Override
            public int compare(RAddin o1, RAddin o2) {
                String f1 = "";
                String f2 = "";

                if (index == 0) {
                    f1 = o1.getPackage();
                    f2 = o2.getPackage();
                } else if (index == 1) {
                    f1 = o1.getName();
                    f2 = o2.getName();
                } else if (index == 2) {
                    f1 = o1.getDescription();
                    f2 = o2.getDescription();
                }

                return forward ? f1.compareTo(f2) : f2.compareTo(f1);
            }

        });
    }

    private void filter(String query) {
        final String[] splat = query.toLowerCase().split("\\s+");
        List<RAddin> data = ListUtil.filter(originalData_, new FilterPredicate<RAddin>() {
            @Override
            public boolean test(RAddin object) {
                for (String el : splat) {
                    boolean match = object.getName().toLowerCase().contains(el)
                            || object.getPackage().toLowerCase().contains(el);

                    if (!match)
                        return false;
                }
                return true;
            }
        });
        dataProvider_.setList(data);
    }

    @Override
    protected Command collectInput() {
        if (selection_ == null) {
            return new Command() {
                @Override
                public void execute() {
                }
            };
        }

        return new ExecuteAddinCommand(addins_.get(selection_.getId()), new AddinExecutor());
    }

    private static class ExecuteAddinCommand implements Command {
        public ExecuteAddinCommand(RAddin addin, AddinExecutor executor) {
            addin_ = addin;
            executor_ = executor;
        }

        @Override
        public void execute() {
            executor_.execute(addin_);
        }

        private final RAddin addin_;
        private final AddinExecutor executor_;
    }

    @Override
    protected Widget createMainWidget() {
        return container_;
    }

    private Label emptyTableLabel(String caption) {
        Label label = new Label(caption);
        label.getElement().getStyle().setMarginTop(20, Unit.PX);
        label.getElement().getStyle().setColor("#888");
        return label;
    }

    // Private members ----
    private final VerticalPanel container_;
    private final FilterWidget filterWidget_;
    private final HelpLink helpLink_;

    private final DataGrid<RAddin> table_;
    private TextColumn<RAddin> pkgColumn_;
    private TextColumn<RAddin> nameColumn_;
    private TextColumn<RAddin> descColumn_;

    private final ProvidesKey<RAddin> keyProvider_;
    private final ListDataProvider<RAddin> dataProvider_;
    private final SingleSelectionModel<RAddin> selectionModel_;

    private List<RAddin> originalData_;
    private RAddins addins_;
    private RAddin selection_;

    // Injected ----
    private AddinsCommandManager addinsCommandManager_;

    // Resources, etc ----
    public interface Resources extends RStudioDataGridResources {
        @Source({ RStudioDataGridStyle.RSTUDIO_DEFAULT_CSS })
        Styles dataGridStyle();
    }

    public interface Styles extends RStudioDataGridStyle {
    }

    private static final Resources RES = GWT.create(Resources.class);

    static {
        RES.dataGridStyle().ensureInjected();
    }

}