Author: jfuerth
Date: Fri Mar 27 15:48:48 2009
New Revision: 2959
Modified:
trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java
trunk/src/ca/sqlpower/architect/swingui/ContainerPane.java
trunk/src/ca/sqlpower/architect/swingui/PlayPen.java
trunk/src/ca/sqlpower/architect/swingui/PlayPenComponent.java
trunk/src/ca/sqlpower/architect/swingui/action/ExportPlaypenToPDFAction.java
trunk/src/ca/sqlpower/architect/swingui/action/ProgressAction.java
trunk/src/ca/sqlpower/architect/swingui/olap/CubePane.java
trunk/src/ca/sqlpower/architect/swingui/olap/DimensionPane.java
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPContextMenuFactory.java
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPPane.java
trunk/src/ca/sqlpower/architect/swingui/olap/UsageComponent.java
trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java
Log:
Implemented Export to PDF for OLAP playpens
Changes in support of this feature:
-copy constructors for all OLAP playpen components
-ability to specify a target playpen from a ProgressAction subclass
Modified: trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/ArchitectFrame.java Fri Mar 27
15:48:48 2009
@@ -365,7 +365,7 @@
printAction.putValue(AbstractAction.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(KeyEvent.VK_P, accelMask));
- exportPlaypenToPDFAction = new ExportPlaypenToPDFAction(session);
+ exportPlaypenToPDFAction = new ExportPlaypenToPDFAction(session,
session.getPlayPen());
zoomInAction = new ZoomAction(session, session.getPlayPen(),
ZOOM_STEP);
zoomOutAction = new ZoomAction(session, session.getPlayPen(),
ZOOM_STEP * -1.0);
Modified: trunk/src/ca/sqlpower/architect/swingui/ContainerPane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/ContainerPane.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/ContainerPane.java Fri Mar 27
15:48:48 2009
@@ -91,6 +91,27 @@
*/
protected final Set<C> selectedItems = new HashSet<C>();
+ /**
+ * Creates a copy of this container pane suitable for use with
printing or
+ * PDF generation. The new copy may not have all listeners set up
properly
+ * for interactive use.
+ *
+ * @param copyMe
+ * the container pane to copy.
+ */
+ protected ContainerPane(ContainerPane<T, C> copyMe, PlayPenContentPane
parent) {
+ super(copyMe, parent);
+ dashed = copyMe.dashed;
+ // itemSelectionListeners should not be copied
+ if (copyMe.margin != null) {
+ margin = new Insets(
+ copyMe.margin.top, copyMe.margin.left,
+ copyMe.margin.bottom, copyMe.margin.right);
+ }
+ model = copyMe.model;
+ rounded = copyMe.rounded;
+ }
+
protected ContainerPane(PlayPenContentPane parent) {
super(parent);
this.backgroundColor = new Color(240, 240, 240);
Modified: trunk/src/ca/sqlpower/architect/swingui/PlayPen.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/PlayPen.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/PlayPen.java Fri Mar 27
15:48:48 2009
@@ -418,26 +418,40 @@
*/
public PlayPen(ArchitectSwingSession session, PlayPen pp) {
this(session);
-
+ logger.debug("Copying PlayPen@" + System.identityHashCode(pp) + " into "
+ System.identityHashCode(this));
this.antialiasSetting = pp.antialiasSetting;
setFont(pp.getFont());
this.setForeground(pp.getForeground());
this.setBackground(pp.getBackground());
+ // XXX this should be done by making PlayPenComponent cloneable.
+ // it's silly that playpen has to know about every subclass of
ppc
+ logger.debug("Copying " + pp.getContentPane().getComponentCount() + "
components...");
for (int i = 0; i < pp.getContentPane().getComponentCount();
i++) {
PlayPenComponent ppc =
pp.getContentPane().getComponent(i);
if (ppc instanceof TablePane) {
TablePane tp = (TablePane) ppc;
- addImpl(new TablePane(tp, contentPane), ppc.getPreferredLocation(),
contentPane.getComponentCount());
- }
- }
-
- for (int i = 0; i < pp.getContentPane().getComponentCount();
i++) {
- PlayPenComponent ppc =
pp.getContentPane().getComponent(i);
- if (ppc instanceof Relationship) {
+ addImpl(new TablePane(tp, contentPane),
ppc.getPreferredLocation(), i);
+ } else if (ppc instanceof Relationship) {
Relationship rel = (Relationship) ppc;
- addImpl(new Relationship(rel, contentPane),
ppc.getPreferredLocation(), contentPane.getComponentCount());
+ addImpl(new Relationship(rel, contentPane),
ppc.getPreferredLocation(), i);
+ } else if (ppc instanceof CubePane) {
+ CubePane cp = (CubePane) ppc;
+ addImpl(new CubePane(cp, contentPane),
ppc.getPreferredLocation(), i);
+ } else if (ppc instanceof DimensionPane) {
+ DimensionPane dp = (DimensionPane) ppc;
+ addImpl(new DimensionPane(dp, contentPane),
ppc.getPreferredLocation(), i);
+ } else if (ppc instanceof VirtualCubePane) {
+ VirtualCubePane vcp = (VirtualCubePane) ppc;
+ addImpl(new VirtualCubePane(vcp, contentPane),
ppc.getPreferredLocation(), i);
+ } else if (ppc instanceof UsageComponent) {
+ UsageComponent uc = (UsageComponent) ppc;
+ getContentPane().add(new UsageComponent(uc, contentPane),
i);
+ } else {
+ throw new UnsupportedOperationException(
+ "I don't know how to copy PlayPenComponent type
" +
+ ppc.getClass().getName());
}
}
setSize(getPreferredSize());
@@ -458,6 +472,7 @@
* stop using it.
*/
public void destroy() {
+ // FIXME the content pane must be notified of this destruction,
either explicitly or via a lifecycle event
firePlayPenLifecycleEvent();
try {
removeHierarcyListeners(session.getTargetDatabase());
Modified: trunk/src/ca/sqlpower/architect/swingui/PlayPenComponent.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/PlayPenComponent.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/PlayPenComponent.java Fri Mar
27 15:48:48 2009
@@ -70,6 +70,40 @@
protected boolean selected;
protected boolean componentPreviouslySelected;
+
+ /**
+ * Copy constructor. Makes deep copies of all PlayPenComponent state.
+ * Subclasses that implement a copy constructor should chain to this
+ * constructor in their own copy constructors.
+ * <p>
+ * The parent reference of the new copy will be null. Copy
constructors in
+ * subclasses should also leave the parent pointer null--it is up to
the
+ * code initiating the copy to add the newly-copied component to some
parent
+ * (if you want it to belong to some parent).
+ *
+ * @param copyMe the playpen component this new component should be a
copy of
+ * @param parent the parent content pane of this new copy
+ */
+ protected PlayPenComponent(PlayPenComponent copyMe, PlayPenContentPane
parent) {
+ backgroundColor = copyMe.backgroundColor;
+ if (copyMe.bounds != null) {
+ bounds = new Rectangle(copyMe.bounds);
+ }
+ componentPreviouslySelected = copyMe.componentPreviouslySelected;
+ foregroundColor = copyMe.foregroundColor;
+ if (copyMe.insets != null) {
+ insets = new Insets(
+ copyMe.insets.top, copyMe.insets.left,
+ copyMe.insets.bottom, copyMe.insets.right);
+ }
+ opaque = copyMe.opaque;
+ this.parent = parent;
+ // pcs should not be copied
+ selected = copyMe.selected;
+ // selectionListeners should not be copied
+ toolTipText = copyMe.toolTipText;
+ // ui should not be copied, but subclass should call updateUI()
+ }
protected PlayPenComponent(PlayPenContentPane parent) {
this.parent = parent;
@@ -452,7 +486,7 @@
// --------------------- SELECTABLE SUPPORT ---------------------
- private List<SelectionListener> selectionListeners = new
LinkedList<SelectionListener>();
+ private final List<SelectionListener> selectionListeners = new
LinkedList<SelectionListener>();
public final void addSelectionListener(SelectionListener l) {
selectionListeners.add(l);
Modified:
trunk/src/ca/sqlpower/architect/swingui/action/ExportPlaypenToPDFAction.java
==============================================================================
---
trunk/src/ca/sqlpower/architect/swingui/action/ExportPlaypenToPDFAction.java
(original)
+++
trunk/src/ca/sqlpower/architect/swingui/action/ExportPlaypenToPDFAction.java
Fri Mar 27 15:48:48 2009
@@ -50,10 +50,20 @@
private static final String FILE_KEY = "FILE_KEY"; //$NON-NLS-1$
- private static int OUTSIDE_PADDING = 10;
+ private static int OUTSIDE_PADDING = 10;
- public ExportPlaypenToPDFAction(ArchitectSwingSession session) {
- super(session,
Messages.getString("ExportPlaypenToPDFAction.name"),
Messages.getString("ExportPlaypenToPDFAction.description")); //$NON-NLS-1$
//$NON-NLS-2$
+ /**
+ * Creates an action that exports the session's relational playpen to
a PDF
+ * file.
+ *
+ * @param session
+ * The session that owns this action.
+ * @param playPen
+ * The playpen to export. Could be the relational playpen
or one
+ * of the OLAP playpens.
+ */
+ public ExportPlaypenToPDFAction(ArchitectSwingSession session, PlayPen
playPen) {
+ super(session, playPen,
Messages.getString("ExportPlaypenToPDFAction.name"),
Messages.getString("ExportPlaypenToPDFAction.description"), null);
//$NON-NLS-1$ //$NON-NLS-2$
}
/**
@@ -69,7 +79,7 @@
File file = null;
while (true) {
- int response =
chooser.showSaveDialog(session.getArchitectFrame());
+ int response = chooser.showSaveDialog(playpen);
if (response != JFileChooser.APPROVE_OPTION) {
return false;
@@ -107,6 +117,7 @@
@Override
public void doStuff(MonitorableImpl monitor, Map<String, Object>
properties) {
+ logger.debug("Creating PDF of playpen: " + playpen);
PlayPen playPen = new PlayPen(session, playpen);
// don't need this playpen to be interactive or respond to
SQLObject changes
@@ -141,6 +152,9 @@
int j=0;
for (int i = contentPane.getComponentCount() - 1; i >= 0; i--)
{
PlayPenComponent ppc = contentPane.getComponent(i);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Painting component " + ppc);
+ }
g.translate(ppc.getLocation().x, ppc.getLocation().y);
ppc.paint(g);
g.translate(-ppc.getLocation().x, -ppc.getLocation().y);
Modified: trunk/src/ca/sqlpower/architect/swingui/action/ProgressAction.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/action/ProgressAction.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/action/ProgressAction.java Fri
Mar 27 15:48:48 2009
@@ -31,6 +31,7 @@
import ca.sqlpower.architect.swingui.ASUtils;
import ca.sqlpower.architect.swingui.ArchitectSwingSession;
+import ca.sqlpower.architect.swingui.PlayPen;
import ca.sqlpower.swingui.ProgressWatcher;
import ca.sqlpower.swingui.SPSwingWorker;
import ca.sqlpower.util.MonitorableImpl;
@@ -45,6 +46,15 @@
* bar. The dialog automatically closes when the job finishes.
*/
public abstract class ProgressAction extends AbstractArchitectAction {
+
+ public ProgressAction(
+ ArchitectSwingSession session,
+ PlayPen playpen,
+ String actionName,
+ String actionDescription,
+ Icon icon) {
+ super(session, playpen, actionName, actionDescription, icon);
+ }
public ProgressAction(
ArchitectSwingSession session,
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/CubePane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/CubePane.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/CubePane.java Fri Mar 27
15:48:48 2009
@@ -42,6 +42,11 @@
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(CubePane.class);
+ public CubePane(CubePane copyMe, PlayPenContentPane parent) {
+ super(copyMe, parent);
+ updateUI();
+ }
+
public CubePane(Cube model, PlayPenContentPane parent) {
super(parent);
this.model = model;
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/DimensionPane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/DimensionPane.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/DimensionPane.java Fri Mar
27 15:48:48 2009
@@ -104,6 +104,11 @@
private final HierarchyWatcher hierarchyWatcher = new
HierarchyWatcher();
+ public DimensionPane(DimensionPane copyMe, PlayPenContentPane parent) {
+ super(copyMe, parent);
+ updateUI();
+ }
+
public DimensionPane(Dimension m, PlayPenContentPane parent) {
super(parent);
this.model = m;
Modified:
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPContextMenuFactory.java
==============================================================================
---
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPContextMenuFactory.java
(original)
+++
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPContextMenuFactory.java
Fri Mar 27 15:48:48 2009
@@ -31,6 +31,7 @@
import ca.sqlpower.architect.olap.MondrianModel.VirtualCube;
import ca.sqlpower.architect.swingui.ArchitectSwingSession;
import ca.sqlpower.architect.swingui.PopupMenuFactory;
+import ca.sqlpower.architect.swingui.action.ExportPlaypenToPDFAction;
import ca.sqlpower.architect.swingui.olap.action.CreateEnergonCubeAction;
import ca.sqlpower.architect.swingui.olap.action.EditCubeAction;
import ca.sqlpower.architect.swingui.olap.action.EditDimensionAction;
@@ -72,6 +73,7 @@
m.add(oSession.getCreateVirtualCubeAction());
m.addSeparator();
m.add(oSession.getExportSchemaAction());
+ m.add(new ExportPlaypenToPDFAction(session,
oSession.getOlapPlayPen()));
} else if (obj instanceof Schema) {
m.add(oSession.getCreateCubeAction());
m.add(oSession.getCreateDimensionAction());
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/OLAPPane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/OLAPPane.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/OLAPPane.java Fri Mar 27
15:48:48 2009
@@ -92,7 +92,20 @@
*/
private PlayPenCoordinate<T, C> insertionPoint;
-
+ /**
+ * Creates a copy of this OLAP pane suitable for use with printing or
+ * PDF generation. The new copy may not have all listeners set up
properly
+ * for interactive use.
+ *
+ * @param copyMe
+ * the OLAP pane to copy.
+ */
+ protected OLAPPane(OLAPPane<T, C> copyMe, PlayPenContentPane parent) {
+ super(copyMe, parent);
+ sections.addAll(copyMe.sections); // XXX might need deep copy
(could be tricky)
+ // don't worry about preserving selections
+ }
+
protected OLAPPane(PlayPenContentPane parent) {
super(parent);
}
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/UsageComponent.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/UsageComponent.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/UsageComponent.java Fri
Mar 27 15:48:48 2009
@@ -52,6 +52,24 @@
private final OLAPPanesWatcher olapPanesWatcher = new
OLAPPanesWatcher();
+ /**
+ * Creates a copy of the given UsageComponent.
+ *
+ * <p>BUG: The new copy will not react properly to its associated panes
+ * moving around. It should, however, be sufficient for printing or PDF
+ * generation.
+ *
+ * @param copyMe The UsageComponent to copy.
+ */
+ public UsageComponent(UsageComponent copyMe, PlayPenContentPane
parent) {
+ super(copyMe, parent);
+ model = copyMe.model;
+ // TODO refactor listener strategy so listeners could be set up
here
+ pane1 = copyMe.pane1;
+ pane2 = copyMe.pane2;
+ updateUI();
+ }
+
public UsageComponent(PlayPenContentPane parent, OLAPObject model,
OLAPPane<?, ?> pane1, OLAPPane<?, ?> pane2) {
super(parent);
this.model = model;
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/VirtualCubePane.java Fri
Mar 27 15:48:48 2009
@@ -39,6 +39,11 @@
public class VirtualCubePane extends OLAPPane<VirtualCube, OLAPObject> {
+ public VirtualCubePane(VirtualCubePane copyMe, PlayPenContentPane
parent) {
+ super(copyMe, parent);
+ updateUI();
+ }
+
public VirtualCubePane(VirtualCube model, PlayPenContentPane parent) {
super(parent);
this.model = model;