|
/*
de.kupzog.ktools.kprint* Version 1.1
_______________________________________________________________________
This is the source of a print layout package for Java SWT applications.
The features in short terms:
- creating well layouted printed documents by putting image and text
boxes on a document
- printing swt tables and ktables (see de.kupzog.ktable) within this framework
- a page setup dialog (sorry, only in german)
- a print preview dialog (sorry, also only in german)
For a detailed function description refer to the api documentation that
is included in the sourcefiles. For examples how to use KPrint, see the
de.kupzog.ktools.kprint.example package.
Known problems:
_______________________________________________________________________
- Oversized images and tables will be printed over the margins
(but not over the page border)
- No bold/italic words within other words in a text box available
(only the complete box can be bold)
- The Print Preview can differ from the printed document (slightly
different page breakes). This is because the space occupied by text
changes with the font resolution. You can observe this phenomenon
also in some cases by changing the preview size.
The author welcomes any feedback: fkmk@kupzog.de
*/
/* Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author: Friederich Kupzog
fkmk@kupzog.de
www.kupzog.de/fkmk
*/
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
/**
* This example shows how to print data from a KTableModel. More information
* about this can be found in the text that is produced by KPrintExample.java.
*
* @author Friederich Kupzog
*
*/
public class PrintKTableExample {
private Display d;
public PrintKTableExample() {
d = new Display();
// create a document with default settings from PageSetup
PDocument doc = new PDocument("KTable printing example");
// put some header text on it
PTextBox t;
t = new PTextBox(doc);
t.setText("KTABLE PRINTING EXAMPLE");
new PVSpace(doc, 0.1);
new PHLine(doc, 0.02, SWT.COLOR_BLACK);
new PVSpace(doc, 0.5);
// create the table
PTable table = new PTable(doc);
table.setModel(new ExampleTableModel());
table.setBoxProvider(new PTableBoxProvider());
PrintPreview pr = new PrintPreview(null, "Test", IconSource
.getImage("print"), doc);
pr.open();
d.dispose();
}
/**
* This function would print the document witout the print preview.
*
* @param doc
*/
public void print(PDocument doc) {
PrintDialog dialog = new PrintDialog(null, SWT.BORDER);
PrinterData data = dialog.open();
if (data == null)
return;
if (data.printToFile) {
data.fileName = "print.out"; // you probably want to ask the user
// for a filename
}
Printer printer = new Printer(data);
GC gc = new GC(printer);
PBox.setParameters(gc, printer, printer.getDPI(), 100);
if (printer.startJob("DoSys Druckauftrag")) {
printer.startPage();
doc.layout();
doc.draw(1);
printer.endJob();
}
gc.dispose();
}
public static void main(String[] args) {
new PrintKTableExample();
}
}
/*
* Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Friederich Kupzog fkmk@kupzog.de www.kupzog.de/fkmk
*/
/*
* This feature was contributed by Onsel Armagan, Istanbul, Turkey Thanks a lot!
*/
class SWTPTable {
protected Table table;
protected PTableBoxProvider boxProvider;
protected PContainer parent;
public SWTPTable(PContainer parent) {
this.parent = parent;
}
protected void fillDocument() {
boolean abgeschnitten = false;
calculatePageLengths();
// Zeilen
/**
* TODO Print Table Header if (j == 0) style = PBox.POS_BELOW |
* PBox.ROW_ALIGN;
*/
double width = parent.getPossibleWidth();
for (int j = 0; j < table.getColumnCount(); j++) {
// System.out.println(" Zeile "+j);
int height = table.getHeaderHeight();
int style = PBox.POS_RIGHT | PBox.ROW_ALIGN;
if (j == 0)
style = PBox.POS_BELOW | PBox.ROW_ALIGN;
PBox box = boxProvider.createBox(parent, style, j, 0, table
.getColumn(j).getWidth(), height, true, table.getColumn(j)
.getText());
double boxWidth = Math.max(box.minCm, parent.getPossibleWidth()
* box.hWeight);
width -= boxWidth;
if (width < 0) {
box.dispose();
abgeschnitten = true;
break;
}
}
for (int i = 0; i < table.getItemCount(); i++) {
// System.out.println("Spalte "+i);
int height = table.getItemHeight();
width = parent.getPossibleWidth();
// Spalten
for (int j = 0; j < table.getColumnCount(); j++) {
// System.out.println(" Zeile "+j);
int style = PBox.POS_RIGHT | PBox.ROW_ALIGN;
if (j == 0)
style = PBox.POS_BELOW | PBox.ROW_ALIGN;
PBox box = boxProvider.createBox(parent, style, j, i, table
.getColumn(j).getWidth(), height, false, table.getItem(
i).getText(j));
double boxWidth = Math.max(box.minCm, parent.getPossibleWidth()
* box.hWeight);
width -= boxWidth;
if (width < 0) {
box.dispose();
abgeschnitten = true;
break;
}
}
}
if (abgeschnitten)
MsgBox.show("Tabelle ist zu breit fur die Seite\n"
+ "und wird deshalb abgeschnitten.");
}
public void calculatePageLengths() {
if (table != null) {
PDocument doc = (PDocument) parent;
double width = parent.getPossibleWidth();
for (int j = 0; j < table.getColumnCount(); j++) {
// System.out.println(" Zeile "+j);
int height = table.getHeaderHeight();
double boxWidth = Math.max(0,
table.getColumn(j).getWidth() * 0.03);
width -= boxWidth;
if (width < 0) {
break;
}
}
if (width < 0) {
doc.setPageHeight(PageSetup.paperWidth);
doc.setPageWidth(PageSetup.paperHeight);
}
}
}
/**
* @return PTableBoxProvider
*/
public PTableBoxProvider getBoxProvider() {
return boxProvider;
}
/**
* @return KTableModel
*/
public Table getTable() {
return table;
}
/**
* Sets the boxProvider.
*
* @param boxProvider
* The boxProvider to set
*/
public void setBoxProvider(PTableBoxProvider boxProvider) {
this.boxProvider = boxProvider;
if (this.boxProvider != null && this.table != null) {
fillDocument();
}
}
/**
* Sets the table.
*
* @param table
* The table to set
*/
public void setTable(Table table) {
this.table = table;
if (this.boxProvider != null && this.table != null) {
fillDocument();
}
}
}
/*
* Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Friederich Kupzog fkmk@kupzog.de www.kupzog.de/fkmk
*/
/**
* Vertical whitspace.
*
* @author Friederich Kupzog
*/
class PVSpace extends PBox {
private double cm;
/**
* Creates a new Space
*/
public PVSpace(PContainer parent, double cm) {
super(parent);
this.cm = cm;
// getBoxStyle().backColor = SWT.COLOR_CYAN;
}
/*
* overridden from superclass
*/
protected int getWidth() {
// return 1;
return 0;
}
/*
* overridden from superclass
*/
protected int getHeight() {
if (forcedHeight > 0)
return forcedHeight;
return PBox.pixelY(cm);
}
}
/*
* Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Friederich Kupzog fkmk@kupzog.de www.kupzog.de/fkmk
*/
/**
* A style for printable objects that that contain text.
*
* @author Friederich Kupzog
*/
class PTextStyle {
public static final int ALIGN_LEFT = 1;
public static final int ALIGN_RIGHT = 2;
public static final int ALIGN_CENTER = 3;
protected static HashMap fonts = new HashMap();
public int fontSize;
public String fontName;
public int fontStyle;
public int fontColor;
public int textAlign;
protected double marginLeft;
protected double marginRight;
protected double marginTop;
protected double marginBottom;
public PTextStyle() {
fontName = "Arial";
fontStyle = SWT.NORMAL;
fontSize = 10;
fontColor = SWT.COLOR_BLACK;
textAlign = ALIGN_LEFT;
marginLeft = 0.0;
marginRight = 0.0;
marginTop = 0.0;
marginBottom = 0.0;
}
public static void disposeFonts() {
for (Iterator iter = fonts.values().iterator(); iter.hasNext();) {
Font element = (Font) iter.next();
element.dispose();
}
fonts.clear();
}
public static PTextStyle getDefaultStyle() {
return new PTextStyle();
}
public Font getFont() {
int height = Math.abs(fontSize * PBox.scalingPercent / 100);
String key = PBox.device.getDPI().x + "|" + PBox.device.getDPI().y
+ "|" + fontName + "|" + height + "|" + fontStyle;
Font font = (Font) fonts.get(key);
if (font != null)
return font;
font = new Font(PBox.device, fontName, Math.abs(fontSize
* PBox.scalingPercent / 100), fontStyle);
fonts.put(key, font);
return font;
}
public Color getFontColor() {
return PBox.device.getSystemColor(fontColor);
}
/**
* @return double
*/
public double getMarginLeft() {
return marginLeft;
}
/**
* @return double
*/
public double getMarginRight() {
return marginRight;
}
/**
* Sets the marginLeft.
*
* @param marginLeft
* The marginLeft to set
*/
public void setMarginLeft(double marginLeft) {
this.marginLeft = marginLeft;
}
/**
* Sets the marginRight.
*
* @param marginRight
* The marginRight to set
*/
public void setMarginRight(double marginRight) {
this.marginRight = marginRight;
}
/**
* @return double
*/
public double getMarginBottom() {
return marginBottom;
}
/**
* @return double
*/
public double getMarginTop() {
return marginTop;
}
/**
* Sets the marginBottom.
*
* @param marginBottom
* The marginBottom to set
*/
public void setMarginBottom(double marginBottom) {
this.marginBottom = marginBottom;
}
/**
* Sets the marginTop.
*
* @param marginTop
* The marginTop to set
*/
public void setMarginTop(double marginTop) {
this.marginTop = marginTop;
}
}
/*
* Copyright (C) 2004 by Friederich Kupzog Elektronik & Software
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Friederich Kupzog fkmk@kupzog.de www.kupzog.de/fkmk
*/
/**
* A printable text label that can occupy more than one page. If you are shure
* that the box will not be bigger than one page, you can use PLittleTextBox to
* make the layout process quicker.
*
* @author Friederich Kupzog For more details
* @see PDocument and
* @see PBox
*/
class PTextBox extends PBox {
protected String text;
protected PTextStyle textStyle;
// multi-page
protected ArrayList pageList;
protected ArrayList textLines;
protected int unplacedLines;
/**
* Creates a non-wrapping text box with a fixed size according to its text.
*
* @param parent
* @param style
*/
public PTextBox(PContainer parent) {
super(parent);
init();
}
/**
* Creates a non-wrapping text box with a fixed size according to its text.
*
* @param parent
* @param style
*/
public PTextBox(PContainer parent, int style) {
super(parent, style);
init();
}
/**
* Creates a text box with wrapping capabilities if hWeight is > 0.
*
* @param parent
* @param style
* @param hWeight
* Specify -1 for a non-wrapping text box (If the text has
* newlines it will be a multi-line textbox). Spezify a number
* between 0 and 1 for a multiline textbox that consumes the
* given fraction of the available document width.
* @param minWidth
* This allows you to specify a minimum width for the text. The
* text box will consume some space depending to hWeight or its
* text if hWeight is -1, but at least the given amount of
* centimeters. For a box with a fixed width for example set
* hWeigth = 0 and specify a non-zero minWidth.
*/
public PTextBox(PContainer parent, int style, double hWeight,
double minWidth) {
super(parent, style, hWeight, minWidth);
init();
}
private void init() {
text = "";
textStyle = PTextStyle.getDefaultStyle();
pageList = new ArrayList();
textLines = new ArrayList();
unplacedLines = 0;
}
public void setText(String text) {
if (text == null)
text = "";
this.text = text;
}
protected int layoutHowMuchWouldYouOccupyOf(Point spaceLeft, int page) {
if (textLines.size() == 0)
splitIntoLines();
if (unplacedLines == 0)
return 0;
gc.setFont(textStyle.getFont());
int lineHeight = gc.stringExtent("A").y;
// System.out.println("LineH: "+lineHeight+" Space: "+spaceLeft.y);
int erg = 0;
int ctr = 0;
do {
erg += lineHeight;
ctr++;
if (ctr == unplacedLines)
break;
} while (erg + lineHeight <= spaceLeft.y);
if (erg > spaceLeft.y)
return -1;
return erg;
}
/*
* overridden from superclass
*/
protected boolean layoutWouldYouFinishWithin(Point spaceLeft, int page) {
gc.setFont(textStyle.getFont());
int lineHeight = gc.stringExtent("A").y;
return ((unplacedLines * lineHeight) <= spaceLeft.y);
}
/*
* overridden from superclass
*/
protected int layoutOccupy(Point origin, Point spaceLeft, int page) {
if (textLines.size() == 0)
splitIntoLines();
if (unplacedLines == 0)
return 0;
if (this.origin.page == 0) {
this.origin.page = page;
this.origin.x = origin.x;
this.origin.y = origin.y;
}
gc.setFont(textStyle.getFont());
int lineHeight = gc.stringExtent("A").y;
int erg = 0;
int ctr = 0;
do {
erg += lineHeight;
ctr++;
if (ctr == unplacedLines)
break;
} while (erg + lineHeight <= spaceLeft.y);
if (erg > spaceLeft.y)
return 0;
PTextPart part = new PTextPart();
part.numOfLines = ctr;
part.origin = new Point(origin.x, origin.y);
part.startLine = textLines.size() - unplacedLines;
pageList.add(part);
unplacedLines -= ctr;
return erg;
}
/*
* overridden from superclass
*/
protected boolean layoutIsOnPage(int page) {
if (page >= origin.page && page < origin.page + pageList.size())
return true;
return false;
}
/*
* overridden from superclass
*/
protected int getWidth() {
if
|