/*****************************************************************************
* Limpet - the Lightweight InforMation ProcEssing Toolkit
* http://limpet.info
*
* (C) 2015-2016, Deep Blue C Technologies Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html)
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
package info.limpet.ui.core_view;
import info.limpet.IChangeListener;
import info.limpet.IStoreItem;
import info.limpet.data.operations.CollectionComplianceTests;
import info.limpet.ui.Activator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
public abstract class CoreAnalysisView extends ViewPart
{
private Action newView;
private Action copyToClipboard;
private Action followSelection;
private ISelectionListener selListener;
private final CollectionComplianceTests aTests;
private final List<IStoreItem> curList = new ArrayList<IStoreItem>();
private IChangeListener changeListener;
private final String _myId;
private final String _myTitle;
public CoreAnalysisView(String myId, String myTitle)
{
super();
_myId = myId;
_myTitle = myTitle;
aTests = new CollectionComplianceTests();
changeListener = new IChangeListener()
{
@Override
public void dataChanged(IStoreItem subject)
{
datasetDataChanged(subject);
display(curList);
}
@Override
public void collectionDeleted(IStoreItem subject)
{
// hmm, we should probably stop listening to that collection
curList.remove(subject);
// and update the UI
display(curList);
}
@Override
public void metadataChanged(IStoreItem subject)
{
display(curList);
}
};
}
/**
* the specified item has changed, and should be re-analysed
*
* @param subject
* the item that has changed
*/
protected void datasetDataChanged(IStoreItem subject)
{
}
/**
* external accessor, since we switch off following when a view has been created specifically to
* view a particular selection
*
* @param val
*/
public void follow(List<IStoreItem> data)
{
followSelection.setChecked(false);
followSelection.setEnabled(false);
followSelection
.setDescription("Disabled - view focussed on particular dataset");
display(data);
// also set the title
if (data.size() == 1)
{
this.setPartName(_myTitle + " - " + data.get(0).getName());
}
else
{
this.setPartName(_myTitle + " - multiple datasets");
}
}
protected void newSelection(ISelection selection)
{
List<IStoreItem> res = new ArrayList<IStoreItem>();
if (selection instanceof StructuredSelection)
{
StructuredSelection str = (StructuredSelection) selection;
// check if it/they are suitable
Iterator<?> iter = str.iterator();
while (iter.hasNext())
{
Object object = (Object) iter.next();
if (object instanceof IAdaptable)
{
IAdaptable ad = (IAdaptable) object;
IStoreItem coll = (IStoreItem) ad.getAdapter(IStoreItem.class);
if (coll != null)
{
res.add(coll);
}
}
else
{
// can we adapt it?
ArrayList<IAdapterFactory> adapters =
Activator.getDefault().getAdapters();
if (adapters != null)
{
Iterator<IAdapterFactory> aIter = adapters.iterator();
while (aIter.hasNext())
{
IAdapterFactory iAdapterFactory = (IAdapterFactory) aIter.next();
Object match =
iAdapterFactory.getAdapter(object, IStoreItem.class);
if (match != null)
{
res.add((IStoreItem) match);
break;
}
}
}
}
}
}
// ok, stop listening to the old list
clearChangeListeners();
// have we found any, and are they suitable for us?
if ((res.size()) > 0 && appliesToMe(res, getATests()))
{
// store the new list
curList.addAll(res);
// now listen to the new list
Iterator<IStoreItem> iter = curList.iterator();
while (iter.hasNext())
{
IStoreItem iC = iter.next();
iC.addChangeListener(changeListener);
}
// ok, display them
display(res);
}
else
{
// ok, nothing to display - clear the graph
display(new ArrayList<IStoreItem>());
}
}
private void clearChangeListeners()
{
if (curList.size() > 0)
{
Iterator<IStoreItem> iter = curList.iterator();
while (iter.hasNext())
{
IStoreItem iC = iter.next();
iC.removeChangeListener(changeListener);
}
// and forget about them all
curList.clear();
}
}
public List<IStoreItem> getData()
{
return curList;
}
/**
* determine if this set of collections are suitable for displaying
*
* @param res
* @param aTests2
* @return
*/
protected abstract boolean appliesToMe(List<IStoreItem> res,
CollectionComplianceTests aTests2);
/**
* show this set of collections
*
* @param res
*/
public abstract void display(List<IStoreItem> res);
protected void fillLocalPullDown(IMenuManager manager)
{
manager.add(newView);
manager.add(copyToClipboard);
manager.add(followSelection);
manager.add(new Separator());
}
protected void fillLocalToolBar(IToolBarManager manager)
{
manager.add(copyToClipboard);
manager.add(followSelection);
}
protected void copyToClipboard()
{
Display display = Display.getCurrent();
Clipboard clipboard = new Clipboard(display);
String output = getTextForClipboard();
clipboard.setContents(new Object[]
{output}, new Transfer[]
{TextTransfer.getInstance()});
clipboard.dispose();
}
protected void contributeToActionBars()
{
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
protected void setupListener()
{
// register as selection listener
selListener = new ISelectionListener()
{
public void selectionChanged(IWorkbenchPart part, ISelection selection)
{
// are we following the selection?
if (followSelection.isChecked())
{
newSelection(selection);
}
}
};
getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(
selListener);
}
public void dispose()
{
// stop listening for data changes
clearChangeListeners();
// and stop listening for selection changes
getSite().getWorkbenchWindow().getSelectionService()
.removeSelectionListener(selListener);
super.dispose();
}
protected abstract String getTextForClipboard();
protected void makeActions()
{
newView = new Action()
{
public void run()
{
createNewView();
}
};
newView.setText("New instance of " + _myTitle);
newView.setToolTipText("Create a fresh instance of this view");
newView.setImageDescriptor(Activator
.getImageDescriptor("icons/newView.png"));
copyToClipboard = new Action()
{
public void run()
{
copyToClipboard();
}
};
copyToClipboard.setText("Copy to clipboard");
copyToClipboard.setToolTipText("Copy analysis to clipboard");
copyToClipboard.setImageDescriptor(PlatformUI.getWorkbench()
.getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
followSelection = new Action("Follow selection", SWT.TOGGLE)
{
public void run()
{
// don't worry, we can ignore the events
}
};
followSelection.setChecked(true);
followSelection.setToolTipText("Link with selection");
followSelection.setImageDescriptor(PlatformUI.getWorkbench()
.getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
}
protected void createNewView()
{
// create a new instance of the specified view
IWorkbenchWindow window =
PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
try
{
String millis = "" + System.currentTimeMillis();
page.showView(_myId, millis, IWorkbenchPage.VIEW_ACTIVATE);
}
catch (PartInitException e)
{
e.printStackTrace();
}
}
protected void fillContextMenu(IMenuManager manager)
{
manager.add(copyToClipboard);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
public CollectionComplianceTests getATests()
{
return aTests;
}
}