/******************************************************************************* * Copyright (c) 2015 Red Hat. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat - Initial Contribution *******************************************************************************/ package org.eclipse.linuxtools.internal.vagrant.ui.views; import java.util.List; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.linuxtools.vagrant.core.IVagrantBox; import org.eclipse.linuxtools.vagrant.core.IVagrantBoxListener; import org.eclipse.linuxtools.vagrant.core.IVagrantConnection; import org.eclipse.linuxtools.vagrant.core.IVagrantVM; import org.eclipse.linuxtools.vagrant.core.VagrantService; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.part.ViewPart; public class VagrantBoxView extends ViewPart implements IVagrantBoxListener { public static final String VIEW_ID = "org.eclipse.linuxtools.vagrant.ui.vagrantBoxView"; //$NON-NLS-1$ private final static String DaemonMissing = "ViewerDaemonMissing.msg"; //$NON-NLS-1$ private Form form; private Text search; private TableViewer viewer; private IVagrantConnection connection; @Override public void setFocus() { } @Override public void dispose() { connection.removeBoxListener(this); super.dispose(); } private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } @Override public void createPartControl(final Composite parent) { final FormToolkit toolkit = new FormToolkit(parent.getDisplay()); form = toolkit.createForm(parent); form.setText(DVMessages.getString(DaemonMissing)); final Composite container = form.getBody(); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).applyTo(container); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(container); createTableViewer(container); hookContextMenu(); } private void createTableViewer(final Composite container) { search = new Text(container, SWT.SEARCH | SWT.ICON_SEARCH); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(search); search.addModifyListener(onSearch()); Composite tableArea = new Composite(container, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).applyTo(tableArea); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) .grab(true, true).applyTo(tableArea); final TableColumnLayout tableLayout = new TableColumnLayout(); tableArea.setLayout(tableLayout); this.viewer = new TableViewer(tableArea, SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); this.viewer.setContentProvider(new VagrantBoxContentProvider()); final Table table = viewer.getTable(); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0) .applyTo(table); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) .grab(true, true).applyTo(table); table.setLinesVisible(true); table.setHeaderVisible(true); // 'NAME' column final TableViewerColumn idColumn = createColumn(DVMessages .getString("NAME")); //$NON-NLS-1$ setLayout(idColumn, tableLayout, 150); idColumn.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(final Object element) { if (element instanceof IVagrantBox) { return ((IVagrantBox) element).getName(); } return super.getText(element); } }); // 'PROVIDER' column final TableViewerColumn tagsColumn = createColumn(DVMessages .getString("PROVIDER")); //$NON-NLS-1$ setLayout(tagsColumn, tableLayout, 150); tagsColumn.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(final Object element) { if (element instanceof IVagrantBox) { return ((IVagrantBox) element).getProvider(); } return super.getText(element); } }); // 'VERSION' column final TableViewerColumn creationDateColumn = createColumn(DVMessages .getString("VERSION")); //$NON-NLS-1$ setLayout(creationDateColumn, tableLayout, 150); creationDateColumn.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(final Object element) { if (element instanceof IVagrantBox) { return ((IVagrantBox) element).getVersion().toString(); } return super.getText(element); } }); // comparator final VagrantBoxComparator comparator = new VagrantBoxComparator(this.viewer); viewer.setComparator(comparator); // apply search filter this.viewer.addFilter(getImagesFilter()); setConnection(VagrantService.getInstance()); connection.addBoxListener(this); // get the current selection in the tableviewer getSite().setSelectionProvider(viewer); } private TableViewerColumn createColumn(final String title) { final TableViewerColumn propertyColumn = new TableViewerColumn(viewer, SWT.BORDER); propertyColumn.getColumn().setText(title); propertyColumn.getColumn().addSelectionListener(onColumnSelected()); return propertyColumn; } private SelectionListener onColumnSelected() { return new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { final TableColumn sortColumn = (TableColumn) e.getSource(); final VagrantBoxComparator comparator = (VagrantBoxComparator) viewer.getComparator(); comparator.setColumn(sortColumn); viewer.refresh(); } }; } private void setLayout(final TableViewerColumn viewerColumn, final TableColumnLayout tableLayout, final int weight) { tableLayout.setColumnData(viewerColumn.getColumn(), new ColumnWeightData(weight, true)); } /** * Filters {@link IVagrantVM} and {@link IVagrantBox} using the input text in the search widget of this view. * @return */ private ModifyListener onSearch() { return e -> VagrantBoxView.this.viewer.refresh(); } /** * @return a {@link ViewerFilter} that will retain {@link IVagrantVM} that match the * content of the {@link VagrantBoxView#search} text widget. */ private ViewerFilter getImagesFilter() { return new ViewerFilter() { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IVagrantBox) { return element.toString().contains(VagrantBoxView.this.search.getText()); } return false; } }; } @Override public void listChanged(final IVagrantConnection connection, final List<IVagrantBox> images) { if (!viewer.getControl().isDisposed()) { Display.getDefault().asyncExec(() -> { // remember the current selection before the viewer is refreshed final ISelection currentSelection = VagrantBoxView.this.viewer .getSelection(); VagrantBoxView.this.viewer.refresh(); // restore the selection if (currentSelection != null) { VagrantBoxView.this.viewer.setSelection(currentSelection); } refreshViewTitle(); }); } } private void refreshViewTitle() { if (this.viewer == null || this.viewer.getControl().isDisposed() || this.form == null || this.connection == null) { return; } else if (!this.connection.isBoxesLoaded()) { form.setText(connection.getName()); } else { this.form.setText(DVMessages.getFormattedString( "VagrantBoxViewTitle.all.msg", connection.getName(), //$NON-NLS-1$ Integer.toString(connection.getBoxes().size()))); } } /** * @return the {@link IVagrantConnection} used to display the current {@link IVagrantVM} */ public IVagrantConnection getConnection() { return connection; } public void setConnection(IVagrantConnection conn) { this.connection = conn; if (conn != null) { viewer.setInput(conn); refreshViewTitle(); } else { viewer.setInput(new IVagrantBox[0]); form.setText(DVMessages.getString(DaemonMissing)); } } /** * @return the current selection */ public ISelection getSelection() { if(this.viewer != null) { return this.viewer.getSelection(); } return null; } /** * @return the {@link TableViewer} showing the containers */ public TableViewer getViewer() { return this.viewer; } }