package com.deepnighttwo.resourceresolver.ui.views;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import com.deepnighttwo.resourceresolver.ui.Activator;
import com.deepnighttwo.resourceresolver.ui.resolver.IColumnItemComparator;
import com.deepnighttwo.resourceresolver.ui.resolver.ResourceResolverColumn;
import com.deepnighttwo.resourceresolver.ui.resolver.ResourceResolverType;
import com.deepnighttwo.resourceresolver.ui.resolver.data.LinkData;
import com.deepnighttwo.resourceresolver.ui.resolver.data.LongTextData;
import com.deepnighttwo.resourceresolver.ui.views.utils.FilePathValidator;
import com.deepnighttwo.resourceresolver.ui.views.utils.ResourceContentProvider;
import com.deepnighttwo.resourceresolver.ui.views.utils.ResourceViewLabelProvider;
import com.deepnighttwo.resourceresolver.ui.views.utils.ResourceViewSorter;
/**
* This sample class demonstrates how to plug-in a new workbench view. The view
* shows data obtained from the model. The sample creates a dummy model on the
* fly, but a real implementation would connect to the model available either in
* this or another plug-in (e.g. the workspace). The view is connected to the
* model using a content provider.
* <p>
* The view uses a label provider to define how model objects should be
* presented in the view. Each view can present the same model objects using
* different labels and icons, if needed. Alternatively, a single label provider
* can be shared between views in order to ensure that objects of the same type
* are presented in the same way everywhere.
* <p>
*/
public class ResourceDetailsView extends ViewPart {
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "movieresolver.ui.views.MovieDetailsView";
private TableViewer viewer;
private Action changeRootAction;
private Action refreshAction;
private Action doubleClickAction;
private Map<ResourceResolverType, TableColumn[]> resolverColumns = new HashMap<ResourceResolverType, TableColumn[]>();
public static IColumnItemComparator[] comparators;
public static final String SOURCE_PATH_PREF = "movieresolver.source.path";
private final static List<ResourceResolverType> resolverTypes = new ArrayList<ResourceResolverType>();
private final static ResourceResolverType[] TYPES;
private static IPreferenceStore prefs;
private static final int COLUMN_COUNT;
private static final ImageDescriptor refreshImage = Activator
.getImageDescriptor("icons/refresh_root.gif");
private static final ImageDescriptor changeRootDirImage = Activator
.getImageDescriptor("icons/change_root_dir.gif");
static {
// set C:\ as the default source path
prefs = Activator.getDefault().getPreferenceStore();
String currDefault = prefs.getDefaultString(SOURCE_PATH_PREF);
if (currDefault == null || currDefault.length() == 0) {
prefs.setDefault(SOURCE_PATH_PREF, "C:\\test");
}
// get all extensions
IExtension[] extensions = Platform.getExtensionRegistry()
.getExtensionPoint(Activator.PLUGIN_ID, "resolverprovider")
.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] configElements = extension
.getConfigurationElements();
for (IConfigurationElement element : configElements) {
ResourceResolverType type = ResourceResolverType
.createResourceResolverTypeFromConfigElement(element);
if (type != null) {
resolverTypes.add(type);
}
}
}
TYPES = resolverTypes.toArray(new ResourceResolverType[0]);
// get total columns
int columnCount = 0;
for (ResourceResolverType type : TYPES) {
columnCount += type.getResolver().getResolveColumnNames().length;
}
COLUMN_COUNT = columnCount;
}
private Display cacheDisplay = null;
private volatile boolean refreshInQueue = false;
/**
* runnable for refresh table data. this should be executed in UI thread.
*/
private Runnable refreshViewTableRunnable = new Runnable() {
@Override
public void run() {
viewer.refresh();
refreshInQueue = false;
}
};
/**
* sorter for resource viewer.
*/
private ResourceViewSorter sorter = new ResourceViewSorter();
/**
* default constructor.
*/
public ResourceDetailsView() {
}
public int getColumnCount() {
return COLUMN_COUNT;
}
public ResourceResolverType[] getResourceResolverTypes() {
return TYPES;
}
/**
* refresh table data.
*/
public synchronized void refreshViewTable() {
if (cacheDisplay == null || refreshInQueue == true) {
return;
}
refreshInQueue = true;
cacheDisplay.asyncExec(refreshViewTableRunnable);
}
public boolean viewIsDisposed() {
return viewer.getTable().isDisposed();
}
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION);
createTableColumns(viewer);
viewer.setContentProvider(new ResourceContentProvider(this));
viewer.setLabelProvider(new ResourceViewLabelProvider());
viewer.setSorter(sorter);
String rootSource = prefs.getString(SOURCE_PATH_PREF);
viewer.setInput(rootSource);
// Create the help context id for the viewer's control
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(viewer.getControl(), "movieresolver.ui.viewer");
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
supportClick();
if (cacheDisplay == null) {
cacheDisplay = viewer.getControl().getDisplay();
}
}
/**
* add double click support for view table.
*/
private void supportClick() {
final Table table = viewer.getTable();
table.addListener(SWT.MouseDoubleClick, new Listener() {
public void handleEvent(Event event) {
// find clicked on which item
Point pt = new Point(event.x, event.y);
TableItem item = table.getItem(pt);
if (item == null)
return;
// find the column
for (int i = 0; i < COLUMN_COUNT; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
// int index = table.indexOf(item);
Object[] obj = (Object[]) item.getData();
if (obj[i] instanceof LinkData) {
Program.launch(obj[i].toString());
} else if (obj[i] instanceof LongTextData) {
LongTextData longText = (LongTextData) obj[i];
MessageDialog.openConfirm(null, "Details",
longText.getDisplayText());
}
}
}
}
});
}
private void createTableColumns(TableViewer view) {
Table table = view.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
int colIndexCounter = 0;
List<IColumnItemComparator> cps = new ArrayList<IColumnItemComparator>();
for (ResourceResolverType type : TYPES) {
ResourceResolverColumn[] resolverCols = type.getResolver()
.getResolveColumnNames();
TableColumn[] columns = new TableColumn[resolverCols.length];
resolverColumns.put(type, columns);
for (int i = 0; i < resolverCols.length; i++) {
final TableColumn column = new TableColumn(table, SWT.LEFT);
column.setText(resolverCols[i].getColumnName());
cps.add(resolverCols[i].getComparator());
column.setResizable(true);
column.setMoveable(true);
column.setWidth(resolverCols[i].getColumnWidth());
column.setImage(resolverCols[i].getImage());
column.addSelectionListener(getTableColumnSorterAdapter(column,
colIndexCounter));
colIndexCounter++;
}
}
comparators = cps.toArray(new IColumnItemComparator[0]);
}
private SelectionAdapter getTableColumnSorterAdapter(
final TableColumn column, final int index) {
SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
sorter.setColumn(index);
System.out.println(index);
int dir = viewer.getTable().getSortDirection();
if (viewer.getTable().getSortColumn() == column) {
dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
} else {
dir = SWT.DOWN;
}
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
};
return selectionAdapter;
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
ResourceDetailsView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(changeRootAction);
manager.add(new Separator());
manager.add(refreshAction);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(changeRootAction);
manager.add(refreshAction);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(changeRootAction);
manager.add(refreshAction);
}
private void makeActions() {
changeRootAction = new Action() {
public void run() {
changeResourceRoot();
}
};
changeRootAction.setText("Change Root");
changeRootAction.setToolTipText("Change Resource Root");
changeRootAction.setImageDescriptor(changeRootDirImage);
refreshAction = new Action() {
public void run() {
String resourceRoot = prefs.getString(SOURCE_PATH_PREF);
viewer.setInput(resourceRoot);
}
};
refreshAction.setText("Refresh");
refreshAction.setToolTipText("Refresh Root");
refreshAction.setImageDescriptor(refreshImage);
doubleClickAction = new Action() {
public void run() {
// ISelection selection = viewer.getSelection();
// Object obj = ((IStructuredSelection) selection)
// .getFirstElement();
// showMessage("Double-click detected on " + obj.toString());
}
};
}
private void hookDoubleClickAction() {
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
doubleClickAction.run();
}
});
}
public void showMessage(String message) {
MessageDialog.openInformation(viewer.getControl().getShell(),
"Movie Details View", message);
}
private void changeResourceRoot() {
Shell currShell = viewer.getControl().getShell();
InputDialog inputDialog = new InputDialog(currShell, "Resource Root",
"Please Specify the resource root:",
prefs.getString(SOURCE_PATH_PREF),
FilePathValidator.getInstance());
int retCode = inputDialog.open();
if (retCode == InputDialog.OK) {
String newPath = inputDialog.getValue();
prefs.setValue(SOURCE_PATH_PREF, newPath);
viewer.setInput(newPath);
}
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}