aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Fauth2013-08-08 02:42:20 (EDT)
committerDirk Fauth2013-08-08 02:42:20 (EDT)
commitb8217f19aee8eb3c3ad45d7bfe70742c5145e629 (patch)
tree6734181cda0cf5ffda6d086bf1ff8e1b7b30e7a1
parentb288d095b6d588fc82dc1c12ea1907111f391b6a (diff)
downloadorg.eclipse.nebula-b8217f19aee8eb3c3ad45d7bfe70742c5145e629.zip
org.eclipse.nebula-b8217f19aee8eb3c3ad45d7bfe70742c5145e629.tar.gz
org.eclipse.nebula-b8217f19aee8eb3c3ad45d7bfe70742c5145e629.tar.bz2
Bug 414144 - Added the possibility to print a GanttChart by using the
already existing image creating functionality. Also added several settings to allow customization.
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/META-INF/MANIFEST.MF1
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java7
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java8
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttChart.java21
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java14
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java22
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java107
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java224
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java117
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java107
10 files changed, 627 insertions, 1 deletions
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/META-INF/MANIFEST.MF b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/META-INF/MANIFEST.MF
index c761e52..793b643 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/META-INF/MANIFEST.MF
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/META-INF/MANIFEST.MF
@@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.swt
Export-Package: org.eclipse.nebula.widgets.ganttchart,
org.eclipse.nebula.widgets.ganttchart.dnd,
+ org.eclipse.nebula.widgets.ganttchart.print,
org.eclipse.nebula.widgets.ganttchart.themes,
org.eclipse.nebula.widgets.ganttchart.undoredo,
org.eclipse.nebula.widgets.ganttchart.undoredo.commands,
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
index 7a04b49..8360374 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
@@ -88,4 +88,11 @@ public abstract class AbstractLanguageManager implements ILanguageManager {
return "Event";
}
+ public String getPrintJobText() {
+ return "GanttChart";
+ }
+
+ public String getPrintPageText() {
+ return "Page";
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
index 0eb06e5..f3a9e8e 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
@@ -538,4 +538,12 @@ public abstract class AbstractSettings implements ISettings {
public boolean alwaysDragAllEvents() {
return false;
}
+
+ public boolean printSelectedVerticallyComplete() {
+ return false;
+ }
+
+ public boolean printFooter() {
+ return true;
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttChart.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttChart.java
index f897146..a910339 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttChart.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttChart.java
@@ -14,6 +14,7 @@ package org.eclipse.nebula.widgets.ganttchart;
import java.util.Calendar;
import java.util.Random;
+import org.eclipse.nebula.widgets.ganttchart.print.GanttChartPrinter;
import org.eclipse.nebula.widgets.ganttchart.undoredo.GanttUndoRedoManager;
import org.eclipse.nebula.widgets.ganttchart.undoredo.IUndoRedoListener;
import org.eclipse.swt.SWT;
@@ -84,6 +85,8 @@ public class GanttChart extends Composite {
private ILanguageManager _languageManager;
private Calendar[] _holidays;
+
+ private GanttChartPrinter _printer;
/**
* Constructs a new GANTT chart widget. For styles, please see {@link GanttFlags}.
@@ -176,6 +179,8 @@ public class GanttChart extends Composite {
_holidays = holidays;
+ _printer = new GanttChartPrinter(this);
+
init();
}
@@ -384,7 +389,21 @@ public class GanttChart extends Composite {
cal.add(Calendar.DATE, -random.nextInt(10));
cal2.add(Calendar.DATE, random.nextInt(10)+1);
- return new GanttEvent(this, "Random Event", cal, cal2, random.nextInt(100));
+ return new GanttEvent(this, "Random Event", cal, cal2, random.nextInt(100)); //$NON-NLS-1$
}
+ /**
+ * Set a different GanttChartPrinter that should be used to print this GanttChart.
+ * @param printer The GanttChartPrinter that should be used to print this GanttChart.
+ */
+ public void setGanttChartPrinter(GanttChartPrinter printer) {
+ this._printer = printer;
+ }
+
+ /**
+ * Will print the GanttChart based on the settings made in the PrintDialog.
+ */
+ public void print() {
+ _printer.print();
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
index 57f705b..1485130 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
@@ -151,4 +151,18 @@ public interface ILanguageManager {
* @return Text
*/
String getNewEventDefaultText();
+
+ /**
+ * The default text of the print job
+ *
+ * @return Text
+ */
+ String getPrintJobText();
+
+ /**
+ * The default text for the page prefix in the print footer
+ *
+ * @return Text
+ */
+ String getPrintPageText();
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
index d8c0fc9..80619af 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
@@ -1131,4 +1131,26 @@ public interface ISettings {
* <code>false</code> if only the current dragged event should be moved.
*/
public boolean alwaysDragAllEvents();
+
+ /**
+ * On printing a GanttChart it is possible to select to print only the selected area.
+ * For GanttChart this means to print the currently visible area. By default currently
+ * visible means vertically AND horizontally visible. This configuration allows to
+ * specify whether the vertical part should extend to the whole chart and only the
+ * horizontal area should be limited for the visible part.
+ * @return <code>true</code> if the printed chart should contain the whole chart
+ * vertically but only the horizontal visible part of the chart,
+ * <code>false</code> if only the visible part of the chart should be printed,
+ * horizontally AND vertically
+ */
+ public boolean printSelectedVerticallyComplete();
+
+ /**
+ * Configure whether a footer should be added to the print pages or not.
+ * The footer contains the page number and the date when the print was
+ * requested.
+ * @return <code>true</code> if a footer should be added to the print pages,
+ * <code>false</code> if not
+ */
+ public boolean printFooter();
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java
new file mode 100644
index 0000000..d3dc54c
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/CompoundGanttChartPrinter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart.print;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.nebula.widgets.ganttchart.GanttChart;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.printing.Printer;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This class is used to print multiple GanttCharts at once.
+ *
+ * @see GanttChartPrinter
+ */
+public class CompoundGanttChartPrinter extends GanttChartPrinter {
+
+ private String jobName;
+ private final List<GanttChart> ganttCharts = new ArrayList<GanttChart>();
+
+ /**
+ * Creates a new CompoundGanttChartPrinter.
+ * Will use the print job name of the first GanttChart in the list of
+ * GanttCharts to print.
+ */
+ public CompoundGanttChartPrinter() {
+ super(null);
+ }
+
+ /**
+ * Creates a new CompoundGanttChartPrinter that uses the given job name as printer job name.
+ * @param jobName The name that will be used for the print job.
+ */
+ public CompoundGanttChartPrinter(String jobName) {
+ super(null);
+ this.jobName = jobName;
+ }
+
+ @Override
+ public void print() {
+ if (!this.ganttCharts.isEmpty()) {
+ final Printer printer = setupPrinter(Display.getCurrent().getActiveShell());
+ if (printer == null) {
+ return;
+ }
+
+ String name = (this.jobName != null && this.jobName.length() > 0) ?
+ this.jobName : this.ganttCharts.get(0).getLanguageManger().getPrintJobText();
+ Display.getDefault().asyncExec(new GanttChartPrintJob(
+ printer, name, ganttCharts.toArray(new GanttChart[] {})));
+ }
+ }
+
+ @Override
+ protected Point getFullPageCount(Printer printer) {
+ Point result = new Point(0, 0);
+
+ for (GanttChart ganttChart : this.ganttCharts) {
+ Image chartImage = ganttChart.getGanttComposite().getFullImage();
+ Point imgPoint = PrintUtils.getPageCount(printer, chartImage);
+ result.x += imgPoint.x;
+ result.y += imgPoint.y;
+ chartImage.dispose();
+ }
+
+ return result;
+ }
+
+ /**
+ * Adds the given GanttChart to the list of GanttCharts that should be
+ * printed by this CompoundGanttChartPrinter.
+ * @param ganttChart The GanttChart to add to the charts to be printed.
+ */
+ public void addGanttChart(GanttChart ganttChart) {
+ this.ganttCharts.add(ganttChart);
+ }
+
+ /**
+ * Adds the given GanttChart at the specified index to the list of GanttCharts
+ * that should be printed by this CompoundGanttChartPrinter.
+ * @param index The index at which the given GanttChart should be added.
+ * @param ganttChart The GanttChart to add to the charts to be printed.
+ */
+ public void addGanttChart(int index, GanttChart ganttChart) {
+ this.ganttCharts.add(index, ganttChart);
+ }
+
+ /**
+ * Removes the given GanttChart from the list of GanttCharts that should be
+ * printed by this CompoundGanttChartPrinter.
+ * @param ganttChart The GanttChart to remove from the charts to be printed.
+ */
+ public void removeGanttChart(GanttChart ganttChart) {
+ this.ganttCharts.remove(ganttChart);
+ }
+}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java
new file mode 100644
index 0000000..d13c7a3
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrintJob.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart.print;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.nebula.widgets.ganttchart.GanttChart;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.printing.Printer;
+import org.eclipse.swt.printing.PrinterData;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Runnable to print one ore more GanttCharts.
+ */
+public class GanttChartPrintJob implements Runnable {
+
+ private final Printer printer;
+
+ private final String jobName;
+
+ private final GanttChart[] ganttCharts;
+
+ private boolean disposePrinter;
+
+ /**
+ * Creates a new GanttChartPrintJob that uses the given printer and print job name
+ * to print the specified GanttChart(s). If not changed afterwards, running this job
+ * will dispose the given printer when it is done.
+ * @param printer The printer to use.
+ * @param jobName The job name to use for the print job.
+ * @param charts The GanttCharts that should be printed.
+ */
+ public GanttChartPrintJob(Printer printer, String jobName, GanttChart... charts) {
+ this(printer, jobName, true, charts);
+ }
+
+ /**
+ * Creates a new GanttChartPrintJob that uses the given printer and print job name
+ * to print the specified GanttChart(s).
+ * @param printer The printer to use.
+ * @param jobName The job name to use for the print job.
+ * @param charts The GanttCharts that should be printed.
+ * @param disposePrinter Flag to configure whether the given printer should be disposed
+ * after the print job is done. Default is <code>true</code>. Only set this
+ * parameter to <code>false</code> if the printer should be reused for additional
+ * print jobs. You need to ensure that the printer will get disposed yourself
+ * in that case!
+ */
+ public GanttChartPrintJob(Printer printer, String jobName, boolean disposePrinter, GanttChart... charts) {
+ this.printer = printer;
+ this.jobName = jobName;
+ this.ganttCharts = charts;
+ this.disposePrinter = disposePrinter;
+ }
+
+ public void run() {
+ if (printer.startJob(jobName)) {
+ GC gc = new GC(printer);
+
+ int currentPage = 1;
+ for (GanttChart ganttChart : this.ganttCharts) {
+
+ Image printerImage = null;
+ if (printer.getPrinterData().scope == PrinterData.SELECTION) {
+ //the user selected to only print the selected area
+ //as this is quite difficult in GanttChart, we specify that
+ //this means to print the visible area
+ //but it is possible to configure via settings what "visible"
+ //area means:
+ // - really only the visible area horizontally and vertically
+ // - only the horizontal visible area, but vertically everything
+ printerImage = ganttChart.getSettings().printSelectedVerticallyComplete() ?
+ ganttChart.getGanttComposite().getVerticallyFullImage() : ganttChart.getGanttComposite().getImage();
+ }
+ else {
+ printerImage = ganttChart.getGanttComposite().getFullImage();
+ }
+
+ final Rectangle printerClientArea = PrintUtils.computePrintArea(printer);
+ final Point scaleFactor = PrintUtils.computeScaleFactor(printer);
+ final Point pageCount = PrintUtils.getPageCount(printer, printerImage);
+
+ // Print pages Left to Right and then Top to Down
+ for (int verticalPageNumber = 0; verticalPageNumber < pageCount.y; verticalPageNumber++) {
+
+ for (int horizontalPageNumber = 0; horizontalPageNumber < pageCount.x; horizontalPageNumber++) {
+
+ // Calculate bounds for the next page
+ int printerClientAreaHeight = ganttChart.getSettings().printFooter() ?
+ (printerClientArea.height - PrintUtils.FOOTER_HEIGHT_IN_PRINTER_DPI) : printerClientArea.height;
+ Rectangle printBounds = new Rectangle((printerClientArea.width / scaleFactor.x) * horizontalPageNumber,
+ (printerClientAreaHeight / scaleFactor.y) * verticalPageNumber,
+ printerClientArea.width / scaleFactor.x,
+ printerClientAreaHeight / scaleFactor.y);
+
+ if (shouldPrint(printer.getPrinterData(), currentPage)) {
+ printer.startPage();
+
+ Transform printerTransform = new Transform(printer);
+
+ // Adjust for DPI difference between display and printer
+ printerTransform.scale(scaleFactor.x, scaleFactor.y);
+
+ // Adjust for margins
+ printerTransform.translate(printerClientArea.x / scaleFactor.x, printerClientArea.y / scaleFactor.y);
+
+ // GanttChart will not automatically print the pages at the left margin.
+ // Example: page 1 will print at x = 0, page 2 at x = 100, page 3 at x = 300
+ // Adjust to print from the left page margin. i.e x = 0
+ printerTransform.translate(-1 * printBounds.x, -1 * printBounds.y);
+ gc.setTransform(printerTransform);
+
+ int imgWidthClipping = printBounds.width;
+ if (((horizontalPageNumber * printBounds.width)+printBounds.width) > printerImage.getImageData().width) {
+ imgWidthClipping = printerImage.getImageData().width - (horizontalPageNumber * printBounds.width);
+ }
+
+ int imgHeightClipping = printBounds.height;
+ if (((verticalPageNumber * printBounds.height)+printBounds.height) > printerImage.getImageData().height) {
+ imgHeightClipping = printerImage.getImageData().height - (verticalPageNumber * printBounds.height);
+ }
+
+ gc.drawImage(printerImage,
+ horizontalPageNumber * printBounds.width,
+ verticalPageNumber * printBounds.height,
+ imgWidthClipping, imgHeightClipping,
+ printBounds.x, printBounds.y, imgWidthClipping, imgHeightClipping);
+
+ if (ganttChart.getSettings().printFooter())
+ printFooter(gc, ganttChart, currentPage, printBounds);
+
+ printer.endPage();
+ printerTransform.dispose();
+
+ }
+ currentPage++;
+ }
+ }
+
+ printerImage.dispose();
+ }
+
+ printer.endJob();
+ gc.dispose();
+
+ //only dispose the printer after the print job is done if it is configured to do so
+ //this configuration enables the possibility to reuse a printer for several jobs
+ if (disposePrinter)
+ printer.dispose();
+ }
+ }
+
+ /**
+ * Render the footer to a print page.
+ * @param gc The graphical context that is used for printing
+ * @param ganttChart The GanttChart which is currently printed.
+ * @param currentPage The number of the current page that is printed
+ * @param printBounds The bounds of the print area
+ */
+ private void printFooter(GC gc, GanttChart ganttChart, int currentPage, Rectangle printBounds) {
+ String footerDate = new SimpleDateFormat(ganttChart.getSettings().getDateFormat()).format(new Date());
+
+ gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
+ gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ gc.setFont(Display.getCurrent().getSystemFont());
+
+ gc.drawLine(printBounds.x,
+ printBounds.y + printBounds.height+10,
+ printBounds.x + printBounds.width,
+ printBounds.y + printBounds.height+10);
+
+ String pageText = ganttChart.getLanguageManger().getPrintPageText() + " " + currentPage; //$NON-NLS-1$
+ gc.drawString(pageText,
+ printBounds.x,
+ printBounds.y + printBounds.height + 15);
+
+ Point dateExtend = gc.stringExtent(footerDate);
+ gc.drawString(footerDate,
+ printBounds.x + printBounds.width - dateExtend.x,
+ printBounds.y + printBounds.height + 15);
+ }
+
+ /**
+ * Checks if a given page number should be printed.
+ * Page is allowed to print if:
+ * User asked to print all pages or page in a specified range
+ * @param printerData The printer settings made by the user. Needed to determine
+ * if a page should be printed dependent to the scope
+ * @param currentPage The page that should be checked
+ * @return <code>true</code> if the given page should be printed,
+ * <code>false</code> if not
+ */
+ private boolean shouldPrint(PrinterData printerData, int currentPage) {
+ if (printerData.scope == PrinterData.PAGE_RANGE) {
+ return currentPage >= printerData.startPage && currentPage <= printerData.endPage;
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @param dispose <code>true</code> if the printer that is set to this GanttChartPrintJob
+ * should be disposed after the print job is done, <code>false</code> if it should
+ * not be disposed so the printer can be reused for additional tasks.
+ */
+ public void setDisposePrinter(boolean dispose) {
+ this.disposePrinter = dispose;
+ }
+}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java
new file mode 100644
index 0000000..ac99887
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/GanttChartPrinter.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart.print;
+
+import org.eclipse.nebula.widgets.ganttchart.GanttChart;
+import org.eclipse.nebula.widgets.ganttchart.ILanguageManager;
+import org.eclipse.nebula.widgets.ganttchart.ISettings;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.printing.PrintDialog;
+import org.eclipse.swt.printing.Printer;
+import org.eclipse.swt.printing.PrinterData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * This class is used to print a GanttChart. For this it will use the already existing
+ * functionality of rendering the GanttChart to an image.
+ * <p>
+ * There are some configuration parameters that have impact on:
+ * <ul>
+ * <li>The horizontal range to print - If everything should be printed, by default the range
+ * from the earliest event start date to the latest event end date (plus possible text)
+ * is used. But configuring a period in the ISettings will also take these values into
+ * account for calculating the horizontal range.</li>
+ * <li>The vertical range to print - If only the selected part should be printed, by default
+ * selection means the visible part of the chart horizontally and vertically. This behavior
+ * can be modified so that horizontally only the visible part of the chart will be printed
+ * but vertically the whole chart gets printed.</li>
+ * <li>The name of the print job</li>
+ * <li>Whether a footer should be printed or not</li>
+ * <li>The name of the page (can be used for localization)</li>
+ * <li>The format of the date in the footer</li>
+ * </ul>
+ *
+ * @see ISettings#getPeriodStart()
+ * @see ISettings#getPeriodEnd()
+ * @see ISettings#printSelectedVerticallyComplete()
+ * @see ISettings#printFooter()
+ * @see ISettings#getDateFormat()
+ * @see ILanguageManager#getPrintJobText()
+ * @see ILanguageManager#getPrintPageText()
+ */
+public class GanttChartPrinter {
+
+ private final GanttChart ganttChart;
+
+ /**
+ * Creates a new GanttChartPrinter for the given GanttChart.
+ * @param ganttChart The GanttChart that should be printed by this GanttChartPrinter.
+ */
+ public GanttChartPrinter(GanttChart ganttChart) {
+ this.ganttChart = ganttChart;
+ }
+
+ /**
+ * First opens the PrintDialog so a user can adjust his print settings and will
+ * then print the chart based on the settings made by the user.
+ */
+ public void print() {
+ final Printer printer = setupPrinter(this.ganttChart.getShell());
+ if (printer == null) {
+ return;
+ }
+
+ Display.getDefault().asyncExec(new GanttChartPrintJob(
+ printer, ganttChart.getLanguageManger().getPrintJobText(), ganttChart));
+ }
+
+ /**
+ * Opens the PrintDialog to let the user specify the printer and print configurations to use.
+ * @param shell The Shell which should be the parent for the PrintDialog
+ * @return The selected printer with the print configuration made by the user.
+ */
+ protected Printer setupPrinter(final Shell shell) {
+ //Calculate the number of pages by using the full image
+ //This is because on setup we want to show how many pages the full print would be
+ Printer defaultPrinter = new Printer();
+ Point pageCount = getFullPageCount(defaultPrinter);
+ defaultPrinter.dispose();
+
+ final PrintDialog printDialog = new PrintDialog(shell);
+
+ PrinterData data = new PrinterData();
+ data.orientation = PrinterData.LANDSCAPE;
+ data.startPage = 1;
+ data.endPage = pageCount.x * pageCount.y;
+ data.scope = PrinterData.ALL_PAGES;
+ printDialog.setPrinterData(data);
+
+ PrinterData printerData = printDialog.open();
+ if (printerData == null){
+ return null;
+ }
+ return new Printer(printerData);
+ }
+
+ /**
+ * Calculates the number of horizontal and vertical pages needed to print the entire chart.
+ * @param printer The printer that is used to determine the page count of a full print.
+ * @return The number of horizontal and vertical pages that will be printed.
+ */
+ protected Point getFullPageCount(Printer printer) {
+ Image chartImage = this.ganttChart.getGanttComposite().getFullImage();
+ Point result = PrintUtils.getPageCount(printer, chartImage);
+ chartImage.dispose();
+ return result;
+ }
+}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java
new file mode 100644
index 0000000..6c5add7
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/print/PrintUtils.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth and others.
+ * 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart.print;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.printing.Printer;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Helper class for computations regarding printing of GanttCharts.
+ */
+public class PrintUtils {
+
+ /**
+ * The height of the footer on a print page.
+ */
+ public static final int FOOTER_HEIGHT_IN_PRINTER_DPI = 200;
+
+ /**
+ * Computes the print area, including margins
+ * @param printer The printer that will be used to print the chart
+ * @return The print area
+ */
+ public static Rectangle computePrintArea(Printer printer) {
+ // Get the printable area
+ Rectangle rect = printer.getClientArea();
+
+ // Compute the trim
+ Rectangle trim = printer.computeTrim(0, 0, 0, 0);
+
+ // Get the printer's DPI
+ Point dpi = printer.getDPI();
+ dpi.x = dpi.x / 2;
+ dpi.y = dpi.y / 2;
+
+ // Calculate the printable area, using 1 inch margins
+ int left = trim.x + dpi.x;
+ if (left < rect.x) left = rect.x;
+
+ int right = (rect.width + trim.x + trim.width) - dpi.x;
+ if (right > rect.width) right = rect.width;
+
+ int top = trim.y + dpi.y;
+ if (top < rect.y) top = rect.y;
+
+ int bottom = (rect.height + trim.y + trim.height) - dpi.y;
+ if (bottom > rect.height) bottom = rect.height;
+
+ return new Rectangle(left, top, right - left, bottom - top);
+ }
+
+ /**
+ *
+ * @param printer The printer that will be used to print the chart
+ * @return Amount to scale the screen resolution by, to match the printer
+ * resolution.
+ */
+ public static Point computeScaleFactor(Printer printer) {
+ Point screenDPI = Display.getDefault().getDPI();
+ Point printerDPI = printer.getDPI();
+
+ int scaleFactorX = printerDPI.x / screenDPI.x;
+ int scaleFactorY = printerDPI.y / screenDPI.y;
+ return new Point(scaleFactorX, scaleFactorY);
+ }
+
+ /**
+ * Calculate number of horizontal and vertical pages needed
+ * to print the given image of the chart.
+ * @param printer The printer that will be used to print the chart
+ * @param image The image of the chart that should be printed.
+ * @return The number of horizontal and vertical pages that will be
+ * printed.
+ */
+ public static Point getPageCount(Printer printer, Image image){
+ Rectangle ganttArea = getVisibleGanttChartArea(image);
+ Rectangle printArea = PrintUtils.computePrintArea(printer);
+ Point scaleFactor = PrintUtils.computeScaleFactor(printer);
+
+ int numOfHorizontalPages = ganttArea.width / (printArea.width / scaleFactor.x);
+ int numOfVerticalPages = ganttArea.height / (printArea.height / scaleFactor.y);
+
+ // Adjusting for 0 index
+ return new Point(numOfHorizontalPages + 1, numOfVerticalPages + 1);
+ }
+
+ /**
+ *
+ * @param image The image of the chart that should be printed.
+ * @return The size of the image representation of the chart that
+ * should be printed.
+ */
+ public static Rectangle getVisibleGanttChartArea(Image image) {
+ return new Rectangle(0, 0, image.getImageData().width, image.getImageData().height);
+ }
+
+}