/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.dart.tools.ui.internal.pub; import com.google.dart.tools.core.pub.IPubPackageListener; import com.google.dart.tools.core.pub.PubPackageManager; import com.google.dart.tools.core.pub.PubPackageObject; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.internal.util.ExternalBrowserUtil; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StyledCellLabelProvider; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.StyledString.Styler; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.TextStyle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.part.ViewPart; import java.util.ArrayList; import java.util.List; /** * A view that shows the packages available on pub with the descriptions and latest versions. Users * can create a copy of the package to explore the package or can view package documentation on pub. */ public class PackagesView extends ViewPart { class PackagesComparator extends ViewerComparator { private static final int DESCENDING = 1; private int direction; public PackagesComparator() { direction = DESCENDING; } @Override public int compare(Viewer viewer, Object e1, Object e2) { if (e1 instanceof PubPackageObject) { PubPackageObject t1 = (PubPackageObject) e1; PubPackageObject t2 = (PubPackageObject) e2; int result = t1.getName().compareTo(t2.getName()); if (direction == DESCENDING) { result *= -1; } return result; } return -1; } public void setColumn(int column) { if (column == 0) { direction = -1 * direction; } else { direction = DESCENDING; } } } class PackagesFilter extends ViewerFilter { private String searchString; @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (searchString == null || searchString.length() == 0) { return true; } if (element instanceof PubPackageObject && (((PubPackageObject) element).getName().matches(searchString) || ((PubPackageObject) element).getDescription().matches( searchString))) { return true; } return false; } public void setSearchText(String s) { this.searchString = "(?i).*" + s + ".*"; } } class PackagesLabelProvider extends StyledCellLabelProvider { @Override public String getToolTipText(Object element) { if (element instanceof PubPackageObject) { return ((PubPackageObject) element).getDescription(); } return null; } @Override public void update(ViewerCell cell) { Object element = cell.getElement(); if (element instanceof PubPackageObject) { String string = ""; StyledString styledString = new StyledString(); switch (cell.getColumnIndex()) { case 0: string = ((PubPackageObject) element).getName(); styledString = new StyledString(string, boldStyler); break; case 1: string = ((PubPackageObject) element).getDescription(); styledString = new StyledString(string, italicStyler); break; case 2: string = ((PubPackageObject) element).getVersion(); styledString = new StyledString(string); break; } cell.setText(styledString.toString()); cell.setStyleRanges(styledString.getStyleRanges()); if (cell.getColumnIndex() == 0) { cell.setImage(DartToolsPlugin.getImage("icons/full/obj16/package_obj.gif")); } } else { if (element instanceof String) { cell.setText((String) element); } else { cell.setText("Unknown element"); //$NON-NLS-1$ } } super.update(cell); } } class PubPackageListener implements IPubPackageListener { @Override public void pubPackagesChanged(final List<PubPackageObject> packages) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { pubPackages = packages; tableViewer.setInput(pubPackages); tableViewer.refresh(); } }); } } public static String ID = "com.google.dart.tools.ui.view.packages"; private static Styler italicStyler; private static Styler boldStyler; private static FontData[] getModifiedFontData(FontData[] originalData, int additionalStyle) { FontData[] styleData = new FontData[originalData.length]; for (int i = 0; i < styleData.length; i++) { FontData base = originalData[i]; styleData[i] = new FontData(base.getName(), base.getHeight(), base.getStyle() | additionalStyle); } return styleData; } private PackagesFilter filter; private TableViewer tableViewer; private Text filterText; private Font boldFont; private Font italicFont; private List<PubPackageObject> pubPackages; private PubPackageListener packageListener = new PubPackageListener(); private PackagesComparator comparator;; @Override public void createPartControl(Composite parent) { Composite client = new Composite(parent, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(client); GridLayoutFactory.swtDefaults().spacing(10, 5).numColumns(1).applyTo(client); Composite filterComp = new Composite(client, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.FILL).grab(false, false).applyTo(filterComp); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(filterComp); Label filterLabel = new Label(filterComp, SWT.NONE); filterLabel.setText("Search by name or description: "); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.FILL).grab(false, false).applyTo(filterLabel); filterText = new Text(filterComp, SWT.BORDER | SWT.SEARCH); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).hint(200, SWT.DEFAULT).applyTo( filterText); filterText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent ke) { filter.setSearchText(filterText.getText()); tableViewer.refresh(); } }); createTable(client); PubPackageManager.getInstance().addListener(packageListener); } @Override public void dispose() { super.dispose(); boldFont.dispose(); italicFont.dispose(); PubPackageManager.getInstance().removeListener(packageListener); } @Override public void setFocus() { } private void createBrowseMenuItem(Menu parent, final TableColumn column) { final MenuItem itemName = new MenuItem(parent, SWT.PUSH); itemName.setText("Browse docs on pub.dartlang.org"); itemName.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { PubPackageObject selection = (PubPackageObject) ((IStructuredSelection) tableViewer.getSelection()).getFirstElement(); if (selection != null) { ExternalBrowserUtil.openInExternalBrowser("http://pub.dartlang.org/packages/" + selection.getName()); } } }); } private TableViewerColumn createColumnsAndMenu(TableColumnLayout tableLayout) { String[] titles = {"Name", "Description", "Version"}; final TableViewerColumn nameColumn = createTableViewerColumn(titles[0], 0); TableViewerColumn descColumn = createTableViewerColumn(titles[1], 1); TableViewerColumn versionColumn = createTableViewerColumn(titles[2], 2); nameColumn.getColumn().pack(); descColumn.getColumn().pack(); versionColumn.getColumn().pack(); int stylesheetWidth = nameColumn.getColumn().getWidth(); int conceptWidth = descColumn.getColumn().getWidth(); tableLayout.setColumnData(nameColumn.getColumn(), new ColumnWeightData(20, stylesheetWidth)); tableLayout.setColumnData(descColumn.getColumn(), new ColumnWeightData(73, conceptWidth)); tableLayout.setColumnData(versionColumn.getColumn(), new ColumnWeightData(7)); nameColumn.getColumn().addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { comparator.setColumn(0); int dir = tableViewer.getTable().getSortDirection(); dir = dir == SWT.DOWN ? SWT.UP : SWT.DOWN; tableViewer.getTable().setSortDirection(dir); tableViewer.getTable().setSortColumn(nameColumn.getColumn()); tableViewer.refresh(); } }); // define the menu and assign to the table Menu headerMenu = new Menu(tableViewer.getTable()); tableViewer.getTable().setMenu(headerMenu); createImportMenuItem(headerMenu, nameColumn.getColumn()); createBrowseMenuItem(headerMenu, nameColumn.getColumn()); return nameColumn; } private void createFontStyles() { boldFont = getBoldFont(tableViewer.getTable().getFont().getFontData()); boldStyler = new Styler() { @Override public void applyStyles(TextStyle textStyle) { textStyle.font = boldFont; } }; italicFont = getItalicFont(tableViewer.getTable().getFont().getFontData()); italicStyler = new Styler() { @Override public void applyStyles(TextStyle textStyle) { textStyle.font = italicFont; } }; } private void createImportMenuItem(Menu parent, TableColumn column) { final MenuItem itemName = new MenuItem(parent, SWT.PUSH); itemName.setText("New application from package"); itemName.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { PubPackageObject selection = (PubPackageObject) ((IStructuredSelection) tableViewer.getSelection()).getFirstElement(); if (selection != null) { AddPackageAction action = new AddPackageAction( getSite(), selection.getName(), selection.getVersion()); action.run(); } } }); } private void createTable(Composite client) { Composite tableComposite = new Composite(client, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, true).applyTo( tableComposite); TableColumnLayout tableLayout = new TableColumnLayout(); tableComposite.setLayout(tableLayout); tableViewer = new TableViewer(tableComposite, SWT.HIDE_SELECTION | SWT.FULL_SELECTION | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP); final Table table = tableViewer.getTable(); table.setLinesVisible(true); table.setHeaderVisible(true); createFontStyles(); final TableViewerColumn nameColumn = createColumnsAndMenu(tableLayout); tableViewer.setContentProvider(new ArrayContentProvider()); tableViewer.setLabelProvider(new PackagesLabelProvider()); tableViewer.getTable().setSortColumn(nameColumn.getColumn()); tableViewer.getTable().setSortDirection(SWT.DOWN); comparator = new PackagesComparator(); comparator.setColumn(0); tableViewer.setComparator(comparator); filter = new PackagesFilter(); tableViewer.addFilter(filter); ColumnViewerToolTipSupport.enableFor(tableViewer, ToolTip.NO_RECREATE); pubPackages = PubPackageManager.getInstance().getPubPackages(); if (pubPackages.size() > 0) { tableViewer.setInput(pubPackages); } else { List<String> strings = new ArrayList<String>(); for (int i = 0; i < 25; i++) { strings.add("Populating data ..."); } tableViewer.setInput(strings); } } private TableViewerColumn createTableViewerColumn(String title, final int colNumber) { final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP); final TableColumn column = viewerColumn.getColumn(); column.setText(title); column.setResizable(true); return viewerColumn; } private Font getBoldFont(FontData[] fontData) { FontData[] boldFontData = getModifiedFontData(fontData, SWT.BOLD); Font boldFont = new Font(Display.getCurrent(), boldFontData); return boldFont; } private Font getItalicFont(FontData[] fontData) { FontData[] iFontData = getModifiedFontData(fontData, SWT.ITALIC); Font italicFont = new Font(Display.getCurrent(), iFontData); return italicFont; } }