From 86c6fb6a0cbe093b78c476d59d3d192561ba4e97 Mon Sep 17 00:00:00 2001 From: Jonatan Liljedahl Date: Sat, 3 Dec 2011 18:22:34 +0100 Subject: [PATCH] Add QPen printing support (and PDF export) with new QPenPrinter class. QPenPrinter-showDialog(okFunc,cancelFunc) shows a print dialog to configure the printer and calls okFunc when user presses "print". QPenPrinter-print(drawFunc) calls drawFunc where QPen operates on the configured printer. All the normal Pen methods can be used inside drawFunc. --- HelpSource/Classes/QPenPrinter.schelp | 125 +++++++++++++++++++++++++++++++ QtCollider/CMakeLists.txt | 2 + QtCollider/widgets/QcPenPrinter.cpp | 31 ++++++++ QtCollider/widgets/QcPenPrinter.h | 97 ++++++++++++++++++++++++ SCClassLibrary/QtCollider/QPenPrinter.sc | 45 +++++++++++ 5 files changed, 300 insertions(+) create mode 100644 HelpSource/Classes/QPenPrinter.schelp create mode 100644 QtCollider/widgets/QcPenPrinter.cpp create mode 100644 QtCollider/widgets/QcPenPrinter.h create mode 100644 SCClassLibrary/QtCollider/QPenPrinter.sc diff --git a/HelpSource/Classes/QPenPrinter.schelp b/HelpSource/Classes/QPenPrinter.schelp new file mode 100644 index 000000000..f386e5d2d --- /dev/null +++ b/HelpSource/Classes/QPenPrinter.schelp @@ -0,0 +1,125 @@ +CLASS:: QPenPrinter +summary:: QPen PDF export and printing of vector graphics +categories:: GUI>Printing +related:: Classes/QPen, Classes/Pen + +DESCRIPTION:: +QPenPrinter allows QPen to operate on a printer device. The graphics can be exported to PDF by using "print to file" as printer device. + +note:: +Due to implementation details of QObject, and the fact that a QPenPrinter object is not a child of another QObject, you should destroy +the object manually when done with it: code::penPrinter.destroy;:: +:: + +CLASSMETHODS:: +private:: qtClass + + +METHOD:: new +Create a new QPenPrinter object. + +returns:: an instance of QPenPrinter + +INSTANCEMETHODS:: +private:: init + +subsection:: Printing + +METHOD:: showDialog +Shows a Print Dialog to allow the user to configure the printer object. This is asynchronous and the method will return immediately. +When the user presses the "Print" button, strong::aOkFunc:: is called with this QPenPrinter object as argument. + +argument:: aOkFunc +A link::Classes/Function:: to be evaluated when the user presses "Print". + +argument:: aCancelFunc +A link::Classes/Function:: to be evaluated if the user presses "Cancel". + + +METHOD:: print +This method does the actual printing or PDF export. It evaluates strong::aPrintFunc:: with the printer object as QPen painter target. This QPenPrinter object is passed as the argument. + +All the ordinary link::Classes/QPen:: commands can be used inside the function. + +argument:: aPrintFunc +A link::Classes/Function:: to be evaluated to draw the graphics. + +discussion:: +If this method is called without configuring the printer object first, it will print on the default printer with default settings. + +This method is typically called from within the strong::aOkFunc:: of link::#-showDialog:: above. After showDialog has configured the printer once, this method can be called multiple times to reuse the last printer configuration. + +The point at (0@0) will coincide with the origin of link::#-pageRect::, which is offset by the page margins. So you don't need to translate the Pen. + + +METHOD:: newPage +Starts a new page. Typically called within the strong::aPrintFunc:: of link::#-print::. + + +subsection:: Properties + +METHOD:: paperRect +Get the paper bounds. + +returns:: a link::Classes/Rect:: + + +METHOD:: pageRect +Get the page bounds, which is the printable area and usually smaller than link::#-paperRect:: due to margins. + +returns:: a link::Classes/Rect:: + +discussion:: +The strong::origin:: of the Rect is relative to the paper, and will be non-zero due to margins. + + +METHOD:: pageSize +Get the page size as a Size. + +returns:: a link::Classes/Size:: + +discussion:: +This can be used to scale the graphics to fit the page if the bounds of the graphics is known: +code:: +x = penPrinter.pageSize.width / bounds.width; +Pen.scale(x,x); +// ... draw stuff here ... +:: + +subsection:: Page range +The methods below returns the page range selected by the user. Page number starts at 1. When both methods returns 0 it means "print all pages". + +METHOD:: fromPage +Get the start page. + +returns:: an link::Classes/Integer:: + +METHOD:: toPage +Get the end page. + +returns:: an link::Classes/Integer:: + + + +EXAMPLES:: + +Basic usage: +code:: +p = QPenPrinter(); +p.showDialog { + p.print { + // first page + Pen.moveTo(100@100); + Pen.lineTo(300@300); + Pen.stroke; + + // second page + p.newPage; + Pen.addRect((0@0) @ p.pageSize); + Pen.stroke; + } +} { + "Printing cancelled!".postln; +}; +:: + diff --git a/QtCollider/CMakeLists.txt b/QtCollider/CMakeLists.txt index 968cdcf33..4ac06419d 100644 --- a/QtCollider/CMakeLists.txt +++ b/QtCollider/CMakeLists.txt @@ -31,6 +31,7 @@ set( QT_COLLIDER_HDRS ${QT_COLLIDER_DIR}/widgets/QcCanvas.h ${QT_COLLIDER_DIR}/widgets/QcSoundFileView.h ${QT_COLLIDER_DIR}/widgets/QcFileDialog.h + ${QT_COLLIDER_DIR}/widgets/QcPenPrinter.h ${QT_COLLIDER_DIR}/widgets/QcWebView.h ${QT_COLLIDER_DIR}/widgets/QcWindow.h ${QT_COLLIDER_DIR}/layouts/layouts.hpp @@ -68,6 +69,7 @@ set( QT_COLLIDER_SRCS ${QT_COLLIDER_DIR}/widgets/QcCanvas.cpp ${QT_COLLIDER_DIR}/widgets/QcSoundFileView.cpp ${QT_COLLIDER_DIR}/widgets/QcFileDialog.cpp + ${QT_COLLIDER_DIR}/widgets/QcPenPrinter.cpp ${QT_COLLIDER_DIR}/widgets/QcWebView.cpp ${QT_COLLIDER_DIR}/layouts/classic_layouts.cpp ${QT_COLLIDER_DIR}/layouts/layouts.cpp diff --git a/QtCollider/widgets/QcPenPrinter.cpp b/QtCollider/widgets/QcPenPrinter.cpp new file mode 100644 index 000000000..75c9d7ca3 --- /dev/null +++ b/QtCollider/widgets/QcPenPrinter.cpp @@ -0,0 +1,31 @@ +/************************************************************************ +* +* Copyright 2011 Jonatan Liljedahl +* +* This file is part of SuperCollider Qt GUI. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +************************************************************************/ + +#include "QcPenPrinter.h" +#include "../QcObjectFactory.h" + +class PenPrinterFactory : public QcObjectFactory +{ + void initialize( QObjectProxy *, QcPenPrinter *penPrinter, QList & args ) { + } +}; + +static PenPrinterFactory penPrinterFactory; diff --git a/QtCollider/widgets/QcPenPrinter.h b/QtCollider/widgets/QcPenPrinter.h new file mode 100644 index 000000000..1ba03e06e --- /dev/null +++ b/QtCollider/widgets/QcPenPrinter.h @@ -0,0 +1,97 @@ +/************************************************************************ +* +* Copyright 2011 Jonatan Liljedahl +* +* This file is part of SuperCollider Qt GUI. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +************************************************************************/ + +#ifndef QC_PEN_PRINTER_H +#define QC_PEN_PRINTER_H + +#include "../painting.h" +#include +#include +#include + +#include + +class QcPenPrinter : public QObject +{ + Q_OBJECT + Q_PROPERTY( QRect pageRect READ pageRect ); + Q_PROPERTY( QRect paperRect READ paperRect ); + Q_PROPERTY( int fromPage READ fromPage ); + Q_PROPERTY( int toPage READ toPage ); + +public: + + QcPenPrinter() { + } + + ~QcPenPrinter() { + } + + QRect pageRect() const { return printer.pageRect(); } + QRect paperRect() const { return printer.paperRect(); } + int fromPage() const { return printer.fromPage(); } + int toPage() const { return printer.toPage(); } + +Q_SIGNALS: + + void ok(); + void cancel(); + void printFunc(); + +private Q_SLOTS: + + void show() { + QPrintDialog *dialog = new QPrintDialog(&printer); + + dialog->setWindowTitle( QString("Print Document") ); + dialog->setOptions ( + QAbstractPrintDialog::PrintToFile | + QAbstractPrintDialog::PrintPageRange | + QAbstractPrintDialog::PrintShowPageSize + ); + if (dialog->exec() != QDialog::Accepted) { + Q_EMIT( cancel() ); + } else { + Q_EMIT( ok() ); + } + delete dialog; + } + + void print() { + QPainter painter; + painter.begin(&printer); + QtCollider::beginPainting(&painter); + Q_EMIT ( printFunc() ); + painter.end(); + QtCollider::endPainting(); + } + + void newPage() { + printer.newPage(); + } + +private: + + QPrinter printer; + +}; + +#endif // QC_PEN_PRINTER_H diff --git a/SCClassLibrary/QtCollider/QPenPrinter.sc b/SCClassLibrary/QtCollider/QPenPrinter.sc new file mode 100644 index 000000000..74b045d32 --- /dev/null +++ b/SCClassLibrary/QtCollider/QPenPrinter.sc @@ -0,0 +1,45 @@ +QPenPrinter : QObject { + var printFunc, cancelFunc, okFunc; + + *qtClass { ^'QcPenPrinter' } + + *new { + ^super.new.init; + } + + init { + this.connectFunction('printFunc()', synchronous:true) { + printFunc.value(this); + printFunc = nil; + }; + this.connectFunction('ok()', synchronous:false) { + okFunc.value(this); + okFunc = nil; + }; + this.connectFunction('cancel()', synchronous:false) { + cancelFunc.value(this); + cancelFunc = nil; + }; + } + + showDialog { |aOkFunc, aCancelFunc| + okFunc = aOkFunc; + cancelFunc = aCancelFunc; + this.invokeMethod(\show, synchronous:false); + } + + print { |aPrintFunc| + printFunc = aPrintFunc; + this.invokeMethod(\print, synchronous:false); + } + + newPage { + this.invokeMethod(\newPage, synchronous:true); + } + + pageRect { ^this.getProperty(\pageRect) } + paperRect { ^this.getProperty(\paperRect) } + fromPage { ^this.getProperty(\fromPage) } + toPage { ^this.getProperty(\toPage) } + pageSize { ^this.pageRect.size } +} -- 2.11.4.GIT