/*******************************************************************************
* Copyright (c) 2013 Xilinx, Inc. and others.
* 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:
* Xilinx - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.internal.debug.ui.launch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
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.tcf.internal.debug.launch.TCFLaunchDelegate;
import org.eclipse.tcf.internal.debug.ui.Activator;
import org.eclipse.tcf.internal.debug.ui.ImageCache;
import org.eclipse.tcf.protocol.JSON;
import org.eclipse.tcf.util.TCFTask;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
public class TCFDownloadTab extends AbstractLaunchConfigurationTab {
private TableViewer viewer;
private Button button_add;
private Button button_edit;
private Button button_remove;
private MenuItem item_add;
private MenuItem item_edit;
private MenuItem item_remove;
private static final String[] column_ids = {
TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME,
TCFLaunchDelegate.FILES_FILE_NAME,
};
private static final int[] column_size = {
300,
400,
};
private final List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
private static final String TAB_ID = "org.eclipse.tcf.launch.downloadTab"; //$NON-NLS-1$
private class FileListContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object input) {
return list.toArray(new Map[list.size()]);
}
public void inputChanged(Viewer viewer, Object old_input, Object new_input) {
}
public void dispose() {
}
}
private class FileListLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int column) {
if (column == 0) return ImageCache.getImage(ImageCache.IMG_ATTRIBUTE);
return null;
}
public String getColumnText(Object element, int column) {
@SuppressWarnings("unchecked")
Map<String,String> e = (Map<String,String>)element;
Object o = e.get(column_ids[column]);
if (o == null) return ""; //$NON-NLS-1$
return o.toString();
}
}
private Exception init_error;
public String getName() {
return "Download"; //$NON-NLS-1$
}
@Override
public Image getImage() {
return ImageCache.getImage(ImageCache.IMG_DOWNLOAD_TAB);
}
@Override
public String getId() {
return TAB_ID;
}
public void createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
composite.setFont(parent.getFont());
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
createTable(composite);
setControl(composite);
}
private void createTable(Composite parent) {
Font font = parent.getFont();
Label map_label = new Label(parent, SWT.WRAP);
map_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
map_label.setFont(font);
map_label.setText("Files to download during launch:"); //$NON-NLS-1$
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setFont(font);
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
viewer = new TableViewer(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
Table table = viewer.getTable();
table.setLayoutData(new GridData(GridData.FILL_BOTH));
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setFont(font);
viewer.setContentProvider(new FileListContentProvider());
viewer.setLabelProvider(new FileListLabelProvider());
viewer.setColumnProperties(column_ids);
for (int i = 0; i < column_ids.length; i++) {
TableColumn c = new TableColumn(table, SWT.NONE, i);
c.setText(column_ids[i]);
c.setWidth(column_size[i]);
}
createTableButtons(composite);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
updateLaunchConfigurationDialog();
}
});
viewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
if (button_edit.isEnabled()) {
onEdit((IStructuredSelection)viewer.getSelection());
}
}
});
}
private void createTableButtons(Composite parent) {
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setFont(font);
composite.setLayout(layout);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
composite.setLayoutData(gd);
Menu menu = new Menu(viewer.getTable());
SelectionAdapter sel_adapter = null;
button_add = new Button(composite, SWT.PUSH);
button_add.setText(" &Add... "); //$NON-NLS-1$
gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
button_add.setLayoutData(gd);
button_add.addSelectionListener(sel_adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Map<String,Object> m = new HashMap<String,Object>();
DownloadFileDialog dialog = new DownloadFileDialog(getShell(), getPeerID(), m);
if (dialog.open() == Window.OK) {
list.add(m);
viewer.add(m);
viewer.setSelection(new StructuredSelection(m), true);
viewer.getTable().setFocus();
updateLaunchConfigurationDialog();
}
}
});
item_add = new MenuItem(menu, SWT.PUSH);
item_add.setText("&Add..."); //$NON-NLS-1$
item_add.addSelectionListener(sel_adapter);
item_add.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ADD));
button_edit = new Button(composite, SWT.PUSH);
button_edit.setText(" &Edit... "); //$NON-NLS-1$
button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
button_edit.addSelectionListener(sel_adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onEdit((IStructuredSelection)viewer.getSelection());
}
});
item_edit= new MenuItem(menu, SWT.PUSH);
item_edit.setText("&Edit..."); //$NON-NLS-1$
item_edit.addSelectionListener(sel_adapter);
button_remove = new Button(composite, SWT.PUSH);
button_remove.setText(" &Remove "); //$NON-NLS-1$
button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
button_remove.addSelectionListener(sel_adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
for (Iterator<?> i = ((IStructuredSelection)viewer.getSelection()).iterator(); i.hasNext();) {
@SuppressWarnings("unchecked")
Map<String,String> m = (Map<String,String>)i.next();
list.remove(m);
viewer.remove(m);
}
updateLaunchConfigurationDialog();
}
});
item_remove = new MenuItem(menu, SWT.PUSH);
item_remove.setText("&Remove"); //$NON-NLS-1$
item_remove.addSelectionListener(sel_adapter);
item_remove.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ETOOL_DELETE));
viewer.getTable().setMenu(menu);
}
private void onEdit(IStructuredSelection selection) {
@SuppressWarnings("unchecked")
Map<String,Object> m = (Map<String,Object>)selection.getFirstElement();
DownloadFileDialog dialog = new DownloadFileDialog(getShell(), getPeerID(), m);
dialog.open();
viewer.refresh(m);
viewer.setSelection(new StructuredSelection(m), true);
viewer.getTable().setFocus();
updateLaunchConfigurationDialog();
}
private String getPeerID() {
String peer_id = "TCP:127.0.0.1:1534";
for (ILaunchConfigurationTab t : getLaunchConfigurationDialog().getTabs()) {
if (t instanceof TCFTargetTab) peer_id = ((TCFTargetTab)t).getPeerID();
}
return peer_id;
}
protected final TableViewer getViewer() {
return viewer;
}
public void initializeFrom(ILaunchConfiguration config) {
setErrorMessage(null);
setMessage(null);
try {
list.clear();
final String s = config.getAttribute(TCFLaunchDelegate.ATTR_FILES, ""); //$NON-NLS-1$
list.addAll(new TCFTask<Collection<Map<String,Object>>>(10000) {
@Override
public void run() {
try {
ArrayList<Map<String,Object>> l = new ArrayList<Map<String,Object>>();
if (s != null && s.length() > 0) {
@SuppressWarnings("unchecked")
Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)JSON.parseOne(s.getBytes("UTF-8"));
for (Map<String,Object> m : c) l.add(new HashMap<String,Object>(m));
}
done(l);
}
catch (Throwable e) {
error(e);
}
}
}.get());
viewer.setInput(config);
button_remove.setEnabled(!viewer.getSelection().isEmpty());
button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
item_remove.setEnabled(!viewer.getSelection().isEmpty());
item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
}
catch (Exception e) {
init_error = e;
setErrorMessage("Cannot read launch configuration: " + e); //$NON-NLS-1$
Activator.log(e);
}
}
public void performApply(ILaunchConfigurationWorkingCopy config) {
if (list.size() == 0) {
config.removeAttribute(TCFLaunchDelegate.ATTR_FILES);
}
else {
String s = new TCFTask<String>(10000) {
@Override
public void run() {
try {
done(JSON.toJSON(list));
}
catch (Throwable e) {
error(e);
}
}
}.getE();
config.setAttribute(TCFLaunchDelegate.ATTR_FILES, s);
}
}
public void setDefaults(ILaunchConfigurationWorkingCopy config) {
config.removeAttribute(TCFLaunchDelegate.ATTR_FILES);
}
@Override
protected void updateLaunchConfigurationDialog() {
super.updateLaunchConfigurationDialog();
button_remove.setEnabled(!viewer.getSelection().isEmpty());
button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
item_remove.setEnabled(!viewer.getSelection().isEmpty());
item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
}
@Override
public boolean isValid(ILaunchConfiguration config) {
setMessage(null);
if (init_error != null) {
setErrorMessage("Cannot read launch configuration: " + init_error); //$NON-NLS-1$
return false;
}
setErrorMessage(null);
return true;
}
}