Bug removed: assertion error when disposed
diff --git a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
index 83b2500..0b5b137 100644
--- a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
+++ b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.chart/src/org/eclipse/amp/agf/chart/ChartEditPart.java
@@ -1,537 +1,557 @@
-/**
- * <copyright>
- *
- * Copyright (c) 2009 Metascape, LLC.
- * 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:
- * Metascape - Initial API and Implementation
- *
- * </copyright>
- *
- */
-package org.eclipse.amp.agf.chart;
-
-import java.util.List;
-
-import org.eclipse.amp.agf.chart.ide.AGFChartPlugin;
-import org.eclipse.amp.axf.core.IModel;
-import org.eclipse.amp.axf.core.IObservationProvider;
-import org.eclipse.amp.axf.view.SWTAsyncModelListener;
-import org.eclipse.birt.chart.api.ChartEngine;
-import org.eclipse.birt.chart.device.ICallBackNotifier;
-import org.eclipse.birt.chart.device.IDeviceRenderer;
-import org.eclipse.birt.chart.exception.ChartException;
-import org.eclipse.birt.chart.factory.GeneratedChartState;
-import org.eclipse.birt.chart.factory.Generator;
-import org.eclipse.birt.chart.factory.RunTimeContext;
-import org.eclipse.birt.chart.model.Chart;
-import org.eclipse.birt.chart.model.attribute.Bounds;
-import org.eclipse.birt.chart.model.attribute.CallBackValue;
-import org.eclipse.birt.chart.model.attribute.ColorDefinition;
-import org.eclipse.birt.chart.model.attribute.Fill;
-import org.eclipse.birt.chart.model.attribute.Palette;
-import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
-import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
-import org.eclipse.birt.chart.model.attribute.impl.PaletteImpl;
-import org.eclipse.birt.core.framework.PlatformConfig;
-import org.eclipse.core.runtime.IAdapterManager;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.draw2d.AbstractLayout;
-import org.eclipse.draw2d.Figure;
-import org.eclipse.draw2d.FigureListener;
-import org.eclipse.draw2d.Graphics;
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.geometry.Dimension;
-import org.eclipse.draw2d.geometry.Point;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
-import org.eclipse.jface.viewers.IColorProvider;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.statushandlers.StatusManager;
-
-public class ChartEditPart extends AbstractGraphicalEditPart implements ICallBackNotifier {
-
- private Chart chart;
-
- private final ResourceManager resourceManager;
-
- private IDeviceRenderer renderer;
-
- private GeneratedChartState chartState;
-
- private IDataProvider dataProvider;
-
- private IColorProvider seriesColorProvider;
-
- private Palette genericPalette;
-
- private Object dataSource;
-
- private ChartModelListener chartListener;
-
- private IDataSelectionListener dataListener;
-
- private int nextOpenPaletteIndex;
-
- private IChartDesignStrategy chartStrategy;
-
- /**
- * Instantiates a new chart edit part.
- */
- public ChartEditPart() {
- resourceManager = new ResourceManager();
- PlatformConfig config = new PlatformConfig();
- try {
- config.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this);
- renderer = ChartEngine.instance(config).getRenderer("dv.SWT");
- } catch (ChartException e) {
- throw new RuntimeException(e);
- }
- genericPalette = PaletteImpl.create(0, true);
- genericPalette.shift(0);
- }
-
- /**
- * The listener interface for receiving chartModel events. The class that is interested in processing a chartModel
- * event implements this interface, and the object created with that class is registered with a component using the
- * component's <code>addChartModelListener<code> method. When
- * the chartModel event occurs, that object's appropriate
- * method is invoked.
- *
- * @see ChartModelEvent
- */
- class ChartModelListener extends SWTAsyncModelListener {
- /**
- * Instantiates a new chart model listener.
- */
- public ChartModelListener() {
- super(null, "Chart Updated View", 10000);
- }
-
- @Override
- public void observing(IObservationProvider observed) {
- // wait for data source to be available from model set..
- while (getDataProvider() == null) {
- try {
- Thread.sleep(25);
- } catch (InterruptedException e) {
- //
- }
- }
- setChartStrategy(ChartType.TIME_SERIES.createStrategy());
- }
-
- @Override
- public void observeStart(IObservationProvider observed) {
- updateChartSelection();
- endPainting();
- }
-
- @Override
- public void observeInitialize(IObservationProvider model) {
- getResourceManager().setImage(null);
- }
-
- @Override
- public void update(final IModel model) {
- beginPainting();
- getChartStrategy().update();
- refresh();
- }
-
- @Override
- public void observationEnd(IObservationProvider model) {
- getDataProvider().removeListener(getDataSource(), getDataListener());
- model = null;
- }
-
- }
-
- private void updateValueSetColor(Object valueSet) {
- String seriesLabel = dataProvider.getText(valueSet);
- Color swtColor = seriesColorProvider.getForeground(seriesLabel);
- EList<Fill> entries = chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries();
- ColorDefinition cd = null;
- if (swtColor == null) {
- // List<Fill> palette = ySeriesDefinition.getSeriesPalette().getEntries();
- // if (nextOpenPaletteIndex >= palette.size()) {
- // nextOpenPaletteIndex = 0;
- // }
- // cd = (ColorDefinition) palette.get(nextOpenPaletteIndex);
- // Color lineColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd
- // .getBlue());
- if (seriesColorProvider instanceof CachedColorProvider) {
- cd = (ColorDefinition) genericPalette.getEntries().get(nextOpenPaletteIndex++);
- if (nextOpenPaletteIndex > genericPalette.getEntries().size() - 1) {
- nextOpenPaletteIndex = 0;
- }
- swtColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd.getBlue());
- ((CachedColorProvider) seriesColorProvider).putForegroundColor(seriesLabel, swtColor);
- }
- } else {
- cd = ColorDefinitionImpl.create(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue());
- // if (chartType == ChartType.TIME_SERIES) {
- // cd = ((LineSeries) lineSeries).getLineAttributes().getColor();
- // } else if (chartType == ChartType.STACKED_AREA) {
- // cd = ((AreaSeries) lineSeries).getLineAttributes().getColor();
- // }
- // cd.setRed(swtColor.getRed());
- // cd.setGreen(swtColor.getGreen());
- // cd.setBlue(swtColor.getBlue());
- }
- entries.add(cd);
- }
-
- @Override
- protected IFigure createFigure() {
- chartListener.setWidget(getViewer().getControl());
-
- final Figure newFigure = new Figure() {
- @Override
- public void paintFigure(Graphics graphics) {
- if (getResourceManager().getImage() != null) {
- graphics.drawImage(getResourceManager().getImage(), 0, 0);
- if (getChartListener() != null) {
- getChartListener().endPainting();
- }
- }
- }
- };
- newFigure.setLayoutManager(new AbstractLayout() {
- @Override
- public Dimension getMinimumSize(IFigure container, int hintWidth, int hintHeight) {
- return new Dimension(hintWidth < 1 ? 1 : hintWidth, hintHeight < 1 ? 1 : hintHeight);
- }
-
- @Override
- protected Dimension calculatePreferredSize(IFigure container, int hintWidth, int hintHeight) {
- return new Dimension(hintWidth < 1 ? 100 : hintWidth, hintHeight < 1 ? 100 : hintHeight);
- }
-
- public void layout(IFigure container) {
- newFigure.setLocation(new Point(0, 0));
- }
- });
- newFigure.addFigureListener(new FigureListener() {
- public void figureMoved(IFigure source) {
- regenerateChart();
- }
- });
-
- return newFigure;
- }
-
- @Override
- protected void createEditPolicies() {
- //
- }
-
- @Override
- public void refresh() {
- new Thread() {
- @Override
- public void run() {
- regenerateChart(true);
- }
- }.run();
- }
-
- @Override
- public void setModel(Object model) {
- super.setModel(model);
- chartListener = new ChartModelListener();
- ((IModel) model).addModelListener(chartListener);
- IAdapterManager adapterManager = Platform.getAdapterManager();
- // We seem to need to force loading of the data provider, at least in the exemplar case
- Object provider = adapterManager.loadAdapter(this.getModel(), "org.eclipse.amp.agf.chart.IDataProvider");
-
- if (!(provider instanceof IDataProvider)) {
- throw new RuntimeException("Couldn't find data provider for chart model. Please ensure that a data provider adapter has been defined for the class: " + this.getModel().getClass());
- }
-
- setDataProvider((IDataProvider) provider);
-
- // createChart();
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart()
- */
- public void regenerateChart() {
- regenerateChart(true);
- }
-
- /**
- * Regenerate chart.
- *
- * @param forceNewImage
- * the force new image
- */
- public synchronized void regenerateChart(boolean forceNewImage) {
- if (forceNewImage) {
- getResourceManager().setImage(null);
- }
- try {
- if (chart != null && chartStrategy.isInitialized() && getFigure() != null && !getFigure().getSize().isEmpty()) {
- createImage();
- Dimension area = getFigure().getSize();
- Bounds chartBounds = BoundsImpl.create(0, 0, area.width, area.height);
- chartBounds.scale(72d / renderer.getDisplayServer().getDpiResolution());
- Generator gr = Generator.instance();
- RunTimeContext rtc = new RunTimeContext();
- rtc.setScriptingEnabled(false);
-
- // rtc.setScriptContext(csc);
- // csc.setChartInstance(chart);
- chartState = gr.build(renderer.getDisplayServer(), chart, chartBounds, rtc);
- gr.render(renderer, chartState);
- getFigure().repaint();
- } else {
- chartListener.endPainting();
- }
- } catch (ChartException ce) {
- StatusManager.getManager().handle(new Status(Status.WARNING, AGFChartPlugin.PLUGIN_ID, "Couldn't generate chart.", ce));
- chartListener.endPainting();
- }
- }
-
- /**
- * Creates the image.
- */
- public void createImage() {
- Dimension area = getFigure().getSize();
- Rectangle swtBounds = new Rectangle(0, 0, Math.max(area.width, 10), Math.max(area.height, 10));
- if (resourceManager.getImage() == null || !resourceManager.getImage().getBounds().equals(swtBounds)) {
- resourceManager.setImage(new Image(getViewer().getControl().getDisplay(), swtBounds));
- resourceManager.setGc(new GC(resourceManager.getImage()));
- renderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, resourceManager.getGc());
- }
- }
-
- /**
- * Creates the chart.
- */
- public synchronized void createChart() {
- chart = chartStrategy.createChart(dataProvider, dataSource);
- chart.getTitle().getLabel().setVisible(false);
- }
-
- /**
- * Update chart series.
- */
- public synchronized void updateChartSelection() {
- chartStrategy.updateSelection();
- @SuppressWarnings("rawtypes")
- List valueSets = dataProvider.getValueSets(dataSource);
- chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries().clear();
- for (Object valueSet : valueSets) {
- updateValueSetColor(valueSet);
- }
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel()
- */
- public Chart getDesignTimeModel() {
- return chart;
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel()
- */
- public Chart getRunTimeModel() {
- return chartState.getChartModel();
- }
-
- ChartModelListener getChartListener() {
- return chartListener;
- }
-
- IChartDesignStrategy getChartStrategy() {
- return chartStrategy;
- }
-
- Object getDataSource() {
- return dataSource;
- }
-
- IDataSelectionListener getDataListener() {
- return dataListener;
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance()
- */
- public Object peerInstance() {
- return this;
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.ICallBackNotifier#callback(java.lang.Object, java.lang.Object,
- * org.eclipse.birt.chart.model.attribute.CallBackValue)
- */
- public void callback(Object arg0, Object arg1, CallBackValue arg2) {
- //
- }
-
- /**
- * Gets the chart.
- *
- * @return the chart
- */
- public Chart getChart() {
- return chart;
- }
-
- /**
- * Sets the series color provider.
- *
- * @param seriesColorProvider
- * the new series color provider
- */
- public void setSeriesColorProvider(IColorProvider seriesColorProvider) {
- this.seriesColorProvider = seriesColorProvider;
- }
-
- /**
- *
- * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart()
- */
- public void repaintChart() {
- refresh();
- }
-
- @Override
- public void deactivate() {
- super.deactivate();
- dataProvider.removeListener(dataSource, dataListener);
- }
-
- /**
- * Gets the data provider.
- *
- * @return the data provider
- */
- public IDataProvider getDataProvider() {
- return dataProvider;
- }
-
- /**
- * Sets the data provider.
- *
- * @param dataProvider
- * the new data provider
- */
- public synchronized void setDataProvider(IDataProvider dataProvider) {
- this.dataProvider = dataProvider;
- dataSource = dataProvider.getDataSource(getModel());
- dataListener = new IDataSelectionListener() {
- public void selectionChanged(Object dataSet) {
- if (getParent() != null && getRoot() != null && getViewer() != null && getChart() != null) {
- updateChartSelection();
- getViewer().getControl().getDisplay().asyncExec(new Runnable() {
- public void run() {
- regenerateChart(true);
- }
- });
- }
- }
- };
- dataProvider.addListener(dataSource, dataListener);
- }
-
- public void setChartStrategy(IChartDesignStrategy chartStrategy) {
- this.chartStrategy = chartStrategy;
- createChart();
- updateChartSelection();
- if (getViewer().getControl().getDisplay() != null) {
- getViewer().getControl().getDisplay().asyncExec(new Runnable() {
- public void run() {
- repaintChart();
- }
- });
- }
- }
-
- /**
- * Gets the series color provider.
- *
- * @return the series color provider
- */
- public IColorProvider getSeriesColorProvider() {
- return seriesColorProvider;
- }
-
- ResourceManager getResourceManager() {
- return resourceManager;
- }
- /**
- * Encapsulate the dispose of gc and image
- * @author fei
- *
- */
- class ResourceManager implements DisposeListener{
- private GC gc;
-
- private Image image;
-
- private Control attachedToDispose;
-
- public ResourceManager() {
- //
- }
-
- void setGc(GC gc) {
- if (this.gc != null && !this.gc.isDisposed()) {
- this.gc.dispose();
- }
- this.gc = gc;
- addDisposeListener();
- }
-
- GC getGc() {
- return gc;
- }
-
- private void addDisposeListener(){
- assert attachedToDispose == null || attachedToDispose.equals(getViewer().getControl());
- if(attachedToDispose == null && getViewer() != null){
- attachedToDispose = getViewer().getControl();
- attachedToDispose.addDisposeListener(this);
- }
- }
-
- Image getImage() {
- return image;
- }
-
- void setImage(Image image) {
- if (this.image != null && !this.image.isDisposed()) {
- this.image.dispose();
- }
- this.image = image;
- addDisposeListener();
- }
-
- public void widgetDisposed(DisposeEvent arg0) {
- setImage(null);
- setGc(null);
- }
- }
-}
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Metascape, LLC.
+ * 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:
+ * Metascape - Initial API and Implementation
+ *
+ * </copyright>
+ *
+ */
+package org.eclipse.amp.agf.chart;
+
+import java.util.List;
+
+import org.eclipse.amp.agf.chart.ide.AGFChartPlugin;
+import org.eclipse.amp.axf.core.IModel;
+import org.eclipse.amp.axf.core.IObservationProvider;
+import org.eclipse.amp.axf.view.SWTAsyncModelListener;
+import org.eclipse.birt.chart.api.ChartEngine;
+import org.eclipse.birt.chart.device.ICallBackNotifier;
+import org.eclipse.birt.chart.device.IDeviceRenderer;
+import org.eclipse.birt.chart.exception.ChartException;
+import org.eclipse.birt.chart.factory.GeneratedChartState;
+import org.eclipse.birt.chart.factory.Generator;
+import org.eclipse.birt.chart.factory.RunTimeContext;
+import org.eclipse.birt.chart.model.Chart;
+import org.eclipse.birt.chart.model.attribute.Bounds;
+import org.eclipse.birt.chart.model.attribute.CallBackValue;
+import org.eclipse.birt.chart.model.attribute.ColorDefinition;
+import org.eclipse.birt.chart.model.attribute.Fill;
+import org.eclipse.birt.chart.model.attribute.Palette;
+import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
+import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
+import org.eclipse.birt.chart.model.attribute.impl.PaletteImpl;
+import org.eclipse.birt.core.framework.PlatformConfig;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.draw2d.AbstractLayout;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.FigureListener;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public class ChartEditPart extends AbstractGraphicalEditPart implements ICallBackNotifier {
+
+ private Chart chart;
+
+ private final ResourceManager resourceManager;
+
+ private IDeviceRenderer renderer;
+
+ private GeneratedChartState chartState;
+
+ private IDataProvider dataProvider;
+
+ private IColorProvider seriesColorProvider;
+
+ private Palette genericPalette;
+
+ private Object dataSource;
+
+ private ChartModelListener chartListener;
+
+ private IDataSelectionListener dataListener;
+
+ private int nextOpenPaletteIndex;
+
+ private IChartDesignStrategy chartStrategy;
+
+ /**
+ * Instantiates a new chart edit part.
+ */
+ public ChartEditPart() {
+ resourceManager = new ResourceManager();
+ PlatformConfig config = new PlatformConfig();
+ try {
+ config.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this);
+ renderer = ChartEngine.instance(config).getRenderer("dv.SWT");
+ } catch (ChartException e) {
+ throw new RuntimeException(e);
+ }
+ genericPalette = PaletteImpl.create(0, true);
+ genericPalette.shift(0);
+ }
+
+ /**
+ * The listener interface for receiving chartModel events. The class that is
+ * interested in processing a chartModel event implements this interface, and
+ * the object created with that class is registered with a component using the
+ * component's <code>addChartModelListener<code> method. When
+ * the chartModel event occurs, that object's appropriate
+ * method is invoked.
+ *
+ * @see ChartModelEvent
+ */
+ class ChartModelListener extends SWTAsyncModelListener {
+ /**
+ * Instantiates a new chart model listener.
+ */
+ public ChartModelListener() {
+ super(null, "Chart Updated View", 10000);
+ }
+
+ @Override
+ public void observing(IObservationProvider observed) {
+ // wait for data source to be available from model set..
+ while (getDataProvider() == null) {
+ try {
+ Thread.sleep(25);
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+ setChartStrategy(ChartType.TIME_SERIES.createStrategy());
+ }
+
+ @Override
+ public void observeStart(IObservationProvider observed) {
+ updateChartSelection();
+ endPainting();
+ }
+
+ @Override
+ public void observeInitialize(IObservationProvider model) {
+ getResourceManager().setImage(null);
+ }
+
+ @Override
+ public void update(final IModel model) {
+ beginPainting();
+ getChartStrategy().update();
+ refresh();
+ }
+
+ @Override
+ public void observationEnd(IObservationProvider model) {
+ getDataProvider().removeListener(getDataSource(), getDataListener());
+ model = null;
+ }
+
+ }
+
+ private void updateValueSetColor(Object valueSet) {
+ String seriesLabel = dataProvider.getText(valueSet);
+ Color swtColor = seriesColorProvider.getForeground(seriesLabel);
+ EList<Fill> entries = chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries();
+ ColorDefinition cd = null;
+ if (swtColor == null) {
+ // List<Fill> palette = ySeriesDefinition.getSeriesPalette().getEntries();
+ // if (nextOpenPaletteIndex >= palette.size()) {
+ // nextOpenPaletteIndex = 0;
+ // }
+ // cd = (ColorDefinition) palette.get(nextOpenPaletteIndex);
+ // Color lineColor = new
+ // Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(),
+ // cd.getGreen(), cd
+ // .getBlue());
+ if (seriesColorProvider instanceof CachedColorProvider) {
+ cd = (ColorDefinition) genericPalette.getEntries().get(nextOpenPaletteIndex++);
+ if (nextOpenPaletteIndex > genericPalette.getEntries().size() - 1) {
+ nextOpenPaletteIndex = 0;
+ }
+ swtColor = new Color(org.eclipse.swt.widgets.Display.getCurrent(), cd.getRed(), cd.getGreen(), cd.getBlue());
+ ((CachedColorProvider) seriesColorProvider).putForegroundColor(seriesLabel, swtColor);
+ }
+ } else {
+ cd = ColorDefinitionImpl.create(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue());
+ // if (chartType == ChartType.TIME_SERIES) {
+ // cd = ((LineSeries) lineSeries).getLineAttributes().getColor();
+ // } else if (chartType == ChartType.STACKED_AREA) {
+ // cd = ((AreaSeries) lineSeries).getLineAttributes().getColor();
+ // }
+ // cd.setRed(swtColor.getRed());
+ // cd.setGreen(swtColor.getGreen());
+ // cd.setBlue(swtColor.getBlue());
+ }
+ entries.add(cd);
+ }
+
+ @Override
+ protected IFigure createFigure() {
+ chartListener.setWidget(getViewer().getControl());
+
+ final Figure newFigure = new Figure() {
+ @Override
+ public void paintFigure(Graphics graphics) {
+ if (getResourceManager().getImage() != null) {
+ graphics.drawImage(getResourceManager().getImage(), 0, 0);
+ if (getChartListener() != null) {
+ getChartListener().endPainting();
+ }
+ }
+ }
+ };
+ newFigure.setLayoutManager(new AbstractLayout() {
+ @Override
+ public Dimension getMinimumSize(IFigure container, int hintWidth, int hintHeight) {
+ return new Dimension(hintWidth < 1 ? 1 : hintWidth, hintHeight < 1 ? 1 : hintHeight);
+ }
+
+ @Override
+ protected Dimension calculatePreferredSize(IFigure container, int hintWidth, int hintHeight) {
+ return new Dimension(hintWidth < 1 ? 100 : hintWidth, hintHeight < 1 ? 100 : hintHeight);
+ }
+
+ public void layout(IFigure container) {
+ newFigure.setLocation(new Point(0, 0));
+ }
+ });
+ newFigure.addFigureListener(new FigureListener() {
+ public void figureMoved(IFigure source) {
+ regenerateChart();
+ }
+ });
+
+ return newFigure;
+ }
+
+ @Override
+ protected void createEditPolicies() {
+ //
+ }
+
+ @Override
+ public void refresh() {
+ new Thread() {
+ @Override
+ public void run() {
+ regenerateChart(true);
+ }
+ }.run();
+ }
+
+ @Override
+ public void setModel(Object model) {
+ super.setModel(model);
+ chartListener = new ChartModelListener();
+ ((IModel) model).addModelListener(chartListener);
+ IAdapterManager adapterManager = Platform.getAdapterManager();
+ // We seem to need to force loading of the data provider, at least in the
+ // exemplar case
+ Object provider = adapterManager.loadAdapter(this.getModel(), "org.eclipse.amp.agf.chart.IDataProvider");
+
+ if (!(provider instanceof IDataProvider)) {
+ throw new RuntimeException("Couldn't find data provider for chart model. Please ensure that a data provider adapter has been defined for the class: " + this.getModel().getClass());
+ }
+
+ setDataProvider((IDataProvider) provider);
+
+ // createChart();
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart()
+ */
+ public void regenerateChart() {
+ regenerateChart(true);
+ }
+
+ /**
+ * Regenerate chart.
+ *
+ * @param forceNewImage
+ * the force new image
+ */
+ public synchronized void regenerateChart(boolean forceNewImage) {
+ if (forceNewImage) {
+ getResourceManager().setImage(null);
+ }
+ try {
+ if (chart != null && chartStrategy.isInitialized() && getFigure() != null && !getFigure().getSize().isEmpty()) {
+ createImage();
+ Dimension area = getFigure().getSize();
+ Bounds chartBounds = BoundsImpl.create(0, 0, area.width, area.height);
+ chartBounds.scale(72d / renderer.getDisplayServer().getDpiResolution());
+ Generator gr = Generator.instance();
+ RunTimeContext rtc = new RunTimeContext();
+ rtc.setScriptingEnabled(false);
+
+ // rtc.setScriptContext(csc);
+ // csc.setChartInstance(chart);
+ chartState = gr.build(renderer.getDisplayServer(), chart, chartBounds, rtc);
+ gr.render(renderer, chartState);
+ getFigure().repaint();
+ } else {
+ chartListener.endPainting();
+ }
+ } catch (ChartException ce) {
+ StatusManager.getManager().handle(new Status(Status.WARNING, AGFChartPlugin.PLUGIN_ID, "Couldn't generate chart.", ce));
+ chartListener.endPainting();
+ }
+ }
+
+ /**
+ * Creates the image.
+ */
+ public void createImage() {
+ Dimension area = getFigure().getSize();
+ Rectangle swtBounds = new Rectangle(0, 0, Math.max(area.width, 10), Math.max(area.height, 10));
+ if (resourceManager.getImage() == null || !resourceManager.getImage().getBounds().equals(swtBounds)) {
+ resourceManager.setImage(new Image(getViewer().getControl().getDisplay(), swtBounds));
+ resourceManager.setGc(new GC(resourceManager.getImage()));
+ renderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, resourceManager.getGc());
+ }
+ }
+
+ /**
+ * Creates the chart.
+ */
+ public synchronized void createChart() {
+ chart = chartStrategy.createChart(dataProvider, dataSource);
+ chart.getTitle().getLabel().setVisible(false);
+ }
+
+ /**
+ * Update chart series.
+ */
+ public synchronized void updateChartSelection() {
+ chartStrategy.updateSelection();
+ @SuppressWarnings("rawtypes")
+ List valueSets = dataProvider.getValueSets(dataSource);
+ chartStrategy.getValueSetsDefinition().getSeriesPalette().getEntries().clear();
+ for (Object valueSet : valueSets) {
+ updateValueSetColor(valueSet);
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel()
+ */
+ public Chart getDesignTimeModel() {
+ return chart;
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel()
+ */
+ public Chart getRunTimeModel() {
+ return chartState.getChartModel();
+ }
+
+ ChartModelListener getChartListener() {
+ return chartListener;
+ }
+
+ IChartDesignStrategy getChartStrategy() {
+ return chartStrategy;
+ }
+
+ Object getDataSource() {
+ return dataSource;
+ }
+
+ IDataSelectionListener getDataListener() {
+ return dataListener;
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance()
+ */
+ public Object peerInstance() {
+ return this;
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.ICallBackNotifier#callback(java.lang.Object,
+ * java.lang.Object,
+ * org.eclipse.birt.chart.model.attribute.CallBackValue)
+ */
+ public void callback(Object arg0, Object arg1, CallBackValue arg2) {
+ //
+ }
+
+ /**
+ * Gets the chart.
+ *
+ * @return the chart
+ */
+ public Chart getChart() {
+ return chart;
+ }
+
+ /**
+ * Sets the series color provider.
+ *
+ * @param seriesColorProvider
+ * the new series color provider
+ */
+ public void setSeriesColorProvider(IColorProvider seriesColorProvider) {
+ this.seriesColorProvider = seriesColorProvider;
+ }
+
+ /**
+ *
+ * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart()
+ */
+ public void repaintChart() {
+ refresh();
+ }
+
+ @Override
+ public void deactivate() {
+ super.deactivate();
+ dataProvider.removeListener(dataSource, dataListener);
+ }
+
+ /**
+ * Gets the data provider.
+ *
+ * @return the data provider
+ */
+ public IDataProvider getDataProvider() {
+ return dataProvider;
+ }
+
+ /**
+ * Sets the data provider.
+ *
+ * @param dataProvider
+ * the new data provider
+ */
+ public synchronized void setDataProvider(IDataProvider dataProvider) {
+ this.dataProvider = dataProvider;
+ dataSource = dataProvider.getDataSource(getModel());
+ dataListener = new IDataSelectionListener() {
+ public void selectionChanged(Object dataSet) {
+ if (getParent() != null && getRoot() != null && getViewer() != null && getChart() != null) {
+ updateChartSelection();
+ getViewer().getControl().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ regenerateChart(true);
+ }
+ });
+ }
+ }
+ };
+ dataProvider.addListener(dataSource, dataListener);
+ }
+
+ public void setChartStrategy(IChartDesignStrategy chartStrategy) {
+ this.chartStrategy = chartStrategy;
+ createChart();
+ updateChartSelection();
+ if (getViewer().getControl().getDisplay() != null) {
+ getViewer().getControl().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ repaintChart();
+ }
+ });
+ }
+ }
+
+ /**
+ * Gets the series color provider.
+ *
+ * @return the series color provider
+ */
+ public IColorProvider getSeriesColorProvider() {
+ return seriesColorProvider;
+ }
+
+ ResourceManager getResourceManager() {
+ return resourceManager;
+ }
+
+ /**
+ * Encapsulate disposing of {@link GC} and {@link Image} resources.
+ *
+ * @author fei
+ */
+ class ResourceManager implements DisposeListener {
+ private GC gc;
+
+ private Image image;
+
+ private Control disposeEventProvider;
+
+ public ResourceManager() {
+ //
+ }
+
+ void setGc(GC gc) {
+ if (this.gc != null && !this.gc.isDisposed()) {
+ this.gc.dispose();
+ }
+ this.gc = gc;
+ addDisposeListener();
+ }
+
+ GC getGc() {
+ return gc;
+ }
+
+ private void removeDisposeListener() {
+ if (disposeEventProvider != null) {
+ if (!disposeEventProvider.isDisposed()) {
+ if (getViewer() != null && disposeEventProvider.equals(getViewer().getControl())) {
+ return;
+ }
+
+ disposeEventProvider.removeDisposeListener(this);
+ }
+ disposeEventProvider = null;
+ }
+ }
+
+ private void addDisposeListener() {
+ removeDisposeListener();
+ if (disposeEventProvider == null && getViewer() != null && getViewer().getControl() != null && !getViewer().getControl().isDisposed()) {
+ disposeEventProvider = getViewer().getControl();
+ disposeEventProvider.addDisposeListener(this);
+ }
+ }
+
+ Image getImage() {
+ return image;
+ }
+
+ void setImage(Image image) {
+ if (this.image != null && !this.image.isDisposed()) {
+ this.image.dispose();
+ }
+ this.image = image;
+ addDisposeListener();
+ }
+
+ public void widgetDisposed(DisposeEvent arg0) {
+ setImage(null);
+ setGc(null);
+ removeDisposeListener();
+ }
+ }
+}