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;

Reply via email to