/*******************************************************************************
* Copyright (c) 2009 the CHISEL group and contributors. 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: the CHISEL group - initial API and implementation
*******************************************************************************/
package ca.uvic.chisel.javasketch.ui.internal.search;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.ISearchResultListener;
import org.eclipse.search.ui.ISearchResultPage;
import org.eclipse.search.ui.ISearchResultViewPart;
import org.eclipse.search.ui.SearchResultEvent;
import org.eclipse.search.ui.text.Match;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.Page;
import ca.uvic.chisel.javasketch.SketchPlugin;
import ca.uvic.chisel.javasketch.data.model.IActivation;
import ca.uvic.chisel.javasketch.data.model.IMessage;
import ca.uvic.chisel.javasketch.data.model.ITraceModelProxy;
import ca.uvic.chisel.javasketch.ui.internal.presentation.commands.CommandAction;
import ca.uvic.chisel.javasketch.ui.internal.presentation.commands.RevealActivationHandler;
/**
* Page for displaying the results of a trace search.
*
* @author Del Myers
*
*/
public class TraceSearchResultPage extends Page implements ISearchResultPage {
private String fid;
private ISearchResultViewPart fpart;
private TreeViewer fViewer;
private ISearchResultListener resultsListener;
private Composite page;
/**
* @author Del Myers
*
*/
private final class SelectionForward implements
ISelectionProvider, ISelectionChangedListener {
ListenerList listeners = new ListenerList();
@Override
public void setSelection(ISelection selection) {
fViewer.setSelection(selection);
}
@Override
public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.remove(listener);
}
@Override
public ISelection getSelection() {
return adaptSelection(fViewer.getSelection());
}
@Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
@Override
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = adaptSelection(event.getSelection());
SelectionChangedEvent adapted = new SelectionChangedEvent(this, selection);
for (Object o : listeners.getListeners()) {
((ISelectionChangedListener)o).selectionChanged(adapted);
}
}
/**
* @param selection
*/
private ISelection adaptSelection(ISelection selection) {
List<Object> selected = new LinkedList<Object>();
if (selection instanceof IStructuredSelection) {
for (Iterator<?> i = ((IStructuredSelection)selection).iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof Match) {
ITraceModelProxy proxy = (ITraceModelProxy) ((Match)o).getElement();
if (proxy.getElement() != null) {
selected.add(proxy.getElement());
}
} else {
selected.add(o);
}
}
}
return new StructuredSelection(selected);
}
}
private class TraceSearchResultListener implements ISearchResultListener {
/*
* (non-Javadoc)
* @see
* org.eclipse.search.ui.ISearchResultListener#searchResultChanged(org
* .eclipse.search.ui.SearchResultEvent)
*/
@Override
public void searchResultChanged(SearchResultEvent e) {
SketchPlugin.getDefault().getWorkbench().getDisplay().asyncExec(
new Runnable() {
@Override
public void run() {
updatePage();
}
});
}
}
/*
* (non-Javadoc)
* @see org.eclipse.search.ui.ISearchResultPage#getID()
*/
@Override
public String getID() {
return fid;
}
/*
* (non-Javadoc)
* @see org.eclipse.search.ui.ISearchResultPage#setID(java.lang.String)
*/
@Override
public void setID(String id) {
fid = id;
}
/*
* (non-Javadoc)
* @see
* org.eclipse.ui.part.Page#createControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createControl(Composite parent) {
page = new Composite(parent, SWT.NULL);
page.setLayout(new GridLayout());
fViewer = new TreeViewer(page, SWT.NONE);
fViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableLayout tl = new TableLayout();
fViewer.getTree().setLayout(tl);
// create columns for the viewer
TreeViewerColumn c = new TreeViewerColumn(fViewer, SWT.NONE);
c.getColumn().setText("Search Result");
c.setLabelProvider(new TraceSearchResultLabelProvider());
GC gc = new GC(fViewer.getTree());
tl.addColumnData(new ColumnPixelData(Dialog
.convertWidthInCharsToPixels(gc.getFontMetrics(), 60)));
gc.dispose();
c = new TreeViewerColumn(fViewer, SWT.NONE);
c.getColumn().setText("Kind");
c.setLabelProvider(new TraceSearchResultLabelProvider());
tl.addColumnData(new ColumnPixelData(50));
c = new TreeViewerColumn(fViewer, SWT.NONE);
c.getColumn().setText("Trace");
c.setLabelProvider(new TraceSearchResultLabelProvider());
tl.addColumnData(new ColumnPixelData(50));
resultsListener = new TraceSearchResultListener();
fViewer.getTree().setHeaderVisible(true);
fViewer.setContentProvider(new TraceSearchResultContentProvider());
//create a context menu for the viewer so that results can be
//linked to
MenuManager manager = new MenuManager("TraceSearchResultsPage", "#TraceSearchResults");
Menu menu = manager.createContextMenu(fViewer.getTree());
manager.setRemoveAllWhenShown(true);
manager.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
fillContextMenu(manager);
IStructuredSelection ss = (IStructuredSelection) getSite().getSelectionProvider().getSelection();
if (!ss.isEmpty()) {
Object o = ss.getFirstElement();
if (o instanceof IActivation || o instanceof IMessage) {
IAction action = new CommandAction(RevealActivationHandler.COMMAND_ID, null);
action.setText("Reveal");
manager.add(action);
}
}
}
});
getSite().registerContextMenu("#TraceSearchResults", manager, fViewer);
fViewer.getTree().setMenu(menu);
SelectionForward forward = new SelectionForward();
fViewer.addSelectionChangedListener(forward);
getSite().setSelectionProvider(forward);
}
/**
* @param manager
*/
protected void fillContextMenu(IMenuManager manager) {
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.part.Page#getControl()
*/
@Override
public Control getControl() {
return page;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.part.Page#setFocus()
*/
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see org.eclipse.search.ui.ISearchResultPage#getLabel()
*/
@Override
public String getLabel() {
return "";
}
/*
* (non-Javadoc)
* @see org.eclipse.search.ui.ISearchResultPage#getUIState()
*/
@Override
public Object getUIState() {
return fViewer.getSelection();
}
/*
* (non-Javadoc)
* @see
* org.eclipse.search.ui.ISearchResultPage#restoreState(org.eclipse.ui.IMemento
* )
*/
@Override
public void restoreState(IMemento memento) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see
* org.eclipse.search.ui.ISearchResultPage#saveState(org.eclipse.ui.IMemento
* )
*/
@Override
public void saveState(IMemento memento) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
* @see
* org.eclipse.search.ui.ISearchResultPage#setInput(org.eclipse.search.ui
* .ISearchResult, java.lang.Object)
*/
@Override
public void setInput(ISearchResult search, Object uiState) {
if (!(search instanceof TraceSearchQueryResults)) {
fViewer.setInput(null);
} else {
if (fViewer.getInput() != null) {
((TraceSearchQueryResults) fViewer.getInput())
.removeListener(resultsListener);
}
search.addListener(resultsListener);
fViewer.setInput(search);
}
}
/*
* (non-Javadoc)
* @see
* org.eclipse.search.ui.ISearchResultPage#setViewPart(org.eclipse.search
* .ui.ISearchResultViewPart)
*/
@Override
public void setViewPart(ISearchResultViewPart part) {
fpart = part;
}
/**
* Sets the layout to either a tree layout or a flat layout. If the layout
* is flat, then sorting is available.
*
* @param tree
* true if the layout should be as a tree.
*/
public void setLayout(boolean tree) {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.part.Page#dispose()
*/
@Override
public void dispose() {
super.dispose();
if (fViewer.getInput() != null) {
((ISearchResult) fViewer.getInput())
.removeListener(resultsListener);
}
fViewer = null;
}
/**
*
*/
protected void updatePage() {
if (fViewer != null) {
fViewer.refresh();
fpart.updateLabel();
}
}
}