PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/org.mwc.cmap.xyplot/src/org/mwc/cmap/xyplot/views/CrossSectionView.java

https://bitbucket.org/ianmayo/debrief
Java | 543 lines | 414 code | 70 blank | 59 comment | 60 complexity | a6031dcb54355304f24e4bad3f07a1c0 MD5 | raw file
  1. package org.mwc.cmap.xyplot.views;
  2. import java.beans.PropertyChangeEvent;
  3. import java.beans.PropertyChangeListener;
  4. import org.eclipse.core.runtime.Status;
  5. import org.eclipse.jface.action.IToolBarManager;
  6. import org.eclipse.jface.viewers.ISelection;
  7. import org.eclipse.jface.viewers.ISelectionChangedListener;
  8. import org.eclipse.jface.viewers.ISelectionProvider;
  9. import org.eclipse.jface.viewers.IStructuredSelection;
  10. import org.eclipse.jface.viewers.SelectionChangedEvent;
  11. import org.eclipse.swt.widgets.Composite;
  12. import org.eclipse.swt.widgets.Display;
  13. import org.eclipse.ui.IActionBars;
  14. import org.eclipse.ui.IEditorPart;
  15. import org.eclipse.ui.IEditorReference;
  16. import org.eclipse.ui.IMemento;
  17. import org.eclipse.ui.IViewSite;
  18. import org.eclipse.ui.IWorkbench;
  19. import org.eclipse.ui.IWorkbenchPage;
  20. import org.eclipse.ui.IWorkbenchPart;
  21. import org.eclipse.ui.IWorkbenchWindow;
  22. import org.eclipse.ui.PartInitException;
  23. import org.eclipse.ui.PlatformUI;
  24. import org.eclipse.ui.part.ViewPart;
  25. import org.mwc.cmap.core.CorePlugin;
  26. import org.mwc.cmap.core.DataTypes.Temporal.TimeProvider;
  27. import org.mwc.cmap.core.property_support.EditableWrapper;
  28. import org.mwc.cmap.core.ui_support.PartMonitor;
  29. import org.mwc.cmap.xyplot.views.providers.CrossSectionDatasetProvider;
  30. import org.mwc.cmap.xyplot.views.providers.ICrossSectionDatasetProvider;
  31. import org.mwc.cmap.xyplot.views.snail.ISnailPeriodChangedListener;
  32. import org.mwc.cmap.xyplot.views.snail.SnailPeriodTracker;
  33. import Debrief.Wrappers.ShapeWrapper;
  34. import MWC.GUI.Editable;
  35. import MWC.GUI.Layer;
  36. import MWC.GUI.Layers;
  37. import MWC.GUI.PlainWrapper;
  38. import MWC.GUI.Plottable;
  39. import MWC.GUI.Shapes.LineShape;
  40. import MWC.GUI.Shapes.PlainShape;
  41. import MWC.GenericData.HiResDate;
  42. public class CrossSectionView extends ViewPart implements ISnailPeriodChangedListener
  43. {
  44. CrossSectionViewer _viewer;
  45. /**
  46. * listen to line annotations being selected
  47. */
  48. private ISelectionChangedListener _selectionChangeListener;
  49. /**
  50. * Provider listening to us
  51. */
  52. private ISelectionProvider _selectionProvider;
  53. /**
  54. * helper application to help track activation/closing of new plots
  55. */
  56. private PartMonitor _partMonitor;
  57. /**
  58. * listen out for new times
  59. */
  60. private PropertyChangeListener _timeListener;
  61. private TimeProvider _timeProvider;
  62. private PropertyChangeListener _lineListener = new LineChangeListener();
  63. /**
  64. * current line annotation being selected
  65. */
  66. private LineShape _line = null;
  67. /**
  68. * Debrief data
  69. */
  70. private Layers _myLayers;
  71. private Layers.DataListener _myLayersListener;
  72. private ICrossSectionDatasetProvider _datasetProvider =
  73. new CrossSectionDatasetProvider();
  74. /**
  75. * store the plot information when we're reloading a plot in a fresh session
  76. */
  77. private IMemento _memento = null;
  78. /**
  79. * Toolbar drop down for specifying time period
  80. */
  81. private SnailPeriodTracker _snailMode = new SnailPeriodTracker();
  82. @Override
  83. public void createPartControl(final Composite parent)
  84. {
  85. _viewer = new CrossSectionViewer(parent);
  86. _partMonitor = new PartMonitor(getSite().getWorkbenchWindow()
  87. .getPartService());
  88. listenToMyParts();
  89. setupFiringTimeChangesToChart();
  90. contributeToActionBars();
  91. _selectionChangeListener = new ISelectionChangedListener()
  92. {
  93. @Override
  94. public void selectionChanged(final SelectionChangedEvent event)
  95. {
  96. final ISelection sel = event.getSelection();
  97. if (!(sel instanceof IStructuredSelection))
  98. return;
  99. final IStructuredSelection ss = (IStructuredSelection) sel;
  100. final Object o = ss.getFirstElement();
  101. if (o instanceof EditableWrapper)
  102. {
  103. // check if Line annotation is selected
  104. final Editable eb = ((EditableWrapper) o).getEditable();
  105. if (eb instanceof ShapeWrapper)
  106. {
  107. final PlainShape shape = ((ShapeWrapper) eb).getShape();
  108. if (shape instanceof LineShape && !shape.equals(_line))
  109. {
  110. clearLineListener();
  111. _line = (LineShape) shape;
  112. _line.addPropertyListener(_lineListener);
  113. _viewer.fillPlot(_myLayers, _line, _datasetProvider);
  114. }
  115. }
  116. }
  117. }
  118. };
  119. _viewer.addSelectionChangedListener(_selectionChangeListener);
  120. _snailMode.addSnailPeriodChangedListener(this);
  121. // have we got our data?
  122. if (_memento != null)
  123. {
  124. // restore it
  125. _viewer.restoreState(_memento);
  126. _snailMode.setPeriod(_viewer.getPeriod());
  127. }
  128. }
  129. private void contributeToActionBars()
  130. {
  131. final IActionBars bars = getViewSite().getActionBars();
  132. fillLocalToolBar(bars.getToolBarManager());
  133. }
  134. private void fillLocalToolBar(final IToolBarManager manager)
  135. {
  136. manager.add(_snailMode);
  137. }
  138. @Override
  139. public void init(final IViewSite site, final IMemento memento) throws PartInitException
  140. {
  141. super.init(site, memento);
  142. if (memento != null)
  143. {
  144. _memento = memento;
  145. }
  146. }
  147. private void listenToMyParts()
  148. {
  149. // Listen to Layers
  150. _partMonitor.addPartListener(Layers.class, PartMonitor.ACTIVATED,
  151. new PartMonitor.ICallback()
  152. {
  153. public void eventTriggered(final String type, final Object part,
  154. final IWorkbenchPart parentPart)
  155. {
  156. processNewLayers(part);
  157. }
  158. });
  159. _partMonitor.addPartListener(Layers.class, PartMonitor.OPENED,
  160. new PartMonitor.ICallback()
  161. {
  162. public void eventTriggered(final String type, final Object part,
  163. final IWorkbenchPart parentPart)
  164. {
  165. processNewLayers(part);
  166. }
  167. });
  168. _partMonitor.addPartListener(Layers.class, PartMonitor.CLOSED,
  169. new PartMonitor.ICallback()
  170. {
  171. public void eventTriggered(final String type, final Object part,
  172. final IWorkbenchPart parentPart)
  173. {
  174. // is this our set of layers?
  175. if (part == _myLayers)
  176. {
  177. clearLineListener();
  178. // stop listening to this layer
  179. clearLayerListener();
  180. }
  181. }
  182. });
  183. _partMonitor.addPartListener(ISelectionProvider.class,
  184. PartMonitor.ACTIVATED, new PartMonitor.ICallback()
  185. {
  186. public void eventTriggered(final String type, final Object part,
  187. final IWorkbenchPart parentPart)
  188. {
  189. // aah, just check it's not is
  190. if (part != _viewer)
  191. {
  192. final ISelectionProvider iS = (ISelectionProvider) part;
  193. if (!iS.equals(_selectionProvider))
  194. {
  195. if (part instanceof IEditorPart)
  196. setUpTimeProvider((IEditorPart) part);
  197. _selectionProvider = iS;
  198. if (_selectionChangeListener != null)
  199. {
  200. _selectionProvider
  201. .addSelectionChangedListener(_selectionChangeListener);
  202. }
  203. }
  204. }
  205. }
  206. });
  207. _partMonitor.addPartListener(ISelectionProvider.class,
  208. PartMonitor.DEACTIVATED, new PartMonitor.ICallback()
  209. {
  210. public void eventTriggered(final String type, final Object part,
  211. final IWorkbenchPart parentPart)
  212. {
  213. // aah, just check it's not is
  214. if (part != _viewer)
  215. {
  216. if (_selectionProvider != null && _selectionChangeListener != null)
  217. {
  218. _selectionProvider
  219. .removeSelectionChangedListener(_selectionChangeListener);
  220. }
  221. }
  222. }
  223. });
  224. // ok we're all ready now. just try and see if the current part is valid
  225. _partMonitor.fireActivePart(getSite().getWorkbenchWindow()
  226. .getActivePage());
  227. }
  228. private void setupFiringTimeChangesToChart()
  229. {
  230. // see if we've alreay been configured
  231. if (_timeListener != null)
  232. return;
  233. // get the document being edited
  234. final IWorkbench wb = PlatformUI.getWorkbench();
  235. final IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
  236. final IWorkbenchPage page = win.getActivePage();
  237. IEditorPart editor = null;
  238. // the page might not yet be open...
  239. if (page != null)
  240. {
  241. editor = page.getActiveEditor();
  242. // do we have an active editor?
  243. if (editor == null)
  244. {
  245. // see if there are any editors at all open
  246. final IEditorReference[] theEditors = page.getEditorReferences();
  247. for (int i = 0; i < theEditors.length; i++)
  248. {
  249. final IEditorReference thisE = theEditors[i];
  250. editor = thisE.getEditor(false);
  251. // right, see if it has a time manager
  252. final TimeProvider tp = (TimeProvider) editor
  253. .getAdapter(TimeProvider.class);
  254. if (tp != null)
  255. {
  256. final String hisId = tp.getId();
  257. if (hisId.equals(_viewer.getPlotId()))
  258. break;
  259. }
  260. }
  261. // nope, drop out.
  262. return;
  263. }
  264. }
  265. setUpTimeProvider(editor);
  266. }
  267. private void setUpTimeProvider(IEditorPart editor)
  268. {
  269. if (editor != null)
  270. {
  271. // get it's time-provider interface
  272. final TimeProvider prov = (TimeProvider) editor.getAdapter(TimeProvider.class);
  273. if (_timeProvider != null && _timeProvider.equals(prov))
  274. return;
  275. if (_timeListener != null)
  276. _timeProvider.removeListener(_timeListener,
  277. TimeProvider.TIME_CHANGED_PROPERTY_NAME);
  278. _timeProvider = prov;
  279. }
  280. else
  281. CorePlugin.logError(Status.WARNING, "Failed to identify time provider",
  282. null);
  283. if (_timeProvider != null)
  284. {
  285. // create our listener
  286. _timeListener = new NewTimeListener();
  287. // add our listener to the time object
  288. _timeProvider.addListener(_timeListener,
  289. TimeProvider.TIME_CHANGED_PROPERTY_NAME);
  290. _viewer.setPlotId(_timeProvider.getId());
  291. }
  292. }
  293. @Override
  294. public void setFocus()
  295. {
  296. //TODO:
  297. }
  298. void processNewLayers(final Object part)
  299. {
  300. // just check we're not already looking at it
  301. if (!part.equals(_myLayers))
  302. {
  303. // de-register current layers before tracking the new one
  304. clearLayerListener();
  305. clearLineListener();
  306. _viewer.clearPlot();
  307. }
  308. else
  309. {
  310. return;
  311. }
  312. _myLayers = (Layers) part;
  313. if (_myLayersListener == null)
  314. {
  315. _myLayersListener = new Layers.DataListener2()
  316. {
  317. public void dataModified(final Layers theData, final Layer changedLayer)
  318. {
  319. processReformattedLayer(theData, changedLayer);
  320. }
  321. public void dataExtended(final Layers theData)
  322. {
  323. dataExtended(theData, null, null);
  324. }
  325. public void dataReformatted(final Layers theData, final Layer changedLayer)
  326. {
  327. processReformattedLayer(theData, changedLayer);
  328. }
  329. public void dataExtended(final Layers theData, final Plottable newItem,
  330. final Layer parentLayer)
  331. {
  332. processNewData(theData, newItem, parentLayer);
  333. }
  334. };
  335. }
  336. // right, listen for data being added
  337. _myLayers.addDataExtendedListener(_myLayersListener);
  338. // and listen for items being reformatted
  339. _myLayers.addDataReformattedListener(_myLayersListener);
  340. // and listen for items being reformatted
  341. _myLayers.addDataModifiedListener(_myLayersListener);
  342. // do an initial population.
  343. processNewData(_myLayers, null, null);
  344. }
  345. void processReformattedLayer(final Layers theData, final Layer changedLayer)
  346. {
  347. _viewer.fillPlot(theData, _line, _datasetProvider);
  348. }
  349. @Override
  350. public void snailPeriodChanged(final long timePeriod)
  351. {
  352. _viewer.fillPlot(_myLayers, _line, _datasetProvider, timePeriod);
  353. }
  354. void processNewData(final Layers theData, final Editable newItem,
  355. final Layer parentLayer)
  356. {
  357. Display.getDefault().asyncExec(new Runnable()
  358. {
  359. public void run()
  360. {
  361. // ok, fire the change in the UI thread
  362. _viewer.fillPlot(theData, _line, _datasetProvider);
  363. }
  364. });
  365. }
  366. /**
  367. * stop listening to the layer, if necessary
  368. */
  369. void clearLayerListener()
  370. {
  371. if (_myLayers != null)
  372. {
  373. _myLayers.removeDataExtendedListener(_myLayersListener);
  374. _myLayers.removeDataModifiedListener(_myLayersListener);
  375. _myLayers.removeDataReformattedListener(_myLayersListener);
  376. _myLayersListener = null;
  377. _myLayers = null;
  378. }
  379. }
  380. void clearLineListener()
  381. {
  382. if (_line != null)
  383. {
  384. _line.removePropertyListener(_lineListener);
  385. _lineListener = null;
  386. _line = null;
  387. }
  388. }
  389. void clearTimeListener()
  390. {
  391. if (_timeProvider != null)
  392. {
  393. _timeProvider.removeListener(_timeListener,
  394. TimeProvider.TIME_CHANGED_PROPERTY_NAME);
  395. _timeListener = null;
  396. _timeProvider = null;
  397. }
  398. }
  399. public void dispose()
  400. {
  401. super.dispose();
  402. // make sure we close the listeners
  403. clearLayerListener();
  404. clearLineListener();
  405. clearTimeListener();
  406. if(_viewer != null)
  407. {
  408. _viewer.removeSelectionChangedListener(_selectionChangeListener);
  409. }
  410. if (_selectionProvider != null)
  411. {
  412. _selectionProvider.removeSelectionChangedListener(_selectionChangeListener);
  413. _selectionProvider = null;
  414. }
  415. _selectionChangeListener = null;
  416. if (_partMonitor != null)
  417. {
  418. _partMonitor.ditch();
  419. }
  420. _viewer.clearPlot();
  421. }
  422. @Override
  423. public void saveState(final IMemento memento)
  424. {
  425. // let our parent go for it first
  426. super.saveState(memento);
  427. _viewer.saveState(memento);
  428. }
  429. protected final class LineChangeListener implements PropertyChangeListener
  430. {
  431. public void propertyChange(final PropertyChangeEvent event)
  432. {
  433. if (event.getPropertyName().equals(
  434. PlainWrapper.LOCATION_CHANGED))
  435. {
  436. final Runnable nextEvent = new Runnable()
  437. {
  438. public void run()
  439. {
  440. if (event.getSource().equals(_line))
  441. {
  442. _viewer.fillPlot(_myLayers, _line, _datasetProvider);
  443. }
  444. }
  445. };
  446. Display.getDefault().syncExec(nextEvent);
  447. }
  448. }
  449. }
  450. protected final class NewTimeListener implements PropertyChangeListener
  451. {
  452. public void propertyChange(final PropertyChangeEvent event)
  453. {
  454. // see if it's the time or the period which
  455. // has changed
  456. if (event.getPropertyName().equals(
  457. TimeProvider.TIME_CHANGED_PROPERTY_NAME))
  458. {
  459. // ok, use the new time
  460. final HiResDate newDTG = (HiResDate) event.getNewValue();
  461. final Runnable nextEvent = new Runnable()
  462. {
  463. public void run()
  464. {
  465. _viewer.newTime(newDTG);
  466. _viewer.fillPlot(_myLayers, _line, _datasetProvider);
  467. }
  468. };
  469. Display.getDefault().syncExec(nextEvent);
  470. }
  471. }
  472. }
  473. }