summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basegfx/inc/basegfx/matrix/b2dhommatrix.hxx10
-rw-r--r--basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx205
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolygontools.hxx61
-rw-r--r--basegfx/source/matrix/b2dhommatrix.cxx174
-rw-r--r--basegfx/source/matrix/b2dhommatrixtools.cxx333
-rw-r--r--basegfx/source/polygon/b2dlinegeometry.cxx9
-rw-r--r--basegfx/source/polygon/b2dpolygonclipper.cxx7
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx311
-rw-r--r--basegfx/source/polygon/b2dsvgpolypolygon.cxx6
-rw-r--r--basegfx/source/tools/gradienttools.cxx17
-rwxr-xr-xbasegfx/source/tools/unopolypolygon.cxx6
-rw-r--r--basegfx/test/basegfx2d.cxx7
-rw-r--r--canvas/source/cairo/cairo_canvashelper.cxx53
-rw-r--r--canvas/source/cairo/cairo_canvashelper.hxx1
-rwxr-xr-xcanvas/source/directx/dx_canvashelper.cxx24
-rwxr-xr-xcanvas/source/directx/dx_canvashelper_texturefill.cxx4
-rwxr-xr-xcanvas/source/directx/dx_impltools.cxx67
-rwxr-xr-xcanvas/source/directx/dx_impltools.hxx15
-rwxr-xr-xcanvas/source/directx/dx_linepolypolygon.cxx4
-rwxr-xr-xcanvas/source/directx/dx_linepolypolygon.hxx2
-rw-r--r--canvas/source/simplecanvas/simplecanvasimpl.cxx11
-rw-r--r--canvas/source/tools/canvastools.cxx11
-rw-r--r--canvas/source/tools/surface.cxx11
-rw-r--r--comphelper/source/property/opropertybag.cxx9
-rw-r--r--comphelper/source/property/property.cxx25
-rw-r--r--cppcanvas/source/mtfrenderer/bitmapaction.cxx19
-rw-r--r--cppcanvas/source/mtfrenderer/implrenderer.cxx46
-rw-r--r--cppcanvas/source/mtfrenderer/mtftools.cxx11
-rw-r--r--cppcanvas/source/mtfrenderer/textaction.cxx5
-rw-r--r--goodies/inc/grfmgr.hxx2
-rw-r--r--goodies/source/filter.vcl/epict/epict.cxx120
-rw-r--r--goodies/source/filter.vcl/epict/makefile.mk2
-rw-r--r--goodies/source/filter.vcl/eps/eps.cxx61
-rw-r--r--goodies/source/filter.vcl/ieps/ieps.cxx68
-rw-r--r--goodies/source/filter.vcl/ios2met/ios2met.cxx2
-rw-r--r--goodies/source/graphic/grfmgr.cxx4
-rw-r--r--padmin/source/padialog.cxx149
-rw-r--r--padmin/source/padialog.hxx2
-rw-r--r--rsc/source/parser/rscicpx.cxx1
-rw-r--r--rsc/source/parser/rsclex.cxx2
-rw-r--r--rsc/source/parser/rsclex.hxx2
-rw-r--r--rsc/source/rsc/makefile.mk4
-rw-r--r--sot/source/sdstor/stgstrms.cxx2
-rw-r--r--sot/source/sdstor/stgstrms.hxx3
-rw-r--r--svl/inc/svl/solar.hrc11
-rw-r--r--svl/inc/svl/svarray.hxx2
-rw-r--r--svl/source/numbers/numhead.cxx2
-rw-r--r--svtools/inc/svtools/imapobj.hxx2
-rw-r--r--svtools/source/control/filectrl.cxx3
-rw-r--r--svtools/source/dialogs/prnsetup.cxx2
-rw-r--r--svtools/source/filter.vcl/filter/filter2.cxx3
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.cxx94
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.hxx4
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.cxx84
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.hxx4
-rw-r--r--svtools/source/misc/imap.cxx7
-rw-r--r--svtools/source/uno/unoiface.cxx80
-rw-r--r--svtools/util/makefile.mk1
-rw-r--r--toolkit/inc/toolkit/awt/vclxprinter.hxx15
-rw-r--r--toolkit/source/awt/vclxprinter.cxx36
-rw-r--r--toolkit/source/awt/vclxwindows.cxx6
-rw-r--r--toolkit/source/controls/formattedcontrol.cxx1
-rw-r--r--toolkit/source/controls/unocontrols.cxx2
-rw-r--r--tools/inc/tools/inetdef.hxx2
-rw-r--r--tools/inc/tools/multisel.hxx104
-rw-r--r--tools/inc/tools/solar.h2
-rw-r--r--tools/inc/tools/stream.hxx5
-rw-r--r--tools/source/fsys/unx.cxx2
-rw-r--r--tools/source/fsys/urlobj.cxx18
-rw-r--r--tools/source/generic/poly.cxx11
-rw-r--r--tools/source/memtools/makefile.mk2
-rw-r--r--tools/source/memtools/multisel.cxx298
-rw-r--r--tools/workben/urltest.cxx14
-rw-r--r--transex3/source/inireader.cxx2
-rw-r--r--unotools/inc/unotools/confignode.hxx3
-rw-r--r--unotools/source/config/confignode.cxx23
-rwxr-xr-xvcl/aqua/inc/aquaprintview.h26
-rw-r--r--vcl/aqua/inc/salgdi.h3
-rw-r--r--vcl/aqua/inc/salprn.h41
-rw-r--r--vcl/aqua/source/gdi/aquaprintaccessoryview.mm1237
-rwxr-xr-xvcl/aqua/source/gdi/aquaprintview.mm11
-rw-r--r--vcl/aqua/source/gdi/makefile.mk1
-rw-r--r--vcl/aqua/source/gdi/salgdi.cxx17
-rwxr-xr-xvcl/aqua/source/gdi/salgdiutils.cxx35
-rw-r--r--vcl/aqua/source/gdi/salprn.cxx320
-rw-r--r--vcl/inc/vcl/arrange.hxx425
-rw-r--r--vcl/inc/vcl/button.hxx16
-rw-r--r--vcl/inc/vcl/configsettings.hxx3
-rw-r--r--vcl/inc/vcl/cvtsvm.hxx4
-rw-r--r--vcl/inc/vcl/edit.hxx1
-rw-r--r--vcl/inc/vcl/fixed.hxx1
-rw-r--r--vcl/inc/vcl/gdimtf.hxx1
-rw-r--r--vcl/inc/vcl/impprn.hxx3
-rw-r--r--vcl/inc/vcl/jobdata.hxx2
-rw-r--r--vcl/inc/vcl/jobset.h13
-rw-r--r--vcl/inc/vcl/lineinfo.hxx37
-rw-r--r--vcl/inc/vcl/lstbox.h5
-rw-r--r--vcl/inc/vcl/menu.hxx2
-rw-r--r--vcl/inc/vcl/oldprintadaptor.hxx (renamed from vcl/source/gdi/implncvt.hxx)60
-rw-r--r--vcl/inc/vcl/outdev.hxx15
-rw-r--r--vcl/inc/vcl/print.h23
-rw-r--r--vcl/inc/vcl/print.hxx393
-rw-r--r--vcl/inc/vcl/printerjob.hxx2
-rw-r--r--vcl/inc/vcl/prndlg.hxx306
-rw-r--r--vcl/inc/vcl/prntypes.hxx3
-rw-r--r--vcl/inc/vcl/salprn.hxx18
-rw-r--r--vcl/inc/vcl/salptype.hxx6
-rw-r--r--vcl/inc/vcl/svdata.hxx8
-rw-r--r--vcl/inc/vcl/svids.hrc100
-rw-r--r--vcl/inc/vcl/tabctrl.hxx13
-rw-r--r--vcl/inc/vcl/toolbox.hxx3
-rw-r--r--vcl/inc/vcl/virdev.hxx11
-rw-r--r--vcl/inc/vcl/window.h3
-rw-r--r--vcl/os2/inc/salprn.h5
-rw-r--r--vcl/os2/source/gdi/salgdi3.cxx6
-rw-r--r--vcl/os2/source/gdi/salprn.cxx11
-rw-r--r--vcl/prj/build.lst2
-rw-r--r--vcl/prj/d.lst2
-rw-r--r--vcl/source/app/salvtables.cxx4
-rw-r--r--vcl/source/app/svdata.cxx11
-rw-r--r--vcl/source/app/svmain.cxx20
-rw-r--r--vcl/source/control/button.cxx99
-rw-r--r--vcl/source/control/edit.cxx45
-rw-r--r--vcl/source/control/fixed.cxx8
-rw-r--r--vcl/source/control/ilstbox.cxx2
-rw-r--r--vcl/source/control/lstbox.cxx57
-rw-r--r--vcl/source/control/tabctrl.cxx189
-rw-r--r--vcl/source/gdi/bmpconv.cxx3
-rw-r--r--vcl/source/gdi/cvtsvm.cxx354
-rw-r--r--vcl/source/gdi/gdimtf.cxx34
-rw-r--r--vcl/source/gdi/implncvt.cxx577
-rw-r--r--vcl/source/gdi/impprn.cxx2
-rw-r--r--vcl/source/gdi/jobset.cxx26
-rw-r--r--vcl/source/gdi/lineinfo.cxx109
-rw-r--r--[-rwxr-xr-x]vcl/source/gdi/makefile.mk11
-rw-r--r--vcl/source/gdi/metaact.cxx77
-rw-r--r--vcl/source/gdi/oldprintadaptor.cxx117
-rw-r--r--vcl/source/gdi/outdev.cxx284
-rw-r--r--vcl/source/gdi/outdev6.cxx14
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx4
-rw-r--r--vcl/source/gdi/print.cxx484
-rw-r--r--vcl/source/gdi/print2.cxx35
-rw-r--r--vcl/source/gdi/print3.cxx1765
-rw-r--r--vcl/source/gdi/region.cxx9
-rw-r--r--vcl/source/gdi/salgdilayout.cxx1
-rwxr-xr-xvcl/source/gdi/sallayout.cxx7
-rw-r--r--vcl/source/gdi/virdev.cxx29
-rw-r--r--vcl/source/glyphs/gcach_ftyp.cxx5
-rw-r--r--vcl/source/glyphs/glyphcache.cxx2
-rw-r--r--vcl/source/helper/xconnection.cxx36
-rw-r--r--vcl/source/src/images.src20
-rw-r--r--vcl/source/src/makefile.mk5
-rw-r--r--vcl/source/src/print.src495
-rw-r--r--vcl/source/src/stdtext.src7
-rw-r--r--vcl/source/window/arrange.cxx906
-rw-r--r--vcl/source/window/makefile.mk4
-rw-r--r--vcl/source/window/printdlg.cxx2489
-rw-r--r--vcl/source/window/toolbox.cxx26
-rw-r--r--vcl/source/window/window.cxx21
-rw-r--r--vcl/source/window/window2.cxx2
-rw-r--r--vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx13
-rw-r--r--vcl/unx/headless/svpprn.cxx114
-rw-r--r--vcl/unx/headless/svpprn.hxx6
-rw-r--r--vcl/unx/inc/salprn.h6
-rw-r--r--vcl/unx/inc/salunx.h6
-rw-r--r--vcl/unx/source/app/i18n_ic.cxx4
-rw-r--r--vcl/unx/source/app/i18n_im.cxx2
-rw-r--r--vcl/unx/source/app/randrwrapper.cxx8
-rw-r--r--vcl/unx/source/app/saldisp.cxx13
-rw-r--r--vcl/unx/source/app/saltimer.cxx3
-rw-r--r--vcl/unx/source/gdi/salgdi.cxx12
-rw-r--r--vcl/unx/source/gdi/salprnpsp.cxx125
-rw-r--r--vcl/unx/source/plugadapt/salplug.cxx4
-rw-r--r--vcl/unx/source/printer/jobdata.cxx22
-rw-r--r--vcl/unx/source/printer/printerinfomanager.cxx2
-rw-r--r--vcl/unx/source/printergfx/printerjob.cxx45
-rw-r--r--vcl/util/hidother.src34
-rw-r--r--vcl/util/makefile.mk1
-rw-r--r--vcl/win/inc/salprn.h5
-rw-r--r--vcl/win/source/gdi/salgdi3.cxx6
-rw-r--r--vcl/win/source/gdi/salgdi_gdiplus.cxx74
-rw-r--r--vcl/win/source/gdi/salnativewidgets-luna.cxx61
-rw-r--r--vcl/win/source/gdi/salprn.cxx72
183 files changed, 12452 insertions, 2508 deletions
diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrix.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrix.hxx
index c7c79d0cd6e9..10b023c5f68c 100644
--- a/basegfx/inc/basegfx/matrix/b2dhommatrix.hxx
+++ b/basegfx/inc/basegfx/matrix/b2dhommatrix.hxx
@@ -52,12 +52,22 @@ namespace basegfx
B2DHomMatrix(const B2DHomMatrix& rMat);
~B2DHomMatrix();
+ /** constructor to allow setting all needed values for a 3x2 matrix at once. The
+ parameter f_0x1 e.g. is the same as using set(0, 1, f)
+ */
+ B2DHomMatrix(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2);
+
/// unshare this matrix with all internally shared instances
void makeUnique();
double get(sal_uInt16 nRow, sal_uInt16 nColumn) const;
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue);
+ /** allow setting all needed values for a 3x2 matrix in one call. The
+ parameter f_0x1 e.g. is the same as using set(0, 1, f)
+ */
+ void set3x2(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2);
+
// test if last line is default to see if last line needs to be
// involved in calculations
bool isLastLineDefault() const;
diff --git a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
index 0b200b812bed..c90f673a8194 100644
--- a/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
+++ b/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
@@ -40,45 +40,190 @@
namespace basegfx
{
- class DecomposedB2DHomMatrixContainer
+ namespace tools
{
- private:
- B2DHomMatrix maB2DHomMatrix;
- B2DVector maScale;
- B2DVector maTranslate;
- double mfRotate;
- double mfShearX;
+ /** If the rotation angle is an approximate multiple of pi/2,
+ force fSin/fCos to -1/0/1, to maintain orthogonality (which
+ might also be advantageous for the other cases, but: for
+ multiples of pi/2, the exact values _can_ be attained. It
+ would be largely unintuitive, if a 180 degrees rotation
+ would introduce slight roundoff errors, instead of exactly
+ mirroring the coordinate system)
+ */
+ void createSinCosOrthogonal(double& o_rSin, double& rCos, double fRadiant);
- // bitfield
- unsigned mbDecomposed : 1;
+ /** Tooling methods for on-the-fly matrix generation e.g. for inline
+ multiplications
+ */
+ B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY);
+ B2DHomMatrix createShearXB2DHomMatrix(double fShearX);
+ B2DHomMatrix createShearYB2DHomMatrix(double fShearY);
+ B2DHomMatrix createRotateB2DHomMatrix(double fRadiant);
+ B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY);
- void impCheckDecompose()
+ /// inline versions for parameters as tuples
+ inline B2DHomMatrix createScaleB2DHomMatrix(const B2DTuple& rScale)
{
- if(!mbDecomposed)
- {
- maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
- mbDecomposed = true;
- }
+ return createScaleB2DHomMatrix(rScale.getX(), rScale.getY());
+ }
+
+ inline B2DHomMatrix createTranslateB2DHomMatrix(const B2DTuple& rTranslate)
+ {
+ return createTranslateB2DHomMatrix(rTranslate.getX(), rTranslate.getY());
+ }
+
+ /** Tooling methods for faster completely combined matrix creation
+ when scale, shearX, rotation and translation needs to be done in
+ exactly that order. It's faster since it direcly calculates
+ each matrix value based on a symbolic calculation of the three
+ matrix multiplications.
+ Inline versions for parameters as tuples added, too.
+ */
+ B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
+ const B2DTuple& rScale,
+ double fShearX,
+ double fRadiant,
+ const B2DTuple& rTranslate)
+ {
+ return createScaleShearXRotateTranslateB2DHomMatrix(
+ rScale.getX(), rScale.getY(),
+ fShearX,
+ fRadiant,
+ rTranslate.getX(), rTranslate.getY());
+ }
+
+ B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
+ double fShearX,
+ double fRadiant,
+ const B2DTuple& rTranslate)
+ {
+ return createShearXRotateTranslateB2DHomMatrix(
+ fShearX,
+ fRadiant,
+ rTranslate.getX(), rTranslate.getY());
}
- public:
- DecomposedB2DHomMatrixContainer(const B2DHomMatrix& rB2DHomMatrix)
- : maB2DHomMatrix(rB2DHomMatrix),
- maScale(),
- maTranslate(),
- mfRotate(0.0),
- mfShearX(0.0),
- mbDecomposed(false)
+ B2DHomMatrix createScaleTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createScaleTranslateB2DHomMatrix(
+ const B2DTuple& rScale,
+ const B2DTuple& rTranslate)
{
+ return createScaleTranslateB2DHomMatrix(
+ rScale.getX(), rScale.getY(),
+ rTranslate.getX(), rTranslate.getY());
}
- // data access
- const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
- const B2DVector& getScale() const { const_cast< DecomposedB2DHomMatrixContainer* >(this)->impCheckDecompose(); return maScale; }
- const B2DVector& getTranslate() const { const_cast< DecomposedB2DHomMatrixContainer* >(this)->impCheckDecompose(); return maTranslate; }
- double getRotate() const { const_cast< DecomposedB2DHomMatrixContainer* >(this)->impCheckDecompose(); return mfRotate; }
- double getShearX() const { const_cast< DecomposedB2DHomMatrixContainer* >(this)->impCheckDecompose(); return mfShearX; }
- };
+ /// special for the often used case of rotation around a point
+ B2DHomMatrix createRotateAroundPoint(
+ double fPointX, double fPointY,
+ double fRadiant);
+ inline B2DHomMatrix createRotateAroundPoint(
+ const B2DTuple& rPoint,
+ double fRadiant)
+ {
+ return createRotateAroundPoint(
+ rPoint.getX(), rPoint.getY(),
+ fRadiant);
+ }
+ } // end of namespace tools
+} // end of namespace basegfx
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ class B2DHomMatrixBufferedDecompose
+ {
+ private:
+ B2DVector maScale;
+ B2DVector maTranslate;
+ double mfRotate;
+ double mfShearX;
+
+ public:
+ B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ : maScale(),
+ maTranslate(),
+ mfRotate(0.0),
+ mfShearX(0.0)
+ {
+ rB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
+ }
+
+ // data access
+ B2DHomMatrix getB2DHomMatrix() const
+ {
+ return createScaleShearXRotateTranslateB2DHomMatrix(
+ maScale, mfShearX, mfRotate, maTranslate);
+ }
+
+ const B2DVector& getScale() const { return maScale; }
+ const B2DVector& getTranslate() const { return maTranslate; }
+ double getRotate() const { return mfRotate; }
+ double getShearX() const { return mfShearX; }
+ };
+ } // end of namespace tools
+} // end of namespace basegfx
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ class B2DHomMatrixBufferedOnDemandDecompose
+ {
+ private:
+ B2DHomMatrix maB2DHomMatrix;
+ B2DVector maScale;
+ B2DVector maTranslate;
+ double mfRotate;
+ double mfShearX;
+
+ // bitfield
+ unsigned mbDecomposed : 1;
+
+ void impCheckDecompose()
+ {
+ if(!mbDecomposed)
+ {
+ maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
+ mbDecomposed = true;
+ }
+ }
+
+ public:
+ B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix)
+ : maB2DHomMatrix(rB2DHomMatrix),
+ maScale(),
+ maTranslate(),
+ mfRotate(0.0),
+ mfShearX(0.0),
+ mbDecomposed(false)
+ {
+ }
+
+ // data access
+ const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
+ const B2DVector& getScale() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maScale; }
+ const B2DVector& getTranslate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maTranslate; }
+ double getRotate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfRotate; }
+ double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; }
+ };
+ } // end of namespace tools
} // end of namespace basegfx
///////////////////////////////////////////////////////////////////////////////
diff --git a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
index 5eff6b0b9cc1..47ff41b75e70 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
@@ -288,14 +288,6 @@ namespace basegfx
*/
B2DPolygon createPolygonFromCircle( const B2DPoint& rCenter, double fRadius );
- /** append a unit circle with one point and the control vectors to the given polygon
- */
- void appendUnitCircleQuadrant(B2DPolygon& rPolygon, sal_uInt32 nQuadrant, bool bEndPoint);
-
- /** append a segment of unit circle with one point and the control vectors to the given polygon
- */
- void appendUnitCircleQuadrantSegment(B2DPolygon& rPolygon, sal_uInt32 nQuadrant, double fStart, double fEnd, bool bEndPoint);
-
/** create a polygon which describes the unit circle and close it
@param nStartQuadrant
@@ -325,59 +317,6 @@ namespace basegfx
*/
B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY );
- /** append a unit circle with one point and the control vectors to the given polygon
- */
- void appendUnitCircleQuadrant(B2DPolygon& rPolygon, sal_uInt32 nQuadrant);
-
- /** append a segment of unit circle with start point, the control vectors and end point to the given polygon
- */
- void appendUnitCircleQuadrantSegment(B2DPolygon& rPolygon, sal_uInt32 nQuadrant, double fStart, double fEnd);
-
- /** Create an ellipse polygon with given radii.
-
- This method creates an ellipse approximation consisting of
- four cubic bezier segments, which approximate the given
- ellipse with an error of less than 0.5 percent.
-
- @param rCenter
- Center point of the circle
-
- @param fRadiusX
- Radius of the ellipse in X direction
-
- @param fRadiusY
- Radius of the ellipse in Y direction
-
- @param fStart
- Start angle where the ellipe segment starts in the range [0.0 .. 2PI[
-
- @param fEnd
- End angle where the ellipe segment ends in the range [0.0 .. 2PI[
- */
- B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY );
-
- /** Create an ellipse polygon with given radii and the given angles, from start to end
-
- This method creates an ellipse approximation consisting of
- four cubic bezier segments, which approximate the given
- ellipse with an error of less than 0.5 percent.
-
- @param rCenter
- Center point of the circle
-
- @param fRadiusX
- Radius of the ellipse in X direction
-
- @param fRadiusY
- Radius of the ellipse in Y direction
-
- @param fStart
- Start angle where the ellipe segment starts in the range [0.0 .. 2PI[
-
- @param fEnd
- End angle where the ellipe segment ends in the range [0.0 .. 2PI[
- */
-
/** Create an unit ellipse polygon with the given angles, from start to end
*/
B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd );
diff --git a/basegfx/source/matrix/b2dhommatrix.cxx b/basegfx/source/matrix/b2dhommatrix.cxx
index 352113fa8ed3..a7777352effb 100644
--- a/basegfx/source/matrix/b2dhommatrix.cxx
+++ b/basegfx/source/matrix/b2dhommatrix.cxx
@@ -36,6 +36,9 @@
#include <hommatrixtemplate.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+///////////////////////////////////////////////////////////////////////////////
namespace basegfx
{
@@ -60,6 +63,17 @@ namespace basegfx
{
}
+ B2DHomMatrix::B2DHomMatrix(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2)
+ : mpImpl( IdentityMatrix::get() ) // use common identity matrix, will be made unique with 1st set-call
+ {
+ mpImpl->set(0, 0, f_0x0);
+ mpImpl->set(0, 1, f_0x1);
+ mpImpl->set(0, 2, f_0x2);
+ mpImpl->set(1, 0, f_1x0);
+ mpImpl->set(1, 1, f_1x1);
+ mpImpl->set(1, 2, f_1x2);
+ }
+
B2DHomMatrix& B2DHomMatrix::operator=(const B2DHomMatrix& rMat)
{
mpImpl = rMat.mpImpl;
@@ -81,6 +95,16 @@ namespace basegfx
mpImpl->set(nRow, nColumn, fValue);
}
+ void B2DHomMatrix::set3x2(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2)
+ {
+ mpImpl->set(0, 0, f_0x0);
+ mpImpl->set(0, 1, f_0x1);
+ mpImpl->set(0, 2, f_0x2);
+ mpImpl->set(1, 0, f_1x0);
+ mpImpl->set(1, 1, f_1x1);
+ mpImpl->set(1, 2, f_1x2);
+ }
+
bool B2DHomMatrix::isLastLineDefault() const
{
return mpImpl->isLastLineDefault();
@@ -206,56 +230,9 @@ namespace basegfx
if(!fTools::equalZero(fRadiant))
{
double fSin(0.0);
- double fCos(0.0);
-
- // is the rotation angle an approximate multiple of pi/2?
- // If yes, force fSin/fCos to -1/0/1, to maintain
- // orthogonality (which might also be advantageous for the
- // other cases, but: for multiples of pi/2, the exact
- // values _can_ be attained. It would be largely
- // unintuitive, if a 180 degrees rotation would introduce
- // slight roundoff errors, instead of exactly mirroring
- // the coordinate system).
- if( fTools::equalZero( fmod( fRadiant, F_PI2 ) ) )
- {
- // determine quadrant
- const sal_Int32 nQuad(
- (4 + fround( 4/F_2PI*fmod( fRadiant, F_2PI ) )) % 4 );
- switch( nQuad )
- {
- case 0: // -2pi,0,2pi
- fSin = 0.0;
- fCos = 1.0;
- break;
-
- case 1: // -3/2pi,1/2pi
- fSin = 1.0;
- fCos = 0.0;
- break;
-
- case 2: // -pi,pi
- fSin = 0.0;
- fCos = -1.0;
- break;
-
- case 3: // -1/2pi,3/2pi
- fSin = -1.0;
- fCos = 0.0;
- break;
-
- default:
- OSL_ENSURE( false,
- "B2DHomMatrix::rotate(): Impossible case reached" );
- }
- }
- else
- {
- // TODO(P1): Maybe use glibc's sincos here (though
- // that's kinda non-portable...)
- fSin = sin(fRadiant);
- fCos = cos(fRadiant);
- }
+ double fCos(1.0);
+ tools::createSinCosOrthogonal(fSin, fCos, fRadiant);
Impl2DHomMatrix aRotMat;
aRotMat.set(0, 0, fCos);
@@ -474,104 +451,7 @@ namespace basegfx
return true;
}
-
-/* Old version: Used 3D decompose when shaer was involved and also a determinant test
- (but only in that case). Keeping as comment since it also worked and to allow a
- fallback in case the new version makes trouble somehow. Definitely missing in the 2nd
- case is the sign correction for Y-Scale, this would need to be added following the above
- pattern
-
- bool B2DHomMatrix::decompose(B2DTuple& rScale, B2DTuple& rTranslate, double& rRotate, double& rShearX) const
- {
- // when perspective is used, decompose is not made here
- if(!mpImpl->isLastLineDefault())
- return false;
-
- // test for rotation and shear
- if(fTools::equalZero(get(0, 1))
- && fTools::equalZero(get(1, 0)))
- {
- // no rotation and shear, direct value extraction
- rRotate = rShearX = 0.0;
-
- // copy scale values
- rScale.setX(get(0, 0));
- rScale.setY(get(1, 1));
-
- // copy translation values
- rTranslate.setX(get(0, 2));
- rTranslate.setY(get(1, 2));
-
- return true;
- }
- else
- {
- // test if shear is zero. That's the case, if the unit vectors in the matrix
- // are perpendicular -> scalar is zero
- const ::basegfx::B2DVector aUnitVecX(get(0, 0), get(1, 0));
- const ::basegfx::B2DVector aUnitVecY(get(0, 1), get(1, 1));
-
- if(fTools::equalZero(aUnitVecX.scalar(aUnitVecY)))
- {
- // no shear, direct value extraction
- rShearX = 0.0;
-
- // calculate rotation
- rShearX = 0.0;
- rRotate = atan2(aUnitVecX.getY(), aUnitVecX.getX());
-
- // calculate scale values
- rScale.setX(aUnitVecX.getLength());
- rScale.setY(aUnitVecY.getLength());
-
- // copy translation values
- rTranslate.setX(get(0, 2));
- rTranslate.setY(get(1, 2));
-
- return true;
- }
- else
- {
- // If determinant is zero, decomposition is not possible
- if(0.0 == determinant())
- return false;
-
- // copy 2x2 matrix and translate vector to 3x3 matrix
- ::basegfx::B3DHomMatrix a3DHomMat;
-
- a3DHomMat.set(0, 0, get(0, 0));
- a3DHomMat.set(0, 1, get(0, 1));
- a3DHomMat.set(1, 0, get(1, 0));
- a3DHomMat.set(1, 1, get(1, 1));
- a3DHomMat.set(0, 3, get(0, 2));
- a3DHomMat.set(1, 3, get(1, 2));
-
- ::basegfx::B3DTuple r3DScale, r3DTranslate, r3DRotate, r3DShear;
-
- if(a3DHomMat.decompose(r3DScale, r3DTranslate, r3DRotate, r3DShear))
- {
- // copy scale values
- rScale.setX(r3DScale.getX());
- rScale.setY(r3DScale.getY());
-
- // copy shear
- rShearX = r3DShear.getX();
-
- // copy rotate
- rRotate = r3DRotate.getZ();
-
- // copy translate
- rTranslate.setX(r3DTranslate.getX());
- rTranslate.setY(r3DTranslate.getY());
-
- return true;
- }
- }
- }
-
- return false;
- } */
-
} // end of namespace basegfx
+///////////////////////////////////////////////////////////////////////////////
// eof
diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx
index 59a1ff432fc7..2c71193f6352 100644
--- a/basegfx/source/matrix/b2dhommatrixtools.cxx
+++ b/basegfx/source/matrix/b2dhommatrixtools.cxx
@@ -38,6 +38,339 @@
namespace basegfx
{
+ namespace tools
+ {
+ void createSinCosOrthogonal(double& o_rSin, double& o_rCos, double fRadiant)
+ {
+ if( fTools::equalZero( fmod( fRadiant, F_PI2 ) ) )
+ {
+ // determine quadrant
+ const sal_Int32 nQuad(
+ (4 + fround( 4/F_2PI*fmod( fRadiant, F_2PI ) )) % 4 );
+ switch( nQuad )
+ {
+ case 0: // -2pi,0,2pi
+ o_rSin = 0.0;
+ o_rCos = 1.0;
+ break;
+
+ case 1: // -3/2pi,1/2pi
+ o_rSin = 1.0;
+ o_rCos = 0.0;
+ break;
+
+ case 2: // -pi,pi
+ o_rSin = 0.0;
+ o_rCos = -1.0;
+ break;
+
+ case 3: // -1/2pi,3/2pi
+ o_rSin = -1.0;
+ o_rCos = 0.0;
+ break;
+
+ default:
+ OSL_ENSURE( false, "createSinCos: Impossible case reached" );
+ }
+ }
+ else
+ {
+ // TODO(P1): Maybe use glibc's sincos here (though
+ // that's kinda non-portable...)
+ o_rSin = sin(fRadiant);
+ o_rCos = cos(fRadiant);
+ }
+ }
+
+ B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
+ {
+ B2DHomMatrix aRetval;
+ const double fOne(1.0);
+
+ if(!fTools::equal(fScaleX, fOne))
+ {
+ aRetval.set(0, 0, fScaleX);
+ }
+
+ if(!fTools::equal(fScaleY, fOne))
+ {
+ aRetval.set(1, 1, fScaleY);
+ }
+
+ return aRetval;
+ }
+
+ B2DHomMatrix createShearXB2DHomMatrix(double fShearX)
+ {
+ B2DHomMatrix aRetval;
+
+ if(!fTools::equalZero(fShearX))
+ {
+ aRetval.set(0, 1, fShearX);
+ }
+
+ return aRetval;
+ }
+
+ B2DHomMatrix createShearYB2DHomMatrix(double fShearY)
+ {
+ B2DHomMatrix aRetval;
+
+ if(!fTools::equalZero(fShearY))
+ {
+ aRetval.set(1, 0, fShearY);
+ }
+
+ return aRetval;
+ }
+
+ B2DHomMatrix createRotateB2DHomMatrix(double fRadiant)
+ {
+ B2DHomMatrix aRetval;
+
+ if(!fTools::equalZero(fRadiant))
+ {
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+ aRetval.set(0, 0, fCos);
+ aRetval.set(1, 1, fCos);
+ aRetval.set(1, 0, fSin);
+ aRetval.set(0, 1, -fSin);
+ }
+
+ return aRetval;
+ }
+
+ B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
+ {
+ B2DHomMatrix aRetval;
+
+ if(!(fTools::equalZero(fTranslateX) && fTools::equalZero(fTranslateY)))
+ {
+ aRetval.set(0, 2, fTranslateX);
+ aRetval.set(1, 2, fTranslateY);
+ }
+
+ return aRetval;
+ }
+
+ B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY)
+ {
+ const double fOne(1.0);
+
+ if(fTools::equal(fScaleX, fOne) && fTools::equal(fScaleY, fOne))
+ {
+ /// no scale, take shortcut
+ return createShearXRotateTranslateB2DHomMatrix(fShearX, fRadiant, fTranslateX, fTranslateY);
+ }
+ else
+ {
+ /// scale used
+ if(fTools::equalZero(fShearX))
+ {
+ /// no shear
+ if(fTools::equalZero(fRadiant))
+ {
+ /// no rotate, take shortcut
+ return createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, fTranslateX, fTranslateY);
+ }
+ else
+ {
+ /// rotate and scale used, no shear
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fCos * fScaleX,
+ /* Row 0, Column 1 */ fScaleY * -fSin,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ fSin * fScaleX,
+ /* Row 1, Column 1 */ fScaleY * fCos,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ }
+ else
+ {
+ /// scale and shear used
+ if(fTools::equalZero(fRadiant))
+ {
+ /// scale and shear, but no rotate
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fScaleX,
+ /* Row 0, Column 1 */ fScaleY * fShearX,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ 0.0,
+ /* Row 1, Column 1 */ fScaleY,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ else
+ {
+ /// scale, shear and rotate used
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fCos * fScaleX,
+ /* Row 0, Column 1 */ fScaleY * ((fCos * fShearX) - fSin),
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ fSin * fScaleX,
+ /* Row 1, Column 1 */ fScaleY * ((fSin * fShearX) + fCos),
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ }
+ }
+ }
+
+ B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY)
+ {
+ if(fTools::equalZero(fShearX))
+ {
+ /// no shear
+ if(fTools::equalZero(fRadiant))
+ {
+ /// no shear, no rotate, take shortcut
+ return createTranslateB2DHomMatrix(fTranslateX, fTranslateY);
+ }
+ else
+ {
+ /// no shear, but rotate used
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fCos,
+ /* Row 0, Column 1 */ -fSin,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ fSin,
+ /* Row 1, Column 1 */ fCos,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ }
+ else
+ {
+ /// shear used
+ if(fTools::equalZero(fRadiant))
+ {
+ /// no rotate, but shear used
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ 1.0,
+ /* Row 0, Column 1 */ fShearX,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ 0.0,
+ /* Row 1, Column 1 */ 1.0,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ else
+ {
+ /// shear and rotate used
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fCos,
+ /* Row 0, Column 1 */ (fCos * fShearX) - fSin,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ fSin,
+ /* Row 1, Column 1 */ (fSin * fShearX) + fCos,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ }
+ }
+
+ B2DHomMatrix createScaleTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fTranslateX, double fTranslateY)
+ {
+ const double fOne(1.0);
+
+ if(fTools::equal(fScaleX, fOne) && fTools::equal(fScaleY, fOne))
+ {
+ /// no scale, take shortcut
+ return createTranslateB2DHomMatrix(fTranslateX, fTranslateY);
+ }
+ else
+ {
+ /// scale used
+ if(fTools::equalZero(fTranslateX) && fTools::equalZero(fTranslateY))
+ {
+ /// no translate, but scale.
+ B2DHomMatrix aRetval;
+
+ aRetval.set(0, 0, fScaleX);
+ aRetval.set(1, 1, fScaleY);
+
+ return aRetval;
+ }
+ else
+ {
+ /// translate and scale
+ B2DHomMatrix aRetval(
+ /* Row 0, Column 0 */ fScaleX,
+ /* Row 0, Column 1 */ 0.0,
+ /* Row 0, Column 2 */ fTranslateX,
+ /* Row 1, Column 0 */ 0.0,
+ /* Row 1, Column 1 */ fScaleY,
+ /* Row 1, Column 2 */ fTranslateY);
+
+ return aRetval;
+ }
+ }
+ }
+
+ B2DHomMatrix createRotateAroundPoint(
+ double fPointX, double fPointY,
+ double fRadiant)
+ {
+ B2DHomMatrix aRetval;
+
+ if(!fTools::equalZero(fRadiant))
+ {
+ double fSin(0.0);
+ double fCos(1.0);
+
+ createSinCosOrthogonal(fSin, fCos, fRadiant);
+
+ aRetval.set3x2(
+ /* Row 0, Column 0 */ fCos,
+ /* Row 0, Column 1 */ -fSin,
+ /* Row 0, Column 2 */ (fPointX * (1.0 - fCos)) + (fSin * fPointY),
+ /* Row 1, Column 0 */ fSin,
+ /* Row 1, Column 1 */ fCos,
+ /* Row 1, Column 2 */ (fPointY * (1.0 - fCos)) - (fSin * fPointX));
+ }
+
+ return aRetval;
+ }
+ } // end of namespace tools
} // end of namespace basegfx
///////////////////////////////////////////////////////////////////////////////
diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx
index 1a9264ab769e..c22b5ea94011 100644
--- a/basegfx/source/polygon/b2dlinegeometry.cxx
+++ b/basegfx/source/polygon/b2dlinegeometry.cxx
@@ -40,6 +40,7 @@
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -85,11 +86,9 @@ namespace basegfx
// get size of the arrow
const B2DRange aArrowSize(getRange(rArrow));
- // build ArrowTransform
- B2DHomMatrix aArrowTransform;
-
- // center in X, align with axis in Y
- aArrowTransform.translate(-aArrowSize.getCenter().getX(), -aArrowSize.getMinimum().getY());
+ // build ArrowTransform; center in X, align with axis in Y
+ B2DHomMatrix aArrowTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ -aArrowSize.getCenter().getX(), -aArrowSize.getMinimum().getY()));
// scale to target size
const double fArrowScale(fWidth / (aArrowSize.getRange().getX()));
diff --git a/basegfx/source/polygon/b2dpolygonclipper.cxx b/basegfx/source/polygon/b2dpolygonclipper.cxx
index f0d325942c07..87e44ed3d063 100644
--- a/basegfx/source/polygon/b2dpolygonclipper.cxx
+++ b/basegfx/source/polygon/b2dpolygonclipper.cxx
@@ -40,6 +40,7 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/tools/rectcliptools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -361,11 +362,10 @@ namespace basegfx
else if(rCandidate.count())
{
const B2DVector aEdge(rPointB - rPointA);
- B2DHomMatrix aMatrixTransform;
B2DPolygon aCandidate(rCandidate);
// translate and rotate polygon so that given edge is on x axis
- aMatrixTransform.translate(-rPointA.getX(), -rPointA.getY());
+ B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix(-rPointA.getX(), -rPointA.getY()));
aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
aCandidate.transform(aMatrixTransform);
@@ -395,11 +395,10 @@ namespace basegfx
else if(rCandidate.count())
{
const B2DVector aEdge(rPointB - rPointA);
- B2DHomMatrix aMatrixTransform;
B2DPolyPolygon aCandidate(rCandidate);
// translate and rotate polygon so that given edge is on x axis
- aMatrixTransform.translate(-rPointA.getX(), -rPointA.getY());
+ B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix(-rPointA.getX(), -rPointA.getY()));
aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
aCandidate.transform(aMatrixTransform);
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index 7485387c6cb9..d62462b8c097 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -33,7 +33,6 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <osl/diagnose.h>
#include <rtl/math.hxx>
-
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2drange.hxx>
@@ -43,6 +42,8 @@
#include <basegfx/matrix/b3dhommatrix.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/curve/b2dbeziertools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <osl/mutex.hxx>
#include <numeric>
#include <limits>
@@ -54,6 +55,7 @@
#ifdef DBG_UTIL
static double fAngleBoundStartValue = ANGLE_BOUND_START_VALUE;
#endif
+#define STEPSPERQUARTER (3)
//////////////////////////////////////////////////////////////////////////////
@@ -1840,145 +1842,106 @@ namespace basegfx
return createPolygonFromEllipse( rCenter, fRadius, fRadius );
}
- void appendUnitCircleQuadrant(B2DPolygon& rPolygon, sal_uInt32 nQuadrant)
+ B2DPolygon impCreateUnitCircle(sal_uInt32 nStartQuadrant)
{
- const double fZero(0.0);
- const double fOne(1.0);
+ B2DPolygon aUnitCircle;
const double fKappa((M_SQRT2 - 1.0) * 4.0 / 3.0);
+ const double fScaledKappa(fKappa * (1.0 / STEPSPERQUARTER));
+ const B2DHomMatrix aRotateMatrix(createRotateB2DHomMatrix(F_PI2 / STEPSPERQUARTER));
+
+ B2DPoint aPoint(1.0, 0.0);
+ B2DPoint aForward(1.0, fScaledKappa);
+ B2DPoint aBackward(1.0, -fScaledKappa);
- // create closed unit-circle with 4 segments
- switch(nQuadrant)
+ if(0 != nStartQuadrant)
{
- case 0 : // first quadrant
- {
- rPolygon.append(B2DPoint(fOne, fZero));
- rPolygon.appendBezierSegment(B2DPoint(fOne, fKappa), B2DPoint(fKappa, fOne), B2DPoint(fZero, fOne));
- break;
- }
- case 1 : // second quadrant
- {
- rPolygon.append(B2DPoint(fZero, fOne));
- rPolygon.appendBezierSegment(B2DPoint(-fKappa, fOne), B2DPoint(-fOne, fKappa), B2DPoint(-fOne, fZero));
- break;
- }
- case 2 : // third quadrant
- {
- rPolygon.append(B2DPoint(-fOne, fZero));
- rPolygon.appendBezierSegment(B2DPoint(-fOne, -fKappa), B2DPoint(-fKappa, -fOne), B2DPoint(fZero, -fOne));
- break;
- }
- default : // last quadrant
- {
- rPolygon.append(B2DPoint(fZero, -fOne));
- rPolygon.appendBezierSegment(B2DPoint(fKappa, -fOne), B2DPoint(fOne, -fKappa), B2DPoint(fOne, fZero));
- break;
- }
+ const B2DHomMatrix aQuadrantMatrix(createRotateB2DHomMatrix(F_PI2 * (nStartQuadrant % 4)));
+ aPoint *= aQuadrantMatrix;
+ aBackward *= aQuadrantMatrix;
+ aForward *= aQuadrantMatrix;
}
- }
- B2DPolygon createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant)
- {
- B2DPolygon aRetval;
+ aUnitCircle.append(aPoint);
- // create unit-circle with all 4 segments, close it
- appendUnitCircleQuadrant(aRetval, nStartQuadrant % 4); nStartQuadrant++;
- appendUnitCircleQuadrant(aRetval, nStartQuadrant % 4); nStartQuadrant++;
- appendUnitCircleQuadrant(aRetval, nStartQuadrant % 4); nStartQuadrant++;
- appendUnitCircleQuadrant(aRetval, nStartQuadrant % 4); nStartQuadrant++;
- aRetval.setClosed(true);
+ for(sal_uInt32 a(0); a < STEPSPERQUARTER * 4; a++)
+ {
+ aPoint *= aRotateMatrix;
+ aBackward *= aRotateMatrix;
+ aUnitCircle.appendBezierSegment(aForward, aBackward, aPoint);
+ aForward *= aRotateMatrix;
+ }
- // remove double points between segments created by segmented creation
- aRetval.removeDoublePoints();
+ aUnitCircle.setClosed(true);
+ aUnitCircle.removeDoublePoints();
- return aRetval;
+ return aUnitCircle;
}
- B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY )
+ B2DPolygon createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant)
{
- const double fOne(1.0);
- B2DPolygon aRetval(createPolygonFromUnitCircle());
-
- // transformation necessary?
- const sal_Bool bScale(!fTools::equal(fRadiusX, fOne) || !fTools::equal(fRadiusY, fOne));
- const sal_Bool bTranslate(!rCenter.equalZero());
-
- if(bScale || bTranslate)
+ switch(nStartQuadrant % 4)
{
- B2DHomMatrix aMatrix;
-
- if(bScale)
- {
- aMatrix.scale(fRadiusX, fRadiusY);
- }
-
- if(bTranslate)
+ case 1 :
{
- aMatrix.translate(rCenter.getX(), rCenter.getY());
- }
-
- aRetval.transform(aMatrix);
- }
-
- return aRetval;
- }
-
- void appendUnitCircleQuadrantSegment(B2DPolygon& rPolygon, sal_uInt32 nQuadrant, double fStart, double fEnd)
- {
- OSL_ENSURE(fStart >= 0.0 && fStart <= 1.0, "appendUnitCircleQuadrantSegment: Access out of range (!)");
- OSL_ENSURE(fEnd >= 0.0 && fEnd <= 1.0, "appendUnitCircleQuadrantSegment: Access out of range (!)");
- OSL_ENSURE(fEnd >= fStart, "appendUnitCircleQuadrantSegment: Access out of range (!)");
- const double fOne(1.0);
- const bool bStartIsZero(fTools::equalZero(fStart));
- const bool bEndIsOne(fTools::equal(fEnd, fOne));
+ static B2DPolygon aUnitCircleStartQuadrantOne;
- if(bStartIsZero && bEndIsOne)
- {
- // add completely
- appendUnitCircleQuadrant(rPolygon, nQuadrant);
- }
- else
- {
- // split and add
- B2DPolygon aQuadrant;
- appendUnitCircleQuadrant(aQuadrant, nQuadrant);
- const bool bStartEndEqual(fTools::equal(fStart, fEnd));
+ if(!aUnitCircleStartQuadrantOne.count())
+ {
+ ::osl::Mutex m_mutex;
+ aUnitCircleStartQuadrantOne = impCreateUnitCircle(1);
+ }
- if(bStartEndEqual)
+ return aUnitCircleStartQuadrantOne;
+ }
+ case 2 :
{
- if(bStartIsZero)
+ static B2DPolygon aUnitCircleStartQuadrantTwo;
+
+ if(!aUnitCircleStartQuadrantTwo.count())
{
- // both zero, add start point
- rPolygon.append(aQuadrant.getB2DPoint(0L));
+ ::osl::Mutex m_mutex;
+ aUnitCircleStartQuadrantTwo = impCreateUnitCircle(2);
}
- else if(bEndIsOne)
+
+ return aUnitCircleStartQuadrantTwo;
+ }
+ case 3 :
+ {
+ static B2DPolygon aUnitCircleStartQuadrantThree;
+
+ if(!aUnitCircleStartQuadrantThree.count())
{
- // both one, add end point
- rPolygon.append(aQuadrant.getB2DPoint(1L));
+ ::osl::Mutex m_mutex;
+ aUnitCircleStartQuadrantThree = impCreateUnitCircle(3);
}
- else
- {
- // both equal but not zero, add split point
- B2DCubicBezier aCubicBezier(
- aQuadrant.getB2DPoint(0L), aQuadrant.getNextControlPoint(0L),
- aQuadrant.getPrevControlPoint(1L), aQuadrant.getB2DPoint(1L));
- aCubicBezier.split(fStart, &aCubicBezier, 0);
- rPolygon.append(aCubicBezier.getEndPoint());
- }
+ return aUnitCircleStartQuadrantThree;
}
- else
+ default : // case 0 :
{
- B2DCubicBezier aCubicBezier(
- aQuadrant.getB2DPoint(0L), aQuadrant.getNextControlPoint(0L),
- aQuadrant.getPrevControlPoint(1L), aQuadrant.getB2DPoint(1L));
+ static B2DPolygon aUnitCircleStartQuadrantZero;
+
+ if(!aUnitCircleStartQuadrantZero.count())
+ {
+ ::osl::Mutex m_mutex;
+ aUnitCircleStartQuadrantZero = impCreateUnitCircle(0);
+ }
- aCubicBezier = aCubicBezier.snippet(fStart, fEnd);
- rPolygon.append(aCubicBezier.getStartPoint());
- rPolygon.appendBezierSegment(aCubicBezier.getControlPointA(), aCubicBezier.getControlPointB(), aCubicBezier.getEndPoint());
+ return aUnitCircleStartQuadrantZero;
}
}
}
+ B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY )
+ {
+ B2DPolygon aRetval(createPolygonFromUnitCircle());
+ const B2DHomMatrix aMatrix(createScaleTranslateB2DHomMatrix(fRadiusX, fRadiusY, rCenter.getX(), rCenter.getY()));
+
+ aRetval.transform(aMatrix);
+
+ return aRetval;
+ }
+
B2DPolygon createPolygonFromUnitEllipseSegment( double fStart, double fEnd )
{
B2DPolygon aRetval;
@@ -2005,49 +1968,74 @@ namespace basegfx
fEnd = 0.0;
}
- const sal_uInt32 nQuadrantStart(sal_uInt32(fStart / F_PI2) % 4L);
- const sal_uInt32 nQuadrantEnd(sal_uInt32(fEnd / F_PI2) % 4L);
- sal_uInt32 nCurrentQuadrant(nQuadrantStart);
- bool bStartDone(false);
- bool bEndDone(false);
-
- do
+ if(fTools::equal(fStart, fEnd))
{
- if(!bStartDone && nQuadrantStart == nCurrentQuadrant)
- {
- if(nQuadrantStart == nQuadrantEnd && fTools::moreOrEqual(fEnd, fStart))
- {
- // both in one quadrant and defining the complete segment, create start to end
- double fSplitOffsetStart((fStart - (nCurrentQuadrant * F_PI2)) / F_PI2);
- double fSplitOffsetEnd((fEnd - (nCurrentQuadrant * F_PI2)) / F_PI2);
- appendUnitCircleQuadrantSegment(aRetval, nCurrentQuadrant, fSplitOffsetStart, fSplitOffsetEnd);
- bStartDone = bEndDone = true;
- }
- else
- {
- // create start to quadrant end
- const double fSplitOffsetStart((fStart - (nCurrentQuadrant * F_PI2)) / F_PI2);
- appendUnitCircleQuadrantSegment(aRetval, nCurrentQuadrant, fSplitOffsetStart, 1.0);
- bStartDone = true;
- }
- }
- else if(!bEndDone && nQuadrantEnd == nCurrentQuadrant)
+ // same start and end angle, add single point
+ aRetval.append(B2DPoint(cos(fStart), sin(fStart)));
+ }
+ else
+ {
+ const sal_uInt32 nSegments(STEPSPERQUARTER * 4);
+ const double fAnglePerSegment(F_PI2 / STEPSPERQUARTER);
+ const sal_uInt32 nStartSegment(sal_uInt32(fStart / fAnglePerSegment) % nSegments);
+ const sal_uInt32 nEndSegment(sal_uInt32(fEnd / fAnglePerSegment) % nSegments);
+ const double fKappa((M_SQRT2 - 1.0) * 4.0 / 3.0);
+ const double fScaledKappa(fKappa * (1.0 / STEPSPERQUARTER));
+
+ B2DPoint aSegStart(cos(fStart), sin(fStart));
+ aRetval.append(aSegStart);
+
+ if(nStartSegment == nEndSegment && fTools::more(fEnd, fStart))
{
- // create quadrant start to end
- const double fSplitOffsetEnd((fEnd - (nCurrentQuadrant * F_PI2)) / F_PI2);
- appendUnitCircleQuadrantSegment(aRetval, nCurrentQuadrant, 0.0, fSplitOffsetEnd);
- bEndDone = true;
+ // start and end in one sector and in the right order, create in one segment
+ const B2DPoint aSegEnd(cos(fEnd), sin(fEnd));
+ const double fFactor(fScaledKappa * ((fEnd - fStart) / fAnglePerSegment));
+
+ aRetval.appendBezierSegment(
+ aSegStart + (B2DPoint(-aSegStart.getY(), aSegStart.getX()) * fFactor),
+ aSegEnd - (B2DPoint(-aSegEnd.getY(), aSegEnd.getX()) * fFactor),
+ aSegEnd);
}
else
{
- // add quadrant completely
- appendUnitCircleQuadrant(aRetval, nCurrentQuadrant);
- }
+ double fSegEndRad((nStartSegment + 1) * fAnglePerSegment);
+ double fFactor(fScaledKappa * ((fSegEndRad - fStart) / fAnglePerSegment));
+ B2DPoint aSegEnd(cos(fSegEndRad), sin(fSegEndRad));
- // next step
- nCurrentQuadrant = (nCurrentQuadrant + 1L) % 4L;
+ aRetval.appendBezierSegment(
+ aSegStart + (B2DPoint(-aSegStart.getY(), aSegStart.getX()) * fFactor),
+ aSegEnd - (B2DPoint(-aSegEnd.getY(), aSegEnd.getX()) * fFactor),
+ aSegEnd);
+
+ sal_uInt32 nSegment((nStartSegment + 1) % nSegments);
+ aSegStart = aSegEnd;
+
+ while(nSegment != nEndSegment)
+ {
+ // No end in this sector, add full sector.
+ fSegEndRad = (nSegment + 1) * fAnglePerSegment;
+ aSegEnd = B2DPoint(cos(fSegEndRad), sin(fSegEndRad));
+
+ aRetval.appendBezierSegment(
+ aSegStart + (B2DPoint(-aSegStart.getY(), aSegStart.getX()) * fScaledKappa),
+ aSegEnd - (B2DPoint(-aSegEnd.getY(), aSegEnd.getX()) * fScaledKappa),
+ aSegEnd);
+
+ nSegment = (nSegment + 1) % nSegments;
+ aSegStart = aSegEnd;
+ }
+
+ // End in this sector
+ const double fSegStartRad(nSegment * fAnglePerSegment);
+ fFactor = fScaledKappa * ((fEnd - fSegStartRad) / fAnglePerSegment);
+ aSegEnd = B2DPoint(cos(fEnd), sin(fEnd));
+
+ aRetval.appendBezierSegment(
+ aSegStart + (B2DPoint(-aSegStart.getY(), aSegStart.getX()) * fFactor),
+ aSegEnd - (B2DPoint(-aSegEnd.getY(), aSegEnd.getX()) * fFactor),
+ aSegEnd);
+ }
}
- while(!(bStartDone && bEndDone));
// remove double points between segments created by segmented creation
aRetval.removeDoublePoints();
@@ -2058,28 +2046,9 @@ namespace basegfx
B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd )
{
B2DPolygon aRetval(createPolygonFromUnitEllipseSegment(fStart, fEnd));
+ const B2DHomMatrix aMatrix(createScaleTranslateB2DHomMatrix(fRadiusX, fRadiusY, rCenter.getX(), rCenter.getY()));
- // transformation necessary?
- const double fOne(1.0);
- const sal_Bool bScale(!fTools::equal(fRadiusX, fOne) || !fTools::equal(fRadiusY, fOne));
- const sal_Bool bTranslate(!rCenter.equalZero());
-
- if(bScale || bTranslate)
- {
- B2DHomMatrix aMatrix;
-
- if(bScale)
- {
- aMatrix.scale(fRadiusX, fRadiusY);
- }
-
- if(bTranslate)
- {
- aMatrix.translate(rCenter.getX(), rCenter.getY());
- }
-
- aRetval.transform(aMatrix);
- }
+ aRetval.transform(aMatrix);
return aRetval;
}
@@ -2709,11 +2678,7 @@ namespace basegfx
if(nPointCount)
{
- B2DHomMatrix aMatrix;
-
- aMatrix.translate(-rCenter.getX(), -rCenter.getY());
- aMatrix.rotate(fAngle);
- aMatrix.translate(rCenter.getX(), rCenter.getY());
+ const B2DHomMatrix aMatrix(basegfx::tools::createRotateAroundPoint(rCenter, fAngle));
aRetval.transform(aMatrix);
}
diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index 2247c237d90f..e38ec3809fb1 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -36,6 +36,7 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <rtl/ustring.hxx>
#include <rtl/math.hxx>
@@ -705,7 +706,7 @@ namespace basegfx
// |y1'| = |-sin phi cos phi| |(y1 - y2)/2|
const B2DPoint p1(nLastX, nLastY);
const B2DPoint p2(nX, nY);
- B2DHomMatrix aTransform; aTransform.rotate(-fPhi*M_PI/180);
+ B2DHomMatrix aTransform(basegfx::tools::createRotateB2DHomMatrix(-fPhi*M_PI/180));
const B2DPoint p1_prime( aTransform * B2DPoint(((p1-p2)/2.0)) );
@@ -797,8 +798,7 @@ namespace basegfx
fTheta1, fTheta2 ));
// transform ellipse by rotation & move to final center
- aTransform.identity();
- aTransform.scale(fRX,fRY);
+ aTransform = basegfx::tools::createScaleB2DHomMatrix(fRX, fRY);
aTransform.translate(aCenter_prime.getX(),
aCenter_prime.getY());
aTransform.rotate(fPhi*M_PI/180);
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx
index 9e78039cd590..51989899ebf4 100644
--- a/basegfx/source/tools/gradienttools.cxx
+++ b/basegfx/source/tools/gradienttools.cxx
@@ -32,9 +32,9 @@
#include "precompiled_basegfx.hxx"
#include <basegfx/tools/gradienttools.hxx>
-
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
namespace basegfx
{
@@ -79,9 +79,8 @@ namespace basegfx
B2DPoint aCenter(0.5, 0.5);
aCenter *= o_rGradientInfo.maTextureTransform;
- o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
- o_rGradientInfo.maTextureTransform.rotate(fAngle);
- o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
+ * o_rGradientInfo.maTextureTransform;
}
// add object translate
@@ -158,9 +157,8 @@ namespace basegfx
B2DPoint aCenter(0.5, 0.5);
aCenter *= o_rGradientInfo.maTextureTransform;
- o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
- o_rGradientInfo.maTextureTransform.rotate(fAngle);
- o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
+ * o_rGradientInfo.maTextureTransform;
}
}
@@ -232,9 +230,8 @@ namespace basegfx
B2DPoint aCenter(0.5, 0.5);
aCenter *= o_rGradientInfo.maTextureTransform;
- o_rGradientInfo.maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
- o_rGradientInfo.maTextureTransform.rotate(fAngle);
- o_rGradientInfo.maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ o_rGradientInfo.maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
+ * o_rGradientInfo.maTextureTransform;
}
// add defined offsets after rotation
diff --git a/basegfx/source/tools/unopolypolygon.cxx b/basegfx/source/tools/unopolypolygon.cxx
index 6d8fcd83edb0..05dbe5b1c823 100755
--- a/basegfx/source/tools/unopolypolygon.cxx
+++ b/basegfx/source/tools/unopolypolygon.cxx
@@ -44,8 +44,8 @@
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
-
#include <basegfx/tools/unopolypolygon.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
using namespace ::com::sun::star;
@@ -138,9 +138,7 @@ namespace unotools
if( !aOffset.equalZero() )
{
- B2DHomMatrix aTranslate;
- aTranslate.translate( aOffset.getX(), aOffset.getY() );
-
+ const B2DHomMatrix aTranslate(tools::createTranslateB2DHomMatrix(aOffset));
aSrcPoly.transform( aTranslate );
}
diff --git a/basegfx/test/basegfx2d.cxx b/basegfx/test/basegfx2d.cxx
index ab6715467dba..1bd15702e143 100644
--- a/basegfx/test/basegfx2d.cxx
+++ b/basegfx/test/basegfx2d.cxx
@@ -484,8 +484,13 @@ public:
}
while ( nIndex >= 0 );
+ // Adapted number of spaces to 50 and 67 because of the new circle construction
+ // methods which produce more points and thus more spaces, too. Use both since
+ // depending on float precision and the getContinuity() implemetation using
+ // fTools::equal, linux and mac produce more 'C' than 'S' statements, while WIN32
+ // uses more 'S' statements (as it should be for circles)
CPPUNIT_ASSERT_MESSAGE("exporting to circle does not produce the expected number of coordinates",
- nCount==18);
+ nCount==67 || nCount==50);
const B2DPolygon aRect(
tools::createPolygonFromRect( B2DRange(0.0,0.0,4000.0,4000.0) ));
diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx
index 9cf2dd978759..7a5e81a5512a 100644
--- a/canvas/source/cairo/cairo_canvashelper.cxx
+++ b/canvas/source/cairo/cairo_canvashelper.cxx
@@ -958,6 +958,7 @@ namespace cairocanvas
void CanvasHelper::doPolyPolygonPath( const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
Operation aOperation,
+ bool bNoLineJoin,
const uno::Sequence< rendering::Texture >* pTextures,
Cairo* pCairo ) const
{
@@ -967,10 +968,47 @@ namespace cairocanvas
if( !pCairo )
pCairo = mpCairo.get();
- doPolyPolygonImplementation( rPolyPoly, aOperation,
- pCairo, pTextures,
- mpSurfaceProvider,
- xPolyPolygon->getFillRule() );
+ if(bNoLineJoin && Stroke == aOperation)
+ {
+ // emulate rendering::PathJoinType::NONE by painting single edges
+ for(sal_uInt32 a(0); a < rPolyPoly.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(rPolyPoly.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(aCandidate.count());
+
+ if(nPointCount)
+ {
+ const sal_uInt32 nEdgeCount(aCandidate.isClosed() ? nPointCount + 1: nPointCount);
+ basegfx::B2DPolygon aEdge;
+ aEdge.append(aCandidate.getB2DPoint(0));
+ aEdge.append(basegfx::B2DPoint(0.0, 0.0));
+
+ for(sal_uInt32 a(0); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex((a + 1) % nPointCount);
+ aEdge.setB2DPoint(1, aCandidate.getB2DPoint(nNextIndex));
+ aEdge.setNextControlPoint(0, aCandidate.getNextControlPoint(a));
+ aEdge.setPrevControlPoint(1, aCandidate.getPrevControlPoint(nNextIndex));
+
+ doPolyPolygonImplementation( basegfx::B2DPolyPolygon(aEdge),
+ aOperation,
+ pCairo, pTextures,
+ mpSurfaceProvider,
+ xPolyPolygon->getFillRule() );
+
+ // prepare next step
+ aEdge.setB2DPoint(0, aEdge.getB2DPoint(1));
+ }
+ }
+ }
+ }
+ else
+ {
+ doPolyPolygonImplementation( rPolyPoly, aOperation,
+ pCairo, pTextures,
+ mpSurfaceProvider,
+ xPolyPolygon->getFillRule() );
+ }
}
uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawPolyPolygon( const rendering::XCanvas* ,
@@ -1039,9 +1077,12 @@ namespace cairocanvas
break;
}
+ bool bNoLineJoin(false);
+
switch( strokeAttributes.JoinType ) {
// cairo doesn't have join type NONE so we use MITER as it's pretty close
case rendering::PathJoinType::NONE:
+ bNoLineJoin = true;
case rendering::PathJoinType::MITER:
cairo_set_line_join( mpCairo.get(), CAIRO_LINE_JOIN_MITER );
break;
@@ -1063,7 +1104,7 @@ namespace cairocanvas
// TODO(rodo) use LineArray of strokeAttributes
- doPolyPolygonPath( xPolyPolygon, Stroke );
+ doPolyPolygonPath( xPolyPolygon, Stroke, bNoLineJoin );
cairo_restore( mpCairo.get() );
} else
@@ -1147,7 +1188,7 @@ namespace cairocanvas
cairo_save( mpCairo.get() );
useStates( viewState, renderState, true );
- doPolyPolygonPath( xPolyPolygon, Fill, &textures );
+ doPolyPolygonPath( xPolyPolygon, Fill, false, &textures );
cairo_restore( mpCairo.get() );
}
diff --git a/canvas/source/cairo/cairo_canvashelper.hxx b/canvas/source/cairo/cairo_canvashelper.hxx
index 1e69a9f41e5b..90d365d63b3c 100644
--- a/canvas/source/cairo/cairo_canvashelper.hxx
+++ b/canvas/source/cairo/cairo_canvashelper.hxx
@@ -276,6 +276,7 @@ namespace cairocanvas
void doPolyPolygonPath( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >& xPolyPolygon,
Operation aOperation,
+ bool bNoLineJoin = false,
const ::com::sun::star::uno::Sequence< ::com::sun::star::rendering::Texture >* pTextures=NULL,
::cairo::Cairo* pCairo=NULL ) const;
diff --git a/canvas/source/directx/dx_canvashelper.cxx b/canvas/source/directx/dx_canvashelper.cxx
index 0642b6c50efb..607f7c076e21 100755
--- a/canvas/source/directx/dx_canvashelper.cxx
+++ b/canvas/source/directx/dx_canvashelper.cxx
@@ -46,6 +46,7 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <comphelper/sequence.hxx>
#include <canvas/canvastools.hxx>
@@ -367,7 +368,11 @@ namespace dxcanvas
pGraphics->GetPixelOffsetMode() );
pGraphics->SetPixelOffsetMode( Gdiplus::PixelOffsetModeNone );
- aPen.SetMiterLimit( static_cast< Gdiplus::REAL >(strokeAttributes.MiterLimit) );
+ const bool bIsMiter(rendering::PathJoinType::MITER == strokeAttributes.JoinType);
+ const bool bIsNone(rendering::PathJoinType::NONE == strokeAttributes.JoinType);
+
+ if(bIsMiter)
+ aPen.SetMiterLimit( static_cast< Gdiplus::REAL >(strokeAttributes.MiterLimit) );
const ::std::vector< Gdiplus::REAL >& rDashArray(
::comphelper::sequenceToContainer< ::std::vector< Gdiplus::REAL > >(
@@ -380,9 +385,10 @@ namespace dxcanvas
aPen.SetLineCap( gdiCapFromCap(strokeAttributes.StartCapType),
gdiCapFromCap(strokeAttributes.EndCapType),
Gdiplus::DashCapFlat );
- aPen.SetLineJoin( gdiJoinFromJoin(strokeAttributes.JoinType) );
+ if(!bIsNone)
+ aPen.SetLineJoin( gdiJoinFromJoin(strokeAttributes.JoinType) );
- GraphicsPathSharedPtr pPath( tools::graphicsPathFromXPolyPolygon2D( xPolyPolygon ) );
+ GraphicsPathSharedPtr pPath( tools::graphicsPathFromXPolyPolygon2D( xPolyPolygon, bIsNone ) );
// TODO(E1): Return value
Gdiplus::Status hr = pGraphics->DrawPath( &aPen, pPath.get() );
@@ -733,10 +739,8 @@ namespace dxcanvas
// add output offset
if( !maOutputOffset.equalZero() )
{
- ::basegfx::B2DHomMatrix aOutputOffset;
- aOutputOffset.translate( maOutputOffset.getX(),
- maOutputOffset.getY() );
-
+ const basegfx::B2DHomMatrix aOutputOffset(basegfx::tools::createTranslateB2DHomMatrix(
+ maOutputOffset.getX(), maOutputOffset.getY()));
aTransform = aOutputOffset * aTransform;
}
@@ -774,10 +778,8 @@ namespace dxcanvas
// add output offset
if( !maOutputOffset.equalZero() )
{
- ::basegfx::B2DHomMatrix aOutputOffset;
- aOutputOffset.translate( maOutputOffset.getX(),
- maOutputOffset.getY() );
-
+ const basegfx::B2DHomMatrix aOutputOffset(basegfx::tools::createTranslateB2DHomMatrix(
+ maOutputOffset.getX(), maOutputOffset.getY()));
aTransform = aOutputOffset * aTransform;
}
diff --git a/canvas/source/directx/dx_canvashelper_texturefill.cxx b/canvas/source/directx/dx_canvashelper_texturefill.cxx
index f291d197c4de..73a2d49bfb62 100755
--- a/canvas/source/directx/dx_canvashelper_texturefill.cxx
+++ b/canvas/source/directx/dx_canvashelper_texturefill.cxx
@@ -43,6 +43,7 @@
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/tools.hxx>
#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <canvas/parametricpolypolygon.hxx>
@@ -452,8 +453,7 @@ namespace dxcanvas
aFillBrush.SetColor( aFillColor );
const double nCurrScale( (nStepCount-i)/(double)nStepCount );
- aScaleMatrix.identity();
- aScaleMatrix.translate( -0.5, -0.5 );
+ aScaleMatrix = basegfx::tools::createTranslateB2DHomMatrix(-0.5, -0.5);
// handle anisotrophic polygon scaling
if( rValues.mnAspectRatio < 1.0 )
diff --git a/canvas/source/directx/dx_impltools.cxx b/canvas/source/directx/dx_impltools.cxx
index 40164c9a1d87..4f5b92d6bcb5 100755
--- a/canvas/source/directx/dx_impltools.cxx
+++ b/canvas/source/directx/dx_impltools.cxx
@@ -194,7 +194,8 @@ namespace dxcanvas
void graphicsPathFromB2DPolygon( GraphicsPathSharedPtr& rOutput,
::std::vector< Gdiplus::PointF >& rPoints,
- const ::basegfx::B2DPolygon& rPoly )
+ const ::basegfx::B2DPolygon& rPoly,
+ bool bNoLineJoin)
{
const sal_uInt32 nPoints( rPoly.count() );
@@ -241,7 +242,18 @@ namespace dxcanvas
rPoints[nCurrOutput++] = Gdiplus::PointF( static_cast<Gdiplus::REAL>(rPoint.getX()),
static_cast<Gdiplus::REAL>(rPoint.getY()) );
- rOutput->AddBeziers( &rPoints[0], nCurrOutput );
+ if(bNoLineJoin && nCurrOutput > 7)
+ {
+ for(sal_uInt32 a(3); a < nCurrOutput; a+=3)
+ {
+ rOutput->StartFigure();
+ rOutput->AddBezier(rPoints[a - 3], rPoints[a - 2], rPoints[a - 1], rPoints[a]);
+ }
+ }
+ else
+ {
+ rOutput->AddBeziers( &rPoints[0], nCurrOutput );
+ }
}
else
{
@@ -251,7 +263,20 @@ namespace dxcanvas
// Therefore, simply don't pass the last two
// points here.
if( nCurrOutput > 3 )
- rOutput->AddBeziers( &rPoints[0], nCurrOutput-2 );
+ {
+ if(bNoLineJoin && nCurrOutput > 7)
+ {
+ for(sal_uInt32 a(3); a < nCurrOutput; a+=3)
+ {
+ rOutput->StartFigure();
+ rOutput->AddBezier(rPoints[a - 3], rPoints[a - 2], rPoints[a - 1], rPoints[a]);
+ }
+ }
+ else
+ {
+ rOutput->AddBeziers( &rPoints[0], nCurrOutput-2 );
+ }
+ }
}
}
else
@@ -267,10 +292,27 @@ namespace dxcanvas
static_cast<Gdiplus::REAL>(rPoint.getY()) );
}
- rOutput->AddLines( &rPoints[0], nPoints );
+ if(bNoLineJoin && nPoints > 2)
+ {
+ for(sal_uInt32 a(1); a < nPoints; a++)
+ {
+ rOutput->StartFigure();
+ rOutput->AddLine(rPoints[a - 1], rPoints[a]);
+ }
+
+ if(bClosedPolygon)
+ {
+ rOutput->StartFigure();
+ rOutput->AddLine(rPoints[nPoints - 1], rPoints[0]);
+ }
+ }
+ else
+ {
+ rOutput->AddLines( &rPoints[0], nPoints );
+ }
}
- if( bClosedPolygon )
+ if( bClosedPolygon && !bNoLineJoin )
rOutput->CloseFigure();
}
}
@@ -426,17 +468,17 @@ namespace dxcanvas
return pRes;
}
- GraphicsPathSharedPtr graphicsPathFromB2DPolygon( const ::basegfx::B2DPolygon& rPoly )
+ GraphicsPathSharedPtr graphicsPathFromB2DPolygon( const ::basegfx::B2DPolygon& rPoly, bool bNoLineJoin )
{
GraphicsPathSharedPtr pRes( new Gdiplus::GraphicsPath() );
::std::vector< Gdiplus::PointF > aPoints;
- graphicsPathFromB2DPolygon( pRes, aPoints, rPoly );
+ graphicsPathFromB2DPolygon( pRes, aPoints, rPoly, bNoLineJoin );
return pRes;
}
- GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly )
+ GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly, bool bNoLineJoin )
{
GraphicsPathSharedPtr pRes( new Gdiplus::GraphicsPath() );
::std::vector< Gdiplus::PointF > aPoints;
@@ -446,24 +488,25 @@ namespace dxcanvas
{
graphicsPathFromB2DPolygon( pRes,
aPoints,
- rPoly.getB2DPolygon( nCurrPoly ) );
+ rPoly.getB2DPolygon( nCurrPoly ),
+ bNoLineJoin);
}
return pRes;
}
- GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
+ GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly, bool bNoLineJoin )
{
LinePolyPolygon* pPolyImpl = dynamic_cast< LinePolyPolygon* >( xPoly.get() );
if( pPolyImpl )
{
- return pPolyImpl->getGraphicsPath();
+ return pPolyImpl->getGraphicsPath( bNoLineJoin );
}
else
{
return tools::graphicsPathFromB2DPolyPolygon(
- polyPolygonFromXPolyPolygon2D( xPoly ) );
+ polyPolygonFromXPolyPolygon2D( xPoly ), bNoLineJoin );
}
}
diff --git a/canvas/source/directx/dx_impltools.hxx b/canvas/source/directx/dx_impltools.hxx
index 072d1063235d..222b1a927305 100755
--- a/canvas/source/directx/dx_impltools.hxx
+++ b/canvas/source/directx/dx_impltools.hxx
@@ -107,11 +107,18 @@ namespace dxcanvas
GraphicsPathSharedPtr graphicsPathFromRealPoint2DSequence( const ::com::sun::star::uno::Sequence<
::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealPoint2D > >& );
- GraphicsPathSharedPtr graphicsPathFromB2DPolygon( const ::basegfx::B2DPolygon& rPoly );
- GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly );
+ GraphicsPathSharedPtr graphicsPathFromB2DPolygon(
+ const ::basegfx::B2DPolygon& rPoly,
+ bool bNoLineJoin = false);
+
+ GraphicsPathSharedPtr graphicsPathFromB2DPolyPolygon(
+ const ::basegfx::B2DPolyPolygon& rPoly,
+ bool bNoLineJoin = false);
+
+ GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >&,
+ bool bNoLineJoin = false );
- GraphicsPathSharedPtr graphicsPathFromXPolyPolygon2D( const ::com::sun::star::uno::Reference<
- ::com::sun::star::rendering::XPolyPolygon2D >& );
bool drawGdiPlusBitmap( const GraphicsSharedPtr& rGraphics,
const BitmapSharedPtr& rBitmap );
bool drawDIBits( const ::boost::shared_ptr< Gdiplus::Graphics >& rGraphics,
diff --git a/canvas/source/directx/dx_linepolypolygon.cxx b/canvas/source/directx/dx_linepolypolygon.cxx
index e63adc3dc613..9a5569384eae 100755
--- a/canvas/source/directx/dx_linepolypolygon.cxx
+++ b/canvas/source/directx/dx_linepolypolygon.cxx
@@ -46,14 +46,14 @@ namespace dxcanvas
{
}
- GraphicsPathSharedPtr LinePolyPolygon::getGraphicsPath() const
+ GraphicsPathSharedPtr LinePolyPolygon::getGraphicsPath( bool bNoLineJoin ) const
{
// generate GraphicsPath only on demand (gets deleted as soon
// as any of the modifying methods above touches the
// B2DPolyPolygon).
if( !mpPath )
{
- mpPath = tools::graphicsPathFromB2DPolyPolygon( getPolyPolygonUnsafe() );
+ mpPath = tools::graphicsPathFromB2DPolyPolygon( getPolyPolygonUnsafe(), bNoLineJoin );
mpPath->SetFillMode( const_cast<LinePolyPolygon*>(this)->getFillRule() == rendering::FillRule_EVEN_ODD ?
Gdiplus::FillModeAlternate : Gdiplus::FillModeWinding );
}
diff --git a/canvas/source/directx/dx_linepolypolygon.hxx b/canvas/source/directx/dx_linepolypolygon.hxx
index 431cd1b87b4f..3e061d76e768 100755
--- a/canvas/source/directx/dx_linepolypolygon.hxx
+++ b/canvas/source/directx/dx_linepolypolygon.hxx
@@ -45,7 +45,7 @@ namespace dxcanvas
public:
explicit LinePolyPolygon( const ::basegfx::B2DPolyPolygon& );
- GraphicsPathSharedPtr getGraphicsPath() const;
+ GraphicsPathSharedPtr getGraphicsPath( bool bNoLineJoin = false) const;
private:
// overridden, to clear mpPath
diff --git a/canvas/source/simplecanvas/simplecanvasimpl.cxx b/canvas/source/simplecanvas/simplecanvasimpl.cxx
index 185979b0220e..7ca251458d22 100644
--- a/canvas/source/simplecanvas/simplecanvasimpl.cxx
+++ b/canvas/source/simplecanvas/simplecanvasimpl.cxx
@@ -46,6 +46,7 @@
#include <comphelper/servicedecl.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include "canvas/canvastools.hxx"
@@ -287,10 +288,7 @@ namespace
::sal_Int8 nTextDirection ) throw (uno::RuntimeException)
{
::osl::MutexGuard aGuard( m_aMutex );
-
- basegfx::B2DHomMatrix offsetTransform;
- offsetTransform.translate(aOutPos.X,aOutPos.Y);
-
+ const basegfx::B2DHomMatrix offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aOutPos.X,aOutPos.Y));
rendering::RenderState aRenderState( createStrokingRenderState() );
tools::appendToRenderState(aRenderState, offsetTransform);
@@ -305,10 +303,7 @@ namespace
const geometry::RealPoint2D& aLeftTop ) throw (uno::RuntimeException)
{
::osl::MutexGuard aGuard( m_aMutex );
-
- basegfx::B2DHomMatrix offsetTransform;
- offsetTransform.translate(aLeftTop.X,aLeftTop.Y);
-
+ const basegfx::B2DHomMatrix offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aLeftTop.X,aLeftTop.Y));
rendering::RenderState aRenderState( createStrokingRenderState() );
tools::appendToRenderState(aRenderState, offsetTransform);
diff --git a/canvas/source/tools/canvastools.cxx b/canvas/source/tools/canvastools.cxx
index 23d6124e4cb8..278789637c72 100644
--- a/canvas/source/tools/canvastools.cxx
+++ b/canvas/source/tools/canvastools.cxx
@@ -63,6 +63,7 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <cppuhelper/compbase1.hxx>
#include <rtl/instance.hxx>
@@ -679,9 +680,8 @@ namespace canvas
i_transformation );
// now move resulting left,top point of bounds to (0,0)
- ::basegfx::B2DHomMatrix aCorrectedTransform;
- aCorrectedTransform.translate( -aTransformedRect.getMinX(),
- -aTransformedRect.getMinY() );
+ const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
// prepend to original transformation
o_transform = aCorrectedTransform * i_transformation;
@@ -745,9 +745,8 @@ namespace canvas
transformation );
// now move resulting left,top point of bounds to (0,0)
- ::basegfx::B2DHomMatrix aCorrectedTransform;
- aCorrectedTransform.translate( -aTransformedRect.getMinX(),
- -aTransformedRect.getMinY() );
+ basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
// scale to match outRect
const double xDenom( aTransformedRect.getWidth() );
diff --git a/canvas/source/tools/surface.cxx b/canvas/source/tools/surface.cxx
index c3161758ea3e..96162f6d78af 100644
--- a/canvas/source/tools/surface.cxx
+++ b/canvas/source/tools/surface.cxx
@@ -33,6 +33,7 @@
#include "surface.hxx"
#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <comphelper/scopeguard.hxx>
#include <boost/bind.hpp>
@@ -150,9 +151,8 @@ namespace canvas
// 4) scale to normalized device coordinates
// 5) flip y-axis
// 6) translate to account for viewport transform
- ::basegfx::B2DHomMatrix aTransform;
- aTransform.translate(maSourceOffset.getX(),
- maSourceOffset.getY());
+ basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ maSourceOffset.getX(), maSourceOffset.getY()));
aTransform = aTransform * rTransform;
aTransform.translate(::basegfx::fround(rPos.getX()),
::basegfx::fround(rPos.getY()));
@@ -277,8 +277,7 @@ namespace canvas
// 1) offset of surface subarea
// 2) surface transform
// 3) translation to output position [rPos]
- ::basegfx::B2DHomMatrix aTransform;
- aTransform.translate(aPos1.getX(),aPos1.getY());
+ basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(aPos1.getX(), aPos1.getY()));
aTransform = aTransform * rTransform;
aTransform.translate(::basegfx::fround(rPos.getX()),
::basegfx::fround(rPos.getY()));
@@ -380,7 +379,7 @@ namespace canvas
// be transformed by the overall transform and uv coordinates will
// be calculated from the result, and this is why we need to use
// integer coordinates here...
- ::basegfx::B2DHomMatrix aTransform;
+ basegfx::B2DHomMatrix aTransform;
aTransform = aTransform * rTransform;
aTransform.translate(::basegfx::fround(rPos.getX()),
::basegfx::fround(rPos.getY()));
diff --git a/comphelper/source/property/opropertybag.cxx b/comphelper/source/property/opropertybag.cxx
index 8b816e8c1ce9..caa895021103 100644
--- a/comphelper/source/property/opropertybag.cxx
+++ b/comphelper/source/property/opropertybag.cxx
@@ -240,7 +240,7 @@ namespace comphelper
if ( !( _element >>= aProperty ) )
throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ClearableMutexGuard g( m_aMutex );
// check whether the type is allowed, everything else will be checked
// by m_aDynamicProperties
@@ -254,6 +254,7 @@ namespace comphelper
// our property info is dirty
m_pArrayHelper.reset();
+ g.clear();
setModified(sal_True);
}
@@ -346,7 +347,7 @@ namespace comphelper
//--------------------------------------------------------------------
void SAL_CALL OPropertyBag::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ClearableMutexGuard g( m_aMutex );
// check whether the type is allowed, everything else will be checked
// by m_aDynamicProperties
@@ -362,19 +363,21 @@ namespace comphelper
// our property info is dirty
m_pArrayHelper.reset();
+ g.clear();
setModified(sal_True);
}
//--------------------------------------------------------------------
void SAL_CALL OPropertyBag::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ ::osl::ClearableMutexGuard g( m_aMutex );
m_aDynamicProperties.removeProperty( _rName );
// our property info is dirty
m_pArrayHelper.reset();
+ g.clear();
setModified(sal_True);
}
diff --git a/comphelper/source/property/property.cxx b/comphelper/source/property/property.cxx
index fe6cbaa9d767..0ccc28d4238b 100644
--- a/comphelper/source/property/property.cxx
+++ b/comphelper/source/property/property.cxx
@@ -38,15 +38,11 @@
#include <osl/diagnose.h>
#if OSL_DEBUG_LEVEL > 0
- #ifndef _RTL_STRBUF_HXX_
#include <rtl/strbuf.hxx>
- #endif
- #ifndef _CPPUHELPER_EXC_HLP_HXX_
#include <cppuhelper/exc_hlp.hxx>
- #endif
- #ifndef _OSL_THREAD_H_
#include <osl/thread.h>
- #endif
+ #include <com/sun/star/lang/XServiceInfo.hpp>
+ #include <typeinfo>
#endif
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
@@ -71,6 +67,10 @@ namespace comphelper
using ::com::sun::star::uno::cpp_queryInterface;
using ::com::sun::star::uno::cpp_acquire;
using ::com::sun::star::uno::cpp_release;
+#if OSL_DEBUG_LEVEL > 0
+ using ::com::sun::star::lang::XServiceInfo;
+#endif
+ using ::com::sun::star::uno::UNO_QUERY;
/** === end UNO using === **/
namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
@@ -110,7 +110,18 @@ void copyProperties(const Reference<XPropertySet>& _rxSource,
::rtl::OStringBuffer aBuffer;
aBuffer.append( "::comphelper::copyProperties: could not copy property '" );
aBuffer.append( ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US ) );
- aBuffer.append( "' to the destination set.\n" );
+ aBuffer.append( "' to the destination set (a '" );
+
+ Reference< XServiceInfo > xSI( _rxDest, UNO_QUERY );
+ if ( xSI.is() )
+ {
+ aBuffer.append( ::rtl::OUStringToOString( xSI->getImplementationName(), osl_getThreadTextEncoding() ) );
+ }
+ else
+ {
+ aBuffer.append( typeid( *_rxDest.get() ).name() );
+ }
+ aBuffer.append( "' implementation).\n" );
Any aException( ::cppu::getCaughtException() );
aBuffer.append( "Caught an exception of type '" );
diff --git a/cppcanvas/source/mtfrenderer/bitmapaction.cxx b/cppcanvas/source/mtfrenderer/bitmapaction.cxx
index 355dd336e2c5..4f54b10c4879 100644
--- a/cppcanvas/source/mtfrenderer/bitmapaction.cxx
+++ b/cppcanvas/source/mtfrenderer/bitmapaction.cxx
@@ -35,25 +35,21 @@
#include <com/sun/star/rendering/XBitmap.hpp>
#include <com/sun/star/rendering/RepaintResult.hpp>
#include <com/sun/star/rendering/XCachedPrimitive.hpp>
-
#include <vcl/bitmapex.hxx>
#include <tools/gen.hxx>
#include <vcl/canvastools.hxx>
-
#include <canvas/canvastools.hxx>
-
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/vector/b2dsize.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/tools/canvastools.hxx>
-
#include <boost/utility.hpp>
-
#include "cachedprimitivebase.hxx"
#include "bitmapaction.hxx"
#include "outdevstate.hxx"
#include "mtftools.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
using namespace ::com::sun::star;
@@ -112,9 +108,7 @@ namespace cppcanvas
// Setup transformation such that the next render call is
// moved rPoint away.
- ::basegfx::B2DHomMatrix aLocalTransformation;
- aLocalTransformation.translate( rDstPoint.getX(),
- rDstPoint.getY() );
+ const basegfx::B2DHomMatrix aLocalTransformation(basegfx::tools::createTranslateB2DHomMatrix(rDstPoint));
::canvas::tools::appendToRenderState( maState,
aLocalTransformation );
@@ -144,15 +138,12 @@ namespace cppcanvas
// moved rPoint away, and scaled according to the ratio
// given by src and dst size.
const ::Size aBmpSize( rBmpEx.GetSizePixel() );
- ::basegfx::B2DHomMatrix aLocalTransformation;
const ::basegfx::B2DVector aScale( rDstSize.getX() / aBmpSize.Width(),
rDstSize.getY() / aBmpSize.Height() );
- aLocalTransformation.scale( aScale.getX(), aScale.getY() );
- aLocalTransformation.translate( rDstPoint.getX(),
- rDstPoint.getY() );
- ::canvas::tools::appendToRenderState( maState,
- aLocalTransformation );
+ const basegfx::B2DHomMatrix aLocalTransformation(basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aScale, rDstPoint));
+ ::canvas::tools::appendToRenderState( maState, aLocalTransformation );
// correct clip (which is relative to original transform)
tools::modifyClip( maState,
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index c6f9a295b332..8ea2ae453a97 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -34,19 +34,14 @@
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/verbosetrace.hxx>
-
#include <osl/mutex.hxx>
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
-
#include <rtl/logfile.hxx>
-
#include <comphelper/sequence.hxx>
#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>
-
#include <cppcanvas/canvas.hxx>
-
#include <com/sun/star/rendering/XGraphicDevice.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
#include <com/sun/star/rendering/XParametricPolyPolygon2DFactory.hpp>
@@ -59,7 +54,6 @@
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/rendering/PathCapType.hpp>
#include <com/sun/star/rendering/PathJoinType.hpp>
-
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
@@ -73,7 +67,6 @@
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
-
#include <canvas/canvastools.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/salbtype.hxx>
@@ -84,11 +77,9 @@
#include <vcl/graphictools.hxx>
#include <tools/poly.hxx>
#include <i18npool/mslangid.hxx>
-
#include <implrenderer.hxx>
#include <tools.hxx>
#include <outdevstate.hxx>
-
#include <action.hxx>
#include <bitmapaction.hxx>
#include <lineaction.hxx>
@@ -96,15 +87,13 @@
#include <polypolyaction.hxx>
#include <textaction.hxx>
#include <transparencygroupaction.hxx>
-
#include <vector>
#include <algorithm>
#include <iterator>
-
#include <boost/scoped_array.hpp>
-
#include "mtftools.hxx"
#include "outdevstate.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
using namespace ::com::sun::star;
@@ -286,10 +275,25 @@ namespace
(getState( rParms.mrStates ).mapModeTransform * aWidth).getX();
// setup reasonable defaults
- o_rStrokeAttributes.MiterLimit = 1.0;
+ o_rStrokeAttributes.MiterLimit = 15.0; // 1.0 was no good default; GDI+'s limit is 10.0, our's is 15.0
o_rStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
o_rStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
- o_rStrokeAttributes.JoinType = rendering::PathJoinType::MITER;
+
+ switch(rLineInfo.GetLineJoin())
+ {
+ default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
+ o_rStrokeAttributes.JoinType = rendering::PathJoinType::NONE;
+ break;
+ case basegfx::B2DLINEJOIN_BEVEL:
+ o_rStrokeAttributes.JoinType = rendering::PathJoinType::BEVEL;
+ break;
+ case basegfx::B2DLINEJOIN_MITER:
+ o_rStrokeAttributes.JoinType = rendering::PathJoinType::MITER;
+ break;
+ case basegfx::B2DLINEJOIN_ROUND:
+ o_rStrokeAttributes.JoinType = rendering::PathJoinType::ROUND;
+ break;
+ }
if( LINE_DASH == rLineInfo.GetStyle() )
{
@@ -729,12 +733,11 @@ namespace cppcanvas
fabs( aBounds.getHeight()*sin(nRotation) ) +
fabs( aBounds.getWidth()*cos(nRotation) )));
- aTextureTransformation.scale( nScale, nScale );
-
- // translate back origin to center of
+ // scale and translate back origin to center of
// primitive
- aTextureTransformation.translate( 0.5*aBounds.getWidth(),
- 0.5*aBounds.getHeight() );
+ aTextureTransformation = basegfx::tools::createScaleTranslateB2DHomMatrix(
+ nScale, nScale, 0.5*aBounds.getWidth(), 0.5*aBounds.getHeight())
+ * aTextureTransformation;
}
break;
@@ -856,9 +859,8 @@ namespace cppcanvas
aTextureTransformation.scale( nScaleX, nScaleY );
// rotate texture according to gradient rotation
- aTextureTransformation.translate( -0.5*nScaleX, -0.5*nScaleY );
- aTextureTransformation.rotate( nRotation );
- aTextureTransformation.translate( 0.5*nScaleX, 0.5*nScaleY );
+ aTextureTransformation = basegfx::tools::createRotateAroundPoint(0.5*nScaleX, 0.5*nScaleY, nRotation)
+ * aTextureTransformation;
aTextureTransformation.translate( nOffsetX, nOffsetY );
}
diff --git a/cppcanvas/source/mtfrenderer/mtftools.cxx b/cppcanvas/source/mtfrenderer/mtftools.cxx
index e4e227955da6..b6a548aa49be 100644
--- a/cppcanvas/source/mtfrenderer/mtftools.cxx
+++ b/cppcanvas/source/mtfrenderer/mtftools.cxx
@@ -34,10 +34,8 @@
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/verbosetrace.hxx>
-
#include <com/sun/star/rendering/RenderState.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
-
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/canvastools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
@@ -45,16 +43,15 @@
#include <basegfx/range/b2drectangle.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <canvas/canvastools.hxx>
-
#include <vcl/gdimtf.hxx>
#include <vcl/metaact.hxx>
#include <vcl/virdev.hxx>
#include <vcl/metric.hxx>
#include <tools/poly.hxx>
-
#include "mtftools.hxx"
#include "outdevstate.hxx"
#include "polypolyaction.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -111,9 +108,9 @@ namespace cppcanvas
const ::Size aSizePixel( rVDev.LogicToPixel( aSizeLogic ) );
- o_rMatrix.identity();
- o_rMatrix.scale( aSizePixel.Width() / (double)aSizeLogic.Width(),
- aSizePixel.Height() / (double)aSizeLogic.Height() );
+ o_rMatrix = basegfx::tools::createScaleB2DHomMatrix(
+ aSizePixel.Width() / (double)aSizeLogic.Width(),
+ aSizePixel.Height() / (double)aSizeLogic.Height() );
return o_rMatrix;
}
diff --git a/cppcanvas/source/mtfrenderer/textaction.cxx b/cppcanvas/source/mtfrenderer/textaction.cxx
index f1191e6e57f3..038b68c3008e 100644
--- a/cppcanvas/source/mtfrenderer/textaction.cxx
+++ b/cppcanvas/source/mtfrenderer/textaction.cxx
@@ -48,6 +48,7 @@
#include <basegfx/vector/b2dsize.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <tools/gen.hxx>
#include <vcl/canvastools.hxx>
@@ -93,9 +94,7 @@ namespace cppcanvas
NULL,
&rState.fontRotation );
- ::basegfx::B2DHomMatrix aLocalTransformation;
-
- aLocalTransformation.rotate( rState.fontRotation );
+ basegfx::B2DHomMatrix aLocalTransformation(basegfx::tools::createRotateB2DHomMatrix(rState.fontRotation));
aLocalTransformation.translate( rStartPoint.getX(),
rStartPoint.getY() );
::canvas::tools::appendToRenderState( o_rRenderState,
diff --git a/goodies/inc/grfmgr.hxx b/goodies/inc/grfmgr.hxx
index b44c27ea65e3..1ef351ae6d32 100644
--- a/goodies/inc/grfmgr.hxx
+++ b/goodies/inc/grfmgr.hxx
@@ -353,7 +353,7 @@ public:
void ReleaseFromCache();
const Graphic& GetGraphic() const;
- void SetGraphic( const Graphic& rGraphic );
+ void SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj = 0);
void SetGraphic( const Graphic& rGraphic, const String& rLink );
/** Get graphic transformed according to given attributes
diff --git a/goodies/source/filter.vcl/epict/epict.cxx b/goodies/source/filter.vcl/epict/epict.cxx
index 3e4dca455d05..cd9e33edd5d9 100644
--- a/goodies/source/filter.vcl/epict/epict.cxx
+++ b/goodies/source/filter.vcl/epict/epict.cxx
@@ -55,6 +55,9 @@
#include "dlgepct.hrc"
#include "dlgepct.hxx"
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+
//============================== PictWriter ===================================
struct PictWriterAttrStackMember {
@@ -77,7 +80,6 @@ struct PictPattern {
sal_uInt32 nLo, nHi;
};
-
class PictWriter {
private:
@@ -178,6 +180,7 @@ private:
void WriteTextArray(Point & rPoint, const String& rString, const sal_Int32 * pDXAry);
+ void HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
void WriteOpcodes(const GDIMetaFile & rMTF);
void WriteHeader(const GDIMetaFile & rMTF);
@@ -1371,6 +1374,65 @@ void PictWriter::WriteTextArray(Point & rPoint, const String& rString, const sal
}
}
+void PictWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
+{
+ if(rLinePolygon.count())
+ {
+ basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+
+ rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
+
+ if(aLinePolyPolygon.count())
+ {
+ aLinePolyPolygon = aLinePolyPolygon.getDefaultAdaptiveSubdivision();
+ const sal_uInt32 nPolyCount(aLinePolyPolygon.count());
+ SetAttrForFrame();
+
+ for(sal_uInt32 a(0); a < nPolyCount; a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(aCandidate.count());
+
+ if(nPointCount)
+ {
+ const sal_uInt32 nEdgeCount(aCandidate.isClosed() ? nPointCount + 1 : nPointCount);
+ const basegfx::B2DPoint aCurr(aCandidate.getB2DPoint(0));
+ Point nCurr(basegfx::fround(aCurr.getX()), basegfx::fround(aCurr.getY()));
+
+ for(sal_uInt32 b(0); b < nEdgeCount; b++)
+ {
+ const sal_uInt32 nNextIndex((b + 1) % nPointCount);
+ const basegfx::B2DPoint aNext(aCandidate.getB2DPoint(nNextIndex));
+ const Point nNext(basegfx::fround(aNext.getX()), basegfx::fround(aNext.getY()));
+
+ WriteOpcode_Line(nCurr, nNext);
+ nCurr = nNext;
+ }
+ }
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor(aLineColor);
+ const Color aOldFillColor(aFillColor);
+
+ aLineColor = Color( COL_TRANSPARENT );
+ aFillColor = aOldLineColor;
+ SetAttrForPaint();
+
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a).getDefaultAdaptiveSubdivision());
+ WriteOpcode_Poly(PDM_PAINT, aPolygon);
+ }
+
+ aLineColor = aOldLineColor;
+ aFillColor = aOldFillColor;
+ }
+ }
+}
void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
{
@@ -1417,8 +1479,19 @@ void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
if( aLineColor != Color( COL_TRANSPARENT ) )
{
- SetAttrForFrame();
- WriteOpcode_Line( pA->GetStartPoint(),pA->GetEndPoint() );
+ if(pA->GetLineInfo().IsDefault())
+ {
+ SetAttrForFrame();
+ WriteOpcode_Line( pA->GetStartPoint(),pA->GetEndPoint() );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
+ aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
+ }
}
break;
}
@@ -1571,24 +1644,35 @@ void PictWriter::WriteOpcodes( const GDIMetaFile & rMTF )
{
const Polygon& rPoly = pA->GetPolygon();
- Polygon aSimplePoly;
- if ( rPoly.HasFlags() )
- rPoly.AdaptiveSubdivide( aSimplePoly );
- else
- aSimplePoly = rPoly;
-
- const USHORT nSize = aSimplePoly.GetSize();
- Point aLast;
-
- if ( nSize )
+ if( rPoly.GetSize() )
{
- SetAttrForFrame();
- aLast = aSimplePoly[0];
+ if(pA->GetLineInfo().IsDefault())
+ {
+ Polygon aSimplePoly;
+ if ( rPoly.HasFlags() )
+ rPoly.AdaptiveSubdivide( aSimplePoly );
+ else
+ aSimplePoly = rPoly;
- for ( USHORT i = 1; i < nSize; i++ )
+ const USHORT nSize = aSimplePoly.GetSize();
+ Point aLast;
+
+ if ( nSize )
+ {
+ SetAttrForFrame();
+ aLast = aSimplePoly[0];
+
+ for ( USHORT i = 1; i < nSize; i++ )
+ {
+ WriteOpcode_Line( aLast, aSimplePoly[i] );
+ aLast = aSimplePoly[i];
+ }
+ }
+ }
+ else
{
- WriteOpcode_Line( aLast, aSimplePoly[i] );
- aLast = aSimplePoly[i];
+ // LineInfo used; handle Dash/Dot and fat lines
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
}
}
}
diff --git a/goodies/source/filter.vcl/epict/makefile.mk b/goodies/source/filter.vcl/epict/makefile.mk
index 4aa4bab80ffc..9f25a562488a 100644
--- a/goodies/source/filter.vcl/epict/makefile.mk
+++ b/goodies/source/filter.vcl/epict/makefile.mk
@@ -61,7 +61,7 @@ RESLIB1SRSFILES=$(SRS)$/$(TARGET).srs
.IF "$(L10N_framework)"==""
SHL1TARGET= ept$(DLLPOSTFIX)
SHL1IMPLIB= epict
-SHL1STDLIBS= $(TOOLSLIB) $(VCLLIB) $(SVTOOLLIB) $(CPPULIB) $(SALLIB)
+SHL1STDLIBS= $(TOOLSLIB) $(VCLLIB) $(SVTOOLLIB) $(CPPULIB) $(SALLIB) $(BASEGFXLIB)
SHL1LIBS= $(SLB)$/epict.lib
diff --git a/goodies/source/filter.vcl/eps/eps.cxx b/goodies/source/filter.vcl/eps/eps.cxx
index dc8e407b178e..83b5a94f97f2 100644
--- a/goodies/source/filter.vcl/eps/eps.cxx
+++ b/goodies/source/filter.vcl/eps/eps.cxx
@@ -388,7 +388,7 @@ BOOL PSWriter::WritePS( const Graphic& rGraphic, SvStream& rTargetStream, Filter
bTextFillColor = TRUE;
aTextFillColor = Color( COL_BLACK );
fLineWidth = 1;
- fMiterLimit = 10;
+ fMiterLimit = 15; // use same limit as most graphic systems and basegfx
eLineCap = SvtGraphicStroke::capButt;
eJoinType = SvtGraphicStroke::joinMiter;
aBackgroundColor = Color( COL_WHITE );
@@ -701,7 +701,40 @@ void PSWriter::ImplWriteActions( const GDIMetaFile& rMtf, VirtualDevice& rVDev )
Polygon aPoly( ( (const MetaPolyLineAction*) pMA )->GetPolygon() );
const LineInfo& rLineInfo = ( ( const MetaPolyLineAction*)pMA )->GetLineInfo();
ImplWriteLineInfo( rLineInfo );
- ImplPolyLine( aPoly );
+
+ if(basegfx::B2DLINEJOIN_NONE == rLineInfo.GetLineJoin()
+ && rLineInfo.GetWidth() > 1)
+ {
+ // emulate B2DLINEJOIN_NONE by creating single edges
+ const sal_uInt16 nPoints(aPoly.GetSize());
+ const bool bCurve(aPoly.HasFlags());
+
+ for(sal_uInt16 a(0); a + 1 < nPoints; a++)
+ {
+ if(bCurve
+ && POLY_NORMAL != aPoly.GetFlags(a + 1)
+ && a + 2 < nPoints
+ && POLY_NORMAL != aPoly.GetFlags(a + 2)
+ && a + 3 < nPoints)
+ {
+ const Polygon aSnippet(4,
+ aPoly.GetConstPointAry() + a,
+ aPoly.GetConstFlagAry() + a);
+ ImplPolyLine(aSnippet);
+ a += 2;
+ }
+ else
+ {
+ const Polygon aSnippet(2,
+ aPoly.GetConstPointAry() + a);
+ ImplPolyLine(aSnippet);
+ }
+ }
+ }
+ else
+ {
+ ImplPolyLine( aPoly );
+ }
}
break;
@@ -2343,8 +2376,28 @@ void PSWriter::ImplWriteLineInfo( const LineInfo& rLineInfo )
SvtGraphicStroke::DashArray l_aDashArray;
if ( rLineInfo.GetStyle() == LINE_DASH )
l_aDashArray.push_back( 2 );
- double fLWidth = ( ( rLineInfo.GetWidth() + 1 ) + ( rLineInfo.GetWidth() + 1 ) ) * 0.5;
- ImplWriteLineInfo( fLWidth, 10.0, SvtGraphicStroke::capButt, SvtGraphicStroke::joinMiter, l_aDashArray );
+ const double fLWidth(( ( rLineInfo.GetWidth() + 1 ) + ( rLineInfo.GetWidth() + 1 ) ) * 0.5);
+ SvtGraphicStroke::JoinType aJoinType(SvtGraphicStroke::joinMiter);
+
+ switch(rLineInfo.GetLineJoin())
+ {
+ default: // B2DLINEJOIN_NONE, B2DLINEJOIN_MIDDLE
+ // do NOT use SvtGraphicStroke::joinNone here
+ // since it will be written as numerical value directly
+ // and is NOT a valid EPS value
+ break;
+ case basegfx::B2DLINEJOIN_MITER:
+ aJoinType = SvtGraphicStroke::joinMiter;
+ break;
+ case basegfx::B2DLINEJOIN_BEVEL:
+ aJoinType = SvtGraphicStroke::joinBevel;
+ break;
+ case basegfx::B2DLINEJOIN_ROUND:
+ aJoinType = SvtGraphicStroke::joinRound;
+ break;
+ }
+
+ ImplWriteLineInfo( fLWidth, fMiterLimit, SvtGraphicStroke::capButt, aJoinType, l_aDashArray );
}
//---------------------------------------------------------------------------------
diff --git a/goodies/source/filter.vcl/ieps/ieps.cxx b/goodies/source/filter.vcl/ieps/ieps.cxx
index f315ee864310..7f1ecfc65bd0 100644
--- a/goodies/source/filter.vcl/ieps/ieps.cxx
+++ b/goodies/source/filter.vcl/ieps/ieps.cxx
@@ -164,12 +164,54 @@ static void MakeAsMeta(Graphic &rGraphic)
rGraphic = aMtf;
}
+static oslProcessError runProcessWithPathSearch(const rtl::OUString &rProgName,
+ rtl_uString* pArgs[], sal_uInt32 nArgs, oslProcess *pProcess,
+ oslFileHandle *pIn, oslFileHandle *pOut, oslFileHandle *pErr)
+{
+#ifdef WNT
+ /*
+ * ooo#72096
+ * On Window the underlying SearchPath searches in order of...
+ * The directory from which the application loaded.
+ * The current directory.
+ * The Windows system directory.
+ * The Windows directory.
+ * The directories that are listed in the PATH environment variable.
+ *
+ * Because one of our programs is called "convert" and there is a convert
+ * in the windows system directory, we want to explicitly search the PATH
+ * to avoid picking up on that one if ImageMagick's convert preceeds it in
+ * PATH.
+ *
+ */
+ rtl::OUString url;
+ rtl::OUString path(_wgetenv(L"PATH"));
+
+ oslFileError err = osl_searchFileURL(rProgName.pData, path.pData, &url.pData);
+ if (err != osl_File_E_None)
+ return osl_Process_E_NotFound;
+ return osl_executeProcess_WithRedirectedIO(url.pData,
+ pArgs, nArgs, osl_Process_HIDDEN,
+ osl_getCurrentSecurity(), 0, 0, 0, pProcess, pIn, pOut, pErr);
+#else
+ return osl_executeProcess_WithRedirectedIO(rProgName.pData,
+ pArgs, nArgs, osl_Process_SEARCHPATH | osl_Process_HIDDEN,
+ osl_getCurrentSecurity(), 0, 0, 0, pProcess, pIn, pOut, pErr);
+#endif
+}
+
+#if defined(WNT) || defined(OS2)
+# define EXESUFFIX ".exe"
+#else
+# define EXESUFFIX ""
+#endif
+
static bool RenderAsEMF(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &rGraphic)
{
TempFile aTemp;
aTemp.EnableKillingFile();
rtl::OUString fileName =
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("pstoedit"));
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("pstoedit"EXESUFFIX));
rtl::OUString arg1 =
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-f"));
rtl::OUString arg2 =
@@ -186,10 +228,10 @@ static bool RenderAsEMF(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &r
oslFileHandle pIn = NULL;
oslFileHandle pOut = NULL;
oslFileHandle pErr = NULL;
- oslProcessError eErr = osl_executeProcess_WithRedirectedIO(fileName.pData,
- args, sizeof(args)/sizeof(rtl_uString *),
- osl_Process_SEARCHPATH | osl_Process_HIDDEN,
- osl_getCurrentSecurity(), 0, 0, 0, &aProcess, &pIn, &pOut, &pErr);
+ oslProcessError eErr = runProcessWithPathSearch(fileName,
+ args, sizeof(args)/sizeof(rtl_uString *),
+ &aProcess, &pIn, &pOut, &pErr);
+
if (eErr!=osl_Process_E_None)
return false;
@@ -222,15 +264,15 @@ static bool RenderAsEMF(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &r
}
static bool RenderAsPNGThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRead,
- Graphic &rGraphic, rtl::OUString &rProgName, rtl_uString **pArgs, size_t nArgs)
+ Graphic &rGraphic, rtl::OUString &rProgName, rtl_uString *pArgs[], size_t nArgs)
{
oslProcess aProcess;
oslFileHandle pIn = NULL;
oslFileHandle pOut = NULL;
oslFileHandle pErr = NULL;
- oslProcessError eErr = osl_executeProcess_WithRedirectedIO(rProgName.pData,
- pArgs, nArgs, osl_Process_SEARCHPATH | osl_Process_HIDDEN,
- osl_getCurrentSecurity(), 0, 0, 0, &aProcess, &pIn, &pOut, &pErr);
+ oslProcessError eErr = runProcessWithPathSearch(rProgName,
+ pArgs, nArgs,
+ &aProcess, &pIn, &pOut, &pErr);
if (eErr!=osl_Process_E_None)
return false;
@@ -251,7 +293,7 @@ static bool RenderAsPNGThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRea
aMemStm.Seek(0);
if (
- eFileErr == osl_File_E_None &&
+ aMemStm.GetEndOfData() &&
GraphicConverter::Import(aMemStm, rGraphic, CVT_PNG) == ERRCODE_NONE
)
{
@@ -270,7 +312,7 @@ static bool RenderAsPNGThroughConvert(const sal_uInt8* pBuf, sal_uInt32 nBytesRe
Graphic &rGraphic)
{
rtl::OUString fileName =
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("convert"));
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("convert"EXESUFFIX));
// density in pixel/inch
rtl::OUString arg1 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-density"));
// since the preview is also used for PDF-Export & printing on non-PS-printers,
@@ -293,10 +335,10 @@ static bool RenderAsPNGThroughGS(const sal_uInt8* pBuf, sal_uInt32 nBytesRead,
{
#ifdef WNT
rtl::OUString fileName =
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gswin32c"));
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gswin32c"EXESUFFIX));
#else
rtl::OUString fileName =
- rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gs"));
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gs"EXESUFFIX));
#endif
rtl::OUString arg1 =
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-q"));
diff --git a/goodies/source/filter.vcl/ios2met/ios2met.cxx b/goodies/source/filter.vcl/ios2met/ios2met.cxx
index 0fbf24f56029..8c3c19e22379 100644
--- a/goodies/source/filter.vcl/ios2met/ios2met.cxx
+++ b/goodies/source/filter.vcl/ios2met/ios2met.cxx
@@ -846,7 +846,7 @@ void OS2METReader::ReadRelLine(BOOL bGivenPos, USHORT nOrderLen)
if (nPolySize==0) return;
Polygon aPolygon(nPolySize);
for (i=0; i<nPolySize; i++) {
-#if (defined SOLARIS && defined PPC) || defined IRIX
+#if defined SOLARIS && defined PPC
UINT8 nunsignedbyte;
*pOS2MET >> nunsignedbyte; aP0.X()+=(INT8)nunsignedbyte;
*pOS2MET >> nunsignedbyte; aP0.Y()+=(INT8)nunsignedbyte;
diff --git a/goodies/source/graphic/grfmgr.cxx b/goodies/source/graphic/grfmgr.cxx
index 39c1e53e7184..7f5970383075 100644
--- a/goodies/source/graphic/grfmgr.cxx
+++ b/goodies/source/graphic/grfmgr.cxx
@@ -845,7 +845,7 @@ const Graphic& GraphicObject::GetGraphic() const
// -----------------------------------------------------------------------------
-void GraphicObject::SetGraphic( const Graphic& rGraphic )
+void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
{
mpMgr->ImplUnregisterObj( *this );
@@ -858,7 +858,7 @@ void GraphicObject::SetGraphic( const Graphic& rGraphic )
delete mpLink, mpLink = NULL;
delete mpSimpleCache, mpSimpleCache = NULL;
- mpMgr->ImplRegisterObj( *this, maGraphic );
+ mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj);
if( mpSwapOutTimer )
mpSwapOutTimer->Start();
diff --git a/padmin/source/padialog.cxx b/padmin/source/padialog.cxx
index f73427526be6..5a6a1d0e319e 100644
--- a/padmin/source/padialog.cxx
+++ b/padmin/source/padialog.cxx
@@ -60,11 +60,16 @@
#include "unotools/localedatawrapper.hxx"
#include "unotools/configitem.hxx"
#include "unotools/configmgr.hxx"
+
+#include "com/sun/star/awt/Size.hpp"
+
using namespace psp;
using namespace rtl;
using namespace padmin;
using namespace osl;
+using namespace com::sun::star;
using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
PADialog* PADialog::Create( Window* pParent, BOOL bAdmin )
{
@@ -96,7 +101,6 @@ PADialog::PADialog( Window* pParent, BOOL /*bAdmin*/ ) :
m_aCancelButton( this, PaResId( RID_PA_BTN_CANCEL ) ),
m_aDefPrt( PaResId( RID_PA_STR_DEFPRT ) ),
m_aRenameStr( PaResId( RID_PA_STR_RENAME ) ),
- m_pPrinter( 0 ),
m_rPIManager( PrinterInfoManager::get() )
{
FreeResource();
@@ -248,18 +252,6 @@ IMPL_LINK( PADialog, SelectHdl, ListBox*, pListBox )
return 0;
}
-IMPL_LINK( PADialog, EndPrintHdl, void*, EMPTYARG )
-{
- String aInfoString( PaResId( RID_PA_TXT_TESTPAGE_PRINTED ) );
- InfoBox aInfoBox( this, aInfoString );
- aInfoBox.SetText( String( PaResId( RID_BXT_TESTPAGE ) ) );
- aInfoBox.Execute();
-
- delete m_pPrinter;
- m_pPrinter = NULL;
- return 0;
-}
-
void PADialog::UpdateDefPrt()
{
m_rPIManager.setDefaultPrinter( getSelectedDevice() );
@@ -369,66 +361,77 @@ static Color approachColor( const Color& rFrom, const Color& rTo )
return aColor;
}
-#define DELTA 5.0
-void PADialog::PrintTestPage()
+class SpaPrinterController : public vcl::PrinterController
{
- if( m_pPrinter ) // already printing; user pressed button twice
- return;
+public:
+ SpaPrinterController( const boost::shared_ptr<Printer>& i_pPrinter )
+ : vcl::PrinterController( i_pPrinter )
+ {}
+ virtual ~SpaPrinterController()
+ {}
+
+ virtual int getPageCount() const { return 1; }
+ virtual Sequence< PropertyValue > getPageParameters( int i_nPage ) const;
+ virtual void printPage( int i_nPage ) const;
+ virtual void jobFinished( com::sun::star::view::PrintableState );
+};
+
+Sequence< PropertyValue > SpaPrinterController::getPageParameters( int ) const
+{
+ Sequence< PropertyValue > aRet( 1 );
- String sPrinter( getSelectedDevice() );
+ Size aPageSize( getPrinter()->GetPaperSizePixel() );
+ aPageSize = getPrinter()->PixelToLogic( aPageSize, MapMode( MAP_100TH_MM ) );
+
+ awt::Size aSize;
+ aSize.Width = aPageSize.Width();
+ aSize.Height = aPageSize.Height();
+ aRet[0].Value = makeAny(aSize);
- m_pPrinter = new Printer( sPrinter );
+ return aRet;
+}
- PrinterInfo aInfo( m_rPIManager.getPrinterInfo( sPrinter ) );
+void SpaPrinterController::printPage( int ) const
+{
+ const double DELTA = 5.0;
+
+ boost::shared_ptr<Printer> pPrinter( getPrinter() );
+
+ PrinterInfo aInfo( psp::PrinterInfoManager::get().getPrinterInfo( pPrinter->GetName() ) );
const PPDParser* pPrintParser = aInfo.m_pParser;
MapMode aMapMode( MAP_100TH_MM );
Bitmap aButterfly( PaResId( RID_BUTTERFLY ) );
- m_pPrinter->SetMapMode( aMapMode );
- m_pPrinter->SetEndPrintHdl( LINK( this, PADialog, EndPrintHdl ) );
+ pPrinter->SetMapMode( aMapMode );
Any aRet = utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::PRODUCTNAME );
OUString aJobName;
aRet >>= aJobName;
aJobName = aJobName + OUString( RTL_CONSTASCII_USTRINGPARAM( " Testpage" ) );
- if( m_pPrinter->GetName() != sPrinter || ! m_pPrinter->StartJob( aJobName ) )
- {
- String aString( PaResId( RID_ERR_NOPRINTER ) );
- aString.SearchAndReplaceAscii( "%s", sPrinter );
- ErrorBox aErrorBox( this, WB_OK | WB_DEF_OK, aString );
- aErrorBox.SetText( String( PaResId( RID_BXT_ENVIRONMENT ) ) );
- aErrorBox.Execute();
- delete m_pPrinter;
- m_pPrinter = 0;
- return;
- }
- m_pPrinter->StartPage();
-
- Size aPaperSize=m_pPrinter->GetOutputSize();
+ Size aPaperSize=pPrinter->GetOutputSize();
Point aCenter( aPaperSize.Width()/2-300,
aPaperSize.Height() - aPaperSize.Width()/2 );
Point aP1( aPaperSize.Width()/48, 0), aP2( aPaperSize.Width()/40, 0 ), aPoint;
- m_pPrinter->DrawRect( Rectangle( Point( 0,0 ), aPaperSize ) );
- m_pPrinter->DrawRect( Rectangle( Point( 100,100 ),
+ pPrinter->DrawRect( Rectangle( Point( 0,0 ), aPaperSize ) );
+ pPrinter->DrawRect( Rectangle( Point( 100,100 ),
Size( aPaperSize.Width()-200,
aPaperSize.Height()-200 ) ) );
- m_pPrinter->DrawRect( Rectangle( Point( 200,200 ),
+ pPrinter->DrawRect( Rectangle( Point( 200,200 ),
Size( aPaperSize.Width()-400,
aPaperSize.Height()-400 ) ) );
- m_pPrinter->DrawRect( Rectangle( Point( 300,300 ),
+ pPrinter->DrawRect( Rectangle( Point( 300,300 ),
Size( aPaperSize.Width()-600,
aPaperSize.Height()-600 ) ) );
- Font aFont( m_pPrinter->GetFont() );
- aFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Courier" ) ) );
+ Font aFont( String( RTL_CONSTASCII_USTRINGPARAM( "Courier" ) ), Size( 0, 400 ) );
aFont.SetWeight( WEIGHT_NORMAL );
aFont.SetItalic( ITALIC_NONE );
- m_pPrinter->SetFont( aFont );
+ pPrinter->SetFont( aFont );
OUStringBuffer aPrintText(1024);
long nWidth = 0, nMaxWidth = 0;
@@ -455,12 +458,12 @@ void PADialog::PrintTestPage()
aToken = String::CreateFromAscii( aResIds[i].pDirect );
else
aToken = String( PaResId( aResIds[i].nResId ) );
- nMaxWidth = ( nWidth = m_pPrinter->GetTextWidth( aToken ) ) > nMaxWidth ? nWidth : nMaxWidth;
+ nMaxWidth = ( nWidth = pPrinter->GetTextWidth( aToken ) ) > nMaxWidth ? nWidth : nMaxWidth;
aPrintText.append( aToken );
aPrintText.append( (sal_Unicode)'\n' );
};
- m_pPrinter->DrawText( Rectangle( Point( 1000, 2000 ),
+ pPrinter->DrawText( Rectangle( Point( 1000, 1000 ),
Size( aPaperSize.Width() - 2000,
aPaperSize.Height() - 4000 ) ),
aPrintText.makeStringAndClear(),
@@ -470,7 +473,7 @@ void PADialog::PrintTestPage()
const LocaleDataWrapper& rLocaleWrapper( aSettings.GetLocaleDataWrapper() );
aPrintText.appendAscii( ": " );
- aPrintText.append( sPrinter );
+ aPrintText.append( pPrinter->GetName() );
aPrintText.appendAscii( "\n: " );
if( pPrintParser )
aPrintText.append( pPrintParser->getPrinterName() );
@@ -487,17 +490,17 @@ void PADialog::PrintTestPage()
aPrintText.appendAscii( "\n: " );
aPrintText.append( rLocaleWrapper.getTime( Time() ) );
- m_pPrinter->DrawText( Rectangle( Point( 1100 + nMaxWidth, 2000 ),
+ pPrinter->DrawText( Rectangle( Point( 1100 + nMaxWidth, 1000 ),
Size( aPaperSize.Width() - 2100 - nMaxWidth,
aPaperSize.Height() - 4000 ) ),
aPrintText.makeStringAndClear(),
TEXT_DRAW_MULTILINE );
- m_pPrinter->DrawBitmap( Point( aPaperSize.Width() - 4000, 1000 ),
+ pPrinter->DrawBitmap( Point( aPaperSize.Width() - 4000, 1000 ),
Size( 3000,3000 ),
aButterfly );
- m_pPrinter->SetFillColor();
- m_pPrinter->DrawRect( Rectangle( Point( aPaperSize.Width() - 4000, 1000 ),
+ pPrinter->SetFillColor();
+ pPrinter->DrawRect( Rectangle( Point( aPaperSize.Width() - 4000, 1000 ),
Size( 3000,3000 ) ) );
Color aWhite( 0xff, 0xff, 0xff );
@@ -511,22 +514,22 @@ void PADialog::PrintTestPage()
Gradient aGradient( GRADIENT_LINEAR, aBlack, aWhite );
aGradient.SetAngle( 900 );
- m_pPrinter->DrawGradient( Rectangle( Point( 1000, 5500 ),
+ pPrinter->DrawGradient( Rectangle( Point( 1000, 5500 ),
Size( aPaperSize.Width() - 2000,
500 ) ), aGradient );
aGradient.SetStartColor( aDarkRed );
aGradient.SetEndColor( aLightBlue );
- m_pPrinter->DrawGradient( Rectangle( Point( 1000, 6300 ),
+ pPrinter->DrawGradient( Rectangle( Point( 1000, 6300 ),
Size( aPaperSize.Width() - 2000,
500 ) ), aGradient );
aGradient.SetStartColor( aDarkBlue );
aGradient.SetEndColor( aLightGreen );
- m_pPrinter->DrawGradient( Rectangle( Point( 1000, 7100 ),
+ pPrinter->DrawGradient( Rectangle( Point( 1000, 7100 ),
Size( aPaperSize.Width() - 2000,
500 ) ), aGradient );
aGradient.SetStartColor( aDarkGreen );
aGradient.SetEndColor( aLightRed );
- m_pPrinter->DrawGradient( Rectangle( Point( 1000, 7900 ),
+ pPrinter->DrawGradient( Rectangle( Point( 1000, 7900 ),
Size( aPaperSize.Width() - 2000,
500 ) ), aGradient );
@@ -543,7 +546,7 @@ void PADialog::PrintTestPage()
{
aLineInfo.SetWidth( n/3 );
aLineColor = approachColor( aLineColor, aApproachColor );
- m_pPrinter->SetLineColor( aLineColor );
+ pPrinter->SetLineColor( aLineColor );
// switch aproach color
if( aApproachColor.IsRGBEqual( aLineColor ) )
@@ -556,7 +559,7 @@ void PADialog::PrintTestPage()
aApproachColor = Color( 0, 200, 0 );
}
- m_pPrinter->DrawLine( project( aP1 ) + aCenter,
+ pPrinter->DrawLine( project( aP1 ) + aCenter,
project( aP2 ) + aCenter,
aLineInfo );
aPoint.X() = (int)((((double)aP1.X())*cosd - ((double)aP1.Y())*sind)*factor);
@@ -569,8 +572,38 @@ void PADialog::PrintTestPage()
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
fprintf( stderr, "%d lines\n",n );
#endif
- m_pPrinter->EndPage();
- m_pPrinter->EndJob();
+}
+
+void SpaPrinterController::jobFinished( com::sun::star::view::PrintableState )
+{
+ String aInfoString( PaResId( RID_PA_TXT_TESTPAGE_PRINTED ) );
+ InfoBox aInfoBox( NULL, aInfoString );
+ aInfoBox.SetText( String( PaResId( RID_BXT_TESTPAGE ) ) );
+ aInfoBox.Execute();
+}
+
+void PADialog::PrintTestPage()
+{
+ String sPrinter( getSelectedDevice() );
+
+ boost::shared_ptr<Printer> pPrinter( new Printer( sPrinter ) );
+
+ if( pPrinter->GetName() != sPrinter )
+ {
+ String aString( PaResId( RID_ERR_NOPRINTER ) );
+ aString.SearchAndReplaceAscii( "%s", sPrinter );
+
+ ErrorBox aErrorBox( this, WB_OK | WB_DEF_OK, aString );
+ aErrorBox.SetText( String( PaResId( RID_BXT_ENVIRONMENT ) ) );
+ aErrorBox.Execute();
+ return;
+ }
+
+ boost::shared_ptr<vcl::PrinterController> pController( new SpaPrinterController( pPrinter ) );
+ JobSetup aJobSetup( pPrinter->GetJobSetup() );
+ aJobSetup.SetValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ),
+ String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
+ Printer::PrintJob( pController, aJobSetup );
}
void PADialog::AddDevice()
diff --git a/padmin/source/padialog.hxx b/padmin/source/padialog.hxx
index ac6ee8f4279f..0350f66a2905 100644
--- a/padmin/source/padialog.hxx
+++ b/padmin/source/padialog.hxx
@@ -83,7 +83,6 @@ namespace padmin {
String m_aDefPrt;
String m_aRenameStr;
- Printer* m_pPrinter;
::psp::PrinterInfoManager& m_rPIManager;
::std::list< ::rtl::OUString > m_aPrinters;
@@ -94,7 +93,6 @@ namespace padmin {
DECL_LINK( ClickBtnHdl, PushButton* );
DECL_LINK( DoubleClickHdl, ListBox* );
DECL_LINK( SelectHdl, ListBox* );
- DECL_LINK( EndPrintHdl, void* );
DECL_LINK( DelPressedHdl, ListBox* );
PADialog( Window*, BOOL );
diff --git a/rsc/source/parser/rscicpx.cxx b/rsc/source/parser/rscicpx.cxx
index 9ae58087a335..e59a1e056f4b 100644
--- a/rsc/source/parser/rscicpx.cxx
+++ b/rsc/source/parser/rscicpx.cxx
@@ -2281,6 +2281,7 @@ RscTop * RscTypCont::InitClassTabControl( RscTop * pSuper,
RSC_TABCONTROL_ITEMLIST );
INS_WINBIT( pClassTabControl, SingleLine );
+ INS_WINBIT( pClassTabControl, DropDown );
}
return pClassTabControl;
diff --git a/rsc/source/parser/rsclex.cxx b/rsc/source/parser/rsclex.cxx
index 3c2c95e541d1..8c34637fa304 100644
--- a/rsc/source/parser/rsclex.cxx
+++ b/rsc/source/parser/rsclex.cxx
@@ -317,7 +317,7 @@ int yylex()
/****************** yyerror **********************************************/
#ifdef RS6000
extern "C" void yyerror( char* pMessage )
-#elif defined HP9000 || defined SCO || defined IRIX || defined SOLARIS
+#elif defined HP9000 || defined SCO || defined SOLARIS
extern "C" void yyerror( const char* pMessage )
#else
void yyerror( char* pMessage )
diff --git a/rsc/source/parser/rsclex.hxx b/rsc/source/parser/rsclex.hxx
index 89feed4dd132..63afd0b208c7 100644
--- a/rsc/source/parser/rsclex.hxx
+++ b/rsc/source/parser/rsclex.hxx
@@ -107,7 +107,7 @@ class ObjectStack {
extern "C" int yyparse(); // forward Deklaration fuer erzeugte Funktion
extern "C" void yyerror( char * );
extern "C" int yylex( void );
-#elif defined( HP9000 ) || defined( SCO ) || defined ( IRIX ) || defined ( SOLARIS )
+#elif defined( HP9000 ) || defined( SCO ) || defined ( SOLARIS )
extern "C" int yyparse(); // forward Deklaration fuer erzeugte Funktion
extern "C" void yyerror( const char * );
extern "C" int yylex( void );
diff --git a/rsc/source/rsc/makefile.mk b/rsc/source/rsc/makefile.mk
index 40e2d77740a3..89abd22207d9 100644
--- a/rsc/source/rsc/makefile.mk
+++ b/rsc/source/rsc/makefile.mk
@@ -40,10 +40,6 @@ ENABLE_EXCEPTIONS=true
.INCLUDE : settings.mk
-.IF "$(OS)"=="IRIX"
-NOOPTFILES= $(OBJ)$/rsc.obj
-.ENDIF
-
OBJFILES= $(OBJ)$/rsc.obj
.INCLUDE : target.mk
diff --git a/sot/source/sdstor/stgstrms.cxx b/sot/source/sdstor/stgstrms.cxx
index 46ae3529439c..0e20af6118af 100644
--- a/sot/source/sdstor/stgstrms.cxx
+++ b/sot/source/sdstor/stgstrms.cxx
@@ -1104,7 +1104,7 @@ StgTmpStrm::~StgTmpStrm()
}
}
-ULONG StgTmpStrm::GetSize()
+ULONG StgTmpStrm::GetSize() const
{
ULONG n;
if( pStrm )
diff --git a/sot/source/sdstor/stgstrms.hxx b/sot/source/sdstor/stgstrms.hxx
index 806d562af6d0..fd7971da3aba 100644
--- a/sot/source/sdstor/stgstrms.hxx
+++ b/sot/source/sdstor/stgstrms.hxx
@@ -167,8 +167,7 @@ public:
~StgTmpStrm();
BOOL Copy( StgTmpStrm& );
void SetSize( ULONG );
- using SvMemoryStream::GetSize;
- ULONG GetSize();
+ ULONG GetSize() const;
};
#endif
diff --git a/svl/inc/svl/solar.hrc b/svl/inc/svl/solar.hrc
index 96149b89131c..26ab8a959c5e 100644
--- a/svl/inc/svl/solar.hrc
+++ b/svl/inc/svl/solar.hrc
@@ -2,13 +2,10 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2008 by Sun Microsystems, Inc.
+ * Copyright 2009 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
- * $RCSfile: solar.hrc,v $
- * $Revision: 1.6 $
- *
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -171,6 +168,9 @@
#define HID_START 32768
+#define HID_VCL_START (HID_START+100)
+#define HID_VCL_END (HID_START+150)
+
#define HID_SVTOOLS_START (HID_START+200)
#define HID_SVTOOLS_END (HID_START+299)
@@ -207,8 +207,10 @@
#define HID_GOODIES_START (HID_LIB_START+2100)
#define HID_GOODIES_END (HID_LIB_START+2199)
+#if 0 // currently unused range
#define HID_SCHEDULE_START (HID_LIB_START+2200)
#define HID_SCHEDULE_END (HID_LIB_START+3399)
+#endif
#define HID_CHANNEL_START (HID_LIB_START+3400)
#define HID_CHANNEL_END (HID_LIB_START+3499)
@@ -300,6 +302,5 @@
#define HID_EXTENSIONS_START (HID_OBJ_START+2281)
#define HID_EXTENSIONS_END (HID_OBJ_START+2800)
-
#endif
diff --git a/svl/inc/svl/svarray.hxx b/svl/inc/svl/svarray.hxx
index d2479cd5364f..555b7ad5fe84 100644
--- a/svl/inc/svl/svarray.hxx
+++ b/svl/inc/svl/svarray.hxx
@@ -1034,7 +1034,7 @@ public:\
#define C40_PTR_REPLACE( c, p) Replace( (c const *) p )
#define C40_GETPOS( c, r) GetPos( (c const *)r )
#else
-#if defined WTC || defined IRIX || defined ICC || defined HPUX || (defined GCC && __GNUC__ >= 3) || (defined(WNT) && _MSC_VER >= 1400)
+#if defined WTC || defined ICC || defined HPUX || (defined GCC && __GNUC__ >= 3) || (defined(WNT) && _MSC_VER >= 1400)
#define C40_INSERT( c, p, n ) Insert( (c const *&) p, n )
#define C40_PUSH( c, p) Push( (c const *&) p )
#define C40_PTR_INSERT( c, p ) Insert( (c const *&) p )
diff --git a/svl/source/numbers/numhead.cxx b/svl/source/numbers/numhead.cxx
index 99ff33433de3..3bb650b0c9ae 100644
--- a/svl/source/numbers/numhead.cxx
+++ b/svl/source/numbers/numhead.cxx
@@ -139,7 +139,7 @@ ImpSvNumMultipleReadHeader::ImpSvNumMultipleReadHeader(SvStream& rNewStream) :
ImpSvNumMultipleReadHeader::~ImpSvNumMultipleReadHeader()
{
- DBG_ASSERT( pMemStream->Tell() == pMemStream->GetSize(),
+ DBG_ASSERT( pMemStream->Tell() == pMemStream->GetEndOfData(),
"Sizes nicht vollstaendig gelesen" );
delete pMemStream;
delete [] pBuf;
diff --git a/svtools/inc/svtools/imapobj.hxx b/svtools/inc/svtools/imapobj.hxx
index b8da0e5c3ee8..46b73ee95f2c 100644
--- a/svtools/inc/svtools/imapobj.hxx
+++ b/svtools/inc/svtools/imapobj.hxx
@@ -96,7 +96,7 @@ public:
static rtl_TextEncoding nActualTextEncoding;
- IMapObject() {};
+ IMapObject();
IMapObject( const String& rURL,
const String& rAltText,
const String& rDesc,
diff --git a/svtools/source/control/filectrl.cxx b/svtools/source/control/filectrl.cxx
index d820dce097ed..f00cf45be0e6 100644
--- a/svtools/source/control/filectrl.cxx
+++ b/svtools/source/control/filectrl.cxx
@@ -78,6 +78,9 @@ WinBits FileControl::ImplInitStyle( WinBits nStyle )
maButton.SetStyle( (maButton.GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
}
+ const WinBits nAlignmentStyle = ( WB_TOP | WB_VCENTER | WB_BOTTOM );
+ maEdit.SetStyle( ( maEdit.GetStyle() & ~nAlignmentStyle ) | ( nStyle & nAlignmentStyle ) );
+
if ( !(nStyle & WB_NOGROUP) )
nStyle |= WB_GROUP;
diff --git a/svtools/source/dialogs/prnsetup.cxx b/svtools/source/dialogs/prnsetup.cxx
index dedb5b2d7143..74cfe7b1286a 100644
--- a/svtools/source/dialogs/prnsetup.cxx
+++ b/svtools/source/dialogs/prnsetup.cxx
@@ -59,7 +59,7 @@ void ImplFillPrnDlgListBox( const Printer* pPrinter,
}
pBox->Enable( nCount != 0 );
- pPropBtn->Enable( pPrinter->HasSupport( SUPPORT_SETUPDIALOG ) );
+ pPropBtn->Show( pPrinter->HasSupport( SUPPORT_SETUPDIALOG ) );
}
// -----------------------------------------------------------------------
diff --git a/svtools/source/filter.vcl/filter/filter2.cxx b/svtools/source/filter.vcl/filter/filter2.cxx
index d570dd34e50f..9e0e3ba43d54 100644
--- a/svtools/source/filter.vcl/filter/filter2.cxx
+++ b/svtools/source/filter.vcl/filter/filter2.cxx
@@ -471,7 +471,8 @@ BOOL GraphicDescriptor::ImpDetectJPG( SvStream& rStm, BOOL bExtendedInfo )
// Groesse des verbleibenden Puffers ermitteln
if ( bLinked )
- nMax = ( (SvMemoryStream&) rStm ).GetSize() - 16;
+ nMax = static_cast< SvMemoryStream& >(rStm).GetEndOfData()
+ - 16;
else
nMax = DATA_SIZE - 16;
diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter.vcl/wmf/emfwr.cxx
index df56afc4a250..e011dde1a0e8 100644
--- a/svtools/source/filter.vcl/wmf/emfwr.cxx
+++ b/svtools/source/filter.vcl/wmf/emfwr.cxx
@@ -33,6 +33,9 @@
#include "emfwr.hxx"
#include <vcl/salbtype.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/lineinfo.hxx>
// -----------
// - Defines -
@@ -829,6 +832,46 @@ void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, cons
// -----------------------------------------------------------------------------
+void EMFWriter::Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
+{
+ if(rLinePolygon.count())
+ {
+ basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+
+ rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
+
+ if(aLinePolyPolygon.count())
+ {
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ ImplWritePolygonRecord( Polygon(aCandidate), FALSE );
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor(maVDev.GetLineColor());
+ const Color aOldFillColor(maVDev.GetFillColor());
+
+ maVDev.SetLineColor();
+ maVDev.SetFillColor(aOldLineColor);
+
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
+ ImplWritePolyPolygonRecord(PolyPolygon(Polygon(aPolygon)));
+ }
+
+ maVDev.SetLineColor(aOldLineColor);
+ maVDev.SetFillColor(aOldFillColor);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
{
for( ULONG j = 0, nActionCount = rMtf.GetActionCount(); j < nActionCount; j++ )
@@ -871,20 +914,31 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
{
const MetaLineAction* pA = (const MetaLineAction*) pAction;
- ImplCheckLineAttr();
+ if(pA->GetLineInfo().IsDefault())
+ {
+ ImplCheckLineAttr();
- ImplBeginRecord( WIN_EMR_MOVETOEX );
- ImplWritePoint( pA->GetStartPoint() );
- ImplEndRecord();
+ ImplBeginRecord( WIN_EMR_MOVETOEX );
+ ImplWritePoint( pA->GetStartPoint() );
+ ImplEndRecord();
- ImplBeginRecord( WIN_EMR_LINETO );
- ImplWritePoint( pA->GetEndPoint() );
- ImplEndRecord();
+ ImplBeginRecord( WIN_EMR_LINETO );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplEndRecord();
- ImplBeginRecord( WIN_EMR_SETPIXELV );
- ImplWritePoint( pA->GetEndPoint() );
- ImplWriteColor( maVDev.GetLineColor() );
- ImplEndRecord();
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
+ aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
+ Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
+ }
}
}
break;
@@ -983,7 +1037,23 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
case( META_POLYLINE_ACTION ):
{
if( maVDev.IsLineColor() )
- ImplWritePolygonRecord( ( (const MetaPolyLineAction*) pAction )->GetPolygon(), FALSE );
+ {
+ const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction;
+ const Polygon& rPoly = pA->GetPolygon();
+
+ if( rPoly.GetSize() )
+ {
+ if(pA->GetLineInfo().IsDefault())
+ {
+ ImplWritePolygonRecord( rPoly, FALSE );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ Impl_handleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
+ }
+ }
+ }
}
break;
diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter.vcl/wmf/emfwr.hxx
index 150aa1692ade..2d3c8801ba49 100644
--- a/svtools/source/filter.vcl/wmf/emfwr.hxx
+++ b/svtools/source/filter.vcl/wmf/emfwr.hxx
@@ -42,6 +42,9 @@
// - EMFWriter -
// -------------
+class LineInfo;
+namespace basegfx { class B2DPolygon; }
+
class EMFWriter
{
private:
@@ -86,6 +89,7 @@ private:
void ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, const Size& rSz, UINT32 nROP );
void ImplWriteTextRecord( const Point& rPos, const String rText, const sal_Int32* pDXArray, sal_uInt32 nWidth );
+ void Impl_handleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
void ImplWrite( const GDIMetaFile& rMtf );
public:
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter.vcl/wmf/wmfwr.cxx
index d25d4e94f97a..30d4ff06c0d2 100644
--- a/svtools/source/filter.vcl/wmf/wmfwr.cxx
+++ b/svtools/source/filter.vcl/wmf/wmfwr.cxx
@@ -42,8 +42,9 @@
#include <i18nutil/unicode.hxx> //unicode::getUnicodeScriptType
#endif
-
#include <vcl/metric.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
//====================== MS-Windows-defines ===============================
@@ -1136,6 +1137,49 @@ void WMFWriter::SetAllAttr()
}
+void WMFWriter::HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon)
+{
+ if(rLinePolygon.count())
+ {
+ basegfx::B2DPolyPolygon aLinePolyPolygon(rLinePolygon);
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+
+ rInfo.applyToB2DPolyPolygon(aLinePolyPolygon, aFillPolyPolygon);
+
+ if(aLinePolyPolygon.count())
+ {
+ aSrcLineInfo = rInfo;
+ SetLineAndFillAttr();
+
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ WMFRecord_PolyLine(Polygon(aCandidate));
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor(aSrcLineColor);
+ const Color aOldFillColor(aSrcFillColor);
+
+ aSrcLineColor = Color( COL_TRANSPARENT );
+ aSrcFillColor = aOldLineColor;
+ SetLineAndFillAttr();
+
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
+ WMFRecord_Polygon(Polygon(aPolygon));
+ }
+
+ aSrcLineColor = aOldLineColor;
+ aSrcFillColor = aOldFillColor;
+ SetLineAndFillAttr();
+ }
+ }
+}
+
void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
{
ULONG nA, nACount;
@@ -1176,10 +1220,21 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
case META_LINE_ACTION:
{
const MetaLineAction* pA = (const MetaLineAction *) pMA;
- aSrcLineInfo = pA->GetLineInfo();
- SetLineAndFillAttr();
- WMFRecord_MoveTo( pA->GetStartPoint() );
- WMFRecord_LineTo( pA->GetEndPoint() );
+ if(pA->GetLineInfo().IsDefault())
+ {
+ aSrcLineInfo = pA->GetLineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_MoveTo( pA->GetStartPoint() );
+ WMFRecord_LineTo( pA->GetEndPoint() );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(basegfx::B2DPoint(pA->GetStartPoint().X(), pA->GetStartPoint().Y()));
+ aPolygon.append(basegfx::B2DPoint(pA->GetEndPoint().X(), pA->GetEndPoint().Y()));
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), aPolygon);
+ }
}
break;
@@ -1241,9 +1296,22 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
case META_POLYLINE_ACTION:
{
const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
- aSrcLineInfo = pA->GetLineInfo();
- SetLineAndFillAttr();
- WMFRecord_PolyLine( pA->GetPolygon() );
+ const Polygon& rPoly = pA->GetPolygon();
+
+ if( rPoly.GetSize() )
+ {
+ if(pA->GetLineInfo().IsDefault())
+ {
+ aSrcLineInfo = pA->GetLineInfo();
+ SetLineAndFillAttr();
+ WMFRecord_PolyLine( rPoly );
+ }
+ else
+ {
+ // LineInfo used; handle Dash/Dot and fat lines
+ HandleLineInfoPolyPolygons(pA->GetLineInfo(), rPoly.getB2DPolygon());
+ }
+ }
}
break;
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter.vcl/wmf/wmfwr.hxx
index 48986a280404..03ca14e7633f 100644
--- a/svtools/source/filter.vcl/wmf/wmfwr.hxx
+++ b/svtools/source/filter.vcl/wmf/wmfwr.hxx
@@ -65,6 +65,9 @@ struct WMFWriterAttrStackMember
// -------------
class StarSymbolToMSMultiFont;
+class LineInfo;
+namespace basegfx { class B2DPolygon; }
+
class WMFWriter
{
private:
@@ -202,6 +205,7 @@ private:
void SetLineAndFillAttr();
void SetAllAttr();
+ void HandleLineInfoPolyPolygons(const LineInfo& rInfo, const basegfx::B2DPolygon& rLinePolygon);
void WriteRecords(const GDIMetaFile & rMTF);
void WriteHeader(const GDIMetaFile & rMTF, BOOL bPlaceable);
diff --git a/svtools/source/misc/imap.cxx b/svtools/source/misc/imap.cxx
index df7760f7931b..b0aaee113c20 100644
--- a/svtools/source/misc/imap.cxx
+++ b/svtools/source/misc/imap.cxx
@@ -64,6 +64,12 @@ UINT16 IMapObject::nActualTextEncoding = (UINT16) RTL_TEXTENCODING_DONTKNOW;
#pragma optimize ( "", off )
#endif
+IMapObject::IMapObject()
+ : bActive( false )
+ , nReadVersion( 0 )
+{
+}
+
IMapObject::IMapObject( const String& rURL, const String& rAltText, const String& rDesc,
const String& rTarget, const String& rName, BOOL bURLActive )
: aURL( rURL )
@@ -72,6 +78,7 @@ IMapObject::IMapObject( const String& rURL, const String& rAltText, const String
, aTarget( rTarget )
, aName( rName )
, bActive( bURLActive )
+, nReadVersion( 0 )
{
}
diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx
index a1ff1ad2ac3e..9c7c3eec33d1 100644
--- a/svtools/source/uno/unoiface.cxx
+++ b/svtools/source/uno/unoiface.cxx
@@ -549,86 +549,6 @@ void VCLXMultiLineEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
}
// ----------------------------------------------------
-// class VCLXFileDialog
-// ----------------------------------------------------
-/*
-VCLXFileDialog::VCLXFileDialog()
-{
-}
-
-VCLXFileDialog::~VCLXFileDialog()
-{
-}
-
-::com::sun::star::uno::Any VCLXFileDialog::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
-{
- ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
- SAL_STATIC_CAST( ::com::sun::star::awt::XXX*, this ) );
- return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
-}
-
-// ::com::sun::star::lang::XTypeProvider
-IMPL_XTYPEPROVIDER_START( VCLXFileDialog )
- getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XXX>* ) NULL )
-IMPL_XTYPEPROVIDER_END
-
-void VCLXFileDialog::setPath( const ::rtl::OUString& rPath )
-{
- ::vos::OGuard aGuard( GetMutex() );
-
- FileDialog* pDlg = (FileDialog*)GetWindow();
- if ( pDlg )
- pDlg->SetPath( ::rtl::OUStringToOString( rPath, CHARSET_SYSTEM ) );
-}
-
-::rtl::OUString VCLXFileDialog::getPath()
-{
- ::vos::OGuard aGuard( GetMutex() );
-
- ::rtl::OUString aPath;
- FileDialog* pDlg = (FileDialog*)GetWindow();
- if ( pDlg )
- aPath = StringToOUString( pDlg->GetPath(), CHARSET_SYSTEM );
- return aPath;
-}
-
-void VCLXFileDialog::setFilters( const ::com::sun::star::uno::Sequence< ::rtl::OUString>& rFilterNames, const ::com::sun::star::uno::Sequence< ::rtl::OUString>& rMasks )
-{
- ::vos::OGuard aGuard( GetMutex() );
-
- FileDialog* pDlg = (FileDialog*)GetWindow();
- if ( pDlg )
- {
- sal_uInt32 nFlts = rFilterNames.getLength();
- for ( sal_uInt32 n = 0; n < nFlts; n++ )
- pDlg->AddFilter(
- ::rtl::OUStringToOString( rFilterNames.getConstArray()[n], CHARSET_SYSTEM ),
- ::rtl::OUStringToOString( rMasks.getConstArray()[n], CHARSET_SYSTEM ) );
- }
-}
-
-void VCLXFileDialog::setCurrentFilter( const ::rtl::OUString& rFilterName )
-{
- ::vos::OGuard aGuard( GetMutex() );
-
- FileDialog* pDlg = (FileDialog*)GetWindow();
- if ( pDlg )
- pDlg->SetCurFilter( ::rtl::OUStringToOString( rFilterName, CHARSET_SYSTEM ) );
-}
-
-::rtl::OUString VCLXFileDialog::getCurrentFilter()
-{
- ::vos::OGuard aGuard( GetMutex() );
-
- ::rtl::OUString aFilter;
- FileDialog* pDlg = (FileDialog*)GetWindow();
- if ( pDlg )
- aFilter = StringToOUString( pDlg->GetCurFilter(), CHARSET_SYSTEM );
- return aFilter;
-}
-*/
-
-// ----------------------------------------------------
// class VCLXFileControl
// ----------------------------------------------------
VCLXFileControl::VCLXFileControl() : maTextListeners( *this )
diff --git a/svtools/util/makefile.mk b/svtools/util/makefile.mk
index 51ea7a9fef31..22be04f95d3f 100644
--- a/svtools/util/makefile.mk
+++ b/svtools/util/makefile.mk
@@ -112,6 +112,7 @@ SHL1STDLIBS+= \
$(VCLLIB) \
$(SVLLIB) \
$(SOTLIB) \
+ $(BASEGFXLIB) \
$(UNOTOOLSLIB) \
$(TOOLSLIB) \
$(I18NISOLANGLIB) \
diff --git a/toolkit/inc/toolkit/awt/vclxprinter.hxx b/toolkit/inc/toolkit/awt/vclxprinter.hxx
index e94864b51280..4db43a3c5d77 100644
--- a/toolkit/inc/toolkit/awt/vclxprinter.hxx
+++ b/toolkit/inc/toolkit/awt/vclxprinter.hxx
@@ -43,9 +43,7 @@
#include <toolkit/helper/mutexandbroadcasthelper.hxx>
#include <cppuhelper/propshlp.hxx>
-class Printer;
-class String;
-
+#include "vcl/oldprintadaptor.hxx"
// Fuer den Drucker relevante Properties:
/*
@@ -65,20 +63,17 @@ class VCLXPrinterPropertySet : public ::com::sun::star::awt::XPrinterPropertySe
public MutexAndBroadcastHelper,
public ::cppu::OPropertySetHelper
{
-private:
- Printer* mpPrinter;
+protected:
+ boost::shared_ptr<Printer> mpPrinter;
::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > mxPrnDevice;
sal_Int16 mnOrientation;
sal_Bool mbHorizontal;
-
-protected:
-
public:
VCLXPrinterPropertySet( const String& rPrinterName );
virtual ~VCLXPrinterPropertySet();
- Printer* GetPrinter() const { return mpPrinter; }
+ Printer* GetPrinter() const { return mpPrinter.get(); }
::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > GetDevice();
// ::com::sun::star::uno::XInterface
@@ -120,6 +115,8 @@ class VCLXPrinter: public ::com::sun::star::awt::XPrinter,
public VCLXPrinterPropertySet,
public ::cppu::OWeakObject
{
+ boost::shared_ptr<vcl::OldStylePrintAdaptor> mpListener;
+ JobSetup maInitJobSetup;
public:
VCLXPrinter( const String& rPrinterName );
~VCLXPrinter();
diff --git a/toolkit/source/awt/vclxprinter.cxx b/toolkit/source/awt/vclxprinter.cxx
index 69d8dd827497..a8059463a297 100644
--- a/toolkit/source/awt/vclxprinter.cxx
+++ b/toolkit/source/awt/vclxprinter.cxx
@@ -102,10 +102,10 @@ IMPL_XTYPEPROVIDER_END
VCLXPrinterPropertySet::VCLXPrinterPropertySet( const String& rPrinterName )
: OPropertySetHelper( BrdcstHelper )
+ , mpPrinter( new Printer( rPrinterName ) )
{
osl::Guard< vos::IMutex > aSolarGuard( Application::GetSolarMutex() );
- mpPrinter = new Printer( rPrinterName );
mnOrientation = 0;
mbHorizontal = sal_False;
}
@@ -113,8 +113,7 @@ VCLXPrinterPropertySet::VCLXPrinterPropertySet( const String& rPrinterName )
VCLXPrinterPropertySet::~VCLXPrinterPropertySet()
{
osl::Guard< vos::IMutex > aSolarGuard( Application::GetSolarMutex() );
-
- delete mpPrinter;
+ mpPrinter.reset();
}
::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXPrinterPropertySet::GetDevice()
@@ -326,13 +325,16 @@ IMPL_XTYPEPROVIDER_START( VCLXPrinter )
VCLXPrinterPropertySet::getTypes()
IMPL_XTYPEPROVIDER_END
-sal_Bool VCLXPrinter::start( const ::rtl::OUString& rJobName, sal_Int16 /*nCopies*/, sal_Bool /*bCollate*/ ) throw(::com::sun::star::awt::PrinterException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+sal_Bool VCLXPrinter::start( const ::rtl::OUString& /*rJobName*/, sal_Int16 /*nCopies*/, sal_Bool /*bCollate*/ ) throw(::com::sun::star::awt::PrinterException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
::osl::Guard< ::osl::Mutex > aGuard( Mutex );
sal_Bool bDone = sal_True;
- if ( GetPrinter() )
- bDone = GetPrinter()->StartJob( rJobName );
+ if ( mpListener.get() )
+ {
+ maInitJobSetup = mpPrinter->GetJobSetup();
+ mpListener.reset( new vcl::OldStylePrintAdaptor( mpPrinter ) );
+ }
return bDone;
}
@@ -341,24 +343,28 @@ void VCLXPrinter::end( ) throw(::com::sun::star::awt::PrinterException, ::com::
{
::osl::Guard< ::osl::Mutex > aGuard( Mutex );
- if ( GetPrinter() )
- GetPrinter()->EndJob();
+ if ( mpListener.get() )
+ {
+ Printer::PrintJob( mpListener, maInitJobSetup );
+ mpListener.reset();
+ }
}
void VCLXPrinter::terminate( ) throw(::com::sun::star::uno::RuntimeException)
{
::osl::Guard< ::osl::Mutex > aGuard( Mutex );
- if ( GetPrinter() )
- GetPrinter()->AbortJob();
+ mpListener.reset();
}
::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXPrinter::startPage( ) throw(::com::sun::star::awt::PrinterException, ::com::sun::star::uno::RuntimeException)
{
::osl::Guard< ::osl::Mutex > aGuard( Mutex );
- if ( GetPrinter() )
- GetPrinter()->StartPage();
+ if ( mpListener.get() )
+ {
+ mpListener->StartPage();
+ }
return GetDevice();
}
@@ -366,8 +372,10 @@ void VCLXPrinter::endPage( ) throw(::com::sun::star::awt::PrinterException, ::c
{
::osl::Guard< ::osl::Mutex > aGuard( Mutex );
- if ( GetPrinter() )
- GetPrinter()->EndPage();
+ if ( mpListener.get() )
+ {
+ mpListener->EndPage();
+ }
}
diff --git a/toolkit/source/awt/vclxwindows.cxx b/toolkit/source/awt/vclxwindows.cxx
index 7757d170256a..e41de1e8bd25 100644
--- a/toolkit/source/awt/vclxwindows.cxx
+++ b/toolkit/source/awt/vclxwindows.cxx
@@ -3390,6 +3390,7 @@ void VCLXEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_PAINTTRANSPARENT,
BASEPROPERTY_AUTOHSCROLL,
BASEPROPERTY_AUTOVSCROLL,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
0);
@@ -4283,6 +4284,7 @@ void VCLXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_ENFORCE_FORMAT,
BASEPROPERTY_TEXT,
BASEPROPERTY_HIDEINACTIVESELECTION,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
@@ -4624,6 +4626,7 @@ void VCLXTimeField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_ENFORCE_FORMAT,
BASEPROPERTY_TEXT,
BASEPROPERTY_HIDEINACTIVESELECTION,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
@@ -4927,6 +4930,7 @@ void VCLXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_VALUE_DOUBLE,
BASEPROPERTY_ENFORCE_FORMAT,
BASEPROPERTY_HIDEINACTIVESELECTION,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
@@ -5521,6 +5525,7 @@ void VCLXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_VALUE_DOUBLE,
BASEPROPERTY_ENFORCE_FORMAT,
BASEPROPERTY_HIDEINACTIVESELECTION,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
@@ -5868,6 +5873,7 @@ void VCLXPatternField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
BASEPROPERTY_TABSTOP,
BASEPROPERTY_TEXT,
BASEPROPERTY_HIDEINACTIVESELECTION,
+ BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
diff --git a/toolkit/source/controls/formattedcontrol.cxx b/toolkit/source/controls/formattedcontrol.cxx
index 6171067f1185..5ac7a0237479 100644
--- a/toolkit/source/controls/formattedcontrol.cxx
+++ b/toolkit/source/controls/formattedcontrol.cxx
@@ -160,6 +160,7 @@ namespace toolkit
ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT );
+ ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
ImplRegisterProperty( BASEPROPERTY_WRITING_MODE );
ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE );
ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR );
diff --git a/toolkit/source/controls/unocontrols.cxx b/toolkit/source/controls/unocontrols.cxx
index 3abacef7b67f..9e508c884f59 100644
--- a/toolkit/source/controls/unocontrols.cxx
+++ b/toolkit/source/controls/unocontrols.cxx
@@ -476,6 +476,7 @@ void UnoEditControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) t
// ----------------------------------------------------
UnoControlFileControlModel::UnoControlFileControlModel()
{
+ ImplRegisterProperty( BASEPROPERTY_ALIGN );
ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
ImplRegisterProperty( BASEPROPERTY_BORDER );
ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
@@ -489,6 +490,7 @@ UnoControlFileControlModel::UnoControlFileControlModel()
ImplRegisterProperty( BASEPROPERTY_READONLY );
ImplRegisterProperty( BASEPROPERTY_TABSTOP );
ImplRegisterProperty( BASEPROPERTY_TEXT );
+ ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
ImplRegisterProperty( BASEPROPERTY_WRITING_MODE );
ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE );
ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
diff --git a/tools/inc/tools/inetdef.hxx b/tools/inc/tools/inetdef.hxx
index 38cd8935e06b..d9861f64961d 100644
--- a/tools/inc/tools/inetdef.hxx
+++ b/tools/inc/tools/inetdef.hxx
@@ -61,8 +61,6 @@
#define TOOLS_INETDEF_OS "FreeBSD/amd64"
#elif defined SINIX
#define TOOLS_INETDEF_OS "SINIX"
-#elif defined IRIX
-#define TOOLS_INETDEF_OS "IRIX"
#else // AIX, HPUX, SOLARIS, ...
#define TOOLS_INETDEF_OS "Unix"
#endif // AIX, HPUX, SOLARIS, ...
diff --git a/tools/inc/tools/multisel.hxx b/tools/inc/tools/multisel.hxx
index 46fd8947e21b..9de3cc172e70 100644
--- a/tools/inc/tools/multisel.hxx
+++ b/tools/inc/tools/multisel.hxx
@@ -35,6 +35,9 @@
#include <tools/list.hxx>
#include <tools/string.hxx>
+#include <vector>
+#include <set>
+
//------------------------------------------------------------------
#ifdef _SV_MULTISEL_CXX
@@ -112,4 +115,105 @@ public:
const Range& GetRange( ULONG nRange ) const { return *(const Range*)aSels.GetObject(nRange); }
};
+class TOOLS_DLLPUBLIC StringRangeEnumerator
+{
+ struct Range
+ {
+ sal_Int32 nFirst;
+ sal_Int32 nLast;
+
+ Range() : nFirst( -1 ), nLast( -1 ) {}
+ Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {}
+ };
+ std::vector< StringRangeEnumerator::Range > maSequence;
+ sal_Int32 mnCount;
+ sal_Int32 mnMin;
+ sal_Int32 mnMax;
+ sal_Int32 mnOffset;
+
+ bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence, bool bMayAdjust );
+ bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+public:
+ class TOOLS_DLLPUBLIC Iterator
+ {
+ const StringRangeEnumerator* pEnumerator;
+ const std::set< sal_Int32 >* pPossibleValues;
+ sal_Int32 nRangeIndex;
+ sal_Int32 nCurrent;
+
+ friend class StringRangeEnumerator;
+ Iterator( const StringRangeEnumerator* i_pEnum,
+ const std::set< sal_Int32 >* i_pPossibleValues,
+ sal_Int32 i_nRange,
+ sal_Int32 i_nCurrent )
+ : pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues )
+ , nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {}
+ public:
+ Iterator() : pEnumerator( NULL ), pPossibleValues( NULL ), nRangeIndex( -1 ), nCurrent( -1 ) {}
+ Iterator& operator++();
+ sal_Int32 operator*() const;
+ bool operator==(const Iterator&) const;
+ bool operator!=(const Iterator& i_rComp) const
+ { return ! (*this == i_rComp); }
+ };
+
+ friend class StringRangeEnumerator::Iterator;
+
+ StringRangeEnumerator() : mnCount( 0 ), mnMin( -1 ), mnMax( -1 ), mnOffset( -1 ) {}
+ StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1
+ );
+
+ size_t size() const { return size_t(mnCount); }
+ Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+ Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+
+ sal_Int32 getMin() const { return mnMin; }
+ void setMin( sal_Int32 i_nMinValue ) { mnMin = i_nMinValue; }
+ sal_Int32 getMax() const { return mnMax; }
+ void setMax( sal_Int32 i_nMaxValue ) { mnMax = i_nMaxValue; }
+ sal_Int32 getLogicalOffset() const { return mnOffset; }
+ void setLogicalOffset( sal_Int32 i_nOffset ) { mnOffset = i_nOffset; }
+
+ bool setRange( const rtl::OUString& i_rNewRange, bool i_bStrict = false );
+ bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+
+
+ /**
+ i_rPageRange: the string to be changed into a sequence of numbers
+ valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well
+ o_rPageVector: the output sequence of numbers
+ i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence
+ example: a user enters page numbers from 1 to n (since that is logical)
+ of course usable page numbers in code would start from 0 and end at n-1
+ so the logical offset would be -1
+ i_nMinNumber: the minimum allowed number, a negative number means no minimum check
+ i_nMaxNumber: the maximum allowed number, a negative number means no maximum check
+
+ @returns: true if the input string was valid, o_rPageVector will contain the resulting sequence
+ false if the input string was invalid, o_rPageVector will be unchanged
+
+ behavior:
+ - only non-negative sequence numbers are allowed
+ - only non-negative values in the input string are allowed
+ - the string "-3" will be either
+ * an error if no minimum is given
+ * or result in the sequence i_nMinNumber to 3
+ - the string "3-" will be either
+ * an error if no maximum is given
+ * or result in the seqeuence 3 to i_nMaxNumber
+ - an empty string as input is valid and will result in the range [min,max] if given
+ or an empty vector, if not
+ */
+ static bool getRangesFromString( const rtl::OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1,
+ std::set< sal_Int32 >* i_pPossibleValues = NULL
+ );
+};
+
#endif // _SV_MULTISEL_HXX
diff --git a/tools/inc/tools/solar.h b/tools/inc/tools/solar.h
index cd069886d8b6..195a6fd3ce87 100644
--- a/tools/inc/tools/solar.h
+++ b/tools/inc/tools/solar.h
@@ -393,8 +393,6 @@ template<typename T> inline T Abs(T a) { return (a>=0?a:-a); }
#define __DLLEXTENSION "fi.so"
#elif defined FREEBSD && defined X86_64
#define __DLLEXTENSION "fx.so"
-#elif defined IRIX
- #define __DLLEXTENSION "im.so"
#elif defined MACOSX && defined POWERPC
#define __DLLEXTENSION "mxp.dylib"
#elif defined MACOSX && defined X86
diff --git a/tools/inc/tools/stream.hxx b/tools/inc/tools/stream.hxx
index bacaac89fe44..23496322fa4c 100644
--- a/tools/inc/tools/stream.hxx
+++ b/tools/inc/tools/stream.hxx
@@ -776,6 +776,9 @@ class TOOLS_DLLPUBLIC SvMemoryStream : public SvStream
SvMemoryStream (const SvMemoryStream&);
SvMemoryStream & operator= (const SvMemoryStream&);
+ friend class SvCacheStream;
+ sal_Size GetSize() const { return nSize; }
+
protected:
sal_Size nSize;
sal_Size nResize;
@@ -817,7 +820,7 @@ public:
virtual void ResetError();
- sal_Size GetSize() const { return nSize; }
+ sal_Size GetEndOfData() const { return nEndOfData; }
const void* GetData() { Flush(); return pBuf; }
operator const void*() { Flush(); return pBuf; }
virtual sal_uInt16 IsA() const;
diff --git a/tools/source/fsys/unx.cxx b/tools/source/fsys/unx.cxx
index 76910683df13..4a2e3c6ad76a 100644
--- a/tools/source/fsys/unx.cxx
+++ b/tools/source/fsys/unx.cxx
@@ -36,7 +36,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <utime.h>
-#if defined HPUX || defined LINUX || defined IRIX
+#if defined HPUX || defined LINUX
#include <mntent.h>
#define mnttab mntent
#elif defined SCO
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index f7ffed5e4dd1..e0f711bd2883 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -1022,16 +1022,14 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
{
sal_Unicode const * p1 = pPos + 2;
- if (
- p1 == pEnd || *p1 == nFragmentDelimiter || *p1 == '/' ||
- (
- (
- scanDomain(p1, pEnd) > 0 ||
- scanIPv6reference(p1, pEnd)
- ) &&
- (p1 == pEnd || *p1 == nFragmentDelimiter || *p1 == '/')
- )
- )
+ while (p1 != pEnd && *p1 != '/' &&
+ *p1 != nFragmentDelimiter)
+ {
+ ++p1;
+ }
+ if (parseHostOrNetBiosName(
+ pPos + 2, p1, bOctets, ENCODE_ALL,
+ RTL_TEXTENCODING_DONTKNOW, true, NULL))
{
aSynAbsURIRef.
appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx
index 7f1eb94b646d..509d2ab4969d 100644
--- a/tools/source/generic/poly.cxx
+++ b/tools/source/generic/poly.cxx
@@ -1615,7 +1615,16 @@ void Polygon::Clip( const Rectangle& rRect, BOOL bPolygon )
Rectangle Polygon::GetBoundRect() const
{
DBG_CHKTHIS( Polygon, NULL );
- DBG_ASSERT( !mpImplPolygon->mpFlagAry, "GetBoundRect could fail with beziers!" );
+ // Removing the assert. Bezier curves have the attribute that each single
+ // curve segment defined by four points can not exit the four-point polygon
+ // defined by that points. This allows to say that the curve segment can also
+ // never leave the Range of it's defining points.
+ // The result is that Polygon::GetBoundRect() may not create the minimal
+ // BoundRect of the Polygon (to get that, use basegfx::B2DPolygon classes),
+ // but will always create a valid BoundRect, at least as long as this method
+ // 'blindly' travels over all points, including control points.
+ //
+ // DBG_ASSERT( !mpImplPolygon->mpFlagAry, "GetBoundRect could fail with beziers!" );
USHORT nCount = mpImplPolygon->mnPoints;
if( ! nCount )
diff --git a/tools/source/memtools/makefile.mk b/tools/source/memtools/makefile.mk
index 037dadbf4a46..51d831ec0fed 100644
--- a/tools/source/memtools/makefile.mk
+++ b/tools/source/memtools/makefile.mk
@@ -47,6 +47,8 @@ SLOFILES= $(SLO)$/contnr.obj \
$(SLO)$/mempool.obj \
$(SLO)$/multisel.obj
+EXCEPTIONSFILES= $(SLO)$/multisel.obj $(OBJ)$/multisel.obj
+
OBJFILES= $(OBJ)$/contnr.obj \
$(OBJ)$/table.obj \
$(OBJ)$/unqidx.obj \
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
index 6b32badc283e..5fe920b6998a 100644
--- a/tools/source/memtools/multisel.cxx
+++ b/tools/source/memtools/multisel.cxx
@@ -41,12 +41,16 @@
#include <tools/debug.hxx>
#include <tools/multisel.hxx>
+#include "rtl/ustrbuf.hxx"
+
#ifdef MI_DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif
+using namespace rtl;
+
//==================================================================
#ifdef MI_DEBUG
@@ -865,3 +869,297 @@ void MultiSelection::SetTotalRange( const Range& rTotRange )
bCurValid = FALSE;
nCurIndex = 0;
}
+
+// -----------------------------------------------------------------------
+//
+// StringRangeEnumerator
+//
+// -----------------------------------------------------------------------
+StringRangeEnumerator::StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset
+ )
+ : mnCount( 0 )
+ , mnMin( i_nMinNumber )
+ , mnMax( i_nMaxNumber )
+ , mnOffset( i_nLogicalOffset )
+{
+ setRange( i_rInput );
+}
+
+bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( mnMin >= 0 && i_nValue < mnMin )
+ return false;
+ if( mnMax >= 0 && i_nValue > mnMax )
+ return false;
+ if( i_nValue < 0 )
+ return false;
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ return true;
+}
+
+bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
+{
+ bool bSuccess = true;
+ if( bSequence )
+ {
+ if( i_nFirst == -1 )
+ i_nFirst = mnMin;
+ if( i_nLast == -1 )
+ i_nLast = mnMax;
+ if( bMayAdjust )
+ {
+ if( i_nFirst < mnMin )
+ i_nFirst = mnMin;
+ if( i_nFirst > mnMax )
+ i_nFirst = mnMax;
+ if( i_nLast < mnMin )
+ i_nLast = mnMin;
+ if( i_nLast > mnMax )
+ i_nLast = mnMax;
+ }
+ if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nLast ) );
+ sal_Int32 nNumber = i_nLast - i_nFirst;
+ nNumber = nNumber < 0 ? -nNumber : nNumber;
+ mnCount += nNumber + 1;
+ }
+ else
+ bSuccess = false;
+ }
+ else
+ {
+ if( i_nFirst >= 0 )
+ {
+ if( checkValue( i_nFirst ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nFirst ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ if( i_nLast >= 0 )
+ {
+ if( checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nLast, i_nLast ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ }
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::setRange( const rtl::OUString& i_rNewRange, bool i_bStrict )
+{
+ mnCount = 0;
+ maSequence.clear();
+
+ // we love special cases
+ if( i_rNewRange.getLength() == 0 )
+ {
+ if( mnMin >= 0 && mnMax >= 0 )
+ {
+ insertRange( mnMin, mnMax, mnMin != mnMax, ! i_bStrict );
+ }
+ return true;
+ }
+
+ const sal_Unicode* pInput = i_rNewRange.getStr();
+ rtl::OUStringBuffer aNumberBuf( 16 );
+ sal_Int32 nLastNumber = -1, nNumber = -1;
+ bool bSequence = false;
+ bool bSuccess = true;
+ while( *pInput )
+ {
+ while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') )
+ aNumberBuf.append( *pInput++ );
+ if( aNumberBuf.getLength() )
+ {
+ if( nNumber != -1 )
+ {
+ if( bSequence )
+ {
+ if( ! insertRange( nLastNumber, nNumber, true, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nLastNumber = -1;
+ }
+ else
+ {
+ if( ! insertRange( nNumber, nNumber, false, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ }
+ }
+ nNumber = aNumberBuf.makeStringAndClear().toInt32();
+ nNumber += mnOffset;
+ }
+ bool bInsertRange = false;
+ if( *pInput == sal_Unicode('-') )
+ {
+ nLastNumber = nNumber;
+ nNumber = -1;
+ bSequence = true;
+ }
+ else if( *pInput == ' ' )
+ {
+ }
+ else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') )
+ bInsertRange = true;
+ else if( *pInput )
+ {
+
+ bSuccess = false;
+ break; // parse error
+ }
+
+ if( bInsertRange )
+ {
+ if( ! insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nNumber = nLastNumber = -1;
+ bSequence = false;
+ }
+ if( *pInput )
+ pInput++;
+ }
+ // insert last entries
+ insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict );
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ size_t n = maSequence.size();
+ for( size_t i= 0; i < n; ++i )
+ {
+ const StringRangeEnumerator::Range rRange( maSequence[i] );
+ if( rRange.nFirst < rRange.nLast )
+ {
+ if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
+ return true;
+ }
+ else
+ {
+ if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
+ return true;
+ }
+ }
+ return false;
+}
+
+StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
+{
+ if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
+ {
+ const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
+ bool bRangeChange = false;
+ if( rRange.nLast < rRange.nFirst )
+ {
+ // backward range
+ if( nCurrent > rRange.nLast )
+ nCurrent--;
+ else
+ bRangeChange = true;
+ }
+ else
+ {
+ // forward range
+ if( nCurrent < rRange.nLast )
+ nCurrent++;
+ else
+ bRangeChange = true;
+ }
+ if( bRangeChange )
+ {
+ nRangeIndex++;
+ if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
+ {
+ // reached the end
+ nRangeIndex = nCurrent = -1;
+ }
+ else
+ nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
+ }
+ if( nRangeIndex != -1 && nCurrent != -1 )
+ {
+ if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
+ return ++(*this);
+ }
+ }
+ return *this;
+}
+
+sal_Int32 StringRangeEnumerator::Iterator::operator*() const
+{
+ return nCurrent;
+}
+
+bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
+{
+ return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ StringRangeEnumerator::Iterator it( this,
+ i_pPossibleValues,
+ maSequence.empty() ? -1 : 0,
+ maSequence.empty() ? -1 : maSequence[0].nFirst );
+ if( ! checkValue(*it, i_pPossibleValues ) )
+ ++it;
+ return it;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
+}
+
+bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset,
+ std::set< sal_Int32 >* i_pPossibleValues
+ )
+{
+ StringRangeEnumerator aEnum;
+ aEnum.setMin( i_nMinNumber );
+ aEnum.setMax( i_nMaxNumber );
+ aEnum.setLogicalOffset( i_nLogicalOffset );
+
+ bool bRes = aEnum.setRange( i_rPageRange );
+ if( bRes )
+ {
+ o_rPageVector.clear();
+ o_rPageVector.reserve( aEnum.size() );
+ for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
+ it != aEnum.end( i_pPossibleValues ); ++it )
+ {
+ o_rPageVector.push_back( *it );
+ }
+ }
+
+ return bRes;
+}
+
diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx
index a232f8ebdd93..0e9d22081cb4 100644
--- a/tools/workben/urltest.cxx
+++ b/tools/workben/urltest.cxx
@@ -1629,6 +1629,20 @@ main()
rtl::OUString(urlobj.GetMainURL(INetURLObject::NO_DECODE)));
}
+ if (true) { // #i53184#
+ rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("file://comp_name/path"));
+ bSuccess &= assertEqual(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("#i53184# smart INET_PROT_FILE")),
+ INetURLObject(url, INET_PROT_FILE).GetMainURL(
+ INetURLObject::NO_DECODE),
+ url);
+ bSuccess &= assertEqual(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("#i53184# strict")),
+ INetURLObject(url).GetMainURL(INetURLObject::NO_DECODE), url);
+ }
+
if (true) {
rtl::OUString path;
path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/a/b/c"));
diff --git a/transex3/source/inireader.cxx b/transex3/source/inireader.cxx
index 0985e788452d..1ff34fad8e95 100644
--- a/transex3/source/inireader.cxx
+++ b/transex3/source/inireader.cxx
@@ -120,7 +120,7 @@ void INIreader::toStlString( const UnicodeString& str , string& stl_str)
char* buffer = new char[ str.length()*3 ];
str.extract( 0 , str.length() , buffer );
stl_str = string( buffer );
- delete buffer;
+ delete[] buffer;
}
void INIreader::trim( string& str )
diff --git a/unotools/inc/unotools/confignode.hxx b/unotools/inc/unotools/confignode.hxx
index 580274004e1a..2e305030fa2b 100644
--- a/unotools/inc/unotools/confignode.hxx
+++ b/unotools/inc/unotools/confignode.hxx
@@ -88,6 +88,9 @@ namespace utl
/// dtor
~OConfigurationNode() {}
+ /// returns the local name of the node
+ ::rtl::OUString getLocalName() const;
+
/** open a sub node
@param _rPath access path of the to-be-opened sub node. May be a hierarchical path.
*/
diff --git a/unotools/source/config/confignode.cxx b/unotools/source/config/confignode.cxx
index 4b1b9fe272db..56d258461e95 100644
--- a/unotools/source/config/confignode.cxx
+++ b/unotools/source/config/confignode.cxx
@@ -41,6 +41,7 @@
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/util/XStringEscape.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XNamed.hpp>
#include <comphelper/extract.hxx>
#include <rtl/string.hxx>
#if OSL_DEBUG_LEVEL > 0
@@ -139,6 +140,22 @@ namespace utl
}
//------------------------------------------------------------------------
+ ::rtl::OUString OConfigurationNode::getLocalName() const
+ {
+ ::rtl::OUString sLocalName;
+ try
+ {
+ Reference< XNamed > xNamed( m_xDirectAccess, UNO_QUERY_THROW );
+ sLocalName = xNamed->getName();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sLocalName;
+ }
+
+ //------------------------------------------------------------------------
::rtl::OUString OConfigurationNode::normalizeName(const ::rtl::OUString& _rName, NAMEORIGIN _eOrigin) const
{
::rtl::OUString sName(_rName);
@@ -155,13 +172,9 @@ namespace utl
else
sName = xEscaper->unescapeString(sName);
}
- catch(IllegalArgumentException&)
- {
- OSL_ENSURE(sal_False, "OConfigurationNode::normalizeName: illegal argument (caught an exception saying so)!");
- }
catch(Exception&)
{
- OSL_ENSURE(sal_False, "OConfigurationNode::normalizeName: caught an exception!");
+ DBG_UNHANDLED_EXCEPTION();
}
}
}
diff --git a/vcl/aqua/inc/aquaprintview.h b/vcl/aqua/inc/aquaprintview.h
index c5ce20c17425..55a85678cd50 100755
--- a/vcl/aqua/inc/aquaprintview.h
+++ b/vcl/aqua/inc/aquaprintview.h
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: aquaprintview.h,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.114.1 $
*
* This file is part of OpenOffice.org.
*
@@ -35,20 +35,36 @@
#include <Cocoa/Cocoa.h>
#include "postmac.h"
-class ImplQPrinter;
+#include "vcl/print.hxx"
+
class AquaSalInfoPrinter;
+struct PrintAccessoryViewState
+{
+ bool bNeedRestart;
+ sal_Int32 nLastPage;
+
+ PrintAccessoryViewState()
+ : bNeedRestart( false ), nLastPage( 0 ) {}
+};
+
@interface AquaPrintView : NSView
{
- ImplQPrinter* mpQPrinter;
- AquaSalInfoPrinter* mpInfoPrinter;
+ vcl::PrinterController* mpController;
+ AquaSalInfoPrinter* mpInfoPrinter;
}
--(id)initWithQPrinter: (ImplQPrinter*)pPrinter withInfoPrinter: (AquaSalInfoPrinter*)pInfoPrinter;
+-(id)initWithController: (vcl::PrinterController*)pController withInfoPrinter: (AquaSalInfoPrinter*)pInfoPrinter;
-(MacOSBOOL)knowsPageRange: (NSRangePointer)range;
-(NSRect)rectForPage: (int)page;
-(NSPoint)locationOfPrintRect: (NSRect)aRect;
-(void)drawRect: (NSRect)rect;
@end
+@interface AquaPrintAccessoryView : NSObject
+{
+}
++(NSObject*)setupPrinterPanel: (NSPrintOperation*)pOp withController: (vcl::PrinterController*)pController withState: (PrintAccessoryViewState*)pState;
+@end
+
#endif
diff --git a/vcl/aqua/inc/salgdi.h b/vcl/aqua/inc/salgdi.h
index 4933dbc48586..e835ac773a50 100644
--- a/vcl/aqua/inc/salgdi.h
+++ b/vcl/aqua/inc/salgdi.h
@@ -175,6 +175,9 @@ public:
void RefreshRect(float lX, float lY, float lWidth, float lHeight);
void SetState();
+ void UnsetState();
+ // InvalidateContext does an UnsetState and sets mrContext to 0
+ void InvalidateContext();
virtual BOOL unionClipRegion( long nX, long nY, long nWidth, long nHeight );
virtual bool unionClipRegion( const ::basegfx::B2DPolyPolygon& );
diff --git a/vcl/aqua/inc/salprn.h b/vcl/aqua/inc/salprn.h
index ec08261e8321..bf9c3c25bc87 100644
--- a/vcl/aqua/inc/salprn.h
+++ b/vcl/aqua/inc/salprn.h
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: salprn.h,v $
- * $Revision: 1.12 $
+ * $Revision: 1.12.56.1 $
*
* This file is part of OpenOffice.org.
*
@@ -73,8 +73,8 @@ class AquaSalInfoPrinter : public SalInfoPrinter
int mnStartPageOffsetX;
int mnStartPageOffsetY;
- ULONG mnCurPageRangeStart;
- ULONG mnCurPageRangeCount;
+ sal_Int32 mnCurPageRangeStart;
+ sal_Int32 mnCurPageRangeCount;
public:
AquaSalInfoPrinter( const SalPrinterQueueInfo& pInfo );
@@ -96,19 +96,17 @@ class AquaSalInfoPrinter : public SalInfoPrinter
virtual String GetPaperBinName( const ImplJobSetup* i_pSetupData, ULONG i_nPaperBin );
virtual void InitPaperFormats( const ImplJobSetup* i_pSetupData );
virtual int GetLandscapeAngle( const ImplJobSetup* i_pSetupData );
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* i_pSetupData );
-
// the artificial separation between InfoPrinter and Printer
// is not really useful for us
// so let's make AquaSalPrinter just a forwarder to AquaSalInfoPrinter
// and concentrate the real work in one class
// implement pull model print system
- BOOL StartJob( const String* pFileName,
- const String& rAppName,
- ImplJobSetup* pSetupData,
- ImplQPrinter* pQPrinter,
- bool bIsQuickJob );
+ BOOL StartJob( const String* i_pFileName,
+ const String& rJobName,
+ const String& i_rAppName,
+ ImplJobSetup* i_pSetupData,
+ vcl::PrinterController& i_rController );
BOOL EndJob();
BOOL AbortJob();
SalGraphics* StartPage( ImplJobSetup* i_pSetupData, BOOL i_bNewJobData );
@@ -117,8 +115,12 @@ class AquaSalInfoPrinter : public SalInfoPrinter
NSPrintInfo* getPrintInfo() const { return mpPrintInfo; }
void setStartPageOffset( int nOffsetX, int nOffsetY ) { mnStartPageOffsetX = nOffsetX; mnStartPageOffsetY = nOffsetY; }
- ULONG getCurPageRangeStart() const { return mnCurPageRangeStart; }
- ULONG getCurPageRangeCount() const { return mnCurPageRangeCount; }
+ sal_Int32 getCurPageRangeStart() const { return mnCurPageRangeStart; }
+ sal_Int32 getCurPageRangeCount() const { return mnCurPageRangeCount; }
+
+ // match width/height against known paper formats, possibly switching orientation
+ const PaperInfo* matchPaper( long i_nWidth, long i_nHeight, Orientation& o_rOrientation ) const;
+ void setPaperSize( long i_nWidth, long i_nHeight, Orientation i_eSetOrientation );
private:
AquaSalInfoPrinter( const AquaSalInfoPrinter& );
@@ -139,13 +141,16 @@ class AquaSalPrinter : public SalPrinter
virtual BOOL StartJob( const XubString* i_pFileName,
const XubString& i_rJobName,
const XubString& i_rAppName,
- ULONG i_nCopies, BOOL i_bCollate,
+ ULONG i_nCopies,
+ bool i_bCollate,
+ bool i_bDirect,
ImplJobSetup* i_pSetupData );
// implement pull model print system
- virtual BOOL StartJob( const String* pFileName,
- const String& rAppName,
- ImplJobSetup* pSetupData,
- ImplQPrinter* pQPrinter );
+ virtual BOOL StartJob( const String* i_pFileName,
+ const String& rJobName,
+ const String& i_rAppName,
+ ImplJobSetup* i_pSetupData,
+ vcl::PrinterController& i_rListener );
virtual BOOL EndJob();
virtual BOOL AbortJob();
@@ -162,7 +167,7 @@ const double fPtTo100thMM = 35.27777778;
inline int PtTo10Mu( double nPoints ) { return (int)(((nPoints)*fPtTo100thMM)+0.5); }
-inline double TenMuToPt( double nUnits ) { return (((nUnits)/fPtTo100thMM)+0.5); }
+inline double TenMuToPt( double nUnits ) { return floor(((nUnits)/fPtTo100thMM)+0.5); }
diff --git a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm
new file mode 100644
index 000000000000..798fefef1b25
--- /dev/null
+++ b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm
@@ -0,0 +1,1237 @@
+/************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: aquaprintview.mm,v $
+ * $Revision: 1.5.56.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include "aquaprintview.h"
+#include "salinst.h"
+#include "vcl/print.hxx"
+#include "vcl/image.hxx"
+#include "vcl/virdev.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/unohelp.hxx"
+
+#include "vcl/svids.hrc"
+
+#include "tools/resary.hxx"
+
+#include "com/sun/star/i18n/XBreakIterator.hpp"
+#include "com/sun/star/i18n/WordType.hpp"
+
+#include <map>
+
+using namespace vcl;
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+
+/* Note: the accesory view as implemented here is already deprecated in Leopard. Unfortunately
+ as long as our baseline is Tiger we cannot gain the advantages over multiple accessory views
+ as well havs having accessory views AND a preview (as long as you are linked vs. 10.4 libraries
+ the preview insists on not being present. This is unfortunate.
+*/
+
+class ControllerProperties;
+
+@interface ControlTarget : NSObject
+{
+ ControllerProperties* mpController;
+}
+-(id)initWithControllerMap: (ControllerProperties*)pController;
+-(void)triggered:(id)pSender;
+-(void)triggeredNumeric:(id)pSender;
+-(void)triggeredPreview:(id)pSender;
+-(void)dealloc;
+@end
+
+
+class ControllerProperties
+{
+ vcl::PrinterController* mpController;
+ std::map< int, rtl::OUString > maTagToPropertyName;
+ std::map< int, sal_Int32 > maTagToValueInt;
+ std::map< NSView*, NSView* > maViewPairMap;
+ std::vector< NSObject* > maViews;
+ int mnNextTag;
+ sal_Int32 mnLastPageCount;
+ PrintAccessoryViewState* mpState;
+ NSPrintOperation* mpOp;
+ NSView* mpAccessoryView;
+ NSTabView* mpTabView;
+ NSBox* mpPreviewBox;
+ NSImageView* mpPreview;
+ NSTextField* mpPageEdit;
+ NSStepper* mpStepper;
+ NSTextView* mpPagesLabel;
+ ResStringArray maLocalizedStrings;
+
+ public:
+ ControllerProperties( vcl::PrinterController* i_pController,
+ NSPrintOperation* i_pOp,
+ NSView* i_pAccessoryView,
+ NSTabView* i_pTabView,
+ PrintAccessoryViewState* i_pState )
+ : mpController( i_pController ),
+ mnNextTag( 0 ),
+ mnLastPageCount( i_pController->getFilteredPageCount() ),
+ mpState( i_pState ),
+ mpOp( i_pOp ),
+ mpAccessoryView( i_pAccessoryView ),
+ mpTabView( i_pTabView ),
+ mpPreviewBox( nil ),
+ mpPreview( nil ),
+ mpPageEdit( nil ),
+ mpStepper( nil ),
+ mpPagesLabel( nil ),
+ maLocalizedStrings( VclResId( SV_PRINT_NATIVE_STRINGS ) )
+ {
+ mpState->bNeedRestart = false;
+ DBG_ASSERT( maLocalizedStrings.Count() >= 4, "resources not found !" );
+ }
+
+ rtl::OUString getMoreString()
+ {
+ return maLocalizedStrings.Count() >= 4
+ ? rtl::OUString( maLocalizedStrings.GetString( 3 ) )
+ : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "More" ) );
+ }
+
+ void updatePrintJob()
+ {
+ // TODO: refresh page count etc from mpController
+
+ // page range may have changed depending on options
+ sal_Int32 nPages = mpController->getFilteredPageCount();
+ #if OSL_DEBUG_LEVEL > 1
+ if( nPages != mnLastPageCount )
+ fprintf( stderr, "trouble: number of pages changed from %ld to %ld !\n", mnLastPageCount, nPages );
+ #endif
+ mpState->bNeedRestart = (nPages != mnLastPageCount);
+ NSTabViewItem* pItem = [mpTabView selectedTabViewItem];
+ if( pItem )
+ mpState->nLastPage = [mpTabView indexOfTabViewItem: pItem];
+ else
+ mpState->nLastPage = 0;
+ mnLastPageCount = nPages;
+ if( mpState->bNeedRestart )
+ {
+ #if 0
+ // Warning: bad hack ahead
+ // Apple does not give us a chance of changing the page count,
+ // and they don't let us cancel the dialog either
+ // hack: send a cancel message to the window displaying our views.
+ // this is ugly.
+ for( std::vector< NSObject* >::iterator it = maViews.begin(); it != maViews.end(); ++it )
+ {
+ if( [*it isKindOfClass: [NSView class]] )
+ {
+ NSView* pView = (NSView*)*it;
+ NSWindow* pWindow = [pView window];
+ if( pWindow )
+ {
+ [pWindow cancelOperation: nil];
+ break;
+ }
+ }
+ }
+ #else
+ NSWindow* pWindow = [NSApp modalWindow];
+ if( pWindow )
+ [pWindow cancelOperation: nil];
+ #endif
+ [[mpOp printInfo] setJobDisposition: NSPrintCancelJob];
+ }
+ else
+ {
+ sal_Int32 nPage = [mpStepper intValue];
+ updatePreviewImage( nPage-1 );
+ }
+ }
+
+ int addNameTag( const rtl::OUString& i_rPropertyName )
+ {
+ int nNewTag = mnNextTag++;
+ maTagToPropertyName[ nNewTag ] = i_rPropertyName;
+ return nNewTag;
+ }
+
+ int addNameAndValueTag( const rtl::OUString& i_rPropertyName, sal_Int32 i_nValue )
+ {
+ int nNewTag = mnNextTag++;
+ maTagToPropertyName[ nNewTag ] = i_rPropertyName;
+ maTagToValueInt[ nNewTag ] = i_nValue;
+ return nNewTag;
+ }
+
+ void addObservedControl( NSObject* i_pView )
+ {
+ maViews.push_back( i_pView );
+ }
+
+ void addViewPair( NSView* i_pLeft, NSView* i_pRight )
+ {
+ maViewPairMap[ i_pLeft ] = i_pRight;
+ maViewPairMap[ i_pRight ] = i_pLeft;
+ }
+
+ NSView* getPair( NSView* i_pLeft ) const
+ {
+ NSView* pRight = nil;
+ std::map< NSView*, NSView* >::const_iterator it = maViewPairMap.find( i_pLeft );
+ if( it != maViewPairMap.end() )
+ pRight = it->second;
+ return pRight;
+ }
+
+ void changePropertyWithIntValue( int i_nTag )
+ {
+ std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag );
+ std::map< int, sal_Int32 >::const_iterator value_it = maTagToValueInt.find( i_nTag );
+ if( name_it != maTagToPropertyName.end() && value_it != maTagToValueInt.end() )
+ {
+ PropertyValue* pVal = mpController->getValue( name_it->second );
+ if( pVal )
+ {
+ pVal->Value <<= value_it->second;
+ updatePrintJob();
+ }
+ }
+ }
+
+ void changePropertyWithIntValue( int i_nTag, sal_Int64 i_nValue )
+ {
+ std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag );
+ if( name_it != maTagToPropertyName.end() )
+ {
+ PropertyValue* pVal = mpController->getValue( name_it->second );
+ if( pVal )
+ {
+ pVal->Value <<= i_nValue;
+ updatePrintJob();
+ }
+ }
+ }
+
+ void changePropertyWithBoolValue( int i_nTag, sal_Bool i_bValue )
+ {
+ std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag );
+ if( name_it != maTagToPropertyName.end() )
+ {
+ PropertyValue* pVal = mpController->getValue( name_it->second );
+ if( pVal )
+ {
+ pVal->Value <<= i_bValue;
+ updatePrintJob();
+ }
+ }
+ }
+
+ void changePropertyWithStringValue( int i_nTag, const rtl::OUString& i_rValue )
+ {
+ std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( i_nTag );
+ if( name_it != maTagToPropertyName.end() )
+ {
+ PropertyValue* pVal = mpController->getValue( name_it->second );
+ if( pVal )
+ {
+ pVal->Value <<= i_rValue;
+ updatePrintJob();
+ }
+ }
+ }
+
+ void updateEnableState()
+ {
+ for( std::vector< NSObject* >::iterator it = maViews.begin(); it != maViews.end(); ++it )
+ {
+ NSObject* pObj = *it;
+ NSControl* pCtrl = nil;
+ NSCell* pCell = nil;
+ if( [pObj isKindOfClass: [NSControl class]] )
+ pCtrl = (NSControl*)pObj;
+ else if( [pObj isKindOfClass: [NSCell class]] )
+ pCell = (NSCell*)pObj;
+
+ int nTag = pCtrl ? [pCtrl tag] :
+ pCell ? [pCell tag] :
+ -1;
+
+ std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( nTag );
+ if( name_it != maTagToPropertyName.end() )
+ {
+ MacOSBOOL bEnabled = mpController->isUIOptionEnabled( name_it->second ) ? YES : NO;
+ if( pCtrl )
+ {
+ [pCtrl setEnabled: bEnabled];
+ NSView* pOther = getPair( pCtrl );
+ if( pOther && [pOther isKindOfClass: [NSControl class]] )
+ [(NSControl*)pOther setEnabled: bEnabled];
+ }
+ else if( pCell )
+ [pCell setEnabled: bEnabled];
+
+ }
+ }
+ }
+
+ void updatePreviewImage( sal_Int32 i_nPage )
+ {
+ sal_Int32 nPages = mpController->getFilteredPageCount();
+ NSRect aViewFrame = [mpPreview frame];
+ Size aPixelSize( static_cast<long>(aViewFrame.size.width),
+ static_cast<long>(aViewFrame.size.height) );
+ if( i_nPage >= 0 && nPages > i_nPage )
+ {
+ GDIMetaFile aMtf;
+ PrinterController::PageSize aPageSize( mpController->getFilteredPageFile( i_nPage, aMtf, false ) );
+ VirtualDevice aDev;
+ // see salprn.cxx, currently we pretend to be a 720dpi device on printers
+ aDev.SetReferenceDevice( 720, 720 );
+ aDev.EnableOutput( TRUE );
+ Size aLogicSize( aDev.PixelToLogic( aPixelSize, MapMode( MAP_100TH_MM ) ) );
+ double fScaleX = double(aLogicSize.Width())/double(aPageSize.aSize.Width());
+ double fScaleY = double(aLogicSize.Height())/double(aPageSize.aSize.Height());
+ double fScale = (fScaleX < fScaleY) ? fScaleX : fScaleY;
+ aMtf.WindStart();
+ aMtf.Scale( fScale, fScale );
+ aMtf.WindStart();
+ aLogicSize.Width() = long(double(aPageSize.aSize.Width()) * fScale);
+ aLogicSize.Height() = long(double(aPageSize.aSize.Height()) * fScale);
+ aPixelSize = aDev.LogicToPixel( aLogicSize, MapMode( MAP_100TH_MM ) );
+ aDev.SetOutputSizePixel( aPixelSize );
+ aMtf.WindStart();
+ aDev.SetMapMode( MapMode( MAP_100TH_MM ) );
+ aMtf.Play( &aDev, Point( 0, 0 ), aLogicSize );
+ aDev.EnableMapMode( FALSE );
+ Image aImage( aDev.GetBitmap( Point( 0, 0 ), aPixelSize ) );
+ NSImage* pImage = CreateNSImage( aImage );
+ [mpPreview setImage: [pImage autorelease]];
+ }
+ else
+ [mpPreview setImage: nil];
+ }
+
+ void setupPreview( ControlTarget* i_pCtrlTarget )
+ {
+ if( maLocalizedStrings.Count() < 3 )
+ return;
+
+ // get the preview control
+ NSRect aPreviewFrame = [mpAccessoryView frame];
+ aPreviewFrame.origin.x = 0;
+ aPreviewFrame.origin.y = 5;
+ aPreviewFrame.size.width = 190;
+ aPreviewFrame.size.height -= 7;
+
+ // create a box to put the preview controls in
+ mpPreviewBox = [[NSBox alloc] initWithFrame: aPreviewFrame];
+ [mpPreviewBox setTitle: [CreateNSString( maLocalizedStrings.GetString( 0 ) ) autorelease]];
+ [mpAccessoryView addSubview: [mpPreviewBox autorelease]];
+
+ // now create the image view of the preview
+ NSSize aMargins = [mpPreviewBox contentViewMargins];
+ aPreviewFrame.origin.x = 0;
+ aPreviewFrame.origin.y = 34;
+ aPreviewFrame.size.height -= 61;
+ mpPreview = [[NSImageView alloc] initWithFrame: aPreviewFrame];
+ [mpPreview setImageScaling: NSScaleNone];
+ [mpPreview setImageAlignment: NSImageAlignCenter];
+ [mpPreview setImageFrameStyle: NSImageFrameNone];
+ [mpPreviewBox addSubview: [mpPreview autorelease]];
+
+ // add a label
+ sal_Int32 nPages = mpController->getFilteredPageCount();
+ rtl::OUStringBuffer aBuf( 16 );
+ aBuf.appendAscii( "/ " );
+ aBuf.append( rtl::OUString::valueOf( nPages ) );
+
+ NSString* pText = CreateNSString( aBuf.makeStringAndClear() );
+ NSRect aTextRect = { { 100, 5 }, { 100, 22 } };
+ mpPagesLabel = [[NSTextView alloc] initWithFrame: aTextRect];
+ [mpPagesLabel setFont: [NSFont controlContentFontOfSize: 0]];
+ [mpPagesLabel setEditable: NO];
+ [mpPagesLabel setSelectable: NO];
+ [mpPagesLabel setDrawsBackground: NO];
+ [mpPagesLabel setString: [pText autorelease]];
+ [mpPagesLabel setToolTip: [CreateNSString( maLocalizedStrings.GetString( 2 ) ) autorelease]];
+ [mpPreviewBox addSubview: [mpPagesLabel autorelease]];
+
+ NSRect aFieldRect = { { 45, 5 }, { 35, 25 } };
+ mpPageEdit = [[NSTextField alloc] initWithFrame: aFieldRect];
+ [mpPageEdit setEditable: YES];
+ [mpPageEdit setSelectable: YES];
+ [mpPageEdit setDrawsBackground: YES];
+ [mpPageEdit setToolTip: [CreateNSString( maLocalizedStrings.GetString( 1 ) ) autorelease]];
+ [mpPreviewBox addSubview: [mpPageEdit autorelease]];
+
+ // add a stepper control
+ NSRect aStepFrame = { { 85, 5 }, { 15, 25 } };
+ mpStepper = [[NSStepper alloc] initWithFrame: aStepFrame];
+ [mpStepper setIncrement: 1];
+ [mpStepper setValueWraps: NO];
+ [mpPreviewBox addSubview: [mpStepper autorelease]];
+
+ // constrain the text field to decimal numbers
+ NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init];
+ [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4];
+ [pFormatter setMinimum: [[NSNumber numberWithInt: 1] autorelease]];
+ [pFormatter setMaximum: [[NSNumber numberWithInt: nPages] autorelease]];
+ [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
+ [pFormatter setAllowsFloats: NO];
+ [pFormatter setMaximumFractionDigits: 0];
+ [mpPageEdit setFormatter: pFormatter];
+ [mpStepper setMinValue: 1];
+ [mpStepper setMaxValue: nPages];
+
+ [mpPageEdit setIntValue: 1];
+ [mpStepper setIntValue: 1];
+
+ // connect target and action
+ [mpStepper setTarget: i_pCtrlTarget];
+ [mpStepper setAction: @selector(triggeredPreview:)];
+ [mpPageEdit setTarget: i_pCtrlTarget];
+ [mpPageEdit setAction: @selector(triggeredPreview:)];
+
+ // set first preview image
+ updatePreviewImage( 0 );
+ }
+
+ void changePreview( NSObject* i_pSender )
+ {
+ if( [i_pSender isMemberOfClass: [NSTextField class]] )
+ {
+ NSTextField* pField = (NSTextField*)i_pSender;
+ if( pField == mpPageEdit ) // sanity check
+ {
+ sal_Int32 nPage = [pField intValue];
+ [mpStepper setIntValue: nPage];
+ updatePreviewImage( nPage-1 );
+ }
+ }
+ else if( [i_pSender isMemberOfClass: [NSStepper class]] )
+ {
+ NSStepper* pStepper = (NSStepper*)i_pSender;
+ if( pStepper == mpStepper ) // sanity check
+ {
+ sal_Int32 nPage = [pStepper intValue];
+ [mpPageEdit setIntValue: nPage];
+ updatePreviewImage( nPage-1 );
+ }
+ }
+ }
+};
+
+static void filterAccelerator( rtl::OUString& io_rText )
+{
+ rtl::OUStringBuffer aBuf( io_rText.getLength() );
+ for( sal_Int32 nIndex = 0; nIndex != -1; )
+ aBuf.append( io_rText.getToken( 0, '~', nIndex ) );
+ io_rText = aBuf.makeStringAndClear();
+}
+
+@implementation ControlTarget
+-(id)initWithControllerMap: (ControllerProperties*)pController
+{
+ if( (self = [super init]) )
+ {
+ mpController = pController;
+ }
+ return self;
+}
+-(void)triggered:(id)pSender;
+{
+ if( [pSender isMemberOfClass: [NSPopUpButton class]] )
+ {
+ NSPopUpButton* pBtn = (NSPopUpButton*)pSender;
+ NSMenuItem* pSelected = [pBtn selectedItem];
+ if( pSelected )
+ {
+ int nTag = [pSelected tag];
+ mpController->changePropertyWithIntValue( nTag );
+ }
+ }
+ else if( [pSender isMemberOfClass: [NSButton class]] )
+ {
+ NSButton* pBtn = (NSButton*)pSender;
+ int nTag = [pBtn tag];
+ mpController->changePropertyWithBoolValue( nTag, [pBtn state] == NSOnState );
+ }
+ else if( [pSender isMemberOfClass: [NSMatrix class]] )
+ {
+ NSObject* pObj = [(NSMatrix*)pSender selectedCell];
+ if( [pObj isMemberOfClass: [NSButtonCell class]] )
+ {
+ NSButtonCell* pCell = (NSButtonCell*)pObj;
+ int nTag = [pCell tag];
+ mpController->changePropertyWithIntValue( nTag );
+ }
+ }
+ else if( [pSender isMemberOfClass: [NSTextField class]] )
+ {
+ NSTextField* pField = (NSTextField*)pSender;
+ int nTag = [pField tag];
+ rtl::OUString aValue = GetOUString( [pSender stringValue] );
+ mpController->changePropertyWithStringValue( nTag, aValue );
+ }
+ else
+ {
+ DBG_ERROR( "unsupported class" );
+ }
+ mpController->updateEnableState();
+}
+-(void)triggeredNumeric:(id)pSender;
+{
+ if( [pSender isMemberOfClass: [NSTextField class]] )
+ {
+ NSTextField* pField = (NSTextField*)pSender;
+ int nTag = [pField tag];
+ sal_Int64 nValue = [pField intValue];
+
+ NSView* pOther = mpController->getPair( pField );
+ if( pOther )
+ [(NSControl*)pOther setIntValue: nValue];
+
+ mpController->changePropertyWithIntValue( nTag, nValue );
+ }
+ else if( [pSender isMemberOfClass: [NSStepper class]] )
+ {
+ NSStepper* pStep = (NSStepper*)pSender;
+ int nTag = [pStep tag];
+ sal_Int64 nValue = [pStep intValue];
+
+ NSView* pOther = mpController->getPair( pStep );
+ if( pOther )
+ [(NSControl*)pOther setIntValue: nValue];
+
+ mpController->changePropertyWithIntValue( nTag, nValue );
+ }
+ else
+ {
+ DBG_ERROR( "unsupported class" );
+ }
+ mpController->updateEnableState();
+}
+-(void)triggeredPreview:(id)pSender
+{
+ mpController->changePreview( pSender );
+}
+-(void)dealloc
+{
+ delete mpController;
+ [super dealloc];
+}
+@end
+
+struct ColumnItem
+{
+ NSControl* pControl;
+ long nOffset;
+ NSControl* pSubControl;
+
+ ColumnItem( NSControl* i_pControl = nil, long i_nOffset = 0, NSControl* i_pSub = nil )
+ : pControl( i_pControl )
+ , nOffset( i_nOffset )
+ , pSubControl( i_pSub )
+ {}
+
+ long getWidth() const
+ {
+ long nWidth = 0;
+ if( pControl )
+ {
+ NSRect aCtrlRect = [pControl frame];
+ nWidth = aCtrlRect.size.width;
+ nWidth += nOffset;
+ if( pSubControl )
+ {
+ NSRect aSubRect = [pSubControl frame];
+ nWidth += aSubRect.size.width;
+ nWidth += aSubRect.origin.x - (aCtrlRect.origin.x + aCtrlRect.size.width);
+ }
+ }
+ return nWidth;
+ }
+};
+
+static void adjustViewAndChildren( NSView* pView, NSSize& rMaxSize,
+ std::vector< ColumnItem >& rLeftColumn,
+ std::vector< ColumnItem >& rRightColumn
+ )
+{
+ // balance columns
+
+ // first get overall column widths
+ long nLeftWidth = 0;
+ long nRightWidth = 0;
+ for( size_t i = 0; i < rLeftColumn.size(); i++ )
+ {
+ long nW = rLeftColumn[i].getWidth();
+ if( nW > nLeftWidth )
+ nLeftWidth = nW;
+ }
+ for( size_t i = 0; i < rRightColumn.size(); i++ )
+ {
+ long nW = rRightColumn[i].getWidth();
+ if( nW > nRightWidth )
+ nRightWidth = nW;
+ }
+
+ // right align left column
+ for( size_t i = 0; i < rLeftColumn.size(); i++ )
+ {
+ if( rLeftColumn[i].pControl )
+ {
+ NSRect aCtrlRect = [rLeftColumn[i].pControl frame];
+ long nX = nLeftWidth - aCtrlRect.size.width;
+ if( rLeftColumn[i].pSubControl )
+ {
+ NSRect aSubRect = [rLeftColumn[i].pSubControl frame];
+ nX -= aSubRect.size.width + (aSubRect.origin.x - (aCtrlRect.origin.x + aCtrlRect.size.width));
+ aSubRect.origin.x = nLeftWidth - aSubRect.size.width;
+ [rLeftColumn[i].pSubControl setFrame: aSubRect];
+ }
+ aCtrlRect.origin.x = nX;
+ [rLeftColumn[i].pControl setFrame: aCtrlRect];
+ }
+ }
+
+ // left align right column
+ for( size_t i = 0; i < rRightColumn.size(); i++ )
+ {
+ if( rRightColumn[i].pControl )
+ {
+ NSRect aCtrlRect = [rRightColumn[i].pControl frame];
+ long nX = nLeftWidth + 3;
+ if( rRightColumn[i].pSubControl )
+ {
+ NSRect aSubRect = [rRightColumn[i].pSubControl frame];
+ aSubRect.origin.x = nX + aSubRect.origin.x - aCtrlRect.origin.x;
+ [rRightColumn[i].pSubControl setFrame: aSubRect];
+ }
+ aCtrlRect.origin.x = nX;
+ [rRightColumn[i].pControl setFrame: aCtrlRect];
+ }
+ }
+
+ NSArray* pSubViews = [pView subviews];
+ unsigned int nViews = [pSubViews count];
+ NSRect aUnion = { { 0, 0 }, { 0, 0 } };
+
+ // get the combined frame of all subviews
+ for( unsigned int n = 0; n < nViews; n++ )
+ {
+ aUnion = NSUnionRect( aUnion, [[pSubViews objectAtIndex: n] frame] );
+ }
+
+ // move everything so it will fit
+ for( unsigned int n = 0; n < nViews; n++ )
+ {
+ NSView* pCurSubView = [pSubViews objectAtIndex: n];
+ NSRect aFrame = [pCurSubView frame];
+ aFrame.origin.x -= aUnion.origin.x - 5;
+ aFrame.origin.y -= aUnion.origin.y - 5;
+ [pCurSubView setFrame: aFrame];
+ }
+
+ // resize the view itself
+ aUnion.size.height += 10;
+ aUnion.size.width += 20;
+ [pView setFrameSize: aUnion.size];
+
+ if( aUnion.size.width > rMaxSize.width )
+ rMaxSize.width = aUnion.size.width;
+ if( aUnion.size.height > rMaxSize.height )
+ rMaxSize.height = aUnion.size.height;
+}
+
+static void adjustTabViews( NSTabView* pTabView, NSSize aTabSize )
+{
+ // loop over all contained tab pages
+ NSArray* pTabbedViews = [pTabView tabViewItems];
+ int nViews = [pTabbedViews count];
+ for( int i = 0; i < nViews; i++ )
+ {
+ NSTabViewItem* pItem = (NSTabViewItem*)[pTabbedViews objectAtIndex: i];
+ NSView* pView = [pItem view];
+ if( pView )
+ {
+ NSRect aRect = [pView frame];
+ double nDiff = aTabSize.height - aRect.size.height;
+ aRect.size = aTabSize;
+ [pView setFrame: aRect];
+
+ NSArray* pSubViews = [pView subviews];
+ unsigned int nSubViews = [pSubViews count];
+
+ // move everything up
+ for( unsigned int n = 0; n < nSubViews; n++ )
+ {
+ NSView* pCurSubView = [pSubViews objectAtIndex: n];
+ NSRect aFrame = [pCurSubView frame];
+ aFrame.origin.y += nDiff;
+ // give separators the correct width
+ // separators are currently the only NSBoxes we use
+ if( [pCurSubView isMemberOfClass: [NSBox class]] )
+ {
+ aFrame.size.width = aTabSize.width - aFrame.origin.x - 10;
+ }
+ [pCurSubView setFrame: aFrame];
+ }
+ }
+ }
+}
+
+static NSControl* createLabel( const rtl::OUString& i_rText )
+{
+ NSString* pText = CreateNSString( i_rText );
+ NSRect aTextRect = { { 0, 0 }, {20, 15} };
+ NSTextField* pTextView = [[NSTextField alloc] initWithFrame: aTextRect];
+ [pTextView setFont: [NSFont controlContentFontOfSize: 0]];
+ [pTextView setEditable: NO];
+ [pTextView setSelectable: NO];
+ [pTextView setDrawsBackground: NO];
+ [pTextView setBordered: NO];
+ [pTextView setStringValue: pText];
+ [pTextView sizeToFit];
+ [pText release];
+ return pTextView;
+}
+
+static sal_Int32 findBreak( const rtl::OUString& i_rText, sal_Int32 i_nPos )
+{
+ sal_Int32 nRet = i_rText.getLength();
+ Reference< i18n::XBreakIterator > xBI( vcl::unohelper::CreateBreakIterator() );
+ if( xBI.is() )
+ {
+ i18n::Boundary aBoundary = xBI->getWordBoundary( i_rText, i_nPos,
+ Application::GetSettings().GetLocale(),
+ i18n::WordType::ANYWORD_IGNOREWHITESPACES,
+ sal_True );
+ nRet = aBoundary.endPos;
+ }
+ return nRet;
+}
+
+static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText )
+{
+ NSString* pText = CreateNSString( i_rText );
+ [pBtn setTitle: pText];
+ [pText release];
+ NSSize aSize = [pBtn cellSize];
+ if( aSize.width > 280 )
+ {
+ // need two lines
+ sal_Int32 nLen = i_rText.getLength();
+ sal_Int32 nIndex = nLen / 2;
+ nIndex = findBreak( i_rText, nIndex );
+ if( nIndex < nLen )
+ {
+ rtl::OUStringBuffer aBuf( i_rText );
+ aBuf.setCharAt( nIndex, '\n' );
+ pText = CreateNSString( aBuf.makeStringAndClear() );
+ [pBtn setTitle: pText];
+ [pText release];
+ }
+ }
+}
+
+
+@implementation AquaPrintAccessoryView
++(NSObject*)setupPrinterPanel: (NSPrintOperation*)pOp withController: (vcl::PrinterController*)pController withState: (PrintAccessoryViewState*)pState;
+{
+ const Sequence< PropertyValue >& rOptions( pController->getUIOptions() );
+ if( rOptions.getLength() == 0 )
+ return nil;
+
+ NSView* pCurParent = 0;
+ long nCurY = 0;
+ long nCurX = 0;
+ NSRect aViewFrame = { { 0, 0 }, {600, 400 } };
+ NSRect aTabViewFrame = { { 190, 0 }, {410, 400 } };
+ NSSize aMaxTabSize = { 0, 0 };
+ NSView* pAccessoryView = [[NSView alloc] initWithFrame: aViewFrame];
+ NSTabView* pTabView = [[NSTabView alloc] initWithFrame: aTabViewFrame];
+ [pAccessoryView addSubview: [pTabView autorelease]];
+
+ sal_Bool bIgnoreSubgroup = sal_False;
+
+ ControllerProperties* pControllerProperties = new ControllerProperties( pController, pOp, pAccessoryView, pTabView, pState );
+ ControlTarget* pCtrlTarget = [[ControlTarget alloc] initWithControllerMap: pControllerProperties];
+
+ std::vector< ColumnItem > aLeftColumn, aRightColumn;
+
+ for( int i = 0; i < rOptions.getLength(); i++ )
+ {
+ Sequence< beans::PropertyValue > aOptProp;
+ rOptions[i].Value >>= aOptProp;
+
+ // extract ui element
+ bool bEnabled = true;
+ rtl::OUString aCtrlType;
+ rtl::OUString aText;
+ rtl::OUString aPropertyName;
+ Sequence< rtl::OUString > aChoices;
+ sal_Int64 nMinValue = 0, nMaxValue = 0;
+ long nAttachOffset = 0;
+ sal_Bool bIgnore = sal_False;
+
+ for( int n = 0; n < aOptProp.getLength(); n++ )
+ {
+ const beans::PropertyValue& rEntry( aOptProp[ n ] );
+ if( rEntry.Name.equalsAscii( "Text" ) )
+ {
+ rEntry.Value >>= aText;
+ filterAccelerator( aText );
+ }
+ else if( rEntry.Name.equalsAscii( "ControlType" ) )
+ {
+ rEntry.Value >>= aCtrlType;
+ }
+ else if( rEntry.Name.equalsAscii( "Choices" ) )
+ {
+ rEntry.Value >>= aChoices;
+ }
+ else if( rEntry.Name.equalsAscii( "Property" ) )
+ {
+ PropertyValue aVal;
+ rEntry.Value >>= aVal;
+ aPropertyName = aVal.Name;
+ }
+ else if( rEntry.Name.equalsAscii( "Enabled" ) )
+ {
+ sal_Bool bValue = sal_True;
+ rEntry.Value >>= bValue;
+ bEnabled = bValue;
+ }
+ else if( rEntry.Name.equalsAscii( "MinValue" ) )
+ {
+ rEntry.Value >>= nMinValue;
+ }
+ else if( rEntry.Name.equalsAscii( "MaxValue" ) )
+ {
+ rEntry.Value >>= nMaxValue;
+ }
+ else if( rEntry.Name.equalsAscii( "AttachToDependency" ) )
+ {
+ nAttachOffset = 20;
+ }
+ else if( rEntry.Name.equalsAscii( "InternalUIOnly" ) )
+ {
+ rEntry.Value >>= bIgnore;
+ }
+ }
+
+ if( aCtrlType.equalsAscii( "Group" ) ||
+ aCtrlType.equalsAscii( "Subgroup" ) ||
+ aCtrlType.equalsAscii( "Radio" ) ||
+ aCtrlType.equalsAscii( "List" ) ||
+ aCtrlType.equalsAscii( "Edit" ) ||
+ aCtrlType.equalsAscii( "Range" ) ||
+ aCtrlType.equalsAscii( "Bool" ) )
+ {
+ // since our build target is MacOSX 10.4 we can have only one accessory view
+ // so we have a single accessory view that is tabbed for grouping
+ if( aCtrlType.equalsAscii( "Group" )
+ || ! pCurParent
+ || ( aCtrlType.equalsAscii( "Subgroup" ) && nCurY < -250 && ! bIgnore )
+ )
+ {
+ rtl::OUString aGroupTitle( aText );
+ if( aCtrlType.equalsAscii( "Subgroup" ) )
+ aGroupTitle = pControllerProperties->getMoreString();
+ // set size of current parent
+ if( pCurParent )
+ adjustViewAndChildren( pCurParent, aMaxTabSize, aLeftColumn, aRightColumn );
+
+ // new tab item
+ if( ! aText.getLength() )
+ aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OOo" ) );
+ NSString* pLabel = CreateNSString( aGroupTitle );
+ NSTabViewItem* pItem = [[NSTabViewItem alloc] initWithIdentifier: pLabel ];
+ [pItem setLabel: pLabel];
+ [pTabView addTabViewItem: pItem];
+ pCurParent = [[NSView alloc] initWithFrame: aTabViewFrame];
+ [pItem setView: pCurParent];
+ [pLabel release];
+
+ // reset indent
+ nCurX = 20;
+ // reset Y
+ nCurY = 0;
+ // clear columns
+ aLeftColumn.clear();
+ aRightColumn.clear();
+ }
+
+ if( aCtrlType.equalsAscii( "Subgroup" ) && pCurParent )
+ {
+ bIgnoreSubgroup = bIgnore;
+ if( bIgnore )
+ continue;
+
+ NSControl* pTextView = createLabel( aText );
+ [pCurParent addSubview: [pTextView autorelease]];
+ NSRect aTextRect = [pTextView frame];
+ // move to nCurY
+ aTextRect.origin.y = nCurY - aTextRect.size.height;
+ [pTextView setFrame: aTextRect];
+
+ NSRect aSepRect = { { aTextRect.size.width + 1, aTextRect.origin.y }, { 100, 6 } };
+ NSBox* pBox = [[NSBox alloc] initWithFrame: aSepRect];
+ [pBox setBoxType: NSBoxSeparator];
+ [pCurParent addSubview: [pBox autorelease]];
+
+ // update nCurY
+ nCurY = aTextRect.origin.y - 5;
+ }
+ else if( bIgnoreSubgroup || bIgnore )
+ continue;
+ else if( aCtrlType.equalsAscii( "Bool" ) && pCurParent )
+ {
+ NSRect aCheckRect = { { nCurX + nAttachOffset, 0 }, { 0, 15 } };
+ NSButton* pBtn = [[NSButton alloc] initWithFrame: aCheckRect];
+ [pBtn setButtonType: NSSwitchButton];
+ sal_Bool bVal = sal_False;
+ PropertyValue* pVal = pController->getValue( aPropertyName );
+ if( pVal )
+ pVal->Value >>= bVal;
+ [pBtn setState: bVal ? NSOnState : NSOffState];
+ linebreakCell( [pBtn cell], aText );
+ [pBtn sizeToFit];
+ [pCurParent addSubview: [pBtn autorelease]];
+
+ aRightColumn.push_back( ColumnItem( pBtn ) );
+
+ // connect target
+ [pBtn setTarget: pCtrlTarget];
+ [pBtn setAction: @selector(triggered:)];
+ int nTag = pControllerProperties->addNameTag( aPropertyName );
+ pControllerProperties->addObservedControl( pBtn );
+ [pBtn setTag: nTag];
+
+ aCheckRect = [pBtn frame];
+
+ // move to nCurY
+ aCheckRect.origin.y = nCurY - aCheckRect.size.height;
+ [pBtn setFrame: aCheckRect];
+
+ // update nCurY
+ nCurY = aCheckRect.origin.y - 5;
+ }
+ else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent )
+ {
+ sal_Int32 nOff = 0;
+ if( aText.getLength() )
+ {
+ // add a label
+ NSControl* pTextView = createLabel( aText );
+ NSRect aTextRect = [pTextView frame];
+ aTextRect.origin.x = nCurX + nAttachOffset;
+ [pCurParent addSubview: [pTextView autorelease]];
+
+ aLeftColumn.push_back( ColumnItem( pTextView ) );
+
+ // move to nCurY
+ aTextRect.origin.y = nCurY - aTextRect.size.height;
+ [pTextView setFrame: aTextRect];
+
+ // update nCurY
+ nCurY = aTextRect.origin.y - 5;
+
+ // indent the radio group relative to the text
+ // nOff = 20;
+ }
+
+ // setup radio matrix
+ NSButtonCell* pProto = [[NSButtonCell alloc] init];
+
+ NSRect aRadioRect = { { nCurX + nOff, 0 }, { 280 - nCurX, 5*aChoices.getLength() } };
+ [pProto setTitle: @"RadioButtonGroup"];
+ [pProto setButtonType: NSRadioButton];
+ NSMatrix* pMatrix = [[NSMatrix alloc] initWithFrame: aRadioRect
+ mode: NSRadioModeMatrix
+ prototype: (NSCell*)pProto
+ numberOfRows: aChoices.getLength()
+ numberOfColumns: 1];
+ // get currently selected value
+ sal_Int32 nSelectVal = 0;
+ PropertyValue* pVal = pController->getValue( aPropertyName );
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= nSelectVal;
+ // set individual titles
+ NSArray* pCells = [pMatrix cells];
+ for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
+ {
+ NSCell* pCell = [pCells objectAtIndex: m];
+ filterAccelerator( aChoices[m] );
+ linebreakCell( pCell, aChoices[m] );
+ //NSString* pTitle = CreateNSString( aChoices[m] );
+ //[pCell setTitle: pTitle];
+ // connect target and action
+ [pCell setTarget: pCtrlTarget];
+ [pCell setAction: @selector(triggered:)];
+ int nTag = pControllerProperties->addNameAndValueTag( aPropertyName, m );
+ pControllerProperties->addObservedControl( pCell );
+ [pCell setTag: nTag];
+ //[pTitle release];
+ // set current selection
+ if( nSelectVal == m )
+ [pMatrix selectCellAtRow: m column: 0];
+ }
+ [pMatrix sizeToFit];
+ aRadioRect = [pMatrix frame];
+
+ // move it down, so it comes to the correct position
+ aRadioRect.origin.y = nCurY - aRadioRect.size.height;
+ [pMatrix setFrame: aRadioRect];
+ [pCurParent addSubview: [pMatrix autorelease]];
+
+ aRightColumn.push_back( ColumnItem( pMatrix ) );
+
+ // update nCurY
+ nCurY = aRadioRect.origin.y - 5;
+
+ [pProto release];
+ }
+ else if( aCtrlType.equalsAscii( "List" ) && pCurParent )
+ {
+ // don't indent attached lists, looks bad in the existing cases
+ NSControl* pTextView = createLabel( aText );
+ [pCurParent addSubview: [pTextView autorelease]];
+ aLeftColumn.push_back( ColumnItem( pTextView ) );
+ NSRect aTextRect = [pTextView frame];
+ aTextRect.origin.x = nCurX /* + nAttachOffset*/;
+
+ // don't indent attached lists, looks bad in the existing cases
+ NSRect aBtnRect = { { nCurX /*+ nAttachOffset*/ + aTextRect.size.width, 0 }, { 0, 15 } };
+ NSPopUpButton* pBtn = [[NSPopUpButton alloc] initWithFrame: aBtnRect pullsDown: NO];
+
+ // iterate options
+ for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
+ {
+ NSString* pItemText = CreateNSString( aChoices[m] );
+ [pBtn addItemWithTitle: pItemText];
+ NSMenuItem* pItem = [pBtn itemWithTitle: pItemText];
+ int nTag = pControllerProperties->addNameAndValueTag( aPropertyName, m );
+ [pItem setTag: nTag];
+ [pItemText release];
+ }
+
+ PropertyValue* pVal = pController->getValue( aPropertyName );
+ sal_Int32 aSelectVal = 0;
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= aSelectVal;
+ [pBtn selectItemAtIndex: aSelectVal];
+
+ // add the button to observed controls for enabled state changes
+ // also add a tag just for this purpose
+ pControllerProperties->addObservedControl( pBtn );
+ [pBtn setTag: pControllerProperties->addNameTag( aPropertyName )];
+
+ [pBtn sizeToFit];
+ [pCurParent addSubview: [pBtn autorelease]];
+
+ aRightColumn.push_back( ColumnItem( pBtn ) );
+
+ // connect target and action
+ [pBtn setTarget: pCtrlTarget];
+ [pBtn setAction: @selector(triggered:)];
+
+ // move to nCurY
+ aBtnRect = [pBtn frame];
+ aBtnRect.origin.y = nCurY - aBtnRect.size.height;
+ [pBtn setFrame: aBtnRect];
+
+ // align label
+ aTextRect.origin.y = aBtnRect.origin.y + (aBtnRect.size.height - aTextRect.size.height)/2;
+ [pTextView setFrame: aTextRect];
+
+ // update nCurY
+ nCurY = aBtnRect.origin.y - 5;
+ }
+ else if( (aCtrlType.equalsAscii( "Edit" ) || aCtrlType.equalsAscii( "Range" )) && pCurParent )
+ {
+ sal_Int32 nOff = 0;
+ if( aText.getLength() )
+ {
+ // add a label
+ NSControl* pTextView = createLabel( aText );
+ [pCurParent addSubview: [pTextView autorelease]];
+
+ aLeftColumn.push_back( ColumnItem( pTextView ) );
+
+ // move to nCurY
+ NSRect aTextRect = [pTextView frame];
+ aTextRect.origin.x = nCurX + nAttachOffset;
+ aTextRect.origin.y = nCurY - aTextRect.size.height;
+ [pTextView setFrame: aTextRect];
+
+ // update nCurY
+ nCurY = aTextRect.origin.y - 5;
+
+ // and set the offset for the real edit field
+ nOff = aTextRect.size.width + 5;
+ }
+
+ NSRect aFieldRect = { { nCurX + nOff + nAttachOffset, 0 }, { 100, 25 } };
+ NSTextField* pFieldView = [[NSTextField alloc] initWithFrame: aFieldRect];
+ [pFieldView setEditable: YES];
+ [pFieldView setSelectable: YES];
+ [pFieldView setDrawsBackground: YES];
+ [pFieldView sizeToFit]; // FIXME: this does nothing
+ [pCurParent addSubview: [pFieldView autorelease]];
+
+ aRightColumn.push_back( ColumnItem( pFieldView ) );
+
+ // add the field to observed controls for enabled state changes
+ // also add a tag just for this purpose
+ pControllerProperties->addObservedControl( pFieldView );
+ int nTag = pControllerProperties->addNameTag( aPropertyName );
+ [pFieldView setTag: nTag];
+ // pControllerProperties->addNamedView( pFieldView, aPropertyName );
+
+ // move to nCurY
+ aFieldRect.origin.y = nCurY - aFieldRect.size.height;
+ [pFieldView setFrame: aFieldRect];
+
+ // current value
+ PropertyValue* pVal = pController->getValue( aPropertyName );
+ if( aCtrlType.equalsAscii( "Range" ) )
+ {
+ // add a stepper control
+ NSRect aStepFrame = { { aFieldRect.origin.x + aFieldRect.size.width + 5,
+ aFieldRect.origin.y },
+ { 15, aFieldRect.size.height } };
+ NSStepper* pStep = [[NSStepper alloc] initWithFrame: aStepFrame];
+ [pStep setIncrement: 1];
+ [pStep setValueWraps: NO];
+ [pStep setTag: nTag];
+ [pCurParent addSubview: [pStep autorelease]];
+
+ aRightColumn.back().pSubControl = pStep;
+
+ pControllerProperties->addObservedControl( pStep );
+ [pStep setTarget: pCtrlTarget];
+ [pStep setAction: @selector(triggered:)];
+
+ // constrain the text field to decimal numbers
+ NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init];
+ [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4];
+ [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
+ [pFormatter setAllowsFloats: NO];
+ [pFormatter setMaximumFractionDigits: 0];
+ if( nMinValue != nMaxValue )
+ {
+ [pFormatter setMinimum: [[NSNumber numberWithInt: nMinValue] autorelease]];
+ [pStep setMinValue: nMinValue];
+ [pFormatter setMaximum: [[NSNumber numberWithInt: nMaxValue] autorelease]];
+ [pStep setMaxValue: nMaxValue];
+ }
+ [pFieldView setFormatter: pFormatter];
+
+ sal_Int64 nSelectVal = 0;
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= nSelectVal;
+
+ [pFieldView setIntValue: nSelectVal];
+ [pStep setIntValue: nSelectVal];
+
+ pControllerProperties->addViewPair( pFieldView, pStep );
+ // connect target and action
+ [pFieldView setTarget: pCtrlTarget];
+ [pFieldView setAction: @selector(triggeredNumeric:)];
+ [pStep setTarget: pCtrlTarget];
+ [pStep setAction: @selector(triggeredNumeric:)];
+ }
+ else
+ {
+ // connect target and action
+ [pFieldView setTarget: pCtrlTarget];
+ [pFieldView setAction: @selector(triggered:)];
+
+ if( pVal && pVal->Value.hasValue() )
+ {
+ rtl::OUString aValue;
+ pVal->Value >>= aValue;
+ if( aValue.getLength() )
+ {
+ NSString* pText = CreateNSString( aValue );
+ [pFieldView setStringValue: pText];
+ [pText release];
+ }
+ }
+ }
+
+ // update nCurY
+ nCurY = aFieldRect.origin.y - 5;
+
+ }
+ }
+ else
+ {
+ DBG_ERROR( "Unsupported UI option" );
+ }
+ }
+
+ pControllerProperties->updateEnableState();
+ adjustViewAndChildren( pCurParent, aMaxTabSize, aLeftColumn, aRightColumn );
+
+ // leave some space for the preview
+ if( aMaxTabSize.height < 200 )
+ aMaxTabSize.height = 200;
+
+ // now reposition everything again so it is upper bound
+ adjustTabViews( pTabView, aMaxTabSize );
+
+ // find the minimum needed tab size
+ NSSize aTabCtrlSize = [pTabView minimumSize];
+ aTabCtrlSize.height += aMaxTabSize.height + 10;
+ if( aTabCtrlSize.width < aMaxTabSize.width + 10 )
+ aTabCtrlSize.width = aMaxTabSize.width + 10;
+ [pTabView setFrameSize: aTabCtrlSize];
+ aViewFrame.size.width = aTabCtrlSize.width + aTabViewFrame.origin.x;
+ aViewFrame.size.height = aTabCtrlSize.height + aTabViewFrame.origin.y;
+ [pAccessoryView setFrameSize: aViewFrame.size];
+
+ pControllerProperties->setupPreview( pCtrlTarget );
+
+ // set the accessory view
+ [pOp setAccessoryView: [pAccessoryView autorelease]];
+
+ // set the current selecte tab item
+ if( pState->nLastPage >= 0 && pState->nLastPage < [pTabView numberOfTabViewItems] )
+ [pTabView selectTabViewItemAtIndex: pState->nLastPage];
+
+ return pCtrlTarget;
+}
+
+@end
diff --git a/vcl/aqua/source/gdi/aquaprintview.mm b/vcl/aqua/source/gdi/aquaprintview.mm
index ba139da5f5a4..870b7cbab6f0 100755
--- a/vcl/aqua/source/gdi/aquaprintview.mm
+++ b/vcl/aqua/source/gdi/aquaprintview.mm
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: aquaprintview.mm,v $
- * $Revision: 1.5 $
+ * $Revision: 1.5.56.1 $
*
* This file is part of OpenOffice.org.
*
@@ -33,15 +33,15 @@
#include "aquaprintview.h"
#include "salprn.h"
-#include "vcl/impprn.hxx"
+#include "vcl/print.hxx"
@implementation AquaPrintView
--(id)initWithQPrinter: (ImplQPrinter*)pPrinter withInfoPrinter: (AquaSalInfoPrinter*)pInfoPrinter
+-(id)initWithController: (vcl::PrinterController*)pController withInfoPrinter: (AquaSalInfoPrinter*)pInfoPrinter
{
NSRect aRect = { { 0, 0 }, [pInfoPrinter->getPrintInfo() paperSize] };
if( (self = [super initWithFrame: aRect]) != nil )
{
- mpQPrinter = pPrinter;
+ mpController = pController;
mpInfoPrinter = pInfoPrinter;
}
return self;
@@ -79,6 +79,7 @@
int nPage = (int)(aPaperSize.width * rect.origin.y + rect.origin.x);
// page count is 1 based
- mpQPrinter->PrintPage( nPage-1 + mpInfoPrinter->getCurPageRangeStart() );
+ if( nPage - 1 < (mpInfoPrinter->getCurPageRangeStart() + mpInfoPrinter->getCurPageRangeCount() ) )
+ mpController->printFilteredPage( nPage-1 );
}
@end
diff --git a/vcl/aqua/source/gdi/makefile.mk b/vcl/aqua/source/gdi/makefile.mk
index 6598ac71ae91..832d93d4a5a0 100644
--- a/vcl/aqua/source/gdi/makefile.mk
+++ b/vcl/aqua/source/gdi/makefile.mk
@@ -61,6 +61,7 @@ SLOFILES= $(SLO)$/salmathutils.obj \
$(SLO)$/salvd.obj \
$(SLO)$/salprn.obj \
$(SLO)$/aquaprintview.obj \
+ $(SLO)$/aquaprintaccessoryview.obj \
$(SLO)$/salbmp.obj
.IF "$(ENABLE_CAIRO)" == "TRUE"
diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx
index 1c9bdda3fbdb..dedae3ac7cfc 100644
--- a/vcl/aqua/source/gdi/salgdi.cxx
+++ b/vcl/aqua/source/gdi/salgdi.cxx
@@ -54,6 +54,7 @@
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolygontools.hxx"
#include "basegfx/matrix/b2dhommatrix.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
using namespace vcl;
@@ -603,7 +604,8 @@ void AquaSalGraphics::EndSetClipRegion()
void AquaSalGraphics::SetLineColor()
{
maLineColor.SetAlpha( 0.0 ); // transparent
- CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
+ if( CheckContext() )
+ CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
}
// -----------------------------------------------------------------------
@@ -611,7 +613,8 @@ void AquaSalGraphics::SetLineColor()
void AquaSalGraphics::SetLineColor( SalColor nSalColor )
{
maLineColor = RGBAColor( nSalColor );
- CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
+ if( CheckContext() )
+ CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
}
// -----------------------------------------------------------------------
@@ -619,7 +622,8 @@ void AquaSalGraphics::SetLineColor( SalColor nSalColor )
void AquaSalGraphics::SetFillColor()
{
maFillColor.SetAlpha( 0.0 ); // transparent
- CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+ if( CheckContext() )
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
}
// -----------------------------------------------------------------------
@@ -627,7 +631,8 @@ void AquaSalGraphics::SetFillColor()
void AquaSalGraphics::SetFillColor( SalColor nSalColor )
{
maFillColor = RGBAColor( nSalColor );
- CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+ if( CheckContext() )
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
}
// -----------------------------------------------------------------------
@@ -1768,9 +1773,7 @@ BOOL AquaSalGraphics::GetGlyphOutline( long nGlyphId, basegfx::B2DPolyPolygon& r
GgoClosePathProc( &aGgoData );
if( mfFontScale != 1.0 ) {
- basegfx::B2DHomMatrix aScale;
- aScale.scale( +mfFontScale, +mfFontScale );
- rPolyPoly.transform( aScale );
+ rPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(+mfFontScale, +mfFontScale));
}
return true;
}
diff --git a/vcl/aqua/source/gdi/salgdiutils.cxx b/vcl/aqua/source/gdi/salgdiutils.cxx
index 99a1629006d2..6df50f79e9d0 100755
--- a/vcl/aqua/source/gdi/salgdiutils.cxx
+++ b/vcl/aqua/source/gdi/salgdiutils.cxx
@@ -68,6 +68,13 @@ void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, lon
mnRealDPIX = nDPIX;
mnRealDPIY = nDPIY;
+ // a previously set clip path is now invalid
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+
if( mrContext )
{
CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
@@ -126,6 +133,28 @@ void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContex
// ----------------------------------------------------------------------
+void AquaSalGraphics::InvalidateContext()
+{
+ UnsetState();
+ mrContext = 0;
+}
+
+// ----------------------------------------------------------------------
+
+void AquaSalGraphics::UnsetState()
+{
+ if( mrContext )
+ {
+ CGContextRestoreGState( mrContext );
+ mrContext = 0;
+ }
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+}
+
void AquaSalGraphics::SetState()
{
CGContextRestoreGState( mrContext );
@@ -134,9 +163,9 @@ void AquaSalGraphics::SetState()
// setup clipping
if( mxClipPath )
{
- CGContextBeginPath( mrContext ); // discard any existing path
+ CGContextBeginPath( mrContext ); // discard any existing path
CGContextAddPath( mrContext, mxClipPath ); // set the current path to the clipping path
- CGContextClip( mrContext ); // use it for clipping
+ CGContextClip( mrContext ); // use it for clipping
}
// set RGB colorspace and line and fill colors
@@ -205,7 +234,7 @@ bool AquaSalGraphics::CheckContext()
CGContextRelease( rReleaseContext );
}
- DBG_ASSERT( mrContext, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
+ DBG_ASSERT( mrContext || mbPrinter, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
return (mrContext != NULL);
}
diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx
index b9a1f4ef7748..47c027a033aa 100644
--- a/vcl/aqua/source/gdi/salprn.cxx
+++ b/vcl/aqua/source/gdi/salprn.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: salprn.cxx,v $
- * $Revision: 1.16 $
+ * $Revision: 1.16.56.2 $
*
* This file is part of OpenOffice.org.
*
@@ -38,7 +38,6 @@
#include "saldata.hxx"
#include "vcl/jobset.h"
#include "vcl/salptype.hxx"
-#include "vcl/impprn.hxx"
#include "vcl/print.hxx"
#include "vcl/unohelp.hxx"
@@ -47,11 +46,13 @@
#include "com/sun/star/lang/XMultiServiceFactory.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/awt/Size.hpp"
#include <algorithm>
using namespace rtl;
using namespace vcl;
+using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
@@ -67,7 +68,9 @@ AquaSalInfoPrinter::AquaSalInfoPrinter( const SalPrinterQueueInfo& i_rQueue ) :
mpPrintInfo( nil ),
mePageOrientation( ORIENTATION_PORTRAIT ),
mnStartPageOffsetX( 0 ),
- mnStartPageOffsetY( 0 )
+ mnStartPageOffsetY( 0 ),
+ mnCurPageRangeStart( 0 ),
+ mnCurPageRangeCount( 0 )
{
NSString* pStr = CreateNSString( i_rQueue.maPrinterName );
mpPrinter = [NSPrinter printerWithName: pStr];
@@ -87,6 +90,7 @@ AquaSalInfoPrinter::AquaSalInfoPrinter( const SalPrinterQueueInfo& i_rQueue ) :
const int nWidth = 100, nHeight = 100;
maContextMemory.reset( reinterpret_cast<sal_uInt8*>( rtl_allocateMemory( nWidth * 4 * nHeight ) ),
boost::bind( rtl_freeMemory, _1 ) );
+
if( maContextMemory )
{
mrContext = CGBitmapContextCreate( maContextMemory.get(), nWidth, nHeight, 8, nWidth * 4, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst );
@@ -134,7 +138,7 @@ void AquaSalInfoPrinter::SetupPrinterGraphics( CGContextRef i_rContext ) const
dY -= aPaperSize.height - aImageRect.size.height - aImageRect.origin.y;
CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetX, dY - mnStartPageOffsetY );
// scale to be top/down and reflect our "virtual" DPI
- CGContextScaleCTM( i_rContext, 0.1, -0.1 );
+ CGContextScaleCTM( i_rContext, 72.0/double(nDPIX), -(72.0/double(nDPIY)) );
}
else
{
@@ -148,7 +152,7 @@ void AquaSalInfoPrinter::SetupPrinterGraphics( CGContextRef i_rContext ) const
dY = -aPaperSize.width;
CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetY, dY - mnStartPageOffsetX );
// scale to be top/down and reflect our "virtual" DPI
- CGContextScaleCTM( i_rContext, -0.1, 0.1 );
+ CGContextScaleCTM( i_rContext, -(72.0/double(nDPIY)), (72.0/double(nDPIX)) );
}
mpGraphics->SetPrinterGraphics( i_rContext, nDPIX, nDPIY, 1.0 );
}
@@ -296,6 +300,28 @@ BOOL AquaSalInfoPrinter::SetPrinterData( ImplJobSetup* io_pSetupData )
// -----------------------------------------------------------------------
+void AquaSalInfoPrinter::setPaperSize( long i_nWidth, long i_nHeight, Orientation i_eSetOrientation )
+{
+
+ Orientation ePaperOrientation = ORIENTATION_PORTRAIT;
+ const PaperInfo* pPaper = matchPaper( i_nWidth, i_nHeight, ePaperOrientation );
+
+ if( pPaper )
+ {
+ NSString* pPaperName = [CreateNSString( rtl::OStringToOUString(PaperInfo::toPSName(pPaper->getPaper()), RTL_TEXTENCODING_ASCII_US) ) autorelease];
+ [mpPrintInfo setPaperName: pPaperName];
+ }
+ else if( i_nWidth > 0 && i_nHeight > 0 )
+ {
+ NSSize aPaperSize = { TenMuToPt(i_nWidth), TenMuToPt(i_nHeight) };
+ [mpPrintInfo setPaperSize: aPaperSize];
+ }
+ // this seems counterintuitive
+ mePageOrientation = i_eSetOrientation;
+}
+
+// -----------------------------------------------------------------------
+
BOOL AquaSalInfoPrinter::SetData( ULONG i_nFlags, ImplJobSetup* io_pSetupData )
{
if( ! io_pSetupData || io_pSetupData->mnSystem != JOBSETUP_SYSTEM_MAC )
@@ -304,31 +330,32 @@ BOOL AquaSalInfoPrinter::SetData( ULONG i_nFlags, ImplJobSetup* io_pSetupData )
if( mpPrintInfo )
{
+ if( (i_nFlags & SAL_JOBSET_ORIENTATION) != 0 )
+ mePageOrientation = io_pSetupData->meOrientation;
+
if( (i_nFlags & SAL_JOBSET_PAPERSIZE) != 0)
{
// set paper format
- double width = 0, height = 0;
+ long width = 21000, height = 29700;
if( io_pSetupData->mePaperFormat == PAPER_USER )
{
// #i101108# sanity check
if( io_pSetupData->mnPaperWidth && io_pSetupData->mnPaperHeight )
{
- width = TenMuToPt( io_pSetupData->mnPaperWidth );
- height = TenMuToPt( io_pSetupData->mnPaperHeight );
+ width = io_pSetupData->mnPaperWidth;
+ height = io_pSetupData->mnPaperHeight;
}
}
else
- getPaperSize( width, height, io_pSetupData->mePaperFormat );
-
- if( width > 0 && height > 0 )
{
- NSSize aPaperSize = { width, height };
- [mpPrintInfo setPaperSize: aPaperSize];
+ double w = 595, h = 842;
+ getPaperSize( w, h, io_pSetupData->mePaperFormat );
+ width = static_cast<long>(PtTo10Mu( w ));
+ height = static_cast<long>(PtTo10Mu( h ));
}
- }
- if( (i_nFlags & SAL_JOBSET_ORIENTATION) != 0 )
- mePageOrientation = io_pSetupData->meOrientation;
+ setPaperSize( width, height, mePageOrientation );
+ }
}
return mpPrintInfo != nil;
@@ -424,6 +451,8 @@ ULONG AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup* i_pSetupData, USH
return 0;
case PRINTER_CAPABILITIES_SETORIENTATION:
return 1;
+ case PRINTER_CAPABILITIES_SETDUPLEX:
+ return 0;
case PRINTER_CAPABILITIES_SETPAPERBIN:
return 0;
case PRINTER_CAPABILITIES_SETPAPERSIZE:
@@ -432,6 +461,8 @@ ULONG AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup* i_pSetupData, USH
return 1;
case PRINTER_CAPABILITIES_EXTERNALDIALOG:
return getUseNativeDialog() ? 1 : 0;
+ case PRINTER_CAPABILITIES_PDF:
+ return 1;
default: break;
};
return 0;
@@ -470,58 +501,129 @@ void AquaSalInfoPrinter::GetPageInfo( const ImplJobSetup*,
}
}
-BOOL AquaSalInfoPrinter::StartJob( const String* pFileName,
- const String& rAppName,
- ImplJobSetup* pSetupData,
- ImplQPrinter* pQPrinter,
- bool bIsQuickJob )
+static Size getPageSize( vcl::PrinterController& i_rController, sal_Int32 i_nPage )
+{
+ Size aPageSize;
+ Sequence< PropertyValue > aPageParms( i_rController.getPageParameters( i_nPage ) );
+ for( sal_Int32 nProperty = 0, nPropertyCount = aPageParms.getLength(); nProperty < nPropertyCount; ++nProperty )
+ {
+ if( aPageParms[ nProperty ].Name.equalsAscii( "PageSize" ) )
+ {
+ awt::Size aSize;
+ aPageParms[ nProperty].Value >>= aSize;
+ aPageSize.Width() = aSize.Width;
+ aPageSize.Height() = aSize.Height;
+ break;
+ }
+ }
+ return aPageSize;
+}
+
+BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName,
+ const String& i_rJobName,
+ const String& i_rAppName,
+ ImplJobSetup* i_pSetupData,
+ vcl::PrinterController& i_rController
+ )
{
if( mbJob )
return FALSE;
BOOL bSuccess = FALSE;
- std::vector<ULONG> aPaperRanges;
- if( ! pQPrinter->GetPaperRanges( aPaperRanges, true ) )
- return FALSE;
-
- size_t nRanges = aPaperRanges.size();
+ bool bWasAborted = false;
AquaSalInstance* pInst = GetSalData()->mpFirstInstance;
-
- for( ULONG nCurRange = 0; nCurRange < nRanges-1; nCurRange++ )
+ PrintAccessoryViewState aAccViewState;
+ sal_Int32 nAllPages = 0;
+
+ aAccViewState.bNeedRestart = true;
+
+ // reset IsLastPage
+ i_rController.setLastPage( sal_False );
+
+ // update job data
+ if( i_pSetupData )
+ SetData( ~0, i_pSetupData );
+
+ // do we want a progress panel ?
+ sal_Bool bShowProgressPanel = sal_True;
+ beans::PropertyValue* pMonitor = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MonitorVisible" ) ) );
+ if( pMonitor )
+ pMonitor->Value >>= bShowProgressPanel;
+ if( ! i_rController.isShowDialogs() )
+ bShowProgressPanel = sal_False;
+
+ // FIXME: jobStarted() should be done after the print dialog has ended (if there is one)
+ // how do I know when that might be ?
+ i_rController.jobStarted();
+ do
{
- mnStartPageOffsetX = mnStartPageOffsetY = 0;
+ if( aAccViewState.bNeedRestart )
+ {
+ mnCurPageRangeStart = 0;
+ mnCurPageRangeCount = 0;
+ nAllPages = i_rController.getFilteredPageCount();
+ }
- // update job data
- ImplJobSetup* pSetup = pQPrinter->GetPageSetup( aPaperRanges[ nCurRange ] );
- if( pSetup )
- SetData( ~0, pSetup );
- DBG_ASSERT( pSetup, "no job setup for range" );
+ aAccViewState.bNeedRestart = false;
+
+ Size aCurSize( 21000, 29700 );
+ if( nAllPages > 0 )
+ {
+ mnCurPageRangeCount = 1;
+ aCurSize = getPageSize( i_rController, mnCurPageRangeStart );
+ Size aNextSize( aCurSize );
+
+ // print pages up to a different size
+ while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages )
+ {
+ aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount );
+ if( aCurSize == aNextSize // same page size
+ ||
+ (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation
+ )
+ {
+ mnCurPageRangeCount++;
+ }
+ else
+ break;
+ }
+ }
+ else
+ mnCurPageRangeCount = 0;
+
+ // now for the current run
+ mnStartPageOffsetX = mnStartPageOffsetY = 0;
+ // setup the paper size and orientation
+ // do this on our associated Printer object, since that is
+ // out interface to the applications which occasionally rely on the paper
+ // information (e.g. brochure printing scales to the found paper size)
+ // also SetPaperSizeUser has the advantage that we can share a
+ // platform independent paper matching algorithm
+ boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() );
+ pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
+ pPrinter->SetPaperSizeUser( aCurSize, true );
- mnCurPageRangeStart = aPaperRanges[nCurRange];
- mnCurPageRangeCount = aPaperRanges[nCurRange+1] - aPaperRanges[nCurRange];
// create view
- NSView* pPrintView = [[AquaPrintView alloc] initWithQPrinter: pQPrinter withInfoPrinter: this];
+ NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this];
NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary];
// set filename
- if( pFileName )
+ if( i_pFileName )
{
[mpPrintInfo setJobDisposition: NSPrintSaveJob];
- NSString* pPath = CreateNSString( *pFileName );
+ NSString* pPath = CreateNSString( *i_pFileName );
[pPrintDict setObject: pPath forKey: NSPrintSavePath];
[pPath release];
-
- // in this case we can only deliver the print job in one file
- mnCurPageRangeStart = 0;
- mnCurPageRangeCount = aPaperRanges.back();
- nCurRange = nRanges;
}
- [pPrintDict setObject: [[NSNumber numberWithInt: (int)pQPrinter->GetCopyCount()] autorelease] forKey: NSPrintCopies];
+ [pPrintDict setObject: [[NSNumber numberWithInt: (int)i_rController.getPrinter()->GetCopyCount()] autorelease] forKey: NSPrintCopies];
[pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting];
[pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage];
- [pPrintDict setObject: [[NSNumber numberWithInt: (int)mnCurPageRangeCount] autorelease] forKey: NSPrintLastPage];
+ // #i103253# weird: for some reason, autoreleasing the value below like the others above
+ // leads do a double free malloc error. Why this value should behave differently from all the others
+ // is a mystery.
+ [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage];
// create print operation
@@ -529,17 +631,47 @@ BOOL AquaSalInfoPrinter::StartJob( const String* pFileName,
if( pPrintOperation )
{
- bool bShowPanel = (! bIsQuickJob && getUseNativeDialog() );
+ NSObject* pReleaseAfterUse = nil;
+ bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() );
[pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ];
- // [pPrintOperation setShowsProgressPanel: NO];
+ [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO];
+
+ // set job title (since MacOSX 10.5)
+ if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] )
+ [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]];
+
+ if( bShowPanel && mnCurPageRangeStart == 0 ) // only the first range of pages gets the accesory view
+ pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState];
+
bSuccess = TRUE;
mbJob = true;
pInst->startedPrintJob();
[pPrintOperation runOperation];
pInst->endedPrintJob();
+ bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame;
mbJob = false;
+ if( pReleaseAfterUse )
+ [pReleaseAfterUse release];
}
- }
+
+ mnCurPageRangeStart += mnCurPageRangeCount;
+ mnCurPageRangeCount = 1;
+ } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages );
+
+ // inform application that it can release its data
+ // this is awkward, but the XRenderable interface has no method for this,
+ // so we need to call XRenderadble::render one last time with IsLastPage = TRUE
+ i_rController.setLastPage( sal_True );
+ GDIMetaFile aPageFile;
+ if( mrContext )
+ SetupPrinterGraphics( mrContext );
+ i_rController.getFilteredPageFile( 0, aPageFile );
+
+ i_rController.setJobState( bWasAborted
+ ? view::PrintableState_JOB_ABORTED
+ : view::PrintableState_JOB_SPOOLED );
+
+ mnCurPageRangeStart = mnCurPageRangeCount = 0;
return bSuccess;
}
@@ -581,6 +713,7 @@ SalGraphics* AquaSalInfoPrinter::StartPage( ImplJobSetup* i_pSetupData, BOOL i_b
BOOL AquaSalInfoPrinter::EndPage()
{
+ mpGraphics->InvalidateContext();
return TRUE;
}
@@ -606,31 +739,24 @@ AquaSalPrinter::~AquaSalPrinter()
// -----------------------------------------------------------------------
-BOOL AquaSalPrinter::StartJob( const String* pFileName,
- const String& rAppName,
- ImplJobSetup* pSetupData,
- ImplQPrinter* pQPrinter )
+BOOL AquaSalPrinter::StartJob( const String* i_pFileName,
+ const String& i_rJobName,
+ const String& i_rAppName,
+ ImplJobSetup* i_pSetupData,
+ vcl::PrinterController& i_rController )
{
- bool bIsQuickJob = false;
- std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator quick_it =
- pSetupData->maValueMap.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ) );
-
- if( quick_it != pSetupData->maValueMap.end() )
- {
- if( quick_it->second.equalsIgnoreAsciiCaseAscii( "true" ) )
- bIsQuickJob = true;
- }
-
- return mpInfoPrinter->StartJob( pFileName, rAppName, pSetupData, pQPrinter, bIsQuickJob );
+ return mpInfoPrinter->StartJob( i_pFileName, i_rJobName, i_rAppName, i_pSetupData, i_rController );
}
// -----------------------------------------------------------------------
BOOL AquaSalPrinter::StartJob( const XubString* i_pFileName,
- const XubString& i_rJobName,
- const XubString& i_rAppName,
- ULONG i_nCopies, BOOL i_bCollate,
- ImplJobSetup* i_pSetupData )
+ const XubString& i_rJobName,
+ const XubString& i_rAppName,
+ ULONG i_nCopies,
+ bool i_bCollate,
+ bool i_bDirect,
+ ImplJobSetup* i_pSetupData )
{
DBG_ERROR( "should never be called" );
return FALSE;
@@ -671,20 +797,62 @@ ULONG AquaSalPrinter::GetErrorCode()
return mpInfoPrinter->GetErrorCode();
}
-////////////////////////////
-////// IMPLEMENT US /////
-////////////////////////////
-
-DuplexMode AquaSalInfoPrinter::GetDuplexMode( const ImplJobSetup* i_pSetupData )
+void AquaSalInfoPrinter::InitPaperFormats( const ImplJobSetup* i_pSetupData )
{
- return DUPLEX_UNKNOWN;
+ m_aPaperFormats.clear();
+ m_bPapersInit = true;
+
+ if( mpPrinter )
+ {
+ if( [mpPrinter statusForTable: @"PPD"] == NSPrinterTableOK )
+ {
+ NSArray* pPaperNames = [mpPrinter stringListForKey: @"PageSize" inTable: @"PPD"];
+ if( pPaperNames )
+ {
+ unsigned int nPapers = [pPaperNames count];
+ for( unsigned int i = 0; i < nPapers; i++ )
+ {
+ NSString* pPaper = [pPaperNames objectAtIndex: i];
+ NSSize aPaperSize = [mpPrinter pageSizeForPaper: pPaper];
+ if( aPaperSize.width > 0 && aPaperSize.height > 0 )
+ {
+ PaperInfo aInfo( PtTo10Mu( aPaperSize.width ),
+ PtTo10Mu( aPaperSize.height ) );
+ m_aPaperFormats.push_back( aInfo );
+ }
+ }
+ }
+ }
+ }
}
-void AquaSalInfoPrinter::InitPaperFormats( const ImplJobSetup* i_pSetupData )
+const PaperInfo* AquaSalInfoPrinter::matchPaper( long i_nWidth, long i_nHeight, Orientation& o_rOrientation ) const
{
+ if( ! m_bPapersInit )
+ const_cast<AquaSalInfoPrinter*>(this)->InitPaperFormats( NULL );
+
+ const PaperInfo* pMatch = NULL;
+ o_rOrientation = ORIENTATION_PORTRAIT;
+ for( int n = 0; n < 2 ; n++ )
+ {
+ for( size_t i = 0; i < m_aPaperFormats.size(); i++ )
+ {
+ if( abs( m_aPaperFormats[i].getWidth() - i_nWidth ) < 50 &&
+ abs( m_aPaperFormats[i].getHeight() - i_nHeight ) < 50 )
+ {
+ pMatch = &m_aPaperFormats[i];
+ return pMatch;
+ }
+ }
+ o_rOrientation = ORIENTATION_LANDSCAPE;
+ std::swap( i_nWidth, i_nHeight );
+ }
+ return pMatch;
}
int AquaSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* i_pSetupData )
{
- return 0;
+ return 900;
}
+
+
diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx
new file mode 100644
index 000000000000..309d0bf930ea
--- /dev/null
+++ b/vcl/inc/vcl/arrange.hxx
@@ -0,0 +1,425 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accel.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _VCL_ARRANGE_HXX
+#define _VCL_ARRANGE_HXX
+
+#include "vcl/window.hxx"
+
+#include <vector>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+namespace vcl
+{
+ /* some helper classes for simple window layouting
+ guidelines:
+ - a WindowArranger is not a Window
+ - a WindowArranger hierarchy manages exactly one level of child windows inside a common parent
+ this is to keep the vcl Window hierarchy flat, as some code like accelerators depend on such behavior
+ - a WindowArranger never becomes owner of a Window, windows need to be destroyed separately
+ - a WindowArranger however always is owner of its child WindowArrangers, that is the
+ WindowArranger hierarchy will keep track of its objects and delete them
+ - a managed element of a WindowArranger can either be a Window (a leaf in the hierarchy)
+ or a child WindowArranger (a node in the hierarchy), but never both
+ */
+
+ class WindowArranger
+ {
+ protected:
+ struct Element
+ {
+ Window* m_pElement;
+ boost::shared_ptr<WindowArranger> m_pChild;
+ sal_Int32 m_nExpandPriority;
+ Size m_aMinSize;
+ bool m_bHidden;
+ long m_nLeftBorder;
+ long m_nTopBorder;
+ long m_nRightBorder;
+ long m_nBottomBorder;
+
+ Element()
+ : m_pElement( NULL )
+ , m_pChild()
+ , m_nExpandPriority( 0 )
+ , m_bHidden( false )
+ , m_nLeftBorder( 0 )
+ , m_nTopBorder( 0 )
+ , m_nRightBorder( 0 )
+ , m_nBottomBorder( 0 )
+ {}
+
+ Element( Window* i_pWin,
+ boost::shared_ptr<WindowArranger> const & i_pChild = boost::shared_ptr<WindowArranger>(),
+ sal_Int32 i_nExpandPriority = 0
+ )
+ : m_pElement( i_pWin )
+ , m_pChild( i_pChild )
+ , m_nExpandPriority( i_nExpandPriority )
+ , m_bHidden( false )
+ , m_nLeftBorder( 0 )
+ , m_nTopBorder( 0 )
+ , m_nRightBorder( 0 )
+ , m_nBottomBorder( 0 )
+ {}
+
+ void deleteChild() { m_pChild.reset(); }
+
+ sal_Int32 getExpandPriority() const;
+ Size getOptimalSize( WindowSizeType ) const;
+ bool isVisible() const;
+ void setPosSize( const Point&, const Size& );
+ };
+
+ Window* m_pParentWindow;
+ WindowArranger* m_pParentArranger;
+ Rectangle m_aManagedArea;
+ long m_nOuterBorder;
+
+ virtual Element* getElement( size_t i_nIndex ) = 0;
+ const Element* getConstElement( size_t i_nIndex ) const
+ { return const_cast<WindowArranger*>(this)->getElement( i_nIndex ); }
+
+
+ public:
+ WindowArranger( WindowArranger* i_pParent = NULL )
+ : m_pParentWindow( i_pParent ? i_pParent->m_pParentWindow : NULL )
+ , m_pParentArranger( i_pParent )
+ , m_nOuterBorder( 0 )
+ {}
+ virtual ~WindowArranger();
+
+ // ask what would be the optimal size
+ virtual Size getOptimalSize( WindowSizeType ) const = 0;
+ // call Resize to trigger layouting inside the managed area
+ // without function while parent window is unset
+ virtual void resize() = 0;
+ // avoid this if possible, using the constructor instead
+ // there can be only one parent window and all managed windows MUST
+ // be direct children of that window
+ // violating that condition will result in undefined behavior
+ virtual void setParentWindow( Window* );
+
+ virtual void setParent( WindowArranger* );
+
+ virtual size_t countElements() const = 0;
+ boost::shared_ptr<WindowArranger> getChild( size_t i_nIndex ) const
+ {
+ const Element* pEle = getConstElement( i_nIndex );
+ return pEle ? pEle->m_pChild : boost::shared_ptr<WindowArranger>();
+ }
+ Window* getWindow( size_t i_nIndex ) const
+ {
+ const Element* pEle = getConstElement( i_nIndex );
+ return pEle ? pEle->m_pElement : NULL;
+ }
+
+ virtual bool isVisible() const; // true if any element is visible
+
+ sal_Int32 getExpandPriority( size_t i_nIndex ) const
+ {
+ const Element* pEle = getConstElement( i_nIndex );
+ return pEle ? pEle->getExpandPriority() : 0;
+ }
+
+ Size getMinimumSize( size_t i_nIndex ) const
+ {
+ const Element* pEle = getConstElement( i_nIndex );
+ return pEle ? pEle->m_aMinSize : Size();
+ }
+
+ bool setMinimumSize( size_t i_nIndex, const Size& i_rMinSize )
+ {
+ Element* pEle = getElement( i_nIndex );
+ if( pEle )
+ pEle->m_aMinSize = i_rMinSize;
+ return pEle != NULL;
+ }
+
+ void setBorders( size_t i_nIndex, long i_nLeft, long i_nTop, long i_nRight, long i_nBottom )
+ {
+ Element* pEle = getElement( i_nIndex );
+ if( pEle )
+ {
+ pEle->m_nLeftBorder = i_nLeft;
+ pEle->m_nRightBorder = i_nRight;
+ pEle->m_nTopBorder = i_nTop;
+ pEle->m_nBottomBorder = i_nBottom;
+ }
+ }
+
+ void show( bool i_bShow = true, bool i_bImmediateUpdate = true );
+
+ void setManagedArea( const Rectangle& i_rArea )
+ {
+ m_aManagedArea = i_rArea;
+ resize();
+ }
+ const Rectangle& getManagedArea() const { return m_aManagedArea; }
+
+ void setOuterBorder( long i_nBorder )
+ {
+ m_nOuterBorder = i_nBorder;
+ resize();
+ }
+ };
+
+ class RowOrColumn : public WindowArranger
+ {
+ long m_nBorderWidth;
+ bool m_bColumn;
+
+ std::vector< WindowArranger::Element > m_aElements;
+
+ void distributeRowWidth( std::vector< Size >& io_rSizes, long i_nUsedWidth, long i_nExtraWidth );
+ void distributeColumnHeight( std::vector< Size >& io_rSizes, long i_nUsedHeight, long i_nExtraHeight );
+ protected:
+ virtual Element* getElement( size_t i_nIndex )
+ { return i_nIndex < m_aElements.size() ? &m_aElements[ i_nIndex ] : 0; }
+
+ public:
+ RowOrColumn( WindowArranger* i_pParent = NULL,
+ bool bColumn = true, long i_nBorderWidth = 5 )
+ : WindowArranger( i_pParent )
+ , m_nBorderWidth( i_nBorderWidth )
+ , m_bColumn( bColumn )
+ {}
+
+ virtual ~RowOrColumn();
+
+ virtual Size getOptimalSize( WindowSizeType ) const;
+ virtual void resize();
+ virtual size_t countElements() const { return m_aElements.size(); }
+
+ // add a managed window at the given index
+ // an index smaller than zero means add the window at the end
+ size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 );
+ void remove( Window* );
+
+ size_t addChild( boost::shared_ptr<WindowArranger> const &, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 );
+ // convenience: use for addChild( new WindowArranger( ... ) ) constructs
+ size_t addChild( WindowArranger* i_pNewChild, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 )
+ { return addChild( boost::shared_ptr<WindowArranger>( i_pNewChild ), i_nExpandPrio, i_nIndex ); }
+ void remove( boost::shared_ptr<WindowArranger> const & );
+
+ long getBorderWidth() const { return m_nBorderWidth; }
+ };
+
+ class LabeledElement : public WindowArranger
+ {
+ WindowArranger::Element m_aLabel;
+ WindowArranger::Element m_aElement;
+ long m_nDistance;
+ long m_nLabelColumnWidth;
+ int m_nLabelStyle;
+ protected:
+ virtual Element* getElement( size_t i_nIndex )
+ {
+ if( i_nIndex == 0 )
+ return &m_aLabel;
+ else if( i_nIndex == 1 )
+ return &m_aElement;
+ return 0;
+ }
+
+ public:
+ LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = 5 )
+ : WindowArranger( i_pParent )
+ , m_nDistance( i_nDistance )
+ , m_nLabelColumnWidth( 0 )
+ , m_nLabelStyle( i_nLabelStyle )
+ {}
+
+ virtual ~LabeledElement();
+
+ virtual Size getOptimalSize( WindowSizeType ) const;
+ virtual void resize();
+ virtual size_t countElements() const { return 2; }
+
+ void setLabel( Window* );
+ void setLabel( boost::shared_ptr<WindowArranger> const & );
+ void setElement( Window* );
+ void setElement( boost::shared_ptr<WindowArranger> const & );
+ void setLabelColumnWidth( long i_nWidth )
+ { m_nLabelColumnWidth = i_nWidth; }
+
+ Size getLabelSize( WindowSizeType i_eType ) const
+ { return m_aLabel.getOptimalSize( i_eType ); }
+ Size getElementSize( WindowSizeType i_eType ) const
+ { return m_aElement.getOptimalSize( i_eType ); }
+ };
+
+ class LabelColumn : public RowOrColumn
+ {
+ long getLabelWidth() const;
+ public:
+ LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = 5 )
+ : RowOrColumn( i_pParent, true, i_nBorderWidth )
+ {}
+ virtual ~LabelColumn();
+
+ virtual Size getOptimalSize( WindowSizeType ) const;
+ virtual void resize();
+
+ // returns the index of the added label
+ size_t addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent = 0 );
+ size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0 );
+ };
+
+ class Indenter : public WindowArranger
+ {
+ long m_nIndent;
+ WindowArranger::Element m_aElement;
+
+ protected:
+ virtual Element* getElement( size_t i_nIndex )
+ { return i_nIndex == 0 ? &m_aElement : NULL; }
+
+ public:
+ Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 15 )
+ : WindowArranger( i_pParent )
+ , m_nIndent( i_nIndent )
+ {}
+
+ virtual ~Indenter();
+
+ virtual Size getOptimalSize( WindowSizeType ) const;
+ virtual void resize();
+ virtual size_t countElements() const { return (m_aElement.m_pElement != 0 || m_aElement.m_pChild != 0) ? 1 : 0; }
+
+ void setIndent( long i_nIndent )
+ {
+ m_nIndent = i_nIndent;
+ resize();
+ }
+
+ void setWindow( Window*, sal_Int32 i_nExpandPrio = 0 );
+ void setChild( boost::shared_ptr<WindowArranger> const &, sal_Int32 i_nExpandPrio = 0 );
+ // convenience: use for setChild( new WindowArranger( ... ) ) constructs
+ void setChild( WindowArranger* i_pChild, sal_Int32 i_nExpandPrio = 0 )
+ { setChild( boost::shared_ptr<WindowArranger>( i_pChild ), i_nExpandPrio ); }
+ };
+
+ class Spacer : public WindowArranger
+ {
+ WindowArranger::Element m_aElement;
+ Size m_aSize;
+
+ protected:
+ virtual Element* getElement( size_t i_nIndex )
+ { return i_nIndex == 0 ? &m_aElement : NULL; }
+
+ public:
+ Spacer( WindowArranger* i_pParent = NULL, sal_Int32 i_nPrio = 20, const Size& i_rSize = Size( 0, 0 ) )
+ : WindowArranger( i_pParent )
+ , m_aElement( NULL, boost::shared_ptr<WindowArranger>(), i_nPrio )
+ , m_aSize( i_rSize )
+ {}
+
+ virtual ~Spacer() {}
+
+ virtual Size getOptimalSize( WindowSizeType ) const
+ { return m_aSize; }
+ virtual void resize() {}
+ virtual void setParentWindow( Window* ) {}
+ virtual size_t countElements() const { return 1; }
+ virtual bool isVisible() const { return true; }
+ };
+
+ class MatrixArranger : public WindowArranger
+ {
+ long m_nBorderX;
+ long m_nBorderY;
+
+ struct MatrixElement : public WindowArranger::Element
+ {
+ sal_uInt32 m_nX;
+ sal_uInt32 m_nY;
+
+ MatrixElement()
+ : WindowArranger::Element()
+ , m_nX( 0 )
+ , m_nY( 0 )
+ {}
+
+ MatrixElement( Window* i_pWin,
+ sal_uInt32 i_nX, sal_uInt32 i_nY,
+ boost::shared_ptr<WindowArranger> const & i_pChild = boost::shared_ptr<WindowArranger>(),
+ sal_Int32 i_nExpandPriority = 0
+ )
+ : WindowArranger::Element( i_pWin, i_pChild, i_nExpandPriority )
+ , m_nX( i_nX )
+ , m_nY( i_nY )
+ {
+ }
+ };
+
+ std::vector< MatrixElement > m_aElements;
+ std::map< sal_uInt64, size_t > m_aMatrixMap; // maps (x | (y << 32)) to index in m_aElements
+
+ sal_uInt64 getMap( sal_uInt32 i_nX, sal_uInt32 i_nY )
+ { return static_cast< sal_uInt64 >(i_nX) | (static_cast< sal_uInt64>(i_nY) << 32 ); }
+
+ Size getOptimalSize( WindowSizeType, std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights ) const;
+ protected:
+ virtual Element* getElement( size_t i_nIndex )
+ { return i_nIndex < m_aElements.size() ? &m_aElements[ i_nIndex ] : 0; }
+
+ public:
+ MatrixArranger( WindowArranger* i_pParent = NULL,
+ long i_nBorderX = 5,
+ long i_nBorderY = 5 )
+ : WindowArranger( i_pParent )
+ , m_nBorderX( i_nBorderX )
+ , m_nBorderY( i_nBorderY )
+ {}
+
+ virtual ~MatrixArranger();
+
+ virtual Size getOptimalSize( WindowSizeType ) const;
+ virtual void resize();
+ virtual size_t countElements() const { return m_aElements.size(); }
+
+ // add a managed window at the given matrix position
+ size_t addWindow( Window*, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 );
+ void remove( Window* );
+
+ size_t addChild( boost::shared_ptr<WindowArranger> const &, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 );
+ // convenience: use for addChild( new WindowArranger( ... ) ) constructs
+ size_t addChild( WindowArranger* i_pNewChild, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 )
+ { return addChild( boost::shared_ptr<WindowArranger>( i_pNewChild ), i_nX, i_nY, i_nExpandPrio ); }
+ void remove( boost::shared_ptr<WindowArranger> const & );
+ };
+
+}
+
+#endif
+
diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx
index b80edf6712cd..b5f70217e149 100644
--- a/vcl/inc/vcl/button.hxx
+++ b/vcl/inc/vcl/button.hxx
@@ -425,7 +425,6 @@ private:
SAL_DLLPRIVATE void ImplInitCheckBoxData();
SAL_DLLPRIVATE WinBits ImplInitStyle( const Window* pPrevWindow, WinBits nStyle );
SAL_DLLPRIVATE void ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground );
- SAL_DLLPRIVATE void ImplDrawCheckBoxState();
SAL_DLLPRIVATE void ImplInvalidateOrDrawCheckBoxState();
SAL_DLLPRIVATE void ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
const Point& rPos, const Size& rSize,
@@ -450,10 +449,12 @@ protected:
SAL_DLLPRIVATE virtual const Color&
GetCanonicalTextColor( const StyleSettings& _rStyle ) const;
+ SAL_DLLPRIVATE virtual void ImplDrawCheckBoxState();
+ SAL_DLLPRIVATE const Rectangle& GetStateRect() const { return maStateRect; }
+ SAL_DLLPRIVATE const Rectangle& GetMouseRect() const { return maMouseRect; }
public:
SAL_DLLPRIVATE void ImplCheck();
SAL_DLLPRIVATE void ImplSetMinimumNWFSize();
-
public:
CheckBox( Window* pParent, WinBits nStyle = 0 );
CheckBox( Window* pParent, const ResId& rResId );
@@ -552,4 +553,15 @@ public:
~TriStateBox();
};
+class VCL_DLLPUBLIC DisclosureButton : public CheckBox
+{
+protected:
+ SAL_DLLPRIVATE virtual void ImplDrawCheckBoxState();
+public:
+ DisclosureButton( Window* pParent, WinBits nStyle = 0 );
+ DisclosureButton( Window* pParent, const ResId& rResId );
+
+ virtual void KeyInput( const KeyEvent& rKEvt );
+};
+
#endif // _SV_BUTTON_HXX
diff --git a/vcl/inc/vcl/configsettings.hxx b/vcl/inc/vcl/configsettings.hxx
index aee684a84ca4..211ea3f0892b 100644
--- a/vcl/inc/vcl/configsettings.hxx
+++ b/vcl/inc/vcl/configsettings.hxx
@@ -54,7 +54,6 @@ namespace vcl
std::hash_map< rtl::OUString, SmallOUStrMap, rtl::OUStringHash > m_aSettings;
virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& rPropertyNames );
- virtual void Commit();
void getValues();
SettingsConfigItem();
@@ -65,6 +64,8 @@ namespace vcl
const rtl::OUString& getValue( const rtl::OUString& rGroup, const rtl::OUString& rKey ) const;
void setValue( const rtl::OUString& rGroup, const rtl::OUString& rKey, const rtl::OUString& rValue );
+
+ virtual void Commit();
};
//........................................................................
diff --git a/vcl/inc/vcl/cvtsvm.hxx b/vcl/inc/vcl/cvtsvm.hxx
index 8a17015d99cf..c6f4f2c9a126 100644
--- a/vcl/inc/vcl/cvtsvm.hxx
+++ b/vcl/inc/vcl/cvtsvm.hxx
@@ -85,6 +85,10 @@
#define GDI_COMMENT_COMMENT 1031
#define GDI_UNICODE_COMMENT 1032
+#define GDI_LINEJOIN_ACTION 1033
+#define GDI_EXTENDEDPOLYGON_ACTION 1034
+#define GDI_LINEDASHDOT_ACTION 1035
+
// ----------------
// - SVMConverter -
// ----------------
diff --git a/vcl/inc/vcl/edit.hxx b/vcl/inc/vcl/edit.hxx
index fb99bd028631..ad6a4ee017d9 100644
--- a/vcl/inc/vcl/edit.hxx
+++ b/vcl/inc/vcl/edit.hxx
@@ -120,6 +120,7 @@ private:
SAL_DLLPRIVATE void ImplCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard );
SAL_DLLPRIVATE void ImplPaste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard );
SAL_DLLPRIVATE long ImplGetExtraOffset() const;
+ SAL_DLLPRIVATE long ImplGetTextYPosition() const;
SAL_DLLPRIVATE ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XExtendedInputSequenceChecker > ImplGetInputSequenceChecker() const;
SAL_DLLPRIVATE ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > ImplGetBreakIterator() const;
diff --git a/vcl/inc/vcl/fixed.hxx b/vcl/inc/vcl/fixed.hxx
index a5c834fce486..d6ffc1625afe 100644
--- a/vcl/inc/vcl/fixed.hxx
+++ b/vcl/inc/vcl/fixed.hxx
@@ -187,6 +187,7 @@ public:
virtual void StateChanged( StateChangedType nType );
virtual void DataChanged( const DataChangedEvent& rDCEvt );
virtual void UserDraw( const UserDrawEvent& rUDEvt );
+ virtual Size GetOptimalSize(WindowSizeType eType) const;
void SetImage( const Image& rImage );
const Image& GetImage() const { return maImage; }
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index c53460d35584..e4acd55439cc 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -164,6 +164,7 @@ public:
void Scale( double fScaleX, double fScaleY );
void Scale( const Fraction& rScaleX, const Fraction& rScaleY );
void Rotate( long nAngle10 );
+ void Clip( const Rectangle& );
/* get the bound rect of the contained actions
* caveats:
* - clip actions will limit the contained actions,
diff --git a/vcl/inc/vcl/impprn.hxx b/vcl/inc/vcl/impprn.hxx
index c86090e8b49f..0cd6e9688201 100644
--- a/vcl/inc/vcl/impprn.hxx
+++ b/vcl/inc/vcl/impprn.hxx
@@ -28,7 +28,7 @@
*
************************************************************************/
-#ifndef _SV_IMPPRN_HXX
+#if 0
#define _SV_IMPPRN_HXX
#include <vcl/print.hxx>
@@ -107,7 +107,6 @@ public:
/**
used by pull implementation to emit the next page
*/
- using Printer::PrintPage;
void PrintPage( unsigned int nPage );
/**
used by pull implementation to get the number of physical pages
diff --git a/vcl/inc/vcl/jobdata.hxx b/vcl/inc/vcl/jobdata.hxx
index 4451c566b5bf..d328f41f5b5b 100644
--- a/vcl/inc/vcl/jobdata.hxx
+++ b/vcl/inc/vcl/jobdata.hxx
@@ -74,6 +74,8 @@ struct JobData
JobData( const JobData& rData ) { *this = rData; }
+ void setCollate( bool bCollate );
+
// creates a new buffer using new
// it is up to the user to delete it again
bool getStreamBuffer( void*& pData, int& bytes );
diff --git a/vcl/inc/vcl/jobset.h b/vcl/inc/vcl/jobset.h
index 9f3eefd507d5..fd15d0c076da 100644
--- a/vcl/inc/vcl/jobset.h
+++ b/vcl/inc/vcl/jobset.h
@@ -60,12 +60,13 @@ struct ImplJobSetup
String maPrinterName; // Printer-Name
String maDriver; // Driver-Name
Orientation meOrientation; // Orientation
- USHORT mnPaperBin; // Papierschacht
- Paper mePaperFormat; // Papierformat
- long mnPaperWidth; // Papierbreite in 100tel mm
- long mnPaperHeight; // Papierhoehe in 100tel mm
- ULONG mnDriverDataLen; // Laenge der systemabhaengigen Daten
- BYTE* mpDriverData; // Systemabhaengige Daten die als Byte-Block rausgeschrieben werden
+ DuplexMode meDuplexMode; // Duplex
+ USHORT mnPaperBin; // paper bin / in tray
+ Paper mePaperFormat; // paper format
+ long mnPaperWidth; // paper width (100th mm)
+ long mnPaperHeight; // paper height (100th mm)
+ ULONG mnDriverDataLen; // length of system specific data
+ BYTE* mpDriverData; // system specific data (will be streamed a byte block)
::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash > maValueMap;
ImplJobSetup();
diff --git a/vcl/inc/vcl/lineinfo.hxx b/vcl/inc/vcl/lineinfo.hxx
index 60fdc3a3a0b0..33758046c41e 100644
--- a/vcl/inc/vcl/lineinfo.hxx
+++ b/vcl/inc/vcl/lineinfo.hxx
@@ -32,26 +32,29 @@
#define _SV_LINEINFO_HXX
#include <vcl/dllapi.h>
-
#include <tools/gen.hxx>
#include <vcl/vclenum.hxx>
+#include <basegfx/vector/b2enums.hxx>
// ----------------
// - ImplLineInfo -
// ----------------
class SvStream;
+namespace basegfx { class B2DPolyPolygon; }
struct ImplLineInfo
{
- ULONG mnRefCount;
- LineStyle meStyle;
- long mnWidth;
- USHORT mnDashCount;
- long mnDashLen;
- USHORT mnDotCount;
- long mnDotLen;
- long mnDistance;
+ ULONG mnRefCount;
+ LineStyle meStyle;
+ long mnWidth;
+ USHORT mnDashCount;
+ long mnDashLen;
+ USHORT mnDotCount;
+ long mnDotLen;
+ long mnDistance;
+
+ basegfx::B2DLineJoin meLineJoin;
ImplLineInfo();
ImplLineInfo( const ImplLineInfo& rImplLineInfo );
@@ -107,10 +110,26 @@ public:
void SetDistance( long nDistance );
long GetDistance() const { return mpImplLineInfo->mnDistance; }
+ void SetLineJoin(basegfx::B2DLineJoin eLineJoin);
+ basegfx::B2DLineJoin GetLineJoin() const { return mpImplLineInfo->meLineJoin; }
+
BOOL IsDefault() const { return( !mpImplLineInfo->mnWidth && ( LINE_SOLID == mpImplLineInfo->meStyle ) ); }
friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, LineInfo& rLineInfo );
friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo );
+
+ // helper to check if line width or DashDot is used
+ bool isDashDotOrFatLineUsed() const;
+
+ // helper to get decomposed polygon data with the LineInfo applied. The source
+ // hairline polygon is given in io_rLinePolyPolygon. Both given polygons may
+ // contain results; e.g. when no fat line but DasDot is defined, the resut will
+ // be in io_rLinePolyPolygon while o_rFillPolyPolygon will be empty. When fat line
+ // is defined, it will be vice-versa. If none is defined, io_rLinePolyPolygon will
+ // not be changed (but o_rFillPolyPolygon will be freed)
+ void applyToB2DPolyPolygon(
+ basegfx::B2DPolyPolygon& io_rLinePolyPolygon,
+ basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const;
};
#endif // _SV_LINEINFO_HXX
diff --git a/vcl/inc/vcl/lstbox.h b/vcl/inc/vcl/lstbox.h
index 6097422b556b..9b95b9526d58 100644
--- a/vcl/inc/vcl/lstbox.h
+++ b/vcl/inc/vcl/lstbox.h
@@ -60,4 +60,9 @@
*/
#define LISTBOX_ENTRY_FLAG_MULTILINE 0x0000002
+/** this flags lets the item be drawn disabled (e.g. in grey text)
+ usage only guaranteed with LISTBOX_ENTRY_FLAG_DISABLE_SELECTION
+*/
+#define LISTBOX_ENTRY_FLAG_DRAW_DISABLED 0x0000004
+
#endif // _SV_LSTBOX_H
diff --git a/vcl/inc/vcl/menu.hxx b/vcl/inc/vcl/menu.hxx
index 8d3ac4e8b505..66f35823b06a 100644
--- a/vcl/inc/vcl/menu.hxx
+++ b/vcl/inc/vcl/menu.hxx
@@ -93,6 +93,8 @@ typedef USHORT MenuItemBits;
#define MIB_POPUPSELECT ((MenuItemBits)0x0020)
// not in rsc/vclsrc.hxx because only a prelimitary solution
#define MIB_NOSELECT ((MenuItemBits)0x0040)
+#define MIB_ICON ((MenuItemBits)0x0080)
+#define MIB_TEXT ((MenuItemBits)0x0100)
#define MENU_FLAG_NOAUTOMNEMONICS 0x0001
#define MENU_FLAG_HIDEDISABLEDENTRIES 0x0002
diff --git a/vcl/source/gdi/implncvt.hxx b/vcl/inc/vcl/oldprintadaptor.hxx
index 2d369d12f253..d8b26433af94 100644
--- a/vcl/source/gdi/implncvt.hxx
+++ b/vcl/inc/vcl/oldprintadaptor.hxx
@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
- * $RCSfile: implncvt.hxx,v $
- * $Revision: 1.5 $
- *
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -28,51 +25,28 @@
*
************************************************************************/
-#ifndef _SV_LINECONV_HXX
-#define _SV_LINECONV_HXX
-
-#include <tools/poly.hxx>
-#include <vcl/lineinfo.hxx>
-
-// --------------------
-// - ImplLineConverter
-// --------------------
+#ifndef _VCL_OLDPRINTADAPTOR
+#define _VCL_OLDPRINTADAPTOR
-struct ImplFloatPoint;
+#include "vcl/print.hxx"
-class ImplLineConverter
+namespace vcl
{
- BOOL mbClosed;
- BOOL mbRefPoint;
- INT32 mnRefDistance;
-
- double mfWidthHalf;
- LineInfo maLineInfo;
-
- double mfDashDotLenght;
- double mfDistanceLenght;
-
- UINT32 mnDashCount;
- UINT32 mnDotCount;
-
- Polygon maPolygon;
- UINT32 mnFloat0Points;
- ImplFloatPoint* mpFloat0;
- UINT32 mnFloat1Points;
- ImplFloatPoint* mpFloat1;
-
- UINT32 mnLinesAvailable;
- UINT32 mnLines;
-
- ImplFloatPoint* mpFloatPoint;
-
+ struct ImplOldStyleAdaptorData;
+ class VCL_DLLPUBLIC OldStylePrintAdaptor : public PrinterController
+ {
+ ImplOldStyleAdaptorData* mpData;
public:
+ OldStylePrintAdaptor( const boost::shared_ptr< Printer >& );
+ virtual ~OldStylePrintAdaptor();
- ImplLineConverter( const Polygon& rPoly, const LineInfo& rLineInfo, const Point* pRefPoint );
- ~ImplLineConverter();
+ void StartPage();
+ void EndPage();
- const Polygon* ImplGetFirst();
- const Polygon* ImplGetNext();
-};
+ virtual int getPageCount() const;
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getPageParameters( int i_nPage ) const;
+ virtual void printPage( int i_nPage ) const;
+ };
+}
#endif
diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx
index cff866d39459..54eaba057730 100644
--- a/vcl/inc/vcl/outdev.hxx
+++ b/vcl/inc/vcl/outdev.hxx
@@ -562,6 +562,9 @@ public:
// Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool. Contains no AA check.
SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin);
+ // Helper for line geometry paint with support for graphic expansion (pattern and fat_to_area)
+ void impPaintLineGeometryWithEvtlExpand(const LineInfo& rInfo, basegfx::B2DPolyPolygon aLinePolyPolygon);
+
protected:
OutputDevice();
@@ -1111,7 +1114,12 @@ public:
*/
BOOL HasAlpha();
- void DrawEPS( const Point& rPt, const Size& rSz,
+ /** Added return value to see if EPS could be painted directly.
+ Theoreticaly, handing over a matrix would be needed to handle
+ painting rotated EPS files (e.g. contained mín Metafiles). This
+ would then need to be supported for Mac and PS printers, but
+ that's too much for now, wrote #i107046# for this */
+ bool DrawEPS( const Point& rPt, const Size& rSz,
const GfxLink& rGfxLink, GDIMetaFile* pSubst = NULL );
/// request XCanvas render interface for this OutputDevice
@@ -1146,12 +1154,15 @@ public:
false: output metafile is unchanged input metafile
@attention this is a member method, so current state can influence the result !
+ @attention the output metafile is prepared in pixel mode for the currentOutputDevice
+ state. It can not be moved or rotated reliably anymore.
*/
bool RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf,
long nMaxBmpDPIX, long nMaxBmpDPIY,
bool bReduceTransparency,
bool bTransparencyAutoMode,
- bool bDownsampleBitmaps
+ bool bDownsampleBitmaps,
+ const Color& rBackground = Color( COL_TRANSPARENT )
);
/** Retrieve downsampled and cropped bitmap
diff --git a/vcl/inc/vcl/print.h b/vcl/inc/vcl/print.h
index 51cbb5dee0cf..12c7439aa5b3 100644
--- a/vcl/inc/vcl/print.h
+++ b/vcl/inc/vcl/print.h
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: print.h,v $
- * $Revision: 1.4 $
+ * $Revision: 1.4.114.2 $
*
* This file is part of OpenOffice.org.
*
@@ -31,27 +31,18 @@
#ifndef _SV_PRINT_H
#define _SV_PRINT_H
-#include <tools/list.hxx>
-#include <vcl/sv.h>
-#include <vcl/dllapi.h>
+#include "vcl/sv.h"
+#include "vcl/dllapi.h"
#include <vector>
#include <hash_map>
struct SalPrinterQueueInfo;
class QueueInfo;
+class JobSetup;
-// ------------------------
-// - private printer data -
-// ------------------------
-struct ImplPrivatePrinterData
-{
- bool mbNextJobIsQuick;
-
- ImplPrivatePrinterData() :
- mbNextJobIsQuick( false )
- {}
-};
+namespace vcl
+{ class PrinterListener; }
// --------------------
// - ImplPrnQueueData -
@@ -87,5 +78,7 @@ public:
// --------------
void ImplDeletePrnQueueList();
+void SAL_DLLPRIVATE ImplUpdateJobSetupPaper( JobSetup& rJobSetup );
+
#endif // _SV_PRINT_H
diff --git a/vcl/inc/vcl/print.hxx b/vcl/inc/vcl/print.hxx
index b9176f4106dc..daea0c941dd0 100644
--- a/vcl/inc/vcl/print.hxx
+++ b/vcl/inc/vcl/print.hxx
@@ -31,14 +31,22 @@
#ifndef _SV_PRINT_HXX
#define _SV_PRINT_HXX
-#include <tools/errcode.hxx>
-#include <vcl/sv.h>
-#include <vcl/dllapi.h>
-#include <vcl/outdev.hxx>
-#include <vcl/prntypes.hxx>
-#include <vcl/jobset.hxx>
-#include <vcl/gdimtf.hxx>
-#include <tools/stream.hxx>
+#include "tools/errcode.hxx"
+#include "vcl/sv.h"
+#include "vcl/dllapi.h"
+#include "vcl/outdev.hxx"
+#include "vcl/prntypes.hxx"
+#include "vcl/jobset.hxx"
+#include "vcl/gdimtf.hxx"
+#include "tools/stream.hxx"
+#include "tools/multisel.hxx"
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/view/PrintableState.hpp"
+
+#include <boost/shared_ptr.hpp>
+#include <hash_map>
+#include <set>
struct SalPrinterInfoQueue;
class SalInfoPrinter;
@@ -46,12 +54,11 @@ struct SalPrinterQueueInfo;
class SalPrinter;
class VirtualDevice;
class Window;
-class ImplQPrinter;
-struct ImplPrivatePrinterData;
-namespace com { namespace sun { namespace star { namespace uno {
- class Any;
-} } } }
+namespace vcl {
+ class PrinterController;
+ class PrintDialog;
+}
// -----------------
// - Printer-Types -
@@ -216,16 +223,12 @@ class VCL_DLLPUBLIC Printer : public OutputDevice
friend class ImplQPrinter;
private:
- ImplPrivatePrinterData* mpPrinterData;
SalInfoPrinter* mpInfoPrinter;
SalPrinter* mpPrinter;
- Printer* mpJobPrinter;
SalGraphics* mpJobGraphics;
Printer* mpPrev;
Printer* mpNext;
VirtualDevice* mpDisplayDev;
- ImplQPrinter* mpQPrinter;
- GDIMetaFile* mpQMtf;
PrinterOptions* mpPrinterOptions;
XubString maPrinterName;
XubString maDriver;
@@ -250,9 +253,6 @@ private:
BOOL mbUserSetupCompleted;
BOOL mbUserSetupResult;
Link maErrorHdl;
- Link maStartPrintHdl;
- Link maEndPrintHdl;
- Link maPrintPageHdl;
SAL_DLLPRIVATE void ImplInitData();
SAL_DLLPRIVATE void ImplInit( SalPrinterQueueInfo* pInfo );
@@ -261,22 +261,25 @@ private:
const XubString* pDriver );
SAL_DLLPRIVATE void ImplUpdatePageData();
SAL_DLLPRIVATE void ImplUpdateFontList();
- SAL_DLLPRIVATE void ImplFindPaperFormatForUserSize( JobSetup& );
+ SAL_DLLPRIVATE void ImplFindPaperFormatForUserSize( JobSetup&, bool bMatchNearest );
DECL_DLLPRIVATE_LINK( ImplDestroyPrinterAsync, void* );
-public:
- SAL_DLLPRIVATE void ImplEndPrint();
- SAL_DLLPRIVATE void ImplUpdateQuickStatus();
+
+ SAL_DLLPRIVATE bool StartJob( const rtl::OUString& rJobName, boost::shared_ptr<vcl::PrinterController>& );
+
+ static SAL_DLLPRIVATE ULONG ImplSalPrinterErrorCodeToVCL( ULONG nError );
+
private:
+ SAL_DLLPRIVATE void ImplEndPrint();
+ SAL_DLLPRIVATE BOOL EndJob();
SAL_DLLPRIVATE Printer( const Printer& rPrinter );
SAL_DLLPRIVATE Printer& operator =( const Printer& rPrinter );
-
-#ifdef _SPOOLPRINTER_EXT
+public:
+ SAL_DLLPRIVATE void ImplStartPage();
+ SAL_DLLPRIVATE void ImplEndPage();
public:
void DrawGradientEx( OutputDevice* pOut, const Rectangle& rRect, const Gradient& rGradient );
void DrawGradientEx( OutputDevice* pOut, const PolyPolygon& rPolyPoly, const Gradient& rGradient );
-#endif // _SPOOLPRINTER_EXT
-
protected:
void SetSelfAsQueuePrinter( BOOL bQueuePrinter ) { mbIsQueuePrinter = bQueuePrinter; }
@@ -295,9 +298,6 @@ public:
static XubString GetDefaultPrinterName();
virtual void Error();
- virtual void StartPrint();
- virtual void EndPrint();
- virtual void PrintPage();
const XubString& GetName() const { return maPrinterName; }
const XubString& GetDriverName() const { return maDriver; }
@@ -322,6 +322,7 @@ public:
BOOL SetOrientation( Orientation eOrient );
Orientation GetOrientation() const;
DuplexMode GetDuplexMode() const;
+ BOOL SetDuplexMode( DuplexMode );
// returns the angle that a landscape page will be turned counterclockwise
// wrt to portrait. The return value may be only valid for
// the current paper
@@ -330,6 +331,7 @@ public:
USHORT GetPaperBin() const;
BOOL SetPaper( Paper ePaper );
BOOL SetPaperSizeUser( const Size& rSize );
+ BOOL SetPaperSizeUser( const Size& rSize, bool bMatchNearest );
Paper GetPaper() const;
// returns number of available paper formats
@@ -348,58 +350,333 @@ public:
USHORT GetCopyCount() const { return mnCopyCount; }
BOOL IsCollateCopy() const { return mbCollateCopy; }
- USHORT GetCurPrintPage() const { return mnCurPrintPage; }
BOOL IsPrinting() const { return mbPrinting; }
void SetPrintFile( const XubString& rFileName ) { maPrintFile = rFileName; }
const XubString& GetPrintFile() const { return maPrintFile; }
void EnablePrintFile( BOOL bEnable ) { mbPrintFile = bEnable; }
BOOL IsPrintFileEnabled() const { return mbPrintFile; }
- BOOL StartJob( const XubString& rJobName );
- BOOL EndJob();
BOOL AbortJob();
const XubString& GetCurJobName() const { return maJobName; }
USHORT GetCurPage() const { return mnCurPage; }
BOOL IsJobActive() const { return mbJobActive; }
- BOOL StartPage();
- BOOL EndPage();
-
- void SetPageQueueSize( USHORT nPages ) { mnPageQueueSize = nPages; }
- USHORT GetPageQueueSize() const { return mnPageQueueSize; }
ULONG GetError() const { return ERRCODE_TOERROR(mnError); }
ULONG GetErrorCode() const { return mnError; }
void SetErrorHdl( const Link& rLink ) { maErrorHdl = rLink; }
const Link& GetErrorHdl() const { return maErrorHdl; }
- void SetStartPrintHdl( const Link& rLink ) { maStartPrintHdl = rLink; }
- const Link& GetStartPrintHdl() const { return maStartPrintHdl; }
- void SetEndPrintHdl( const Link& rLink ) { maEndPrintHdl = rLink; }
- const Link& GetEndPrintHdl() const { return maEndPrintHdl; }
- void SetPrintPageHdl( const Link& rLink ) { maPrintPageHdl = rLink; }
- const Link& GetPrintPageHdl() const { return maPrintPageHdl; }
void Compat_OldPrinterMetrics( bool bSet );
- /** Notify that the next StartJob belongs to a UI less "direct print" job
- *
- * deprecated: the canonical way to notify a UI less job is to set the
- * JobSetup value "IsQuickJob" to "true". If set at all, the "IsQuickJob" value
- * on JobSetup will be preferred. However if no "IsQuickJob" value is set,
- * setting SetNextJobIsQuick will cause the following StartJob to set this value
- * to "true" in the current JobSetup.
- *
- * the paramter can be set to "false" again in case a job was not started and the
- * printer is to be reused.
- */
- void SetNextJobIsQuick( bool bQuick = true );
-
/** checks the printer list and updates it necessary
*
* sends a DataChanged event of type DATACHANGED_PRINTER
* if the printer list changed
*/
static void updatePrinters();
+
+ /** execute a print job
+
+ starts a print job asynchronously (that is will return
+
+ */
+ static void PrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController,
+ const JobSetup& i_rInitSetup
+ );
+
+ // implementation detail of PrintJob being asynchronous
+ // not exported, not usable outside vcl
+ static void SAL_DLLPRIVATE ImplPrintJob( const boost::shared_ptr<vcl::PrinterController>& i_pController,
+ const JobSetup& i_rInitSetup
+ );
+};
+
+namespace vcl
+{
+class ImplPrinterControllerData;
+
+class VCL_DLLPUBLIC PrinterController
+{
+ ImplPrinterControllerData* mpImplData;
+protected:
+ PrinterController( const boost::shared_ptr<Printer>& );
+public:
+ enum NupOrderType
+ { LRTB, TBLR };
+ struct MultiPageSetup
+ {
+ // all metrics in 100th mm
+ int nRows;
+ int nColumns;
+ int nRepeat;
+ Size aPaperSize;
+ long nLeftMargin;
+ long nTopMargin;
+ long nRightMargin;
+ long nBottomMargin;
+ long nHorizontalSpacing;
+ long nVerticalSpacing;
+ bool bDrawBorder;
+ PrinterController::NupOrderType nOrder;
+
+ MultiPageSetup()
+ : nRows( 1 ), nColumns( 1 ), nRepeat( 1 ), aPaperSize( 21000, 29700 )
+ , nLeftMargin( 0 ), nTopMargin( 0 )
+ , nRightMargin( 0 ), nBottomMargin( 0 )
+ , nHorizontalSpacing( 0 ), nVerticalSpacing( 0 )
+ , bDrawBorder( false )
+ , nOrder( LRTB )
+ {
+ }
+ };
+
+ struct PageSize
+ {
+ Size aSize; // in 100th mm
+ bool bFullPaper; // full paper, not only imageable area is printed
+
+ PageSize( const Size& i_rSize = Size( 21000, 29700 ),
+ bool i_bFullPaper = false
+ ) : aSize( i_rSize ), bFullPaper( i_bFullPaper ) {}
+ };
+
+ PrinterController();
+ virtual ~PrinterController();
+
+ const boost::shared_ptr<Printer>& getPrinter() const;
+ /* for implementations: get current job properties as changed by e.g. print dialog
+ this gets the current set of properties initially told to Printer::PrintJob
+
+ For convenience a second sequence will be merged in to get a combined sequence.
+ In case of duplicate property names, the value of i_MergeList wins.
+ */
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >
+ getJobProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& i_rMergeList ) const;
+
+ /* get the PropertyValue of a Property
+ */
+ com::sun::star::beans::PropertyValue* getValue( const rtl::OUString& i_rPropertyName );
+ const com::sun::star::beans::PropertyValue* getValue( const rtl::OUString& i_rPropertyName ) const;
+ // get a sequence of properties
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getValues( const com::sun::star::uno::Sequence< rtl::OUString >& ) const;
+ /* get a bool property
+ in case the property is unknown or not convertible to bool, i_bFallback is returned
+ */
+ sal_Bool getBoolProperty( const rtl::OUString& i_rPropertyName, sal_Bool i_bFallback ) const;
+
+ /* set a property value - can also be used to add another UI property
+ */
+ void setValue( const rtl::OUString& i_rPropertyName, const com::sun::star::uno::Any& i_rValue );
+ void setValue( const com::sun::star::beans::PropertyValue& i_rValue );
+
+ /* return the currently active UI options. These are the same that were passed to setUIOptions.
+ */
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& getUIOptions() const;
+ /* set possible UI options. should only be done once before passing the PrinterListener
+ to Printer::PrintJob
+ */
+ void setUIOptions( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& );
+ /* enable/disable an option; this can be used to implement dialog logic.
+ */
+ void enableUIOption( const rtl::OUString& rPropName, bool bEnable );
+ bool isUIOptionEnabled( const rtl::OUString& rPropName ) const;
+ /* returns the property name rPropName depends on or an empty string
+ if no dependency exists.
+ */
+ rtl::OUString getDependency( const rtl::OUString& rPropName ) const;
+ /* makeEnabled will chage the property rPropName depends on to the value
+ that makes rPropName enabled. If the dependency itself is also disabled,
+ no action will be performed.
+
+ returns the property name rPropName depends on or an empty string
+ if no change was made.
+ */
+ rtl::OUString makeEnabled( const rtl::OUString& rPropName );
+
+ virtual int getPageCount() const = 0; // must be overloaded by the app
+ /* get the page parameters, namely the jobsetup that should be active for the page
+ (describing among others the physical page size) and the "page size". In writer
+ case this would probably be the same as the JobSetup since writer sets the page size
+ draw/impress for example print their page on the paper set on the printer,
+ possibly adjusting the page size to fit. That means the page size can be different from
+ the paper size.
+ */
+ // must be overloaded by the app, return page size in 1/100th mm
+ virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getPageParameters( int i_nPage ) const = 0;
+ virtual void printPage( int i_nPage ) const = 0; // must be overloaded by the app
+ virtual void jobStarted(); // will be called after a possible dialog has been shown and the real printjob starts
+ virtual void jobFinished( com::sun::star::view::PrintableState );
+
+ com::sun::star::view::PrintableState getJobState() const;
+
+ void abortJob();
+
+ bool isShowDialogs() const;
+ bool isDirectPrint() const;
+
+ // implementation details, not usable outside vcl
+ SAL_DLLPRIVATE int getFilteredPageCount();
+ SAL_DLLPRIVATE PageSize getPageFile( int i_inUnfilteredPage, GDIMetaFile& rMtf, bool i_bMayUseCache = false );
+ SAL_DLLPRIVATE PageSize getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache = false );
+ SAL_DLLPRIVATE void printFilteredPage( int i_nPage );
+ SAL_DLLPRIVATE void setPrinter( const boost::shared_ptr<Printer>& );
+ SAL_DLLPRIVATE void setOptionChangeHdl( const Link& );
+ SAL_DLLPRIVATE void createProgressDialog();
+ SAL_DLLPRIVATE void setMultipage( const MultiPageSetup& );
+ SAL_DLLPRIVATE const MultiPageSetup& getMultipage() const;
+ SAL_DLLPRIVATE void setLastPage( sal_Bool i_bLastPage );
+ SAL_DLLPRIVATE void setReversePrint( sal_Bool i_bReverse );
+ SAL_DLLPRIVATE bool getReversePrint() const;
+ SAL_DLLPRIVATE void pushPropertiesToPrinter();
+ SAL_DLLPRIVATE void setJobState( com::sun::star::view::PrintableState );
+ SAL_DLLPRIVATE bool setupPrinter( Window* i_pDlgParent );
+
+ SAL_DLLPRIVATE int getPageCountProtected() const;
+ SAL_DLLPRIVATE com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getPageParametersProtected( int i_nPage ) const;
+
+ SAL_DLLPRIVATE ULONG removeTransparencies( GDIMetaFile& i_rIn, GDIMetaFile& o_rOut );
};
+class VCL_DLLPUBLIC PrinterOptionsHelper
+{
+ protected:
+ std::hash_map< rtl::OUString, com::sun::star::uno::Any, rtl::OUStringHash > m_aPropertyMap;
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > m_aUIProperties;
+
+ public:
+ PrinterOptionsHelper() {} // create without ui properties
+ PrinterOptionsHelper( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& i_rUIProperties )
+ : m_aUIProperties( i_rUIProperties )
+ {}
+ ~PrinterOptionsHelper()
+ {}
+
+ /* process a new set of properties
+ * merges changed properties and returns "true" if any occured
+ * if the optional output set is not NULL then the names of the changed properties are returned
+ **/
+ bool processProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& i_rNewProp,
+ std::set< rtl::OUString >* o_pChangeProp = NULL );
+ /* append to a sequence of property values the ui property sequence passed at creation
+ * as the "ExtraPrintUIOptions" property. if that sequence was empty, no "ExtraPrintUIOptions" property
+ * will be appended.
+ **/
+ void appendPrintUIOptions( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& io_rProps ) const;
+
+ // check if a property exists
+ bool hasProperty( const rtl::OUString& i_rPropertyName ) const;
+ bool hasProperty( const char* i_pPropertyName ) const
+ { return hasProperty( rtl::OUString::createFromAscii( i_pPropertyName ) ); }
+
+ // returns an empty Any for not existing properties
+ com::sun::star::uno::Any getValue( const rtl::OUString& i_rPropertyName ) const;
+ // change a value in the property set; this will not have an effect to an eventual PrinterController
+ // the user of setValue must decide whether it is necessary to set the value there also
+ void setValue( const rtl::OUString& i_rPropertyName, const com::sun::star::uno::Any& i_rValue );
+ void setValue( const char* i_pPropertyName, const com::sun::star::uno::Any& i_rValue )
+ { setValue( rtl::OUString::createFromAscii( i_pPropertyName ), i_rValue ); }
+
+ sal_Bool getBoolValue( const rtl::OUString& i_rPropertyName, sal_Bool i_bDefault = sal_False ) const;
+ // convenience for fixed strings
+ sal_Bool getBoolValue( const char* i_pPropName, sal_Bool i_bDefault = sal_False ) const
+ { return getBoolValue( rtl::OUString::createFromAscii( i_pPropName ), i_bDefault ); }
+
+ sal_Int64 getIntValue( const rtl::OUString& i_rPropertyName, sal_Int64 i_nDefault = 0 ) const;
+ // convenience for fixed strings
+ sal_Int64 getIntValue( const char* i_pPropName, sal_Int64 i_nDefault = 0 ) const
+ { return getIntValue( rtl::OUString::createFromAscii( i_pPropName ), i_nDefault ); }
+
+ rtl::OUString getStringValue( const rtl::OUString& i_rPropertyName, const rtl::OUString& i_rDefault = rtl::OUString() ) const;
+ // convenience for fixed strings
+ rtl::OUString getStringValue( const char* i_pPropName, const rtl::OUString& i_rDefault = rtl::OUString() ) const
+ { return getStringValue( rtl::OUString::createFromAscii( i_pPropName ), i_rDefault ); }
+
+ // helper functions for user to create a single control
+ struct UIControlOptions
+ {
+ rtl::OUString maDependsOnName;
+ sal_Int32 mnDependsOnEntry;
+ sal_Bool mbAttachToDependency;
+ rtl::OUString maGroupHint;
+ sal_Bool mbInternalOnly;
+ sal_Bool mbEnabled;
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > maAddProps;
+
+ UIControlOptions( const rtl::OUString& i_rDependsOnName = rtl::OUString(),
+ sal_Int32 i_nDependsOnEntry = -1,
+ sal_Bool i_bAttachToDependency = sal_False,
+ const rtl::OUString& i_rGroupHint = rtl::OUString(),
+ sal_Bool i_bInternalOnly = sal_False,
+ sal_Bool i_bEnabled = sal_True
+ )
+ : maDependsOnName( i_rDependsOnName )
+ , mnDependsOnEntry( i_nDependsOnEntry )
+ , mbAttachToDependency( i_bAttachToDependency )
+ , maGroupHint( i_rGroupHint )
+ , mbInternalOnly( i_bInternalOnly )
+ , mbEnabled( i_bEnabled ) {}
+ };
+
+ // general control
+ static com::sun::star::uno::Any getUIControlOpt( const rtl::OUString& i_rTitle,
+ const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpText,
+ const rtl::OUString& i_rType,
+ const com::sun::star::beans::PropertyValue* i_pValue = NULL,
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+ // create a group (e.g. a TabPage); following controls will be grouped in it until the next
+ // group begins
+ static com::sun::star::uno::Any getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpText );
+
+ // create a subgroup (e.g. a FixedLine); following controls will be grouped in it until the next
+ // subgroup or group begins
+ // setting bJobPage = true will make the subgroup appear on the first page of the print dialog
+ static com::sun::star::uno::Any getSubgroupControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+
+ // create a bool option (usually a checkbox)
+ static com::sun::star::uno::Any getBoolControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ sal_Bool i_bValue,
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+
+ // create a set of choices (either a radio button group or a list box)
+ static com::sun::star::uno::Any getChoiceControlOpt( const rtl::OUString& i_rTitle,
+ const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ const com::sun::star::uno::Sequence< rtl::OUString >& i_rChoices,
+ sal_Int32 i_nValue,
+ const rtl::OUString& i_rType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Radio" ) ),
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+
+ // create an integer range (e.g. a spin field)
+ // note: max value < min value means do not apply min/max values
+ static com::sun::star::uno::Any getRangeControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ sal_Int32 i_nValue,
+ sal_Int32 i_nMinValue = -1,
+ sal_Int32 i_nMaxValue = -2,
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+
+ // create a string field
+ // note: max value < min value means do not apply min/max values
+ static com::sun::star::uno::Any getEditControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ const rtl::OUString& i_rValue,
+ const UIControlOptions& i_rControlOptions = UIControlOptions()
+ );
+};
+
+}
+
+
#endif // _SV_PRINT_HXX
diff --git a/vcl/inc/vcl/printerjob.hxx b/vcl/inc/vcl/printerjob.hxx
index 9880700d4008..e445a81d54c8 100644
--- a/vcl/inc/vcl/printerjob.hxx
+++ b/vcl/inc/vcl/printerjob.hxx
@@ -91,7 +91,7 @@ private: // private methods
bool writeFeatureList( osl::File* pFile, const JobData&, bool bDocumentSetup );
bool writeSetup( osl::File* pFile, const JobData& );
- bool writePageSetup( osl::File* pFile, const JobData& );
+ bool writePageSetup( osl::File* pFile, const JobData&, bool bWriteFeatures = true );
void writeJobPatch( osl::File* File, const JobData& );
bool writeProlog (osl::File* pFile, const JobData& );
diff --git a/vcl/inc/vcl/prndlg.hxx b/vcl/inc/vcl/prndlg.hxx
index 4fd6eaa999da..f1b69e1ca3aa 100644
--- a/vcl/inc/vcl/prndlg.hxx
+++ b/vcl/inc/vcl/prndlg.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: prndlg.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.114.5 $
*
* This file is part of OpenOffice.org.
*
@@ -33,19 +33,301 @@
#include <vcl/dllapi.h>
-#include <vcl/dialog.hxx>
+#include "vcl/print.hxx"
+#include "vcl/print.h"
-class Printer;
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/button.hxx"
+#include "vcl/gdimtf.hxx"
+#include "vcl/lstbox.hxx"
+#include "vcl/field.hxx"
+#include "vcl/tabctrl.hxx"
+#include "vcl/tabpage.hxx"
+#include "vcl/arrange.hxx"
+#include "vcl/virdev.hxx"
-class VCL_DLLPUBLIC SystemDialog : public ModalDialog
+#include <boost/shared_ptr.hpp>
+#include <map>
+
+namespace vcl
{
-public:
- SystemDialog( Window* pParent, WinBits nWinStyle ) :
- ModalDialog( pParent, nWinStyle ) {}
- SystemDialog( Window* pParent, const ResId& rResId ) :
- ModalDialog( pParent, rResId ) {}
-
- virtual short Execute() { return 0; }
-};
+ class PrintDialog : public ModalDialog
+ {
+ class PrintPreviewWindow : public Window
+ {
+ GDIMetaFile maMtf;
+ Size maOrigSize;
+ VirtualDevice maPageVDev;
+ rtl::OUString maReplacementString;
+ rtl::OUString maToolTipString;
+ public:
+ PrintPreviewWindow( Window* pParent, const ResId& );
+ virtual ~PrintPreviewWindow();
+
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Command( const CommandEvent& );
+ virtual void Resize();
+ virtual void DataChanged( const DataChangedEvent& );
+
+ void setPreview( const GDIMetaFile&, const Size&, const rtl::OUString&,
+ sal_Int32 i_nDPIX, sal_Int32 i_nDPIY
+ );
+ };
+
+ class ShowNupOrderWindow : public Window
+ {
+ int mnOrderMode;
+ int mnRows;
+ int mnColumns;
+ void ImplInitSettings();
+ public:
+ ShowNupOrderWindow( Window* pParent );
+ virtual ~ShowNupOrderWindow();
+
+ virtual void Paint( const Rectangle& );
+
+ void setValues( int i_nOrderMode, int i_nColumns, int i_nRows )
+ {
+ mnOrderMode = i_nOrderMode;
+ mnRows = i_nRows;
+ mnColumns = i_nColumns;
+ Invalidate();
+ }
+ };
+
+ class NUpTabPage : public TabPage
+ {
+ public:
+ FixedLine maNupLine;
+ RadioButton maPagesBtn;
+ RadioButton maBrochureBtn;
+ FixedText maPagesBoxTitleTxt;
+ ListBox maNupPagesBox;
+
+ // controls for "Custom" page mode
+ FixedText maNupNumPagesTxt;
+ NumericField maNupColEdt;
+ FixedText maNupTimesTxt;
+ NumericField maNupRowsEdt;
+ FixedText maPageMarginTxt1;
+ MetricField maPageMarginEdt;
+ FixedText maPageMarginTxt2;
+ FixedText maSheetMarginTxt1;
+ MetricField maSheetMarginEdt;
+ FixedText maSheetMarginTxt2;
+ FixedText maNupOrientationTxt;
+ ListBox maNupOrientationBox;
+
+ // page order ("left to right, then down")
+ FixedText maNupOrderTxt;
+ ListBox maNupOrderBox;
+ ShowNupOrderWindow maNupOrderWin;
+ // border around each page
+ CheckBox maBorderCB;
+
+ vcl::RowOrColumn maLayout;
+ boost::shared_ptr< vcl::RowOrColumn > mxBrochureDep;
+ boost::shared_ptr< vcl::LabeledElement >mxPagesBtnLabel;
+
+ void setupLayout();
+
+ NUpTabPage( Window*, const ResId& );
+ virtual ~NUpTabPage();
+
+ void readFromSettings();
+ void storeToSettings();
+ void initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& );
+ void enableNupControls( bool bEnable );
+
+ void showAdvancedControls( bool );
+
+ virtual void Resize();
+ };
+
+ class JobTabPage : public TabPage
+ {
+ public:
+ FixedLine maPrinterFL;
+ ListBox maPrinters;
+ DisclosureButton maDetailsBtn;
+ FixedText maStatusLabel;
+ FixedText maStatusTxt;
+ FixedText maLocationLabel;
+ FixedText maLocationTxt;
+ FixedText maCommentLabel;
+ FixedText maCommentTxt;
+
+ PushButton maSetupButton;
+
+ FixedLine maCopies;
+ FixedLine maCopySpacer;
+ FixedText maCopyCount;
+ NumericField maCopyCountField;
+ CheckBox maCollateBox;
+ FixedImage maCollateImage;
+
+ Image maCollateImg;
+ Image maCollateHCImg;
+ Image maNoCollateImg;
+ Image maNoCollateHCImg;
+
+ long mnCollateUIMode;
+
+ vcl::RowOrColumn maLayout;
+ boost::shared_ptr<vcl::RowOrColumn> mxPrintRange;
+ boost::shared_ptr<vcl::WindowArranger> mxDetails;
+
+ JobTabPage( Window*, const ResId& );
+ virtual ~JobTabPage();
+
+ void readFromSettings();
+ void storeToSettings();
+
+ virtual void Resize();
+
+ void setupLayout();
+ };
+
+ class OutputOptPage : public TabPage
+ {
+ public:
+ FixedLine maOptionsLine;
+ CheckBox maToFileBox;
+ CheckBox maCollateSingleJobsBox;
+ CheckBox maReverseOrderBox;
+
+ vcl::RowOrColumn maLayout;
+ boost::shared_ptr<vcl::RowOrColumn> mxOptGroup;
+
+ OutputOptPage( Window*, const ResId& );
+ virtual ~OutputOptPage();
+
+ void readFromSettings();
+ void storeToSettings();
+
+ virtual void Resize();
+
+ void setupLayout();
+ };
+
+ OKButton maOKButton;
+ CancelButton maCancelButton;
+ HelpButton maHelpButton;
+ PrintPreviewWindow maPreviewWindow;
+ NumericField maPageEdit;
+ FixedText maNumPagesText;
+ PushButton maBackwardBtn;
+ PushButton maForwardBtn;
+
+ TabControl maTabCtrl;
+ NUpTabPage maNUpPage;
+ JobTabPage maJobPage;
+ OutputOptPage maOptionsPage;
+
+ FixedLine maButtonLine;
+
+ boost::shared_ptr< PrinterController > maPController;
+
+ rtl::OUString maPageStr;
+ rtl::OUString maNoPageStr;
+ sal_Int32 mnCurPage;
+ sal_Int32 mnCachedPages;
+
+ std::list< Window* > maControls;
+ std::map< Window*, rtl::OUString > maControlToPropertyMap;
+ std::map< rtl::OUString, std::vector< Window* > >
+ maPropertyToWindowMap;
+ std::map< Window*, sal_Int32 > maControlToNumValMap;
+ std::set< rtl::OUString > maReverseDependencySet;
+
+ Size maNupPortraitSize;
+ Size maNupLandscapeSize;
+
+ // internal, used for automatic Nup-Portrait/landscape
+ Size maFirstPageSize;
+
+ rtl::OUString maPrintToFileText;
+ rtl::OUString maPrintText;
+ rtl::OUString maDefPrtText;
+
+ vcl::RowOrColumn maLayout;
+ boost::shared_ptr<vcl::RowOrColumn> mxPreviewCtrls;
+
+ Size maDetailsCollapsedSize;
+ Size maDetailsExpandedSize;
+
+ sal_Bool mbShowLayoutPage;
+
+ Size getJobPageSize();
+ void updateNup();
+ void updateNupFromPages();
+ void preparePreview( bool i_bPrintChanged = true, bool i_bMayUseCache = false );
+ void setPreviewText( sal_Int32 );
+ void updatePrinterText();
+ void checkControlDependencies();
+ void checkOptionalControlDependencies();
+ void makeEnabled( Window* );
+ void updateWindowFromProperty( const rtl::OUString& );
+ void setupOptionalUI();
+ void readFromSettings();
+ void storeToSettings();
+ com::sun::star::beans::PropertyValue* getValueForWindow( Window* ) const;
+
+ virtual void Resize();
+ virtual void Command( const CommandEvent& );
+ virtual void DataChanged( const DataChangedEvent& );
+
+ DECL_LINK( SelectHdl, ListBox* );
+ DECL_LINK( ClickHdl, Button* );
+ DECL_LINK( ModifyHdl, Edit* );
+ DECL_LINK( UIOptionsChanged, void* );
+
+ DECL_LINK( UIOption_CheckHdl, CheckBox* );
+ DECL_LINK( UIOption_RadioHdl, RadioButton* );
+ DECL_LINK( UIOption_SelectHdl, ListBox* );
+ DECL_LINK( UIOption_ModifyHdl, Edit* );
+
+ void setupLayout();
+ public:
+ PrintDialog( Window*, const boost::shared_ptr< PrinterController >& );
+ virtual ~PrintDialog();
+
+ bool isPrintToFile();
+ int getCopyCount();
+ bool isCollate();
+
+ void previewForward();
+ void previewBackward();
+ };
+
+ class PrintProgressDialog : public ModelessDialog
+ {
+ String maStr;
+ FixedText maText;
+ CancelButton maButton;
+
+ bool mbCanceled;
+ sal_Int32 mnCur;
+ sal_Int32 mnMax;
+ long mnProgressHeight;
+ Rectangle maProgressRect;
+ bool mbNativeProgress;
+
+ DECL_LINK( ClickHdl, Button* );
+
+ void implCalcProgressRect();
+ public:
+ PrintProgressDialog( Window* i_pParent, int i_nMax );
+ ~PrintProgressDialog();
+
+ bool isCanceled() const { return mbCanceled; }
+ void setProgress( int i_nCurrent, int i_nMax = -1 );
+ void tick();
+
+ virtual void Paint( const Rectangle& );
+ };
+}
+
#endif // _SV_PRNDLG_HXX
diff --git a/vcl/inc/vcl/prntypes.hxx b/vcl/inc/vcl/prntypes.hxx
index 681f4f972a7c..a61c1a275474 100644
--- a/vcl/inc/vcl/prntypes.hxx
+++ b/vcl/inc/vcl/prntypes.hxx
@@ -39,7 +39,7 @@
// - Duplex Mode -
// ---------------
-enum DuplexMode { DUPLEX_UNKNOWN, DUPLEX_OFF, DUPLEX_ON };
+enum DuplexMode { DUPLEX_UNKNOWN, DUPLEX_OFF, DUPLEX_LONGEDGE, DUPLEX_SHORTEDGE };
// ---------------
// - Orientation -
@@ -93,5 +93,6 @@ enum Orientation { ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE };
#define PRINTER_CAPABILITIES_FAX ((USHORT)8)
#define PRINTER_CAPABILITIES_PDF ((USHORT)9)
#define PRINTER_CAPABILITIES_EXTERNALDIALOG ((USHORT)10)
+#define PRINTER_CAPABILITIES_SETDUPLEX ((USHORT)11)
#endif // _SV_PRNTYPES_HXX
diff --git a/vcl/inc/vcl/salprn.hxx b/vcl/inc/vcl/salprn.hxx
index 2927215034b5..73f5454457cf 100644
--- a/vcl/inc/vcl/salprn.hxx
+++ b/vcl/inc/vcl/salprn.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: salprn.hxx,v $
- * $Revision: 1.5 $
+ * $Revision: 1.5.114.1 $
*
* This file is part of OpenOffice.org.
*
@@ -41,7 +41,7 @@
class SalGraphics;
class SalFrame;
struct ImplJobSetup;
-class ImplQPrinter;
+namespace vcl { class PrinterController; }
// -----------------------
// - SalPrinterQueueInfo -
@@ -101,7 +101,6 @@ public:
virtual void InitPaperFormats( const ImplJobSetup* pSetupData ) = 0;
// returns angle that a landscape page will be turned counterclockwise wrt to portrait
virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData ) = 0;
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData ) = 0;
};
// --------------
@@ -114,18 +113,21 @@ public: // public for Sal Implementation
SalPrinter() {}
virtual ~SalPrinter();
- virtual BOOL StartJob( const XubString* pFileName,
- const XubString& rJobName,
- const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ virtual BOOL StartJob( const String* pFileName,
+ const String& rJobName,
+ const String& rAppName,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData ) = 0;
// implement for pull model print systems only,
// default implementations (see salvtables.cxx) just returns FALSE
virtual BOOL StartJob( const String* pFileName,
+ const String& rJobName,
const String& rAppName,
ImplJobSetup* pSetupData,
- ImplQPrinter* pQPrinter );
+ vcl::PrinterController& rController );
virtual BOOL EndJob() = 0;
virtual BOOL AbortJob() = 0;
diff --git a/vcl/inc/vcl/salptype.hxx b/vcl/inc/vcl/salptype.hxx
index 7f1c82079f38..bc9883757432 100644
--- a/vcl/inc/vcl/salptype.hxx
+++ b/vcl/inc/vcl/salptype.hxx
@@ -40,7 +40,11 @@
#define SAL_JOBSET_ORIENTATION ((ULONG)0x00000001)
#define SAL_JOBSET_PAPERBIN ((ULONG)0x00000002)
#define SAL_JOBSET_PAPERSIZE ((ULONG)0x00000004)
-#define SAL_JOBSET_ALL (SAL_JOBSET_ORIENTATION | SAL_JOBSET_PAPERBIN | SAL_JOBSET_PAPERSIZE)
+#define SAL_JOBSET_DUPLEXMODE ((ULONG)0x00000008)
+#define SAL_JOBSET_ALL (SAL_JOBSET_ORIENTATION |\
+ SAL_JOBSET_PAPERBIN |\
+ SAL_JOBSET_PAPERSIZE |\
+ SAL_JOBSET_DUPLEXMODE)
// -------------------
// - SalPrinterError -
diff --git a/vcl/inc/vcl/svdata.hxx b/vcl/inc/vcl/svdata.hxx
index 17ad1aa28c1a..081b2fffca0b 100644
--- a/vcl/inc/vcl/svdata.hxx
+++ b/vcl/inc/vcl/svdata.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: svdata.hxx,v $
- * $Revision: 1.13 $
+ * $Revision: 1.13.16.1 $
*
* This file is part of OpenOffice.org.
*
@@ -87,6 +87,7 @@ class Timer;
class AutoTimer;
class Help;
class ImageList;
+class Image;
class PopupMenu;
class Application;
class OutputDevice;
@@ -259,6 +260,10 @@ struct ImplSVCtrlData
ImageList* mpSplitVPinImgList; // ImageList for Vertikale SplitWindows (PIN's)
ImageList* mpSplitHArwImgList; // ImageList for Horizontale SplitWindows (Arrows)
ImageList* mpSplitVArwImgList; // ImageList for Vertikale SplitWindows (Arrows)
+ Image* mpDisclosurePlus;
+ Image* mpDisclosurePlusHC;
+ Image* mpDisclosureMinus;
+ Image* mpDisclosureMinusHC;
ImplTBDragMgr* mpTBDragMgr; // DragMgr for ToolBox
USHORT mnCheckStyle; // CheckBox-Style for ImageList-Update
USHORT mnRadioStyle; // Radio-Style for ImageList-Update
@@ -367,6 +372,7 @@ void ImplDeInitSVData();
void ImplDestroySVData();
Window* ImplGetDefaultWindow();
VCL_DLLPUBLIC ResMgr* ImplGetResMgr();
+VCL_DLLPUBLIC ResId VclResId( sal_Int32 nId ); // throws std::bad_alloc if no res mgr
DockingManager* ImplGetDockingManager();
void ImplWindowAutoMnemonic( Window* pWindow );
diff --git a/vcl/inc/vcl/svids.hrc b/vcl/inc/vcl/svids.hrc
index 48297a04ea0e..e2a8226ac878 100644
--- a/vcl/inc/vcl/svids.hrc
+++ b/vcl/inc/vcl/svids.hrc
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: svids.hrc,v $
- * $Revision: 1.8 $
+ * $Revision: 1.8.84.3 $
*
* This file is part of OpenOffice.org.
*
@@ -31,6 +31,8 @@
#ifndef _SV_SVIDS_HRC
#define _SV_SVIDS_HRC
+#include "svl/solar.hrc"
+
#define SV_RESID_STDOFFSET 0
#define SV_RESID_WINOFFSET 1
#define SV_RESID_OS2OFFSET 2
@@ -58,6 +60,11 @@
#define SV_RESID_BITMAP_CLOSEDOC 1052
#define SV_RESID_BITMAP_CLOSEDOCHC 1053
+#define SV_DISCLOSURE_PLUS 1060
+#define SV_DISCLOSURE_MINUS 1061
+#define SV_DISCLOSURE_PLUS_HC 1062
+#define SV_DISCLOSURE_MINUS_HC 1063
+
#define SV_RESID_MENU_EDIT 2000
#define SV_MENU_EDIT_UNDO 1
#define SV_MENU_EDIT_CUT 2
@@ -74,6 +81,92 @@
#define SV_MENU_MAC_SHOWALL 2005
#define SV_MENU_MAC_QUITAPP 2006
+#define SV_DLG_PRINT 2048
+#define SV_PRINT_OK 1
+#define SV_PRINT_CANCEL 2
+#define SV_PRINT_HELP 3
+#define SV_PRINT_PAGE_PREVIEW 4
+#define SV_PRINT_PAGE_TXT 5
+#define SV_PRINT_PAGE_FORWARD 6
+#define SV_PRINT_PAGE_BACKWARD 7
+#define SV_PRINT_PAGE_EDIT 8
+#define SV_PRINT_TABCTRL 9
+#define SV_PRINT_PRT_TYPE 10
+#define SV_PRINT_PRT_STATUS 11
+#define SV_PRINT_PRT_LOCATION 12
+#define SV_PRINT_PRT_COMMENT 13
+#define SV_PRINT_TOFILE_TXT 14
+#define SV_PRINT_DEFPRT_TXT 15
+#define SV_PRINT_PRINTPREVIEW_TXT 16
+
+#define SV_PRINT_TAB_NUP 1
+#define SV_PRINT_PRT_NUP_LAYOUT_FL 1
+#define SV_PRINT_PRT_NUP_DEFAULT_BTN 2
+#define SV_PRINT_PRT_NUP_BROCHURE_BTN 3
+#define SV_PRINT_PRT_NUP_PAGES_BTN 4
+#define SV_PRINT_PRT_NUP_PAGES_BOX 5
+#define SV_PRINT_PRT_NUP_NUM_PAGES_TXT 6
+#define SV_PRINT_PRT_NUP_COLS_EDT 7
+#define SV_PRINT_PRT_NUP_TIMES_TXT 8
+#define SV_PRINT_PRT_NUP_ROWS_EDT 9
+#define SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT 10
+#define SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT 11
+#define SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT 12
+#define SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT 13
+#define SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT 14
+#define SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT 15
+#define SV_PRINT_PRT_NUP_ORIENTATION_TXT 16
+#define SV_PRINT_PRT_NUP_ORIENTATION_BOX 17
+#define SV_PRINT_PRT_NUP_ORDER_TXT 18
+#define SV_PRINT_PRT_NUP_ORDER_BOX 19
+#define SV_PRINT_PRT_NUP_BORDER_CB 20
+
+#define SV_PRINT_PRT_NUP_ORIENTATION_AUTOMATIC 0
+#define SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT 1
+#define SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE 2
+
+#define SV_PRINT_PRT_NUP_ORDER_LRTD 0
+#define SV_PRINT_PRT_NUP_ORDER_TDLR 1
+
+#define SV_PRINT_TAB_JOB 2
+#define SV_PRINT_PRINTERS_FL 1
+#define SV_PRINT_PRINTERS 2
+#define SV_PRINT_PRT_SETUP 3
+#define SV_PRINT_RANGE 4
+#define SV_PRINT_ALL 5
+#define SV_PRINT_PAGERANGE 6
+#define SV_PRINT_SELECTION 7
+#define SV_PRINT_PAGERANGE_EDIT 8
+#define SV_PRINT_COPIES 9
+#define SV_PRINT_COPYCOUNT 10
+#define SV_PRINT_COPYCOUNT_FIELD 11
+#define SV_PRINT_COLLATE 12
+#define SV_PRINT_COLLATE_IMAGE 13
+#define SV_PRINT_BUTTONLINE 14
+#define SV_PRINT_COLLATE_IMG 15
+#define SV_PRINT_NOCOLLATE_IMG 16
+#define SV_PRINT_COLLATE_HC_IMG 17
+#define SV_PRINT_NOCOLLATE_HC_IMG 18
+#define SV_PRINT_NOPAGES 19
+#define SV_PRINT_STATUS_TXT 20
+#define SV_PRINT_LOCATION_TXT 21
+#define SV_PRINT_COMMENT_TXT 22
+#define SV_PRINT_DETAILS_BTN 23
+
+#define SV_PRINT_TAB_OPT 3
+#define SV_PRINT_OPT_PRINT_FL 1
+#define SV_PRINT_OPT_TOFILE 2
+#define SV_PRINT_OPT_SINGLEJOBS 3
+#define SV_PRINT_OPT_REVERSE 4
+
+#define SV_DLG_PRINT_PROGRESS 2049
+#define SV_PRINT_PROGRESS_CANCEL 1
+#define SV_PRINT_PROGRESS_TEXT 2
+
+#define SV_PRINT_NATIVE_STRINGS 2050
+#define SV_PRINT_NOPRINTERWARNING 2051
+#define SV_PRINT_NOCONTENT 2052
+
#define SV_HELPTEXT_CLOSE 10000
#define SV_HELPTEXT_MINIMIZE 10001
#define SV_HELPTEXT_MAXIMIZE 10002
@@ -108,7 +201,8 @@
#define SV_STDTEXT_ABOUT 10204
#define SV_STDTEXT_PREFERENCES 10205
#define SV_MAC_SCREENNNAME 10206
-#define SV_STDTEXT_LAST SV_MAC_SCREENNNAME
+#define SV_STDTEXT_ALLFILETYPES 10207
+#define SV_STDTEXT_LAST SV_STDTEXT_ALLFILETYPES
#define SV_ACCESSERROR_FIRST SV_ACCESSERROR_WRONG_VERSION
#define SV_ACCESSERROR_WRONG_VERSION 10500
@@ -165,4 +259,6 @@
#define SV_ICON_ID_MACRO 17
#define SV_ICON_ID_PRINTERADMIN 501
+#define HID_PRINTDLG HID_VCL_START
+
#endif // _SV_SVIDS_HRC
diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx
index 30edf6227a60..f6646426b2e7 100644
--- a/vcl/inc/vcl/tabctrl.hxx
+++ b/vcl/inc/vcl/tabctrl.hxx
@@ -31,15 +31,16 @@
#ifndef _SV_TABCTRL_HXX
#define _SV_TABCTRL_HXX
-#include <vcl/sv.h>
-#include <vcl/dllapi.h>
-#include <vcl/ctrl.hxx>
+#include "vcl/sv.h"
+#include "vcl/dllapi.h"
+#include "vcl/ctrl.hxx"
struct ImplTabItem;
struct ImplTabCtrlData;
class ImplTabItemList;
class TabPage;
class PushButton;
+class ListBox;
// --------------------
// - TabControl-Types -
@@ -72,7 +73,7 @@ private:
BOOL mbRestoreUnqId;
BOOL mbSingleLine;
BOOL mbScroll;
- BOOL mbColored;
+ BOOL mbRestoreSmartId;
BOOL mbSmallInvalidate;
BOOL mbExtraSpace;
Link maActivateHdl;
@@ -95,6 +96,7 @@ private:
SAL_DLLPRIVATE void ImplPaint( const Rectangle& rRect, bool bLayout = false );
SAL_DLLPRIVATE void ImplFreeLayoutData();
DECL_DLLPRIVATE_LINK( ImplScrollBtnHdl, PushButton* pBtn );
+ DECL_DLLPRIVATE_LINK( ImplListBoxSelectHdl, ListBox* );
protected:
using Window::ImplInit;
@@ -128,6 +130,9 @@ public:
virtual void ActivatePage();
virtual long DeactivatePage();
+ virtual Size GetOptimalSize(WindowSizeType eType) const;
+ void SetMinimumSizePixel( const Size& );
+
void SetTabPageSizePixel( const Size& rSize );
Size GetTabPageSizePixel() const;
diff --git a/vcl/inc/vcl/toolbox.hxx b/vcl/inc/vcl/toolbox.hxx
index 6e4c300ccc40..c2547e4b01ba 100644
--- a/vcl/inc/vcl/toolbox.hxx
+++ b/vcl/inc/vcl/toolbox.hxx
@@ -124,6 +124,9 @@ typedef USHORT ToolBoxItemBits;
#define TIB_DROPDOWN ((ToolBoxItemBits)0x0020)
#define TIB_REPEAT ((ToolBoxItemBits)0x0040)
#define TIB_DROPDOWNONLY ((ToolBoxItemBits)0x0080 | TIB_DROPDOWN) // this button has only drop down functionality
+#define TIB_TEXT_ONLY ((ToolBoxItemBits)0x0100)
+#define TIB_ICON_ONLY ((ToolBoxItemBits)0x0200)
+#define TIB_TEXTICON ((ToolBoxItemBits) TIB_TEXT_ONLY | TIB_ICON_ONLY )
// -----------------
// - ToolBox-Types -
diff --git a/vcl/inc/vcl/virdev.hxx b/vcl/inc/vcl/virdev.hxx
index bc21dde6f4ac..ea2b49eb8290 100644
--- a/vcl/inc/vcl/virdev.hxx
+++ b/vcl/inc/vcl/virdev.hxx
@@ -74,7 +74,6 @@ private:
#define REFDEV_FORCE_ZERO_EXTLEAD 0x80
SAL_DLLPRIVATE bool ForceZeroExtleadBug() const
{ return ((meRefDevMode & REFDEV_FORCE_ZERO_EXTLEAD) != 0); }
-
public:
VirtualDevice( USHORT nBitCount = 0 );
VirtualDevice( const OutputDevice& rCompDev,
@@ -115,11 +114,19 @@ public:
REFDEV_MODE06 = 1, // 600 dpi
REFDEV_MODE48 = 2, // 4800 dpi
REFDEV_MODE_MSO1 = 3,
- REFDEV_MODE_PDF1 = 4 };
+ REFDEV_MODE_PDF1 = 4,
+ REFDEV_CUSTOM = 5
+ };
void SetReferenceDevice( RefDevMode );
void Compat_ZeroExtleadBug(); // enable workaround for #i60495#
+
+ void SetReferenceDevice( sal_Int32 i_nDPIX, sal_Int32 i_nDPIY );
+
+private:
+ SAL_DLLPRIVATE void ImplSetReferenceDevice( RefDevMode, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY );
+
};
#endif // _SV_VIRDEV_HXX
diff --git a/vcl/inc/vcl/window.h b/vcl/inc/vcl/window.h
index d745f3dcf081..563849873e3b 100644
--- a/vcl/inc/vcl/window.h
+++ b/vcl/inc/vcl/window.h
@@ -358,7 +358,8 @@ public:
mbToolbarFloatingWindow:1,
mbCallHandlersDuringInputDisabled:1,
mbDisableAccessibleLabelForRelation:1,
- mbDisableAccessibleLabeledByRelation:1;
+ mbDisableAccessibleLabeledByRelation:1,
+ mbHelpTextDynamic:1;
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer;
};
diff --git a/vcl/os2/inc/salprn.h b/vcl/os2/inc/salprn.h
index 25ecfe87ed89..2c95965bc609 100644
--- a/vcl/os2/inc/salprn.h
+++ b/vcl/os2/inc/salprn.h
@@ -83,7 +83,6 @@ public:
virtual String GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin );
virtual void InitPaperFormats( const ImplJobSetup* pSetupData );
virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData );
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData );
};
// ------------------
@@ -136,7 +135,9 @@ public:
virtual BOOL StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData );
virtual BOOL EndJob();
virtual BOOL AbortJob();
diff --git a/vcl/os2/source/gdi/salgdi3.cxx b/vcl/os2/source/gdi/salgdi3.cxx
index 573fa7336fb0..b25feee266e4 100644
--- a/vcl/os2/source/gdi/salgdi3.cxx
+++ b/vcl/os2/source/gdi/salgdi3.cxx
@@ -1361,10 +1361,8 @@ BOOL Os2SalGraphics::GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& rB
// rescaling needed for the PolyPolygon conversion
if( rB2DPolyPoly.count() )
{
- ::basegfx::B2DHomMatrix aMatrix;
- aMatrix.scale( 1.0/256, 1.0/256 );
- aMatrix.scale( mfFontScale, mfFontScale );
- rB2DPolyPoly.transform( aMatrix );
+ const double fFactor((1.0/256) * mfFontScale);
+ rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor));
}
return bRet;
diff --git a/vcl/os2/source/gdi/salprn.cxx b/vcl/os2/source/gdi/salprn.cxx
index 0c254e2f6e62..a31a4bb779f8 100644
--- a/vcl/os2/source/gdi/salprn.cxx
+++ b/vcl/os2/source/gdi/salprn.cxx
@@ -1559,7 +1559,9 @@ Os2SalPrinter::~Os2SalPrinter()
BOOL Os2SalPrinter::StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData )
{
DEVOPENSTRUC aDevOpenStruc;
@@ -1831,9 +1833,4 @@ int Os2SalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData )
printf("Os2SalInfoPrinter::GetLandscapeAngle\n");
return 0;
}
-DuplexMode Os2SalInfoPrinter::GetDuplexMode( const ImplJobSetup* pSetupData )
-{
- DuplexMode nRet = DUPLEX_UNKNOWN;
- printf("Os2SalInfoPrinter::GetDuplexMode\n");
- return nRet;
-}
+
diff --git a/vcl/prj/build.lst b/vcl/prj/build.lst
index 5d2aaf90c6f7..cf2824f72942 100644
--- a/vcl/prj/build.lst
+++ b/vcl/prj/build.lst
@@ -1,4 +1,4 @@
-vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools transex3 icc SO:print_header cpputools shell NULL
+vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools transex3 icc SO:print_header cpputools shell svl NULL
vc vcl usr1 - all vc_mkout NULL
vc vcl\inc nmake - all vc_inc NULL
vc vcl\source\glyphs nmake - all vc_glyphs vc_inc NULL
diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst
index 54af0d2e289d..b106ff73729e 100644
--- a/vcl/prj/d.lst
+++ b/vcl/prj/d.lst
@@ -81,10 +81,10 @@ mkdir: %_DEST%\inc%_EXT%\vcl
..\inc\vcl\morebtn.hxx %_DEST%\inc%_EXT%\vcl\morebtn.hxx
..\inc\vcl\msgbox.hxx %_DEST%\inc%_EXT%\vcl\msgbox.hxx
..\inc\vcl\octree.hxx %_DEST%\inc%_EXT%\vcl\octree.hxx
+..\inc\vcl\oldprintadaptor.hxx %_DEST%\inc%_EXT%\vcl\oldprintadaptor.hxx
..\inc\vcl\outdev.hxx %_DEST%\inc%_EXT%\vcl\outdev.hxx
..\inc\vcl\pointr.hxx %_DEST%\inc%_EXT%\vcl\pointr.hxx
..\inc\vcl\print.hxx %_DEST%\inc%_EXT%\vcl\print.hxx
-..\inc\vcl\prndlg.hxx %_DEST%\inc%_EXT%\vcl\prndlg.hxx
..\inc\vcl\prntypes.hxx %_DEST%\inc%_EXT%\vcl\prntypes.hxx
..\inc\vcl\ptrstyle.hxx %_DEST%\inc%_EXT%\vcl\ptrstyle.hxx
..\inc\vcl\regband.hxx %_DEST%\inc%_EXT%\vcl\regband.hxx
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 516b23dd76be..31971468d9c6 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -97,8 +97,8 @@ SalPrinter::~SalPrinter()
{
}
-BOOL SalPrinter::StartJob( const String*, const String&,
- ImplJobSetup*, ImplQPrinter* )
+BOOL SalPrinter::StartJob( const String*, const String&, const String&,
+ ImplJobSetup*, vcl::PrinterController& )
{
return FALSE;
}
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 6a61d15db4c0..e8e56c6ee5a8 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: svdata.cxx,v $
- * $Revision: 1.56 $
+ * $Revision: 1.56.114.1 $
*
* This file is part of OpenOffice.org.
*
@@ -234,6 +234,15 @@ ResMgr* ImplGetResMgr()
return pSVData->mpResMgr;
}
+ResId VclResId( sal_Int32 nId )
+{
+ ResMgr* pMgr = ImplGetResMgr();
+ if( ! pMgr )
+ throw std::bad_alloc();
+
+ return ResId( nId, *pMgr );
+}
+
DockingManager* ImplGetDockingManager()
{
ImplSVData* pSVData = ImplGetSVData();
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 310c01a40673..f1af78662813 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -444,6 +444,26 @@ void DeInitVCL()
delete pSVData->maCtrlData.mpSplitVArwImgList;
pSVData->maCtrlData.mpSplitVArwImgList = NULL;
}
+ if ( pSVData->maCtrlData.mpDisclosurePlus )
+ {
+ delete pSVData->maCtrlData.mpDisclosurePlus;
+ pSVData->maCtrlData.mpDisclosurePlus = NULL;
+ }
+ if ( pSVData->maCtrlData.mpDisclosurePlusHC )
+ {
+ delete pSVData->maCtrlData.mpDisclosurePlusHC;
+ pSVData->maCtrlData.mpDisclosurePlusHC = NULL;
+ }
+ if ( pSVData->maCtrlData.mpDisclosureMinus )
+ {
+ delete pSVData->maCtrlData.mpDisclosureMinus;
+ pSVData->maCtrlData.mpDisclosureMinus = NULL;
+ }
+ if ( pSVData->maCtrlData.mpDisclosureMinusHC )
+ {
+ delete pSVData->maCtrlData.mpDisclosureMinusHC;
+ pSVData->maCtrlData.mpDisclosureMinusHC = NULL;
+ }
if ( pSVData->mpDefaultWin )
{
delete pSVData->mpDefaultWin;
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 53a060af6bd6..b5915cc35daf 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -1983,8 +1983,11 @@ Size PushButton::CalcMinimumSize( long nMaxWidth ) const
}
// cf. ImplDrawPushButton ...
- aSize.Width() += 8;
- aSize.Height() += 8;
+ if( (GetStyle() & WB_SMALLSTYLE) == 0 )
+ {
+ aSize.Width() += 8;
+ aSize.Height() += 8;
+ }
return CalcWindowSize( aSize );
}
@@ -4376,3 +4379,95 @@ TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
TriStateBox::~TriStateBox()
{
}
+
+// =======================================================================
+
+DisclosureButton::DisclosureButton( Window* pParent, WinBits ) :
+ CheckBox( pParent, WB_NOBORDER )
+{
+}
+
+// -----------------------------------------------------------------------
+
+DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) :
+ CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void DisclosureButton::ImplDrawCheckBoxState()
+{
+ /* HACK: DisclosureButton is currently assuming, that the disclosure sign
+ will fit into the rectangle occupied by a normal checkbox on all themes.
+ If this does not hold true for some theme, ImplGetCheckImageSize
+ would have to be overloaded for DisclosureButton; also GetNativeControlRegion
+ for CTRL_LISTNODE would have to be implemented and taken into account
+ */
+
+ Rectangle aStateRect( GetStateRect() );
+
+ ImplControlValue aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 );
+ Region aCtrlRegion( aStateRect );
+ ControlState nState = 0;
+
+ if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
+ if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
+ if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED;
+ if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) )
+ nState |= CTRL_STATE_ROLLOVER;
+
+ if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
+ aControlValue, rtl::OUString() ) )
+ {
+ ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData );
+ if( ! rCtrlData.mpDisclosurePlus )
+ rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) );
+ if( ! rCtrlData.mpDisclosurePlusHC )
+ rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) );
+ if( ! rCtrlData.mpDisclosureMinus )
+ rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) );
+ if( ! rCtrlData.mpDisclosureMinusHC )
+ rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) );
+
+ Image* pImg = NULL;
+ if( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC;
+ else
+ pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus;
+
+ DBG_ASSERT( pImg, "no disclosure image" );
+ if( ! pImg )
+ return;
+
+ USHORT nStyle = 0;
+ if( ! IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+
+ Size aSize( aStateRect.GetSize() );
+ Size aImgSize( pImg->GetSizePixel() );
+ Point aOff( (aSize.Width() - aImgSize.Width())/2,
+ (aSize.Height() - aImgSize.Height())/2 );
+ aOff += aStateRect.TopLeft();
+ DrawImage( aOff, *pImg, nStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DisclosureButton::KeyInput( const KeyEvent& rKEvt )
+{
+ KeyCode aKeyCode = rKEvt.GetKeyCode();
+
+ if( !aKeyCode.GetModifier() &&
+ ( ( aKeyCode.GetCode() == KEY_ADD ) ||
+ ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
+ )
+ {
+ Check( aKeyCode.GetCode() == KEY_ADD );
+ }
+ else
+ Button::KeyInput( rKEvt );
+}
+
+
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index b654e034470f..320f235a8c30 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -492,6 +492,17 @@ void Edit::ImplInvalidateOrRepaint( xub_StrLen nStart, xub_StrLen nEnd )
// -----------------------------------------------------------------------
+long Edit::ImplGetTextYPosition() const
+{
+ if ( GetStyle() & WB_TOP )
+ return ImplGetExtraOffset();
+ else if ( GetStyle() & WB_BOTTOM )
+ return GetOutputSizePixel().Height() - GetTextHeight() - ImplGetExtraOffset();
+ return ( GetOutputSizePixel().Height() - GetTextHeight() ) / 2;
+}
+
+// -----------------------------------------------------------------------
+
void Edit::ImplRepaint( xub_StrLen nStart, xub_StrLen nEnd, bool bLayout )
{
if ( !IsReallyVisible() )
@@ -516,10 +527,8 @@ void Edit::ImplRepaint( xub_StrLen nStart, xub_StrLen nEnd, bool bLayout )
GetCaretPositions( aText, pDX, nStart, nEnd );
}
- // center vertically
- long nH = GetOutputSize().Height();
long nTH = GetTextHeight();
- Point aPos( mnXOffset, (nH-nTH)/2 );
+ Point aPos( mnXOffset, ImplGetTextYPosition() );
if( bLayout )
{
@@ -1193,7 +1202,7 @@ void Edit::ImplShowCursor( BOOL bOnlyIfVisible )
long nCursorPosX = nTextPos + mnXOffset + ImplGetExtraOffset();
// Cursor muss im sichtbaren Bereich landen:
- Size aOutSize = GetOutputSizePixel();
+ const Size aOutSize = GetOutputSizePixel();
if ( (nCursorPosX < 0) || (nCursorPosX >= aOutSize.Width()) )
{
long nOldXOffset = mnXOffset;
@@ -1227,8 +1236,8 @@ void Edit::ImplShowCursor( BOOL bOnlyIfVisible )
ImplInvalidateOrRepaint();
}
- long nTextHeight = GetTextHeight();
- long nCursorPosY = (aOutSize.Height()-nTextHeight) / 2;
+ const long nTextHeight = GetTextHeight();
+ const long nCursorPosY = ImplGetTextYPosition();
pCursor->SetPos( Point( nCursorPosX, nCursorPosY ) );
pCursor->SetSize( Size( nCursorWidth, nTextHeight ) );
pCursor->Show();
@@ -2831,7 +2840,29 @@ void Edit::SetSubEdit( Edit* pEdit )
Size Edit::CalcMinimumSize() const
{
Size aSize ( GetTextWidth( GetText() ), GetTextHeight() );
- return CalcWindowSize( aSize );
+ // do not create edit fields in which one cannot enter anything
+ // a default minimum width should exist for at least 3 characters
+ Size aMinSize ( CalcSize( 3 ) );
+ if( aSize.Width() < aMinSize.Width() )
+ aSize.Width() = aMinSize.Width();
+ // add some space between text entry an border
+ aSize.Height() += 4;
+
+ aSize = CalcWindowSize( aSize );
+
+ // ask NWF what if it has an opinion, too
+ ImplControlValue aControlValue;
+ Rectangle aRect( Point( 0, 0 ), aSize );
+ Region aContent, aBound;
+ if( const_cast<Edit*>(this)->GetNativeControlRegion(
+ CTRL_EDITBOX, PART_ENTIRE_CONTROL,
+ aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) )
+ {
+ Rectangle aBoundRect( aContent.GetBoundRect() );
+ if( aBoundRect.GetHeight() > aSize.Height() )
+ aSize.Height() = aBoundRect.GetHeight();
+ }
+ return aSize;
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index 6698f51b7ab1..3dbc69de8a96 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -1044,6 +1044,14 @@ void FixedImage::Paint( const Rectangle& )
// -----------------------------------------------------------------------
+Size FixedImage::GetOptimalSize( WindowSizeType ) const
+{
+ const Image* pImage = GetSettings().GetStyleSettings().GetHighContrastMode() ? &maImageHC : &maImage;
+ return pImage->GetSizePixel();
+}
+
+// -----------------------------------------------------------------------
+
void FixedImage::UserDraw( const UserDrawEvent& )
{
}
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index a915d8e6b9e8..fd5cd7ae4dac 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -1873,6 +1873,8 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
USHORT nDrawStyle = ImplGetTextStyle();
if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
+ if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_DRAW_DISABLED) )
+ nDrawStyle |= TEXT_DRAW_DISABLE;
DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText );
}
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index ceabbe4ab166..81a8dc0e8242 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -108,6 +108,7 @@ void ListBox::ImplInitListBoxData()
mnDDHeight = 0;
mbDDAutoSize = TRUE;
mnSaveValue = LISTBOX_ENTRY_NOTFOUND;
+ mnLineCount = 0;
}
// -----------------------------------------------------------------------
@@ -1286,31 +1287,47 @@ Size ListBox::CalcMinimumSize() const
else
{
aSz.Height() = mpImplLB->CalcSize( 1 ).Height();
- if( aSz.Height() < mnDDHeight )
+ aSz.Height() += 4; // add a space between entry and border
+ // size to maxmimum entry width and add a little breathing space
+ aSz.Width() = mpImplLB->GetMaxEntryWidth() + 4;
+ // do not create ultrathin ListBoxes, it doesn't look good
+ if( aSz.Width() < GetSettings().GetStyleSettings().GetScrollBarSize() )
+ aSz.Width() = GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ // try native borders; scrollbar size may not be a good indicator
+ // see how large the edit area inside is to estimate what is needed for the dropdown
+ ImplControlValue aControlValue;
+ Point aPoint;
+ Region aContent, aBound;
+ Size aTestSize( 100, 20 );
+ Region aArea( Rectangle( aPoint, aTestSize ) );
+ if( const_cast<ListBox*>(this)->GetNativeControlRegion(
+ CTRL_LISTBOX, PART_SUB_EDIT, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
{
- aSz.Height() = mnDDHeight;
- // FIXME: this is currently only on mac/aqua
- if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
- IsNativeWidgetEnabled() &&
- const_cast<ListBox*>(this)->IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
- {
- ImplControlValue aControlValue;
- Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 20, mnDDHeight ) ) );
- Region aBoundingRgn( aCtrlRegion );
- Region aContentRgn( aCtrlRegion );
- // adjust the size of the edit field
- if( const_cast<ListBox*>(this)->GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL,
- aCtrlRegion, 0, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn) )
- {
- aSz.Height() = aContentRgn.GetBoundRect().GetHeight();
- }
- }
+ // use the themes drop down size
+ Rectangle aContentRect = aContent.GetBoundRect();
+ aSz.Width() += aTestSize.Width() - aContentRect.GetWidth();
}
- aSz.Width() = mpImplLB->GetMaxEntryWidth();
- aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
+ else
+ aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
}
aSz = CalcWindowSize( aSz );
+
+ if ( IsDropDownBox() ) // check minimum height of dropdown box
+ {
+ ImplControlValue aControlValue;
+ Rectangle aRect( Point( 0, 0 ), aSz );
+ Region aContent, aBound;
+ if( const_cast<ListBox*>(this)->GetNativeControlRegion(
+ CTRL_LISTBOX, PART_ENTIRE_CONTROL, aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) )
+ {
+ Rectangle aBoundRect( aBound.GetBoundRect() );
+ if( aBoundRect.GetHeight() > aSz.Height() )
+ aSz.Height() = aBoundRect.GetHeight();
+ }
+ }
+
return aSz;
}
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 9a34629ddf8e..56cc2c3fb012 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -30,25 +30,24 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#include <tools/debug.hxx>
-
-#ifndef _SV_RC_H
-#include <tools/rc.h>
-#endif
-#include <vcl/svdata.hxx>
-#ifndef _SV_APP_HXX
-#include <vcl/svapp.hxx>
-#endif
-#include <vcl/help.hxx>
-#include <vcl/event.hxx>
-#include <vcl/menu.hxx>
-#include <vcl/button.hxx>
-#include <vcl/tabpage.hxx>
-#include <vcl/tabctrl.hxx>
-#include <vcl/controldata.hxx>
-#include <vcl/sound.hxx>
-
-#include <vcl/window.h>
+#include "tools/debug.hxx"
+
+#include "tools/rc.h"
+#include "vcl/svdata.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/help.hxx"
+#include "vcl/event.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/button.hxx"
+#include "vcl/tabpage.hxx"
+#include "vcl/tabctrl.hxx"
+#include "vcl/controllayout.hxx"
+#include "vcl/controldata.hxx"
+#include "vcl/sound.hxx"
+#include "vcl/lstbox.hxx"
+#include "vcl/smartid.hxx"
+
+#include "vcl/window.h"
#include <hash_map>
#include <vector>
@@ -87,6 +86,8 @@ struct ImplTabCtrlData
std::vector< Rectangle > maTabRectangles;
Point maItemsOffset; // offset of the tabitems
std::vector< ImplTabItem > maItemList;
+ ListBox* mpListBox;
+ Size maMinSize;
};
// -----------------------------------------------------------------------
@@ -153,16 +154,25 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle )
mbRestoreUnqId = FALSE;
mbSingleLine = FALSE;
mbScroll = FALSE;
- mbColored = FALSE;
+ mbRestoreSmartId = FALSE;
mbSmallInvalidate = FALSE;
mbExtraSpace = FALSE;
mpTabCtrlData = new ImplTabCtrlData;
mpTabCtrlData->mpLeftBtn = NULL;
mpTabCtrlData->mpRightBtn = NULL;
+ mpTabCtrlData->mpListBox = NULL;
ImplInitSettings( TRUE, TRUE, TRUE );
+ if( (nStyle & WB_DROPDOWN) )
+ {
+ mpTabCtrlData->mpListBox = new ListBox( this, WB_DROPDOWN );
+ mpTabCtrlData->mpListBox->SetPosSizePixel( Point( 0, 0 ), Size( 200, 20 ) );
+ mpTabCtrlData->mpListBox->SetSelectHdl( LINK( this, TabControl, ImplListBoxSelectHdl ) );
+ mpTabCtrlData->mpListBox->Show();
+ }
+
// if the tabcontrol is drawn (ie filled) by a native widget, make sure all contols will have transparent background
// otherwise they will paint with a wrong background
if( IsNativeControlSupported(CTRL_TAB_PANE, PART_ENTIRE_CONTROL) )
@@ -286,6 +296,8 @@ TabControl::~TabControl()
// TabCtrl-Daten loeschen
if ( mpTabCtrlData )
{
+ if( mpTabCtrlData->mpListBox )
+ delete mpTabCtrlData->mpListBox;
if ( mpTabCtrlData->mpLeftBtn )
delete mpTabCtrlData->mpLeftBtn;
if ( mpTabCtrlData->mpRightBtn )
@@ -693,6 +705,8 @@ void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId )
pCtrlParent->SetHelpId( 0 );
if ( mbRestoreUnqId )
pCtrlParent->SetUniqueId( 0 );
+ if( mbRestoreSmartId )
+ pCtrlParent->SetSmartHelpId( SmartId() );
pOldPage->DeactivatePage();
}
@@ -700,8 +714,8 @@ void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId )
{
pPage->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
- // Hier Page aktivieren, damit die Controls entsprechend umgeschaltet
- // werden koennen und HilfeId gegebenenfalls beim Parent umsetzen
+ // activate page here so the conbtrols can be switched
+ // also set the help id of the parent window to that of the tab page
if ( !GetHelpId() )
{
mbRestoreHelpId = TRUE;
@@ -712,6 +726,11 @@ void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId )
mbRestoreUnqId = TRUE;
pCtrlParent->SetUniqueId( pPage->GetUniqueId() );
}
+ if( ! GetSmartHelpId().HasAny() )
+ {
+ mbRestoreSmartId = TRUE;
+ pCtrlParent->SetSmartHelpId( pPage->GetSmartHelpId() );
+ }
pPage->ActivatePage();
@@ -791,7 +810,7 @@ void TabControl::ImplSetFirstPagePos( USHORT )
void TabControl::ImplShowFocus()
{
- if ( !GetPageCount() )
+ if ( !GetPageCount() || mpTabCtrlData->mpListBox )
return;
// make sure the focussed item rect is computed using a bold font
@@ -1062,16 +1081,27 @@ IMPL_LINK( TabControl, ImplScrollBtnHdl, PushButton*, EMPTYARG )
// -----------------------------------------------------------------------
+IMPL_LINK( TabControl, ImplListBoxSelectHdl, ListBox*, EMPTYARG )
+{
+ SelectTabPage( GetPageId( mpTabCtrlData->mpListBox->GetSelectEntryPos() ) );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
{
- if ( rMEvt.IsLeft() )
+ if( mpTabCtrlData->mpListBox == NULL )
{
- USHORT nPageId = GetPageId( rMEvt.GetPosPixel() );
- ImplTabItem* pItem = ImplGetItem( nPageId );
- if( pItem && pItem->mbEnabled )
- SelectTabPage( nPageId );
- else
- Sound::Beep( SOUND_ERROR, this );
+ if( rMEvt.IsLeft() )
+ {
+ USHORT nPageId = GetPageId( rMEvt.GetPosPixel() );
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+ if( pItem && pItem->mbEnabled )
+ SelectTabPage( nPageId );
+ else
+ Sound::Beep( SOUND_ERROR, this );
+ }
}
}
@@ -1079,7 +1109,9 @@ void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
void TabControl::KeyInput( const KeyEvent& rKEvt )
{
- if ( GetPageCount() > 1 )
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->KeyInput( rKEvt );
+ else if ( GetPageCount() > 1 )
{
KeyCode aKeyCode = rKEvt.GetKeyCode();
USHORT nKeyCode = aKeyCode.GetCode();
@@ -1224,7 +1256,7 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout )
}
}
- if ( !mpTabCtrlData->maItemList.empty() )
+ if ( !mpTabCtrlData->maItemList.empty() && mpTabCtrlData->mpListBox == NULL )
{
// Some native toolkits (GTK+) draw tabs right-to-left, with an
// overlap between adjacent tabs
@@ -1294,6 +1326,18 @@ void TabControl::Resize()
if ( !IsReallyShown() )
return;
+ if( mpTabCtrlData->mpListBox )
+ {
+ // get the listbox' preferred size
+ Size aTabCtrlSize( GetSizePixel() );
+ long nPrefWidth = mpTabCtrlData->mpListBox->GetOptimalSize( WINDOWSIZE_PREFERRED ).Width();
+ if( nPrefWidth > aTabCtrlSize.Width() )
+ nPrefWidth = aTabCtrlSize.Width();
+ Size aNewSize( nPrefWidth, LogicToPixel( Size( 12, 12 ), MapMode( MAP_APPFONT ) ).Height() );
+ Point aNewPos( (aTabCtrlSize.Width() - nPrefWidth) / 2, 0 );
+ mpTabCtrlData->mpListBox->SetPosSizePixel( aNewPos, aNewSize );
+ }
+
mbFormat = TRUE;
// Aktuelle TabPage resizen/positionieren
@@ -1343,8 +1387,16 @@ void TabControl::Resize()
void TabControl::GetFocus()
{
- ImplShowFocus();
- SetInputContext( InputContext( GetFont() ) );
+ if( ! mpTabCtrlData->mpListBox )
+ {
+ ImplShowFocus();
+ SetInputContext( InputContext( GetFont() ) );
+ }
+ else
+ {
+ if( mpTabCtrlData->mpListBox->IsReallyVisible() )
+ mpTabCtrlData->mpListBox->GrabFocus();
+ }
Control::GetFocus();
}
@@ -1352,7 +1404,8 @@ void TabControl::GetFocus()
void TabControl::LoseFocus()
{
- HideFocus();
+ if( ! mpTabCtrlData->mpListBox )
+ HideFocus();
Control::LoseFocus();
}
@@ -1446,7 +1499,7 @@ void TabControl::RequestHelp( const HelpEvent& rHEvt )
void TabControl::Command( const CommandEvent& rCEvt )
{
- if ( (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) && (GetPageCount() > 1) )
+ if( (mpTabCtrlData->mpListBox == NULL) && (rCEvt.GetCommand() == COMMAND_CONTEXTMENU) && (GetPageCount() > 1) )
{
Point aMenuPos;
BOOL bMenu;
@@ -1490,7 +1543,11 @@ void TabControl::StateChanged( StateChangedType nType )
Control::StateChanged( nType );
if ( nType == STATE_CHANGE_INITSHOW )
+ {
ImplPosCurTabPage();
+ if( mpTabCtrlData->mpListBox )
+ Resize();
+ }
else if ( nType == STATE_CHANGE_UPDATEMODE )
{
if ( IsUpdateMode() )
@@ -1708,24 +1765,34 @@ void TabControl::InsertPage( USHORT nPageId, const XubString& rText,
DBG_ASSERT( GetPagePos( nPageId ) == TAB_PAGE_NOTFOUND,
"TabControl::InsertPage(): PageId already exists" );
- // set current page id
- if ( !mnCurPageId )
- mnCurPageId = nPageId;
-
// insert new page item
ImplTabItem* pItem = NULL;
if( nPos == TAB_APPEND || size_t(nPos) >= mpTabCtrlData->maItemList.size() )
{
mpTabCtrlData->maItemList.push_back( ImplTabItem() );
pItem = &mpTabCtrlData->maItemList.back();
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->InsertEntry( rText );
}
else
{
std::vector< ImplTabItem >::iterator new_it =
mpTabCtrlData->maItemList.insert( mpTabCtrlData->maItemList.begin() + nPos, ImplTabItem() );
pItem = &(*new_it);
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->InsertEntry( rText, nPos);
+ }
+ if( mpTabCtrlData->mpListBox )
+ {
+ if( ! mnCurPageId )
+ mpTabCtrlData->mpListBox->SelectEntryPos( 0 );
+ mpTabCtrlData->mpListBox->SetDropDownLineCount( mpTabCtrlData->mpListBox->GetEntryCount() );
}
+ // set current page id
+ if ( !mnCurPageId )
+ mnCurPageId = nPageId;
+
// init new page item
pItem->mnId = nPageId;
pItem->mpTabPage = NULL;
@@ -1739,6 +1806,8 @@ void TabControl::InsertPage( USHORT nPageId, const XubString& rText,
Invalidate();
ImplFreeLayoutData();
+ if( mpTabCtrlData->mpListBox ) // reposition/resize listbox
+ Resize();
ImplCallEventListeners( VCLEVENT_TABPAGE_INSERTED, (void*) (ULONG)nPageId );
}
@@ -1756,6 +1825,11 @@ void TabControl::RemovePage( USHORT nPageId )
std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin() + nPos;
bool bIsCurrentPage = (it->mnId == mnCurPageId);
mpTabCtrlData->maItemList.erase( it );
+ if( mpTabCtrlData->mpListBox )
+ {
+ mpTabCtrlData->mpListBox->RemoveEntry( nPos );
+ mpTabCtrlData->mpListBox->SetDropDownLineCount( mpTabCtrlData->mpListBox->GetEntryCount() );
+ }
// If current page is removed, than first page gets the current page
if ( bIsCurrentPage )
@@ -1793,6 +1867,8 @@ void TabControl::Clear()
// clear item list
mpTabCtrlData->maItemList.clear();
mnCurPageId = 0;
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->Clear();
ImplFreeLayoutData();
@@ -1813,6 +1889,9 @@ void TabControl::EnablePage( USHORT i_nPageId, bool i_bEnable )
{
pItem->mbEnabled = i_bEnable;
mbFormat = TRUE;
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->SetEntryFlags( GetPagePos( i_nPageId ),
+ i_bEnable ? 0 : (LISTBOX_ENTRY_FLAG_DISABLE_SELECTION | LISTBOX_ENTRY_FLAG_DRAW_DISABLED) );
if( pItem->mnId == mnCurPageId )
{
// SetCurPageId will change to an enabled page
@@ -1937,6 +2016,8 @@ void TabControl::SelectTabPage( USHORT nPageId )
nPageId = mnActPageId;
mnActPageId = 0;
SetCurPageId( nPageId );
+ if( mpTabCtrlData->mpListBox )
+ mpTabCtrlData->mpListBox->SelectEntryPos( GetPagePos( nPageId ) );
ImplCallEventListeners( VCLEVENT_TABPAGE_ACTIVATE, (void*) (ULONG) nPageId );
}
}
@@ -2001,6 +2082,12 @@ void TabControl::SetPageText( USHORT nPageId, const XubString& rText )
{
pItem->maText = rText;
mbFormat = TRUE;
+ if( mpTabCtrlData->mpListBox )
+ {
+ USHORT nPos = GetPagePos( nPageId );
+ mpTabCtrlData->mpListBox->RemoveEntry( nPos );
+ mpTabCtrlData->mpListBox->InsertEntry( rText, nPos );
+ }
if ( IsUpdateMode() )
Invalidate();
ImplFreeLayoutData();
@@ -2216,3 +2303,25 @@ Point TabControl::GetItemsOffset() const
}
// -----------------------------------------------------------------------
+
+Size TabControl::GetOptimalSize(WindowSizeType eType) const
+{
+ switch (eType) {
+ case WINDOWSIZE_MINIMUM:
+ return mpTabCtrlData ? mpTabCtrlData->maMinSize : Size();
+ default:
+ return Control::GetOptimalSize( eType );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabControl::SetMinimumSizePixel( const Size& i_rSize )
+{
+ if( mpTabCtrlData )
+ mpTabCtrlData->maMinSize = i_rSize;
+}
+
+// -----------------------------------------------------------------------
+
+
diff --git a/vcl/source/gdi/bmpconv.cxx b/vcl/source/gdi/bmpconv.cxx
index 9d9b81ba50d4..03d85acb0159 100644
--- a/vcl/source/gdi/bmpconv.cxx
+++ b/vcl/source/gdi/bmpconv.cxx
@@ -192,7 +192,8 @@ BmpTransporter::BmpTransporter( const Bitmap& rBM )
m_aSize.Height = rBM.GetSizePixel().Height();
SvMemoryStream aStream;
rBM.Write( aStream, FALSE, TRUE );
- m_aBM = Sequence<sal_Int8>((const sal_Int8*)aStream.GetData(), aStream.GetSize() );
+ m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
+ aStream.GetEndOfData());
}
BmpTransporter::~BmpTransporter()
diff --git a/vcl/source/gdi/cvtsvm.cxx b/vcl/source/gdi/cvtsvm.cxx
index 4ecb89ec5a8e..8c4b6f1a2cb2 100644
--- a/vcl/source/gdi/cvtsvm.cxx
+++ b/vcl/source/gdi/cvtsvm.cxx
@@ -88,23 +88,6 @@ void ImplReadPoly( SvStream& rIStm, Polygon& rPoly )
// ------------------------------------------------------------------------
-void ImplWritePoly( SvStream& rOStm, const Polygon& rPoly )
-{
- // #i102224# Here the evtl. curved nature of Polygon was
- // ignored (for all those Years). Adapted to at least write
- // a polygon representing the curve as good as possible
- Polygon aSimplePoly;
- rPoly.AdaptiveSubdivide(aSimplePoly);
- INT32 nSize = aSimplePoly.GetSize();
-
- rOStm << nSize;
-
- for( INT32 i = 0; i < nSize; i++ )
- rOStm << aSimplePoly[ (USHORT) i ];
-}
-
-// ------------------------------------------------------------------------
-
void ImplReadPolyPoly( SvStream& rIStm, PolyPolygon& rPolyPoly )
{
Polygon aPoly;
@@ -139,10 +122,9 @@ void ImplWritePolyPolyAction( SvStream& rOStm, const PolyPolygon& rPolyPoly )
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
- const Polygon& rPoly = rPolyPoly[ n ];
- Polygon aSimplePoly;
- rPoly.AdaptiveSubdivide(aSimplePoly);
- const USHORT nSize = aSimplePoly.GetSize();
+ Polygon aSimplePoly;
+ rPolyPoly[n].AdaptiveSubdivide(aSimplePoly);
+ const USHORT nSize(aSimplePoly.GetSize());
rOStm << (INT32) nSize;
@@ -388,6 +370,128 @@ void ImplSkipActions( SvStream& rIStm, ULONG nSkipCount )
}
}
+// ------------------------------------------------------------------------
+
+bool ImplWriteExtendedPolyPolygonAction(SvStream& rOStm, const PolyPolygon& rPolyPolygon, bool bOnlyWhenCurve)
+{
+ const sal_uInt16 nPolygonCount(rPolyPolygon.Count());
+
+ if(nPolygonCount)
+ {
+ sal_uInt32 nAllPolygonCount(0);
+ sal_uInt32 nAllPointCount(0);
+ sal_uInt32 nAllFlagCount(0);
+ sal_uInt16 a(0);
+
+ for(a = 0; a < nPolygonCount; a++)
+ {
+ const Polygon& rCandidate = rPolyPolygon.GetObject(a);
+ const sal_uInt16 nPointCount(rCandidate.GetSize());
+
+ if(nPointCount)
+ {
+ nAllPolygonCount++;
+ nAllPointCount += nPointCount;
+
+ if(rCandidate.HasFlags())
+ {
+ nAllFlagCount += nPointCount;
+ }
+ }
+ }
+
+ if((bOnlyWhenCurve && nAllFlagCount) || (!bOnlyWhenCurve && nAllPointCount))
+ {
+ rOStm << (INT16) GDI_EXTENDEDPOLYGON_ACTION;
+
+ const sal_Int32 nActionSize(
+ 4 + // Action size
+ 2 + // PolygonCount
+ (nAllPolygonCount * 2) + // Points per polygon
+ (nAllPointCount << 3) + // Points themselves
+ nAllPolygonCount + // Bool if (when poly has points) it has flags, too
+ nAllFlagCount); // Flags themselves
+
+ rOStm << nActionSize;
+ rOStm << (sal_uInt16)nAllPolygonCount;
+
+ for(a = 0; a < nPolygonCount; a++)
+ {
+ const Polygon& rCandidate = rPolyPolygon.GetObject(a);
+ const sal_uInt16 nPointCount(rCandidate.GetSize());
+
+ if(nPointCount)
+ {
+ rOStm << nPointCount;
+
+ for(sal_uInt16 b(0); b < nPointCount; b++)
+ {
+ rOStm << rCandidate[b];
+ }
+
+ if(rCandidate.HasFlags())
+ {
+ rOStm << (BYTE)true;
+
+ for(sal_uInt16 c(0); c < nPointCount; c++)
+ {
+ rOStm << (BYTE)rCandidate.GetFlags(c);
+ }
+ }
+ else
+ {
+ rOStm << (BYTE)false;
+ }
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// ------------------------------------------------------------------------
+
+void ImplReadExtendedPolyPolygonAction(SvStream& rIStm, PolyPolygon& rPolyPoly)
+{
+ rPolyPoly.Clear();
+ sal_uInt16 nPolygonCount(0);
+ rIStm >> nPolygonCount;
+
+ for(sal_uInt16 a(0); a < nPolygonCount; a++)
+ {
+ sal_uInt16 nPointCount(0);
+ rIStm >> nPointCount;
+ Polygon aCandidate(nPointCount);
+
+ if(nPointCount)
+ {
+ for(sal_uInt16 b(0); b < nPointCount; b++)
+ {
+ rIStm >> aCandidate[b];
+ }
+
+ BYTE bHasFlags(false);
+ rIStm >> bHasFlags;
+
+ if(bHasFlags)
+ {
+ BYTE aPolyFlags(0);
+
+ for(sal_uInt16 c(0); c < nPointCount; c++)
+ {
+ rIStm >> aPolyFlags;
+ aCandidate.SetFlags(c, (PolyFlags)aPolyFlags);
+ }
+ }
+ }
+
+ rPolyPoly.Insert(aCandidate);
+ }
+}
+
// ----------------
// - SVMConverter -
// ----------------
@@ -460,6 +564,7 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
rMtf.SetPrefSize( aPrefSz );
rMtf.SetPrefMapMode( aMapMode );
+ sal_uInt32 nLastPolygonAction(0);
for( INT32 i = 0L; i < nActions; i++ )
{
@@ -493,6 +598,99 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
}
break;
+ case (GDI_LINEJOIN_ACTION) :
+ {
+ INT16 nLineJoin(0);
+ rIStm >> nLineJoin;
+ aLineInfo.SetLineJoin((basegfx::B2DLineJoin)nLineJoin);
+ }
+ break;
+
+ case (GDI_LINEDASHDOT_ACTION) :
+ {
+ INT16 a(0);
+ INT32 b(0);
+
+ rIStm >> a; aLineInfo.SetDashCount(a);
+ rIStm >> b; aLineInfo.SetDashLen(b);
+ rIStm >> a; aLineInfo.SetDotCount(a);
+ rIStm >> b; aLineInfo.SetDotLen(b);
+ rIStm >> b; aLineInfo.SetDistance(b);
+
+ if(((aLineInfo.GetDashCount() && aLineInfo.GetDashLen())
+ || (aLineInfo.GetDotCount() && aLineInfo.GetDotLen()))
+ && aLineInfo.GetDistance())
+ {
+ aLineInfo.SetStyle(LINE_DASH);
+ }
+ }
+ break;
+
+ case (GDI_EXTENDEDPOLYGON_ACTION) :
+ {
+ // read the PolyPolygon in every case
+ PolyPolygon aInputPolyPolygon;
+ ImplReadExtendedPolyPolygonAction(rIStm, aInputPolyPolygon);
+
+ // now check if it can be set somewhere
+ if(nLastPolygonAction < rMtf.GetActionCount())
+ {
+ MetaPolyLineAction* pPolyLineAction = dynamic_cast< MetaPolyLineAction* >(rMtf.GetAction(nLastPolygonAction));
+
+ if(pPolyLineAction)
+ {
+ // replace MetaPolyLineAction when we have a single polygon. Do not rely on the
+ // same point count; the originally written GDI_POLYLINE_ACTION may have been
+ // Subdivided for better quality for older usages
+ if(1 == aInputPolyPolygon.Count())
+ {
+ rMtf.ReplaceAction(
+ new MetaPolyLineAction(
+ aInputPolyPolygon.GetObject(0),
+ pPolyLineAction->GetLineInfo()),
+ nLastPolygonAction);
+ pPolyLineAction->Delete();
+ }
+ }
+ else
+ {
+ MetaPolyPolygonAction* pPolyPolygonAction = dynamic_cast< MetaPolyPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
+
+ if(pPolyPolygonAction)
+ {
+ // replace MetaPolyPolygonAction when we have a curved polygon. Do rely on the
+ // same sub-polygon count
+ if(pPolyPolygonAction->GetPolyPolygon().Count() == aInputPolyPolygon.Count())
+ {
+ rMtf.ReplaceAction(
+ new MetaPolyPolygonAction(
+ aInputPolyPolygon),
+ nLastPolygonAction);
+ pPolyPolygonAction->Delete();
+ }
+ }
+ else
+ {
+ MetaPolygonAction* pPolygonAction = dynamic_cast< MetaPolygonAction* >(rMtf.GetAction(nLastPolygonAction));
+
+ if(pPolygonAction)
+ {
+ // replace MetaPolygonAction
+ if(1 == aInputPolyPolygon.Count())
+ {
+ rMtf.ReplaceAction(
+ new MetaPolygonAction(
+ aInputPolyPolygon.GetObject(0)),
+ nLastPolygonAction);
+ pPolygonAction->Delete();
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
case( GDI_RECT_ACTION ):
{
ImplReadRect( rIStm, aRect );
@@ -583,6 +781,7 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
case( GDI_POLYLINE_ACTION ):
{
ImplReadPoly( rIStm, aActionPoly );
+ nLastPolygonAction = rMtf.GetActionCount();
if( bFatLine )
rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
@@ -604,7 +803,10 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
rMtf.AddAction( new MetaPolyLineAction( aActionPoly, aLineInfo ) );
}
else
+ {
+ nLastPolygonAction = rMtf.GetActionCount();
rMtf.AddAction( new MetaPolygonAction( aActionPoly ) );
+ }
}
break;
@@ -625,7 +827,10 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf )
rMtf.AddAction( new MetaPolyLineAction( aPolyPoly[ nPoly ], aLineInfo ) );
}
else
+ {
+ nLastPolygonAction = rMtf.GetActionCount();
rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
+ }
}
break;
@@ -1257,12 +1462,32 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
{
MetaLineAction* pAct = (MetaLineAction*) pAction;
const LineInfo& rInfo = pAct->GetLineInfo();
- const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) );
+ const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
+ const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
+ const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
if( bFatLine )
{
ImplWritePushAction( rOStm );
ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
+
+ if(bLineJoin)
+ {
+ rOStm << (INT16) GDI_LINEJOIN_ACTION;
+ rOStm << (INT32) 6;
+ rOStm << (INT16) rInfo.GetLineJoin();
+ }
+
+ if(bLineDashDot)
+ {
+ rOStm << (INT16) GDI_LINEDASHDOT_ACTION;
+ rOStm << (INT32) 4 + 16;
+ rOStm << (INT16)rInfo.GetDashCount();
+ rOStm << (INT32)rInfo.GetDashLen();
+ rOStm << (INT16)rInfo.GetDotCount();
+ rOStm << (INT32)rInfo.GetDotLen();
+ rOStm << (INT32)rInfo.GetDistance();
+ }
}
rOStm << (INT16) GDI_LINE_ACTION;
@@ -1275,6 +1500,16 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
{
ImplWritePopAction( rOStm );
nCount += 3;
+
+ if(bLineJoin)
+ {
+ nCount += 1;
+ }
+
+ if(bLineDashDot)
+ {
+ nCount += 1;
+ }
}
}
break;
@@ -1355,30 +1590,47 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
for( USHORT n = 0; n < nPoints; n++ )
rOStm << aChordPoly[ n ];
-
nCount++;
}
break;
case( META_POLYLINE_ACTION ):
{
+ // #i102224#
MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
- const Polygon& rPoly = pAct->GetPolygon();
-
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
- Polygon aSimplePoly;
- rPoly.AdaptiveSubdivide(aSimplePoly);
-
- const LineInfo& rInfo = pAct->GetLineInfo();
- const USHORT nPoints = aSimplePoly.GetSize();
- const BOOL bFatLine = ( !rInfo.IsDefault() && ( LINE_NONE != rInfo.GetStyle() ) );
+ Polygon aSimplePoly;
+ pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
+ const LineInfo& rInfo = pAct->GetLineInfo();
+ const USHORT nPoints(aSimplePoly.GetSize());
+ const bool bFatLine(!rInfo.IsDefault() && (LINE_NONE != rInfo.GetStyle()));
+ const bool bLineJoin(bFatLine && basegfx::B2DLINEJOIN_ROUND != rInfo.GetLineJoin());
+ const bool bLineDashDot(LINE_DASH == rInfo.GetStyle());
if( bFatLine )
{
ImplWritePushAction( rOStm );
ImplWriteLineColor( rOStm, rLineCol, 1, rInfo.GetWidth() );
+
+ if(bLineJoin)
+ {
+ rOStm << (INT16) GDI_LINEJOIN_ACTION;
+ rOStm << (INT32) 6;
+ rOStm << (INT16) rInfo.GetLineJoin();
+ }
+ }
+
+ if(bLineDashDot)
+ {
+ rOStm << (INT16) GDI_LINEDASHDOT_ACTION;
+ rOStm << (INT32) 4 + 16;
+ rOStm << (INT16)rInfo.GetDashCount();
+ rOStm << (INT32)rInfo.GetDashLen();
+ rOStm << (INT16)rInfo.GetDotCount();
+ rOStm << (INT32)rInfo.GetDotLen();
+ rOStm << (INT32)rInfo.GetDistance();
}
rOStm << (INT16) GDI_POLYLINE_ACTION;
@@ -1386,30 +1638,45 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
rOStm << (INT32) nPoints;
for( USHORT n = 0; n < nPoints; n++ )
+ {
rOStm << aSimplePoly[ n ];
+ }
nCount++;
+ const PolyPolygon aPolyPolygon(pAct->GetPolygon());
+ if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
+ {
+ nCount++;
+ }
+
if( bFatLine )
{
ImplWritePopAction( rOStm );
nCount += 3;
+
+ if(bLineJoin)
+ {
+ nCount += 1;
+ }
+ }
+
+ if(bLineDashDot)
+ {
+ nCount += 1;
}
}
break;
case( META_POLYGON_ACTION ):
{
- MetaPolygonAction* pAct = (MetaPolygonAction*) pAction;
- const Polygon& rPoly = pAct->GetPolygon();
-
+ MetaPolygonAction* pAct = (MetaPolygonAction*)pAction;
// #i102224# Here the evtl. curved nature of Polygon was
// ignored (for all those Years). Adapted to at least write
// a polygon representing the curve as good as possible
- Polygon aSimplePoly;
- rPoly.AdaptiveSubdivide(aSimplePoly);
-
- const USHORT nPoints = aSimplePoly.GetSize();
+ Polygon aSimplePoly;
+ pAct->GetPolygon().AdaptiveSubdivide(aSimplePoly);
+ const USHORT nPoints(aSimplePoly.GetSize());
rOStm << (INT16) GDI_POLYGON_ACTION;
rOStm << (INT32) ( 8 + ( nPoints << 3 ) );
@@ -1419,6 +1686,12 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
rOStm << aSimplePoly[ n ];
nCount++;
+
+ const PolyPolygon aPolyPolygon(pAct->GetPolygon());
+ if(ImplWriteExtendedPolyPolygonAction(rOStm, aPolyPolygon, true))
+ {
+ nCount++;
+ }
}
break;
@@ -1427,6 +1700,11 @@ ULONG SVMConverter::ImplWriteActions( SvStream& rOStm, GDIMetaFile& rMtf,
MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
ImplWritePolyPolyAction( rOStm, pAct->GetPolyPolygon() );
nCount++;
+
+ if(ImplWriteExtendedPolyPolygonAction(rOStm, pAct->GetPolyPolygon(), true))
+ {
+ nCount++;
+ }
}
break;
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 6483c8292df7..951d80f9af9d 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -876,6 +876,40 @@ void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY )
// ------------------------------------------------------------------------
+void GDIMetaFile::Clip( const Rectangle& i_rClipRect )
+{
+ Rectangle aCurRect( i_rClipRect );
+ VirtualDevice aMapVDev;
+
+ aMapVDev.EnableOutput( FALSE );
+ aMapVDev.SetMapMode( GetPrefMapMode() );
+
+ for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() )
+ {
+ const long nType = pAct->GetType();
+
+ if( ( META_MAPMODE_ACTION == nType ) ||
+ ( META_PUSH_ACTION == nType ) ||
+ ( META_POP_ACTION == nType ) )
+ {
+ pAct->Execute( &aMapVDev );
+ aCurRect = aMapVDev.LogicToLogic( i_rClipRect, GetPrefMapMode(), aMapVDev.GetMapMode() );
+ }
+ else if( nType == META_CLIPREGION_ACTION )
+ {
+ MetaClipRegionAction* pOldAct = (MetaClipRegionAction*)pAct;
+ Region aNewReg( aCurRect );
+ if( pOldAct->IsClipping() )
+ aNewReg.Intersect( pOldAct->GetRegion() );
+ MetaClipRegionAction* pNewAct = new MetaClipRegionAction( aNewReg, TRUE );
+ Replace( pNewAct, GetCurPos() );
+ pOldAct->Delete();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
Point GDIMetaFile::ImplGetRotatedPoint( const Point& rPt, const Point& rRotatePt,
const Size& rOffset, double fSin, double fCos )
{
diff --git a/vcl/source/gdi/implncvt.cxx b/vcl/source/gdi/implncvt.cxx
deleted file mode 100644
index e59fde15b5be..000000000000
--- a/vcl/source/gdi/implncvt.cxx
+++ /dev/null
@@ -1,577 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: implncvt.cxx,v $
- * $Revision: 1.10.136.1 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org 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 version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-#include <vcl/salbtype.hxx>
-#ifndef _SV_IMPLNCVT_HXX
-#include "implncvt.hxx"
-#endif
-
-// -----------
-// - Defines -
-// -----------
-
-#define CURVE_LEFT 1
-#define CURVE_RIGHT 2
-#define CURVE_STRAIGHTON 3
-
-// -----------------
-// - ImplFloatPoint
-// -----------------
-
-struct ImplFloatPoint
-{
- double fX;
- double fY;
-
- inline ImplFloatPoint() {}
- inline ImplFloatPoint( const Point& rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); }
- inline ImplFloatPoint( double _fX, double _fY ) { fX = _fX; fY = _fY; }
- inline ImplFloatPoint( const ImplFloatPoint& rPoint ) { fX = rPoint.fX; fY = rPoint.fY; }
- inline ~ImplFloatPoint() {}
-
- void operator+=( const ImplFloatPoint& rPoint ) { fX += rPoint.fX; fY += rPoint.fY; }
- void operator-=( const ImplFloatPoint& rPoint ) { fX -= rPoint.fX; fY -= rPoint.fY; }
- void operator*=( const double& rD ) { fX *= rD; fY *= rD; }
- BOOL operator==( const ImplFloatPoint& rPoint ) const { return ( ( rPoint.fX == fX ) && ( rPoint.fY == fY ) ); }
- void operator=( const Point& rPoint ) { fX = rPoint.X(); fY = rPoint.Y(); }
-
- ImplFloatPoint GetOVec( const ImplFloatPoint& rPoint ) const;
- ImplFloatPoint GetNVec( const ImplFloatPoint& rPoint ) const;
-};
-
-// -----------------------------------------------------------------------------
-
-ImplFloatPoint ImplFloatPoint::GetOVec( const ImplFloatPoint& rPoint ) const
-{
- double fxt = rPoint.fX - fX;
- double fyt = rPoint.fY - fY;
- double fL;
-
- if( fyt != 0.0 )
- {
- fyt = -fxt / fyt;
- fL = sqrt( 1 + fyt * fyt );
-
- return ImplFloatPoint( 1.0 / fL, fyt / fL );
- }
- else
- return ImplFloatPoint( fyt, ( fxt > 0.0 ) ? 1.0 : -1.0 );
-};
-
-// -----------------------------------------------------------------------------
-
-ImplFloatPoint ImplFloatPoint::GetNVec( const ImplFloatPoint& rPoint ) const
-{
- const double fxt = rPoint.fX - fX;
- const double fyt = rPoint.fY - fY;
- const double fL = hypot( fxt, fyt );
-
- return ImplFloatPoint( fxt / fL, fyt / fL );
-};
-
-// --------------------
-// - ImplLineConverter
-// --------------------
-
-ImplLineConverter::ImplLineConverter( const Polygon& rPolygon, const LineInfo& rLineInfo, const Point* pRefPoint ) :
- mbRefPoint ( FALSE ),
- mfWidthHalf ( rLineInfo.GetWidth() >> 1 ),
- maLineInfo ( rLineInfo ),
- mpFloat0 ( new ImplFloatPoint[ 6 ] ),
- mpFloat1 ( new ImplFloatPoint[ 6 ] ),
- mnLines ( 0 ),
- mpFloatPoint ( NULL )
-{
- UINT16 nIndex, nPolySize = rPolygon.GetSize();
- if ( nPolySize )
- {
- if( rPolygon.GetFlags( 0 ) == POLY_NORMAL )
- {
- mpFloatPoint = new ImplFloatPoint[ nPolySize ];
- mpFloatPoint[ 0 ] = rPolygon[ 0 ];
-
- nIndex = 0;
-
- while( ++nIndex < nPolySize ) // doppelte Punkte eliminieren und ein FloatPointArray anlegen
- {
- if( rPolygon.GetFlags( nIndex ) == POLY_NORMAL )
- {
- double nxt = mpFloatPoint[ mnLines ].fX;
- double nyt = mpFloatPoint[ mnLines ].fY;
-
- if ( ( nxt == rPolygon[ nIndex ].X() ) && ( nyt == rPolygon[ nIndex ].Y() ) )
- continue;
-
- mpFloatPoint[ ++mnLines ] = rPolygon[ nIndex ];
- }
- else
- {
- DBG_ERROR( "Bezier points not supported!" );
- }
- }
- mbClosed = ( mpFloatPoint[ 0 ] == mpFloatPoint[ mnLines ] ) ;
-
- if ( ( mnLines == 1 ) && ( maLineInfo.GetStyle() == LINE_DASH ) )
- {
- BOOL bX = mpFloatPoint[ 0 ].fY == mpFloatPoint[ 1 ].fY;
- BOOL bY = mpFloatPoint[ 0 ].fX == mpFloatPoint[ 1 ].fX;
- mbRefPoint = pRefPoint && ( bX || bY );
- if ( mbRefPoint )
- {
- if ( !maLineInfo.GetDashCount() )
- {
- maLineInfo.SetDashCount( maLineInfo.GetDotCount() );
- maLineInfo.SetDashLen( maLineInfo.GetDotLen() );
- maLineInfo.SetDotCount( 0 );
- }
- INT32 nDistance = maLineInfo.GetDistance();
- INT32 nDashLen = maLineInfo.GetDashCount() * ( maLineInfo.GetDashLen() + nDistance );
- INT32 nDotLen = maLineInfo.GetDotCount() * ( maLineInfo.GetDotLen() + nDistance );
- if ( bX )
- {
- if ( mpFloatPoint[ 1 ].fX > mpFloatPoint[ 0 ].fX )
- {
- ImplFloatPoint aFloat = mpFloatPoint[ 0 ];
- mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ];
- mpFloatPoint[ 1 ] = aFloat;
- }
- mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X();
- }
- else
- {
- if ( mpFloatPoint[ 1 ].fY > mpFloatPoint[ 0 ].fY )
- {
- ImplFloatPoint aFloat = mpFloatPoint[ 0 ];
- mpFloatPoint[ 0 ] = mpFloatPoint[ 1 ];
- mpFloatPoint[ 1 ] = aFloat;
- }
- mnRefDistance = (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y();
- }
-
-// mnRefDistance = ( (INT32)mpFloatPoint[ mnLines ].fX - pRefPoint->X() ) +
-// ( (INT32)mpFloatPoint[ mnLines ].fY - pRefPoint->Y() );
-
- mnRefDistance = mnRefDistance % ( nDashLen + nDotLen );
- if ( mnRefDistance < 0 )
- mnRefDistance = ( nDashLen + nDotLen ) + mnRefDistance;
- }
- }
- }
- }
-};
-
-//------------------------------------------------------------------------
-
-ImplLineConverter::~ImplLineConverter()
-{
- delete[] mpFloat0;
- delete[] mpFloat1;
- delete[] mpFloatPoint;
-};
-
-//------------------------------------------------------------------------
-
-const Polygon* ImplLineConverter::ImplGetFirst()
-{
- mnFloat1Points = 0;
- mnLinesAvailable = mnLines;
-
- if ( mnLines )
- {
- if ( maLineInfo.GetStyle() == LINE_DASH )
- {
- mnDashCount = maLineInfo.GetDashCount();
- mnDotCount = maLineInfo.GetDotCount();
- mfDashDotLenght = mnDashCount ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
-
- if ( mbRefPoint )
- {
- INT32 nDistance = maLineInfo.GetDistance();
- INT32 nDashLen = maLineInfo.GetDashLen() + nDistance;
- INT32 nDashesLen = maLineInfo.GetDashCount() * nDashLen;
- INT32 nDotLen = maLineInfo.GetDotLen() + nDistance;
-
- if ( mnRefDistance >= nDashesLen )
- {
- // get dotcount
- if ( nDotLen )
- {
- INT32 nLen = ( mnRefDistance - nDashesLen ) % nDotLen;
- if ( nLen >= maLineInfo.GetDotLen() )
- {
- mnDotCount -= 1 + ( mnRefDistance - nDashesLen ) / nDotLen;
- if ( mnDotCount )
- mnDashCount = 0;
- else
- mnDotCount = maLineInfo.GetDotCount();
- mfDashDotLenght = 0.0;
- mfDistanceLenght = ( maLineInfo.GetDotLen() + nDistance ) - nLen;
- }
- else
- {
- mnDashCount = 0;
- mfDashDotLenght = maLineInfo.GetDotLen() - nLen;
- mnDotCount -= ( mnRefDistance - nDashesLen ) / nDotLen;
- }
- }
- }
- else
- {
- if ( nDashLen )
- {
- // get dashcount
- INT32 nLen = mnRefDistance % nDashLen;
- if ( nLen >= maLineInfo.GetDashLen() )
- {
- mfDashDotLenght = 0.0;
- mfDistanceLenght = ( maLineInfo.GetDashLen() + nDistance ) - nLen;
- mnDashCount -= 1 + ( mnRefDistance / nDashLen );
- }
- else
- {
- mfDashDotLenght = maLineInfo.GetDashLen() - nLen;
- mnDashCount -= ( mnRefDistance / nDashLen );
- }
- }
- }
- if ( ! ( mnDashCount | mnDotCount ) )
- {
- mnDashCount = maLineInfo.GetDashCount();
- mnDotCount = maLineInfo.GetDotCount();
- }
- if ( ( mfDashDotLenght == 0.0 ) && ( mfDistanceLenght == 0.0 ) )
- mfDistanceLenght = maLineInfo.GetDistance();
- }
- }
- }
- return ImplGetNext();
-};
-
-//------------------------------------------------------------------------
-
-const Polygon* ImplLineConverter::ImplGetNext()
-{
- while( mnFloat1Points || mnLinesAvailable )
- {
- if ( maLineInfo.GetWidth() > 1 )
- {
- if ( !mnFloat1Points )
- {
- ImplFloatPoint aPointA( mpFloatPoint[ mnLinesAvailable-- ] );
- ImplFloatPoint aPointB( mpFloatPoint[ mnLinesAvailable ] );
- ImplFloatPoint aOVecAB( aPointA.GetOVec( aPointB ) );
- ImplFloatPoint aN1Vec( aPointA.GetNVec( aPointB ) );
- aN1Vec *= mfWidthHalf;
-
- if ( !mbClosed && ( ( mnLinesAvailable + 1 ) == mnLines ) )
- aPointA -= aN1Vec;
-
- aOVecAB *= mfWidthHalf;
- mpFloat0[ 0 ] = aPointA;
- mpFloat0[ 0 ] -= aOVecAB;
- mpFloat0[ 3 ] = aPointA;
- mpFloat0[ 3 ] += aOVecAB;
- mpFloat0[ 1 ] = aPointB;
- mpFloat0[ 1 ] -= aOVecAB;
- mpFloat0[ 2 ] = aPointB;
- mpFloat0[ 2 ] += aOVecAB;
-
- double f1D = ( aN1Vec.fX == 0 ) ? 1 : ( aN1Vec.fY / aN1Vec.fX );
- double f2D = -f1D;
-
- mnFloat0Points = 4;
-
- int nDirection;
-
- BOOL bContinues = ( mnLinesAvailable || mbClosed );
- if ( bContinues )
- {
- ImplFloatPoint aPointC;
-
- if ( mnLinesAvailable )
- aPointC = mpFloatPoint[ mnLinesAvailable - 1 ];
- else
- aPointC = mpFloatPoint[ mnLines - 1 ];
-
- ImplFloatPoint aOVecBC( aPointB.GetOVec( aPointC ) );
- aOVecBC *= mfWidthHalf;
- ImplFloatPoint aPointR0( aPointB );
- aPointR0 -= aOVecBC;
- ImplFloatPoint aPointR1( aPointB );
- aPointR1 += aOVecBC;
- ImplFloatPoint aN2Vec( aPointB.GetNVec( aPointC ) );
- aN2Vec *= mfWidthHalf;
-
- f2D = ( fabs( aN2Vec.fX ) < 0.00000001 ) ? 1 : ( aN2Vec.fY / aN2Vec.fX );
- if ( fabs( f1D - f2D ) < 0.00000001 )
- nDirection = CURVE_STRAIGHTON;
- else
- {
- if ( ( aN1Vec.fX * aN2Vec.fY - aN1Vec.fY * aN2Vec.fX ) > 0 )
- nDirection = CURVE_LEFT;
- else
- nDirection = CURVE_RIGHT;
- }
- if ( nDirection != CURVE_STRAIGHTON )
- {
- double fWidth;
- ImplFloatPoint aDestPoint;
- if ( hypot( aPointR0.fX - aPointA.fX, aPointR0.fY - aPointA.fY ) > hypot( aPointR1.fX - aPointA.fX, aPointR1.fY - aPointA.fY ) )
- aDestPoint = aPointR0;
- else
- aDestPoint = aPointR1;
-
- UINT16 nFirst = 0;
- if ( aN1Vec.fY > 0 )
- {
- if ( nDirection != CURVE_RIGHT )
- nFirst++;
- }
- else
- {
- if ( nDirection == CURVE_RIGHT )
- nFirst++;
- }
- fWidth = hypot( mpFloat0[ 1 + nFirst ].fX - aDestPoint.fX, mpFloat0[ 1 + nFirst ].fY - aDestPoint.fY );
- fWidth = sqrt( fWidth * fWidth / 2 );
- if ( fWidth > mfWidthHalf )
- {
- // Spitzer Winkel :
- mnFloat0Points = 6;
- mpFloat0[ (4 + nFirst) ^ 1 ] = aDestPoint;
- aDestPoint -= aN2Vec;
- mpFloat0[ 4 + nFirst ] = aDestPoint;
- mpFloat0[ 1 + nFirst ] += aN1Vec;
- }
- else
- {
- // Stumpferwinkel : Schnittpunkt wird berechnet
- mnFloat0Points = 5;
- ImplFloatPoint aSourcePoint;
- double fX = 0;
- double fY;
- double fBDest = 0;
- double fBSource = 0;
- aSourcePoint = mpFloat0[ 1 + nFirst ];
-
- int nValid = 0;
-
- if ( fabs( aN2Vec.fX ) < 0.00000001 )
- {
- fX = aDestPoint.fX;
- nValid = 1;
- }
- else
- fBDest = aDestPoint.fY - ( aN2Vec.fY / aN2Vec.fX * aDestPoint.fX );
-
- if ( fabs( aN1Vec.fX ) < 0.000000001 )
- {
- fX = aSourcePoint.fX;
- nValid = 2;
- }
- else
- fBSource = aSourcePoint.fY - ( aN1Vec.fY / aN1Vec.fX * aSourcePoint.fX );
-
- if ( !nValid )
- fX = ( fBSource - fBDest ) / ( aN2Vec.fY / aN2Vec.fX - aN1Vec.fY / aN1Vec.fX );
- if ( nValid < 2 )
- fY = aN1Vec.fY / aN1Vec.fX * fX + fBSource;
- else
- fY = aN2Vec.fY / aN2Vec.fX * fX + fBDest;
-
- mpFloat0[ 1 + nFirst ].fX = fX;
- mpFloat0[ 1 + nFirst ].fY = fY;
- mpFloat0[ 4 ] = aDestPoint;
- }
- }
- else if ( ( aN1Vec.fX - aN2Vec.fX + aN1Vec.fY - aN2Vec.fY ) != 0 ) // besitzt zweiter Richtungsvektor die gleiche Steigung aber andere
- bContinues = FALSE; // Richtung, dann wird hinten noch eine halbe Linienbreite angehaengt
- }
- if ( !bContinues )
- {
- mpFloat0[ 1 ] += aN1Vec;
- mpFloat0[ 2 ] += aN1Vec;
- }
- }
- else
- {
- mnFloat0Points = mnFloat1Points;
- ImplFloatPoint* pTemp = mpFloat1;
- mpFloat1 = mpFloat0;
- mpFloat0 = pTemp;
- }
- if ( maLineInfo.GetStyle() == LINE_DASH )
- {
- double fLenghtDone = 0;
- double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght;
-
- double fDistance;
-
- fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY );
- if ( mnFloat0Points == 5 )
- {
- double fDist = hypot( mpFloat0[ 2 ].fX - mpFloat0[ 3 ].fX, mpFloat0[ 2 ].fY - mpFloat0[ 3 ].fY );
- if ( fDist < fDistance )
- fDistance = fDist;
- }
-
- if ( fDistance > fLenght )
- {
- fLenghtDone = fLenght;
-
- ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) );
- aNVec *= fLenght;
- mnFloat1Points = mnFloat0Points;
- ImplFloatPoint* pTemp = mpFloat1;
- mpFloat1 = mpFloat0;
- mpFloat0 = pTemp;
- mnFloat0Points = 4;
- mpFloat0[ 0 ] = mpFloat0[ 1 ] = mpFloat1[ 0 ];
- mpFloat0[ 1 ] += aNVec;
- mpFloat0[ 2 ] = mpFloat0[ 3 ] = mpFloat1[ 3 ];
- mpFloat0[ 2 ] += aNVec;
-
- mpFloat1[ 0 ] = mpFloat0[ 1 ];
- mpFloat1[ 3 ] = mpFloat0[ 2 ];
- }
- else
- {
- mnFloat1Points = 0;
- fLenghtDone = fDistance;
- }
-
- if ( mfDashDotLenght > 0.0 )
- { // Ein Dash oder Dot wurde erzeugt
- mfDashDotLenght -= fLenghtDone;
- if ( mfDashDotLenght == 0.0 )
- { // Komplett erzeugt
- if ( mnDashCount )
- mnDashCount--;
- else
- mnDotCount--;
-
- if ( ! ( mnDashCount | mnDotCount ) )
- {
- mnDashCount = maLineInfo.GetDashCount();
- mnDotCount = maLineInfo.GetDotCount();
- }
- mfDistanceLenght = maLineInfo.GetDistance();
- }
- }
- else
- { // Das erzeugte Polygon muessen wir ignorieren
- mfDistanceLenght -= fLenghtDone;
- if ( mfDistanceLenght == 0.0 )
- mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
- continue;
- }
- }
- maPolygon.SetSize( (UINT16)mnFloat0Points );
- UINT16 i = 0;
- maPolygon[ i++ ] = Point( FRound( mpFloat0[ 0 ].fX ), FRound( mpFloat0[ 0 ].fY ) );
- maPolygon[ i++ ] = Point( FRound( mpFloat0[ 1 ].fX ), FRound( mpFloat0[ 1 ].fY ) );
- if ( mnFloat0Points > 4 )
- maPolygon[ i++ ] = Point( FRound( mpFloat0[ 4 ].fX ), FRound( mpFloat0[ 4 ].fY ) );
- if ( mnFloat0Points > 5 )
- maPolygon[ i++ ] = Point( FRound( mpFloat0[ 5 ].fX ), FRound( mpFloat0[ 5 ].fY ) );
- maPolygon[ i++ ] = Point( FRound( mpFloat0[ 2 ].fX ), FRound( mpFloat0[ 2 ].fY ) );
- maPolygon[ i ] = Point( FRound( mpFloat0[ 3 ].fX ), FRound( mpFloat0[ 3 ].fY ) );
-
- }
- else
- {
- if ( !mnFloat1Points )
- {
- mpFloat0[ 0 ] = mpFloatPoint[ mnLinesAvailable-- ];
- mpFloat0[ 1 ] = mpFloatPoint[ mnLinesAvailable ];
- }
- else
- {
- mpFloat0[ 0 ] = mpFloat1[ 0 ];
- mpFloat0[ 1 ] = mpFloat1[ 1 ];
- }
- if ( maLineInfo.GetStyle() == LINE_DASH )
- {
- double fLenghtDone = 0;
- double fLenght = ( mfDashDotLenght > 0.0 ) ? mfDashDotLenght : mfDistanceLenght;
- double fDistance;
- fDistance = hypot( mpFloat0[ 0 ].fX - mpFloat0[ 1 ].fX, mpFloat0[ 0 ].fY - mpFloat0[ 1 ].fY );
- if ( fDistance > fLenght )
- {
- fLenghtDone = fLenght;
- ImplFloatPoint aNVec( mpFloat0[ 0 ].GetNVec( mpFloat0[ 1 ] ) );
- aNVec *= fLenght;
- mpFloat1[ 1 ] = mpFloat0[ 1 ];
- mpFloat0[ 1 ] = mpFloat0[ 0 ];
- mpFloat0[ 1 ] += aNVec;
- mpFloat1[ 0 ] = mpFloat0[ 1 ];
- mnFloat1Points = 2;
- }
- else
- {
- mnFloat1Points = 0;
- fLenghtDone = fDistance;
- }
- if ( mfDashDotLenght > 0.0 )
- { // Ein Dash oder Dot wurde erzeugt
- mfDashDotLenght -= fLenghtDone;
- if ( mfDashDotLenght == 0.0 )
- { // Komplett erzeugt
- if ( mnDashCount )
- mnDashCount--;
- else
- mnDotCount--;
-
- if ( ! ( mnDashCount | mnDotCount ) )
- {
- mnDashCount = maLineInfo.GetDashCount();
- mnDotCount = maLineInfo.GetDotCount();
- }
- mfDistanceLenght = maLineInfo.GetDistance();
- }
- }
- else
- { // Das erzeugte Polygon muessen wir ignorieren
- mfDistanceLenght -= fLenghtDone;
- if ( mfDistanceLenght == 0.0 )
- mfDashDotLenght = ( mnDashCount ) ? maLineInfo.GetDashLen() : maLineInfo.GetDotLen();
- continue;
- }
- }
- maPolygon.SetSize( 2 );
- maPolygon[ 0 ] = Point( (long)mpFloat0[ 0 ].fX, (long)mpFloat0[ 0 ].fY );
- maPolygon[ 1 ] = Point( (long)mpFloat0[ 1 ].fX, (long)mpFloat0[ 1 ].fY );
- }
- return &maPolygon;
- }
- return NULL;
-};
diff --git a/vcl/source/gdi/impprn.cxx b/vcl/source/gdi/impprn.cxx
index 539c879c89ea..28d92a0b3832 100644
--- a/vcl/source/gdi/impprn.cxx
+++ b/vcl/source/gdi/impprn.cxx
@@ -478,10 +478,12 @@ void ImplQPrinter::EndQueuePrint()
DBG_ASSERT( mpPrinter, "no SalPrinter in ImplQPrinter" );
if( mpPrinter )
{
+ #if 0
mpPrinter->StartJob( mbPrintFile ? &maPrintFile : NULL,
Application::GetDisplayName(),
maJobSetup.ImplGetConstData(),
this );
+ #endif
EndJob();
mpParent->ImplEndPrint();
}
diff --git a/vcl/source/gdi/jobset.cxx b/vcl/source/gdi/jobset.cxx
index 686d33593466..4823a5492ded 100644
--- a/vcl/source/gdi/jobset.cxx
+++ b/vcl/source/gdi/jobset.cxx
@@ -73,6 +73,7 @@ ImplJobSetup::ImplJobSetup()
mnRefCount = 1;
mnSystem = 0;
meOrientation = ORIENTATION_PORTRAIT;
+ meDuplexMode = DUPLEX_UNKNOWN;
mnPaperBin = 0;
mePaperFormat = PAPER_USER;
mnPaperWidth = 0;
@@ -90,6 +91,7 @@ ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
mnRefCount = 1;
mnSystem = rJobSetup.mnSystem;
meOrientation = rJobSetup.meOrientation;
+ meDuplexMode = rJobSetup.meDuplexMode;
mnPaperBin = rJobSetup.mnPaperBin;
mePaperFormat = rJobSetup.mePaperFormat;
mnPaperWidth = rJobSetup.mnPaperWidth;
@@ -277,6 +279,7 @@ BOOL JobSetup::operator==( const JobSetup& rJobSetup ) const
(pData1->maPrinterName == pData2->maPrinterName) &&
(pData1->maDriver == pData2->maDriver) &&
(pData1->meOrientation == pData2->meOrientation) &&
+ (pData1->meDuplexMode == pData2->meDuplexMode) &&
(pData1->mnPaperBin == pData2->mnPaperBin) &&
(pData1->mePaperFormat == pData2->mePaperFormat) &&
(pData1->mnPaperWidth == pData2->mnPaperWidth) &&
@@ -337,6 +340,7 @@ SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup )
pJobData->mnSystem = SVBT16ToShort( pOldJobData->nSystem );
pJobData->mnDriverDataLen = SVBT32ToUInt32( pOldJobData->nDriverDataLen );
pJobData->meOrientation = (Orientation)SVBT16ToShort( pOldJobData->nOrientation );
+ pJobData->meDuplexMode = DUPLEX_UNKNOWN;
pJobData->mnPaperBin = SVBT16ToShort( pOldJobData->nPaperBin );
pJobData->mePaperFormat = (Paper)SVBT16ToShort( pOldJobData->nPaperFormat );
pJobData->mnPaperWidth = (long)SVBT32ToUInt32( pOldJobData->nPaperWidth );
@@ -355,7 +359,19 @@ SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup )
String aKey, aValue;
rIStream.ReadByteString( aKey, RTL_TEXTENCODING_UTF8 );
rIStream.ReadByteString( aValue, RTL_TEXTENCODING_UTF8 );
- pJobData->maValueMap[ aKey ] = aValue;
+ if( aKey.EqualsAscii( "COMPAT_DUPLEX_MODE" ) )
+ {
+ if( aValue.EqualsAscii( "DUPLEX_UNKNOWN" ) )
+ pJobData->meDuplexMode = DUPLEX_UNKNOWN;
+ else if( aValue.EqualsAscii( "DUPLEX_OFF" ) )
+ pJobData->meDuplexMode = DUPLEX_OFF;
+ else if( aValue.EqualsAscii( "DUPLEX_SHORTEDGE" ) )
+ pJobData->meDuplexMode = DUPLEX_SHORTEDGE;
+ else if( aValue.EqualsAscii( "DUPLEX_LONGEDGE" ) )
+ pJobData->meDuplexMode = DUPLEX_LONGEDGE;
+ }
+ else
+ pJobData->maValueMap[ aKey ] = aValue;
}
DBG_ASSERT( rIStream.Tell() == nFirstPos+nLen, "corrupted job setup" );
// ensure correct stream position
@@ -421,6 +437,14 @@ SvStream& operator<<( SvStream& rOStream, const JobSetup& rJobSetup )
rOStream.WriteByteString( it->first, RTL_TEXTENCODING_UTF8 );
rOStream.WriteByteString( it->second, RTL_TEXTENCODING_UTF8 );
}
+ rOStream.WriteByteString( "COMPAT_DUPLEX_MODE" ) ;
+ switch( pJobData->meDuplexMode )
+ {
+ case DUPLEX_UNKNOWN: rOStream.WriteByteString( "DUPLEX_UNKNOWN" );break;
+ case DUPLEX_OFF: rOStream.WriteByteString( "DUPLEX_OFF" );break;
+ case DUPLEX_SHORTEDGE: rOStream.WriteByteString( "DUPLEX_SHORTEDGE" );break;
+ case DUPLEX_LONGEDGE: rOStream.WriteByteString( "DUPLEX_LONGEDGE" );break;
+ }
nLen = sal::static_int_cast<USHORT>(rOStream.Tell() - nPos);
rOStream.Seek( nPos );
rOStream << nLen;
diff --git a/vcl/source/gdi/lineinfo.cxx b/vcl/source/gdi/lineinfo.cxx
index 98f16713a145..7aa50811106b 100644
--- a/vcl/source/gdi/lineinfo.cxx
+++ b/vcl/source/gdi/lineinfo.cxx
@@ -34,6 +34,10 @@
#include <tools/vcompat.hxx>
#include <tools/debug.hxx>
#include <vcl/lineinfo.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+#include <numeric>
DBG_NAME( LineInfo )
@@ -49,7 +53,8 @@ ImplLineInfo::ImplLineInfo() :
mnDashLen ( 0 ),
mnDotCount ( 0 ),
mnDotLen ( 0 ),
- mnDistance ( 0 )
+ mnDistance ( 0 ),
+ meLineJoin ( basegfx::B2DLINEJOIN_ROUND )
{
}
@@ -63,7 +68,8 @@ ImplLineInfo::ImplLineInfo( const ImplLineInfo& rImplLineInfo ) :
mnDashLen ( rImplLineInfo.mnDashLen ),
mnDotCount ( rImplLineInfo.mnDotCount ),
mnDotLen ( rImplLineInfo.mnDotLen ),
- mnDistance ( rImplLineInfo.mnDistance )
+ mnDistance ( rImplLineInfo.mnDistance ),
+ meLineJoin ( rImplLineInfo.meLineJoin )
{
}
@@ -209,6 +215,19 @@ void LineInfo::SetDistance( long nDistance )
// -----------------------------------------------------------------------
+void LineInfo::SetLineJoin(basegfx::B2DLineJoin eLineJoin)
+{
+ DBG_CHKTHIS( LineInfo, NULL );
+
+ if(eLineJoin != mpImplLineInfo->meLineJoin)
+ {
+ ImplMakeUnique();
+ mpImplLineInfo->meLineJoin = eLineJoin;
+ }
+}
+
+// -----------------------------------------------------------------------
+
SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
{
VersionCompat aCompat( rIStm, STREAM_READ );
@@ -225,6 +244,12 @@ SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
rIStm >> rImplLineInfo.mnDistance;
}
+ if( aCompat.GetVersion() >= 3 )
+ {
+ // version 3
+ rIStm >> nTmp16; rImplLineInfo.meLineJoin = (basegfx::B2DLineJoin) nTmp16;
+ }
+
return rIStm;
}
@@ -232,7 +257,7 @@ SvStream& operator>>( SvStream& rIStm, ImplLineInfo& rImplLineInfo )
SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo )
{
- VersionCompat aCompat( rOStm, STREAM_WRITE, 2 );
+ VersionCompat aCompat( rOStm, STREAM_WRITE, 3 );
// version 1
rOStm << (UINT16) rImplLineInfo.meStyle << rImplLineInfo.mnWidth;
@@ -242,6 +267,9 @@ SvStream& operator<<( SvStream& rOStm, const ImplLineInfo& rImplLineInfo )
rOStm << rImplLineInfo.mnDotCount << rImplLineInfo.mnDotLen;
rOStm << rImplLineInfo.mnDistance;
+ // since version3
+ rOStm << (UINT16) rImplLineInfo.meLineJoin;
+
return rOStm;
}
@@ -259,3 +287,78 @@ SvStream& operator<<( SvStream& rOStm, const LineInfo& rLineInfo )
{
return( rOStm << *rLineInfo.mpImplLineInfo );
}
+
+// -----------------------------------------------------------------------
+
+bool LineInfo::isDashDotOrFatLineUsed() const
+{
+ return (LINE_DASH == GetStyle() || GetWidth() > 1);
+}
+
+// -----------------------------------------------------------------------
+
+void LineInfo::applyToB2DPolyPolygon(
+ basegfx::B2DPolyPolygon& io_rLinePolyPolygon,
+ basegfx::B2DPolyPolygon& o_rFillPolyPolygon) const
+{
+ o_rFillPolyPolygon.clear();
+
+ if(io_rLinePolyPolygon.count())
+ {
+ if(LINE_DASH == GetStyle())
+ {
+ ::std::vector< double > fDotDashArray;
+ const double fDashLen(GetDashLen());
+ const double fDotLen(GetDotLen());
+ const double fDistance(GetDistance());
+
+ for(sal_uInt16 a(0); a < GetDashCount(); a++)
+ {
+ fDotDashArray.push_back(fDashLen);
+ fDotDashArray.push_back(fDistance);
+ }
+
+ for(sal_uInt16 b(0); b < GetDotCount(); b++)
+ {
+ fDotDashArray.push_back(fDotLen);
+ fDotDashArray.push_back(fDistance);
+ }
+
+ const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
+
+ if(fAccumulated > 0.0)
+ {
+ basegfx::B2DPolyPolygon aResult;
+
+ for(sal_uInt32 c(0); c < io_rLinePolyPolygon.count(); c++)
+ {
+ basegfx::B2DPolyPolygon aLineTraget;
+ basegfx::tools::applyLineDashing(
+ io_rLinePolyPolygon.getB2DPolygon(c),
+ fDotDashArray,
+ &aLineTraget);
+ aResult.append(aLineTraget);
+ }
+
+ io_rLinePolyPolygon = aResult;
+ }
+ }
+
+ if(GetWidth() > 1 && io_rLinePolyPolygon.count())
+ {
+ const double fHalfLineWidth((GetWidth() * 0.5) + 0.5);
+
+ for(sal_uInt32 a(0); a < io_rLinePolyPolygon.count(); a++)
+ {
+ o_rFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
+ io_rLinePolyPolygon.getB2DPolygon(a),
+ fHalfLineWidth,
+ GetLineJoin()));
+ }
+
+ io_rLinePolyPolygon.clear();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk
index 421505a3d500..ed2a9b2ba1e1 100755..100644
--- a/vcl/source/gdi/makefile.mk
+++ b/vcl/source/gdi/makefile.mk
@@ -57,7 +57,9 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
$(SLO)$/gfxlink.obj \
$(SLO)$/print.obj \
$(SLO)$/print2.obj \
- $(SLO)$/configsettings.obj \
+ $(SLO)$/print3.obj \
+ $(SLO)$/oldprintadaptor.obj \
+ $(SLO)$/configsettings.obj \
$(SLO)$/sallayout.obj \
$(SLO)$/image.obj \
$(SLO)$/impimage.obj \
@@ -72,10 +74,10 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
$(SLO)$/pngread.obj \
$(SLO)$/pngwrite.obj \
$(SLO)$/virdev.obj \
- $(SLO)$/impprn.obj \
$(SLO)$/gdimtf.obj \
$(SLO)$/graphictools.obj \
- $(SLO)$/textlayout.obj
+ $(SLO)$/textlayout.obj \
+ $(SLO)$/lineinfo.obj
SLOFILES= $(EXCEPTIONSFILES) \
$(SLO)$/animate.obj \
@@ -100,8 +102,6 @@ SLOFILES= $(EXCEPTIONSFILES) \
$(SLO)$/impbmp.obj \
$(SLO)$/imagerepository.obj \
$(SLO)$/impvect.obj \
- $(SLO)$/implncvt.obj \
- $(SLO)$/lineinfo.obj \
$(SLO)$/mapmod.obj \
$(SLO)$/metaact.obj \
$(SLO)$/octree.obj \
@@ -119,6 +119,7 @@ SLOFILES= $(EXCEPTIONSFILES) \
$(SLO)$/extoutdevdata.obj \
$(SLO)$/salnativewidgets-none.obj
+
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx
index 82566b2b4362..1f27ad2afe7d 100644
--- a/vcl/source/gdi/metaact.cxx
+++ b/vcl/source/gdi/metaact.cxx
@@ -52,14 +52,6 @@ inline void ImplScalePoint( Point& rPt, double fScaleX, double fScaleY )
// ------------------------------------------------------------------------
-inline void ImplScaleSize( Size& rSz, double fScaleX, double fScaleY )
-{
- rSz.Width() = FRound( fScaleX * rSz.Width() );
- rSz.Height() = FRound( fScaleY * rSz.Height() );
-}
-
-// ------------------------------------------------------------------------
-
inline void ImplScaleRect( Rectangle& rRect, double fScaleX, double fScaleY )
{
Point aTL( rRect.TopLeft() );
@@ -69,6 +61,7 @@ inline void ImplScaleRect( Rectangle& rRect, double fScaleX, double fScaleY )
ImplScalePoint( aBR, fScaleX, fScaleY );
rRect = Rectangle( aTL, aBR );
+ rRect.Justify();
}
// ------------------------------------------------------------------------
@@ -85,7 +78,7 @@ inline void ImplScaleLineInfo( LineInfo& rLineInfo, double fScaleX, double fScal
{
if( !rLineInfo.IsDefault() )
{
- const double fScale = ( fScaleX + fScaleY ) * 0.5;
+ const double fScale = ( fabs(fScaleX) + fabs(fScaleY) ) * 0.5;
rLineInfo.SetWidth( FRound( fScale * rLineInfo.GetWidth() ) );
rLineInfo.SetDashLen( FRound( fScale * rLineInfo.GetDashLen() ) );
@@ -598,8 +591,8 @@ void MetaRoundRectAction::Move( long nHorzMove, long nVertMove )
void MetaRoundRectAction::Scale( double fScaleX, double fScaleY )
{
ImplScaleRect( maRect, fScaleX, fScaleY );
- mnHorzRound = FRound( mnHorzRound * fScaleX );
- mnVertRound = FRound( mnVertRound * fScaleY );
+ mnHorzRound = FRound( mnHorzRound * fabs(fScaleX) );
+ mnVertRound = FRound( mnVertRound * fabs(fScaleY) );
}
// ------------------------------------------------------------------------
@@ -1396,7 +1389,7 @@ void MetaTextArrayAction::Scale( double fScaleX, double fScaleY )
if ( mpDXAry && mnLen )
{
for ( USHORT i = 0, nCount = mnLen; i < nCount; i++ )
- mpDXAry[ i ] = FRound( mpDXAry[ i ] * fScaleX );
+ mpDXAry[ i ] = FRound( mpDXAry[ i ] * fabs(fScaleX) );
}
}
@@ -1524,7 +1517,7 @@ void MetaStretchTextAction::Move( long nHorzMove, long nVertMove )
void MetaStretchTextAction::Scale( double fScaleX, double fScaleY )
{
ImplScalePoint( maPt, fScaleX, fScaleY );
- mnWidth = (ULONG)FRound( mnWidth * fScaleX );
+ mnWidth = (ULONG)FRound( mnWidth * fabs(fScaleX) );
}
// ------------------------------------------------------------------------
@@ -1717,7 +1710,7 @@ void MetaTextLineAction::Move( long nHorzMove, long nVertMove )
void MetaTextLineAction::Scale( double fScaleX, double fScaleY )
{
ImplScalePoint( maPos, fScaleX, fScaleY );
- mnWidth = FRound( mnWidth * fScaleX );
+ mnWidth = FRound( mnWidth * fabs(fScaleX) );
}
// ------------------------------------------------------------------------
@@ -1876,8 +1869,10 @@ void MetaBmpScaleAction::Move( long nHorzMove, long nVertMove )
void MetaBmpScaleAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maPt, fScaleX, fScaleY );
- ImplScaleSize( maSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maPt, maSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maPt = aRectangle.TopLeft();
+ maSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -1953,8 +1948,10 @@ void MetaBmpScalePartAction::Move( long nHorzMove, long nVertMove )
void MetaBmpScalePartAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maDstPt, fScaleX, fScaleY );
- ImplScaleSize( maDstSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maDstPt, maDstSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maDstPt = aRectangle.TopLeft();
+ maDstSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -2099,8 +2096,10 @@ void MetaBmpExScaleAction::Move( long nHorzMove, long nVertMove )
void MetaBmpExScaleAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maPt, fScaleX, fScaleY );
- ImplScaleSize( maSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maPt, maSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maPt = aRectangle.TopLeft();
+ maSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -2176,8 +2175,10 @@ void MetaBmpExScalePartAction::Move( long nHorzMove, long nVertMove )
void MetaBmpExScalePartAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maDstPt, fScaleX, fScaleY );
- ImplScaleSize( maDstSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maDstPt, maDstSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maDstPt = aRectangle.TopLeft();
+ maDstSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -2328,8 +2329,10 @@ void MetaMaskScaleAction::Move( long nHorzMove, long nVertMove )
void MetaMaskScaleAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maPt, fScaleX, fScaleY );
- ImplScaleSize( maSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maPt, maSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maPt = aRectangle.TopLeft();
+ maSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -2408,8 +2411,10 @@ void MetaMaskScalePartAction::Move( long nHorzMove, long nVertMove )
void MetaMaskScalePartAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maDstPt, fScaleX, fScaleY );
- ImplScaleSize( maDstSz, fScaleX, fScaleY );
+ Rectangle aRectangle(maDstPt, maDstSz);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maDstPt = aRectangle.TopLeft();
+ maDstSz = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
@@ -3498,9 +3503,9 @@ MetaAction* MetaFontAction::Clone()
void MetaFontAction::Scale( double fScaleX, double fScaleY )
{
- Size aSize( maFont.GetSize() );
-
- ImplScaleSize( aSize, fScaleX, fScaleY );
+ const Size aSize(
+ FRound(maFont.GetSize().Width() * fabs(fScaleX)),
+ FRound(maFont.GetSize().Height() * fabs(fScaleY)));
maFont.SetSize( aSize );
}
@@ -3791,14 +3796,18 @@ MetaAction* MetaFloatTransparentAction::Clone()
void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove )
{
maPoint.Move( nHorzMove, nVertMove );
+ maMtf.Move(nHorzMove, nVertMove);
}
// ------------------------------------------------------------------------
void MetaFloatTransparentAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maPoint, fScaleX, fScaleY );
- ImplScaleSize( maSize, fScaleX, fScaleY );
+ Rectangle aRectangle(maPoint, maSize);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maPoint = aRectangle.TopLeft();
+ maSize = aRectangle.GetSize();
+ maMtf.Scale(fScaleX, fScaleY);
}
// ------------------------------------------------------------------------
@@ -3872,8 +3881,10 @@ void MetaEPSAction::Move( long nHorzMove, long nVertMove )
void MetaEPSAction::Scale( double fScaleX, double fScaleY )
{
- ImplScalePoint( maPoint, fScaleX, fScaleY );
- ImplScaleSize( maSize, fScaleX, fScaleY );
+ Rectangle aRectangle(maPoint, maSize);
+ ImplScaleRect( aRectangle, fScaleX, fScaleY );
+ maPoint = aRectangle.TopLeft();
+ maSize = aRectangle.GetSize();
}
// ------------------------------------------------------------------------
diff --git a/vcl/source/gdi/oldprintadaptor.cxx b/vcl/source/gdi/oldprintadaptor.cxx
new file mode 100644
index 000000000000..cffd11daaad6
--- /dev/null
+++ b/vcl/source/gdi/oldprintadaptor.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_vcl.hxx"
+
+#include "vcl/oldprintadaptor.hxx"
+#include "vcl/gdimtf.hxx"
+
+#include "com/sun/star/awt/Size.hpp"
+
+#include <vector>
+
+namespace vcl
+{
+ struct AdaptorPage
+ {
+ GDIMetaFile maPage;
+ com::sun::star::awt::Size maPageSize;
+ };
+
+ struct ImplOldStyleAdaptorData
+ {
+ std::vector< AdaptorPage > maPages;
+ };
+}
+
+using namespace vcl;
+using namespace cppu;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+
+OldStylePrintAdaptor::OldStylePrintAdaptor( const boost::shared_ptr< Printer >& i_pPrinter )
+ : PrinterController( i_pPrinter )
+ , mpData( new ImplOldStyleAdaptorData() )
+{
+}
+
+OldStylePrintAdaptor::~OldStylePrintAdaptor()
+{
+}
+
+void OldStylePrintAdaptor::StartPage()
+{
+ Size aPaperSize( getPrinter()->PixelToLogic( getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
+ mpData->maPages.push_back( AdaptorPage() );
+ mpData->maPages.back().maPageSize.Width = aPaperSize.getWidth();
+ mpData->maPages.back().maPageSize.Height = aPaperSize.getHeight();
+ getPrinter()->SetConnectMetaFile( &mpData->maPages.back().maPage );
+
+ // copy state into metafile
+ boost::shared_ptr<Printer> pPrinter( getPrinter() );
+ pPrinter->SetMapMode( pPrinter->GetMapMode() );
+ pPrinter->SetFont( pPrinter->GetFont() );
+ pPrinter->SetDrawMode( pPrinter->GetDrawMode() );
+ pPrinter->SetLineColor( pPrinter->GetLineColor() );
+ pPrinter->SetFillColor( pPrinter->GetFillColor() );
+}
+
+void OldStylePrintAdaptor::EndPage()
+{
+ getPrinter()->SetConnectMetaFile( NULL );
+ mpData->maPages.back().maPage.WindStart();
+}
+
+int OldStylePrintAdaptor::getPageCount() const
+{
+ return int(mpData->maPages.size());
+}
+
+Sequence< PropertyValue > OldStylePrintAdaptor::getPageParameters( int i_nPage ) const
+{
+ Sequence< PropertyValue > aRet( 1 );
+ aRet[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PageSize") );
+ if( i_nPage < int(mpData->maPages.size() ) )
+ aRet[0].Value = makeAny( mpData->maPages[i_nPage].maPageSize );
+ else
+ {
+ awt::Size aEmpty( 0, 0 );
+ aRet[0].Value = makeAny( aEmpty );
+ }
+ return aRet;
+}
+
+void OldStylePrintAdaptor::printPage( int i_nPage ) const
+{
+ if( i_nPage < int(mpData->maPages.size()) )
+ {
+ mpData->maPages[ i_nPage ].maPage.WindStart();
+ mpData->maPages[ i_nPage ].maPage.Play( getPrinter().get() );
+ }
+}
+
diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx
index 6298ff51a16a..91ea8419cba9 100644
--- a/vcl/source/gdi/outdev.cxx
+++ b/vcl/source/gdi/outdev.cxx
@@ -56,7 +56,6 @@
#include <vcl/gdimtf.hxx>
#include <vcl/outdata.hxx>
#include <vcl/print.hxx>
-#include <implncvt.hxx>
#include <vcl/outdev.h>
#include <vcl/outdev.hxx>
#include <vcl/unowrap.hxx>
@@ -77,6 +76,8 @@
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <vcl/unohelp.hxx>
+#include <numeric>
+
using namespace ::com::sun::star;
DBG_NAME( OutputDevice )
@@ -2330,6 +2331,130 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
// -----------------------------------------------------------------------
+void OutputDevice::impPaintLineGeometryWithEvtlExpand(
+ const LineInfo& rInfo,
+ basegfx::B2DPolyPolygon aLinePolyPolygon)
+{
+ const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsLineColor());
+ basegfx::B2DPolyPolygon aFillPolyPolygon;
+ const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
+ const bool bLineWidthUsed(rInfo.GetWidth() > 1);
+
+ if(bDashUsed && aLinePolyPolygon.count())
+ {
+ ::std::vector< double > fDotDashArray;
+ const double fDashLen(rInfo.GetDashLen());
+ const double fDotLen(rInfo.GetDotLen());
+ const double fDistance(rInfo.GetDistance());
+
+ for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
+ {
+ fDotDashArray.push_back(fDashLen);
+ fDotDashArray.push_back(fDistance);
+ }
+
+ for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
+ {
+ fDotDashArray.push_back(fDotLen);
+ fDotDashArray.push_back(fDistance);
+ }
+
+ const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
+
+ if(fAccumulated > 0.0)
+ {
+ basegfx::B2DPolyPolygon aResult;
+
+ for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
+ {
+ basegfx::B2DPolyPolygon aLineTraget;
+ basegfx::tools::applyLineDashing(
+ aLinePolyPolygon.getB2DPolygon(c),
+ fDotDashArray,
+ &aLineTraget);
+ aResult.append(aLineTraget);
+ }
+
+ aLinePolyPolygon = aResult;
+ }
+ }
+
+ if(bLineWidthUsed && aLinePolyPolygon.count())
+ {
+ const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
+
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
+ aLinePolyPolygon.getB2DPolygon(a),
+ fHalfLineWidth,
+ rInfo.GetLineJoin()));
+ }
+
+ aLinePolyPolygon.clear();
+ }
+
+ GDIMetaFile* pOldMetaFile = mpMetaFile;
+ mpMetaFile = NULL;
+
+ if(aLinePolyPolygon.count())
+ {
+ for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
+ {
+ const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
+ bool bDone(false);
+
+ if(bTryAA)
+ {
+ bDone = mpGraphics->DrawPolyLine(aCandidate, basegfx::B2DVector(1.0, 1.0), basegfx::B2DLINEJOIN_NONE, this);
+ }
+
+ if(!bDone)
+ {
+ const Polygon aPolygon(aCandidate);
+ mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
+ }
+ }
+ }
+
+ if(aFillPolyPolygon.count())
+ {
+ const Color aOldLineColor( maLineColor );
+ const Color aOldFillColor( maFillColor );
+
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor( aOldLineColor );
+ ImplInitFillColor();
+
+ bool bDone(false);
+
+ if(bTryAA)
+ {
+ bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
+ }
+
+ if(!bDone)
+ {
+ for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
+ {
+ const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
+ mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
+ }
+ }
+
+ SetFillColor( aOldFillColor );
+ SetLineColor( aOldLineColor );
+ }
+
+ mpMetaFile = pOldMetaFile;
+}
+
+// -----------------------------------------------------------------------
+
void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
const LineInfo& rLineInfo )
{
@@ -2357,47 +2482,22 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
if ( mbOutputClipped )
return;
+ const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
+ const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+ const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
+ const bool bLineWidthUsed(aInfo.GetWidth() > 1);
- if( ( aInfo.GetWidth() > 1L ) || ( LINE_DASH == aInfo.GetStyle() ) )
+ if(bDashUsed || bLineWidthUsed)
{
- Polygon aPoly( 2 ); aPoly[ 0 ] = rStartPt; aPoly[ 1 ] = rEndPt;
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- ImplLineConverter aLineCvt( ImplLogicToDevicePixel( aPoly ), aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
-
- mpMetaFile = NULL;
+ basegfx::B2DPolygon aLinePolygon;
+ aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
+ aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
- if ( aInfo.GetWidth() > 1 )
- {
- const Color aOldLineColor( maLineColor );
- const Color aOldFillColor( maFillColor );
-
- SetLineColor();
- ImplInitLineColor();
- SetFillColor( aOldLineColor );
- ImplInitFillColor();
-
- for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
- mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this );
-
- SetFillColor( aOldFillColor );
- SetLineColor( aOldLineColor );
- }
- else
- {
- if ( mbInitLineColor )
- ImplInitLineColor();
-
- for ( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
- mpGraphics->DrawLine( (*pPoly)[ 0 ].X(), (*pPoly)[ 0 ].Y(), (*pPoly)[ 1 ].X(), (*pPoly)[ 1 ].Y(), this );
- }
- mpMetaFile = pOldMetaFile;
+ impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
}
else
{
- const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
- const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
-
if ( mbInitLineColor )
ImplInitLineColor();
@@ -2546,7 +2646,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo
if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
&& LINE_SOLID == rLineInfo.GetStyle())
{
- DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), basegfx::B2DLINEJOIN_ROUND);
+ DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin());
return;
}
@@ -2558,7 +2658,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo
void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
{
- USHORT nPoints = rPoly.GetSize();
+ USHORT nPoints(rPoly.GetSize());
if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
return;
@@ -2566,11 +2666,19 @@ void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineI
Polygon aPoly = ImplLogicToDevicePixel( rPoly );
// #100127# LineInfo is not curve-safe, subdivide always
- if( aPoly.HasFlags() )
- {
- aPoly = ImplSubdivideBezier( aPoly );
- nPoints = aPoly.GetSize();
- }
+ //
+ // What shall this mean? It's wrong to subdivide here when the
+ // polygon is a fat line. In that case, the painted geometry
+ // WILL be much different.
+ // I also have no idea how this could be related to the given ID
+ // which reads 'consolidate boost versions' in the task description.
+ // Removing.
+ //
+ //if( aPoly.HasFlags() )
+ //{
+ // aPoly = ImplSubdivideBezier( aPoly );
+ // nPoints = aPoly.GetSize();
+ //}
// we need a graphics
if ( !mpGraphics && !ImplGetGraphics() )
@@ -2582,67 +2690,29 @@ void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineI
if ( mbOutputClipped )
return;
- const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
- const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
- && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
- && ROP_OVERPAINT == GetRasterOp()
- && IsLineColor());
-
- if( aInfo.GetWidth() > 1L )
- {
- const Color aOldLineColor( maLineColor );
- const Color aOldFillColor( maFillColor );
- GDIMetaFile* pOldMetaFile = mpMetaFile;
- ImplLineConverter aLineCvt( aPoly, aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
-
- mpMetaFile = NULL;
- SetLineColor();
+ if ( mbInitLineColor )
ImplInitLineColor();
- SetFillColor( aOldLineColor );
- ImplInitFillColor();
- bool bDone(false);
- if(bTryAA)
- {
- // #i101491# try AAed version
- // Use old on-the-fly geometry preparation, combine with AA
- bool bSuccess(true);
-
- for(const Polygon* pPoly = aLineCvt.ImplGetFirst(); bSuccess && pPoly; pPoly = aLineCvt.ImplGetNext())
- {
- bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(pPoly->getB2DPolygon()), 0.0, this);
- }
-
- if(bSuccess)
- {
- bDone = true;
- }
- }
-
- if(!bDone)
- {
- for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
- {
- mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this );
- }
- }
+ const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+ const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
+ const bool bLineWidthUsed(aInfo.GetWidth() > 1);
- SetLineColor( aOldLineColor );
- SetFillColor( aOldFillColor );
- mpMetaFile = pOldMetaFile;
+ if(bDashUsed || bLineWidthUsed)
+ {
+ impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
}
else
{
- if ( mbInitLineColor )
- ImplInitLineColor();
- if ( LINE_DASH == aInfo.GetStyle() )
+ // #100127# the subdivision HAS to be done here since only a pointer
+ // to an array of points is given to the DrawPolyLine method, there is
+ // NO way to find out there that it's a curve.
+ if( aPoly.HasFlags() )
{
- ImplLineConverter aLineCvt( aPoly, aInfo, ( mbRefPoint ) ? &maRefPoint : NULL );
- for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
- mpGraphics->DrawPolyLine( pPoly->GetSize(), (const SalPoint*)pPoly->GetConstPointAry(), this );
+ aPoly = ImplSubdivideBezier( aPoly );
+ nPoints = aPoly.GetSize();
}
- else
- mpGraphics->DrawPolyLine( nPoints, (const SalPoint*) aPoly.GetConstPointAry(), this );
+
+ mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
}
if( mpAlphaVDev )
@@ -3047,7 +3117,12 @@ void OutputDevice::DrawPolyLine(
SetFillColor(aOldLineColor);
ImplInitFillColor();
- ImpDrawPolyPolygonWithB2DPolyPolygon(aAreaPolyPolygon);
+ // draw usig a loop; else the topology will paint a PolyPolygon
+ for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
+ {
+ ImpDrawPolyPolygonWithB2DPolyPolygon(
+ basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
+ }
SetLineColor(aOldLineColor);
ImplInitLineColor();
@@ -3064,14 +3139,15 @@ void OutputDevice::DrawPolyLine(
}
}
}
-
- // fallback to old polygon drawing if needed. This will really
- // use ImplLineConverter, but still try to AA lines
- const Polygon aToolsPolygon( rB2DPolygon );
- LineInfo aLineInfo;
- if( fLineWidth != 0.0 )
- aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
- ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
+ else
+ {
+ // fallback to old polygon drawing if needed
+ const Polygon aToolsPolygon( rB2DPolygon );
+ LineInfo aLineInfo;
+ if( fLineWidth != 0.0 )
+ aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
+ ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
+ }
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index 79986988afd7..2d436ea43659 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -1158,9 +1158,11 @@ void OutputDevice::ImplDraw2ColorFrame( const Rectangle& rRect,
// -----------------------------------------------------------------------
-void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
+bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
const GfxLink& rGfxLink, GDIMetaFile* pSubst )
{
+ bool bDrawn(true);
+
if ( mpMetaFile )
{
GDIMetaFile aSubst;
@@ -1172,20 +1174,20 @@ void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
}
if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
- return;
+ return bDrawn;
if( mbOutputClipped )
- return;
+ return bDrawn;
Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
+
if( !aRect.IsEmpty() )
{
// draw the real EPS graphics
- bool bDrawn = FALSE;
if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
{
if( !mpGraphics && !ImplGetGraphics() )
- return;
+ return bDrawn;
if( mbInitClipRegion )
ImplInitClipRegion();
@@ -1208,4 +1210,6 @@ void OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
if( mpAlphaVDev )
mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
+
+ return bDrawn;
}
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 723f856cac4a..40aa4898ba65 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -63,11 +63,9 @@
#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/util/URL.hpp>
-
-#include "implncvt.hxx"
-
#include "cppuhelper/implbase1.hxx"
#include <icc/sRGB-IEC61966-2.1.hxx>
+#include <vcl/lineinfo.hxx>
using namespace vcl;
using namespace rtl;
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
index 937d966b3978..16f6b53af7a8 100644
--- a/vcl/source/gdi/print.cxx
+++ b/vcl/source/gdi/print.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: print.cxx,v $
- * $Revision: 1.65 $
+ * $Revision: 1.65.114.1 $
*
* This file is part of OpenOffice.org.
*
@@ -31,8 +31,6 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#define _SPOOLPRINTER_EXT
-#define _RMPRINTER_EXT
#define ENABLE_BYTESTRING_STREAM_OPERATORS
#include <list>
@@ -58,7 +56,6 @@
#include <vcl/print.h>
#include <vcl/gdimtf.hxx>
#include <vcl/metaact.hxx>
-#include <vcl/impprn.hxx>
#include <vcl/print.hxx>
#include <comphelper/processfactory.hxx>
@@ -280,7 +277,9 @@ static void ImplInitPrnQueueList()
pSVData->maGDIData.mpPrinterQueueList = new ImplPrnQueueList;
- pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
+ static const char* pEnv = getenv( "SAL_DISABLE_PRINTERLIST" );
+ if( !pEnv || !*pEnv )
+ pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
}
// -----------------------------------------------------------------------
@@ -339,16 +338,20 @@ const QueueInfo* Printer::GetQueueInfo( const String& rPrinterName, bool bStatus
XubString Printer::GetDefaultPrinterName()
{
- ImplSVData* pSVData = ImplGetSVData();
+ static const char* pEnv = getenv( "SAL_DISABLE_DEFAULTPRINTER" );
+ if( !pEnv || !*pEnv )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
- return pSVData->mpDefInst->GetDefaultPrinter();
+ return pSVData->mpDefInst->GetDefaultPrinter();
+ }
+ return XubString();
}
// =======================================================================
void Printer::ImplInitData()
{
- mpPrinterData = new ImplPrivatePrinterData();
mbDevOutput = FALSE;
meOutDevType = OUTDEV_PRINTER;
mbDefPrinter = FALSE;
@@ -366,8 +369,6 @@ void Printer::ImplInitData()
mpInfoPrinter = NULL;
mpPrinter = NULL;
mpDisplayDev = NULL;
- mpQPrinter = NULL;
- mpQMtf = NULL;
mbIsQueuePrinter = FALSE;
mpPrinterOptions = new PrinterOptions;
@@ -414,7 +415,6 @@ void Printer::ImplInit( SalPrinterQueueInfo* pInfo )
mpInfoPrinter = pSVData->mpDefInst->CreateInfoPrinter( pInfo, pJobSetup );
mpPrinter = NULL;
- mpJobPrinter = NULL;
mpJobGraphics = NULL;
ImplUpdateJobSetupPaper( maJobSetup );
@@ -446,7 +446,6 @@ void Printer::ImplInitDisplay( const Window* pWindow )
mpInfoPrinter = NULL;
mpPrinter = NULL;
- mpJobPrinter = NULL;
mpJobGraphics = NULL;
if ( pWindow )
@@ -518,6 +517,26 @@ void Printer::ImplUpdatePageData()
mnOutWidth, mnOutHeight,
maPageOffset.X(), maPageOffset.Y(),
maPaperSize.Width(), maPaperSize.Height() );
+ static const char* pDebugOffset = getenv( "SAL_DBG_PAGEOFFSET" );
+ if( pDebugOffset )
+ {
+ rtl::OString aLine( pDebugOffset );
+ sal_Int32 nIndex = 0;
+ rtl::OString aToken( aLine.getToken( 0, ',', nIndex ) );
+ sal_Int32 nLeft = aToken.toInt32();
+ sal_Int32 nTop = nLeft;
+ if( nIndex > 0 )
+ {
+ aToken = aLine.getToken( 0, ',', nIndex );
+ nTop = aToken.toInt32();
+ }
+ maPageOffset = LogicToPixel( Point( static_cast<long>(nLeft),
+ static_cast<long>(nTop) ),
+ MapMode( MAP_100TH_MM )
+ );
+ mnOutWidth = maPaperSize.Width() - 2*maPageOffset.X();
+ mnOutWidth = maPaperSize.Width() - 2*maPageOffset.Y();
+ }
}
// -----------------------------------------------------------------------
@@ -602,11 +621,6 @@ Printer::~Printer()
{
DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
- DBG_ASSERT( !mpQPrinter, "Printer::~Printer() - QueuePrinter not destroyed" );
- DBG_ASSERT( !mpQMtf, "Printer::~Printer() - QueueMetafile not destroyed" );
-
- delete mpPrinterData;
- mpPrinterData = NULL;
delete mpPrinterOptions;
@@ -653,21 +667,11 @@ Printer::~Printer()
}
// -----------------------------------------------------------------------
-void Printer::SetNextJobIsQuick( bool bQuick )
-{
- mpPrinterData->mbNextJobIsQuick = bQuick;
- if( mpQPrinter )
- mpQPrinter->SetNextJobIsQuick( bQuick );
-}
-
-// -----------------------------------------------------------------------
void Printer::Compat_OldPrinterMetrics( bool bSet )
{
// propagate flag
if( mpInfoPrinter )
mpInfoPrinter->m_bCompatMetrics = bSet;
- if( mpQPrinter )
- mpQPrinter->Compat_OldPrinterMetrics( bSet );
// get new font data
ImplUpdateFontData( TRUE );
@@ -977,12 +981,13 @@ USHORT Printer::GetPaperBin() const
// -----------------------------------------------------------------------
// Map user paper format to a available printer paper formats
-void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup )
+void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup, bool bMatchNearest )
{
ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
int nLandscapeAngle = GetLandscapeAngle();
int nPaperCount = GetPaperInfoCount();
+ bool bFound = false;
PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight);
@@ -995,6 +1000,8 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup )
{
pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
rPaperInfo.getHeight() );
+ pSetupData->meOrientation = ORIENTATION_PORTRAIT;
+ bFound = true;
break;
}
}
@@ -1017,10 +1024,49 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup )
{
pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
rPaperInfo.getHeight() );
+ pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
+ bFound = true;
break;
}
}
}
+
+ if( ! bFound && bMatchNearest )
+ {
+ sal_Int64 nBestMatch = SAL_MAX_INT64;
+ int nBestIndex = 0;
+ Orientation eBestOrientation = ORIENTATION_PORTRAIT;
+ for( int i = 0; i < nPaperCount; i++ )
+ {
+ const PaperInfo& rPaperInfo = GetPaperInfo( i );
+
+ // check protrait match
+ sal_Int64 nDX = pSetupData->mnPaperWidth - rPaperInfo.getWidth();
+ sal_Int64 nDY = pSetupData->mnPaperHeight - rPaperInfo.getHeight();
+ sal_Int64 nMatch = nDX*nDX + nDY*nDY;
+ if( nMatch < nBestMatch )
+ {
+ nBestMatch = nMatch;
+ nBestIndex = i;
+ eBestOrientation = ORIENTATION_PORTRAIT;
+ }
+
+ // check landscape match
+ nDX = pSetupData->mnPaperWidth - rPaperInfo.getHeight();
+ nDY = pSetupData->mnPaperHeight - rPaperInfo.getWidth();
+ nMatch = nDX*nDX + nDY*nDY;
+ if( nMatch < nBestMatch )
+ {
+ nBestMatch = nMatch;
+ nBestIndex = i;
+ eBestOrientation = ORIENTATION_LANDSCAPE;
+ }
+ }
+ const PaperInfo& rBestInfo = GetPaperInfo( nBestIndex );
+ pSetupData->mePaperFormat = ImplGetPaperFormat( rBestInfo.getWidth(),
+ rBestInfo.getHeight() );
+ pSetupData->meOrientation = eBestOrientation;
+ }
}
// -----------------------------------------------------------------------
@@ -1051,7 +1097,7 @@ BOOL Printer::SetPaper( Paper ePaper )
ImplReleaseGraphics();
if ( ePaper == PAPER_USER )
- ImplFindPaperFormatForUserSize( aJobSetup );
+ ImplFindPaperFormatForUserSize( aJobSetup, false );
if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
{
ImplUpdateJobSetupPaper( aJobSetup );
@@ -1072,6 +1118,11 @@ BOOL Printer::SetPaper( Paper ePaper )
BOOL Printer::SetPaperSizeUser( const Size& rSize )
{
+ return SetPaperSizeUser( rSize, false );
+}
+
+BOOL Printer::SetPaperSizeUser( const Size& rSize, bool bMatchNearest )
+{
if ( mbInPrintPage )
return FALSE;
@@ -1095,7 +1146,7 @@ BOOL Printer::SetPaperSizeUser( const Size& rSize )
}
ImplReleaseGraphics();
- ImplFindPaperFormatForUserSize( aJobSetup );
+ ImplFindPaperFormatForUserSize( aJobSetup, bMatchNearest );
// Changing the paper size can also change the orientation!
if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
@@ -1142,7 +1193,44 @@ const PaperInfo& Printer::GetPaperInfo( int nPaper ) const
DuplexMode Printer::GetDuplexMode() const
{
- return mpInfoPrinter ? mpInfoPrinter->GetDuplexMode( maJobSetup.ImplGetConstData() ) : DUPLEX_UNKNOWN;
+ return maJobSetup.ImplGetConstData()->meDuplexMode;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Printer::SetDuplexMode( DuplexMode eDuplex )
+{
+ if ( mbInPrintPage )
+ return FALSE;
+
+ if ( maJobSetup.ImplGetConstData()->meDuplexMode != eDuplex )
+ {
+ JobSetup aJobSetup = maJobSetup;
+ ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
+ pSetupData->meDuplexMode = eDuplex;
+
+ if ( IsDisplayPrinter() )
+ {
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ return TRUE;
+ }
+
+ ImplReleaseGraphics();
+ if ( mpInfoPrinter->SetData( SAL_JOBSET_DUPLEXMODE, pSetupData ) )
+ {
+ ImplUpdateJobSetupPaper( aJobSetup );
+ mbNewJobSetup = TRUE;
+ maJobSetup = aJobSetup;
+ ImplUpdatePageData();
+ ImplUpdateFontList();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ return TRUE;
}
// -----------------------------------------------------------------------
@@ -1184,9 +1272,10 @@ XubString Printer::GetPaperBinName( USHORT nPaperBin ) const
// -----------------------------------------------------------------------
-BOOL Printer::SetCopyCount( USHORT nCopy, BOOL /*bCollate*/ )
+BOOL Printer::SetCopyCount( USHORT nCopy, BOOL bCollate )
{
mnCopyCount = nCopy;
+ mbCollateCopy = bCollate;
return TRUE;
}
@@ -1199,29 +1288,8 @@ void Printer::Error()
// -----------------------------------------------------------------------
-void Printer::StartPrint()
-{
- maStartPrintHdl.Call( this );
-}
-
-// -----------------------------------------------------------------------
-
-void Printer::EndPrint()
-{
- maEndPrintHdl.Call( this );
-}
-
-// -----------------------------------------------------------------------
-
-void Printer::PrintPage()
-{
- maPrintPageHdl.Call( this );
-}
-
-// -----------------------------------------------------------------------
-
-ULONG ImplSalPrinterErrorCodeToVCL( ULONG nError )
+ULONG Printer::ImplSalPrinterErrorCodeToVCL( ULONG nError )
{
ULONG nVCLError;
switch ( nError )
@@ -1247,12 +1315,6 @@ void Printer::ImplEndPrint()
mbPrinting = FALSE;
mnCurPrintPage = 0;
maJobName.Erase();
- if( mpQPrinter ) // not necessarily filled e.g. after AbortJob
- {
- mpQPrinter->Destroy();
- mpQPrinter = NULL;
- }
- EndPrint();
}
// -----------------------------------------------------------------------
@@ -1267,180 +1329,6 @@ IMPL_LINK( Printer, ImplDestroyPrinterAsync, void*, pSalPrinter )
// -----------------------------------------------------------------------
-void Printer::ImplUpdateQuickStatus()
-{
- // remove possibly added "IsQuickJob"
- if( mpPrinterData->mbNextJobIsQuick )
- {
- rtl::OUString aKey( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) );
- // const data means not really const, but change all references
- // to refcounted job setup
- ImplJobSetup* pImpSetup = maJobSetup.ImplGetConstData();
- pImpSetup->maValueMap.erase( aKey );
- mpPrinterData->mbNextJobIsQuick = false;
- }
-}
-
-class QuickGuard
-{
- Printer* mpPrinter;
- public:
- QuickGuard( Printer* pPrn ) : mpPrinter( pPrn ) {}
- ~QuickGuard()
- {
- mpPrinter->ImplUpdateQuickStatus();
- }
-};
-
-BOOL Printer::StartJob( const XubString& rJobName )
-{
- mnError = PRINTER_OK;
-
- if ( IsDisplayPrinter() )
- return FALSE;
-
- if ( IsJobActive() || IsPrinting() )
- return FALSE;
-
- if( mpPrinterData->mbNextJobIsQuick )
- {
- String aKey( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) );
- if( maJobSetup.GetValue( aKey ).Len() == 0 )
- maJobSetup.SetValue( aKey, String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
- }
-
- QuickGuard aQGuard( this );
-
- ULONG nCopies = mnCopyCount;
- BOOL bCollateCopy = mbCollateCopy;
- BOOL bUserCopy = FALSE;
- if ( IsQueuePrinter() )
- {
- if ( ((ImplQPrinter*)this)->IsUserCopy() )
- {
- nCopies = 1;
- bCollateCopy = FALSE;
- }
- }
- else
- {
- if ( nCopies > 1 )
- {
- ULONG nDevCopy;
-
- if ( bCollateCopy )
- nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
- else
- nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );
-
- // Muessen Kopien selber gemacht werden?
- if ( nCopies > nDevCopy )
- {
- bUserCopy = TRUE;
- nCopies = 1;
- bCollateCopy = FALSE;
- }
- }
- else
- bCollateCopy = FALSE;
-
- // we need queue printing
- if( !mnPageQueueSize )
- mnPageQueueSize = 1;
- }
-
- if ( !mnPageQueueSize )
- {
- ImplSVData* pSVData = ImplGetSVData();
- mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
-
- if ( !mpPrinter )
- return FALSE;
-
- XubString* pPrintFile;
- if ( mbPrintFile )
- pPrintFile = &maPrintFile;
- else
- pPrintFile = NULL;
-
- // #125075# StartJob can Reschedule on Windows, sfx
- // depends on IsPrinting() in case of closing a document
- BOOL bSaveNewJobSetup = mbNewJobSetup;
- mbNewJobSetup = FALSE;
- String aSaveJobName = maJobName;
- maJobName = rJobName;
- mnCurPage = 1;
- mnCurPrintPage = 1;
- mbPrinting = TRUE;
-
- if( ! ImplGetSVData()->maGDIData.mbPrinterPullModel )
- {
- // in the pull model the job can only be started when
- // we have collected all pages to be printed
- if ( !mpPrinter->StartJob( pPrintFile, rJobName, Application::GetDisplayName(),
- nCopies, bCollateCopy,
- maJobSetup.ImplGetConstData() ) )
- {
- mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
- if ( !mnError )
- mnError = PRINTER_GENERALERROR;
- pSVData->mpDefInst->DestroyPrinter( mpPrinter );
- mbNewJobSetup = bSaveNewJobSetup;
- maJobName = aSaveJobName;
- mnCurPage = 0;
- mnCurPrintPage = 0;
- mbPrinting = FALSE;
- mpPrinter = NULL;
- return FALSE;
- }
- }
-
- mbJobActive = TRUE;
- StartPrint();
- }
- else
- {
- mpQPrinter = new ImplQPrinter( this );
- if( mpInfoPrinter )
- mpQPrinter->Compat_OldPrinterMetrics( mpInfoPrinter->m_bCompatMetrics );
- mpQPrinter->SetDigitLanguage( GetDigitLanguage() );
- mpQPrinter->SetUserCopy( bUserCopy );
- mpQPrinter->SetPrinterOptions( *mpPrinterOptions );
-
- // #125075# StartJob can Reschedule on Windows, sfx
- // depends on IsPrinting() in case of closing a document
- BOOL bSaveNewJobSetup = mbNewJobSetup;
- mbNewJobSetup = FALSE;
- String aSaveJobName = maJobName;
- maJobName = rJobName;
- mnCurPage = 1;
- mbPrinting = TRUE;
-
- if ( mpQPrinter->StartJob( rJobName ) )
- {
- mbJobActive = TRUE;
- StartPrint();
- mpQPrinter->StartQueuePrint();
- }
- else
- {
- mbNewJobSetup = bSaveNewJobSetup;
- maJobName = aSaveJobName;
- mnCurPage = 0;
- mbPrinting = FALSE;
- mnError = mpQPrinter->GetErrorCode();
- mpQPrinter->Destroy();
- mpQPrinter = NULL;
- return FALSE;
- }
- }
-
-
- return TRUE;
-}
-
-// -----------------------------------------------------------------------
-
BOOL Printer::EndJob()
{
BOOL bRet = FALSE;
@@ -1451,7 +1339,7 @@ BOOL Printer::EndJob()
mbJobActive = FALSE;
- if ( mpPrinter || mpQPrinter )
+ if ( mpPrinter )
{
ImplReleaseGraphics();
@@ -1459,23 +1347,17 @@ BOOL Printer::EndJob()
bRet = TRUE;
- if ( mpPrinter )
- {
- mbPrinting = FALSE;
- mnCurPrintPage = 0;
- maJobName.Erase();
-
- mbDevOutput = FALSE;
- bRet = mpPrinter->EndJob();
- // Hier den Drucker nicht asyncron zerstoeren, da es
- // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
- // und ein Druckerobjekt zerstoert wird
- ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
- mpPrinter = NULL;
- EndPrint();
- }
- else
- mpQPrinter->EndQueuePrint();
+ mbPrinting = FALSE;
+ mnCurPrintPage = 0;
+ maJobName.Erase();
+
+ mbDevOutput = FALSE;
+ bRet = mpPrinter->EndJob();
+ // Hier den Drucker nicht asyncron zerstoeren, da es
+ // W95 nicht verkraftet, wenn gleichzeitig gedruckt wird
+ // und ein Druckerobjekt zerstoert wird
+ ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
+ mpPrinter = NULL;
}
return bRet;
@@ -1494,35 +1376,18 @@ BOOL Printer::AbortJob()
mbInPrintPage = FALSE;
mpJobGraphics = NULL;
- if ( mpPrinter || mpQPrinter )
+ if ( mpPrinter )
{
mbPrinting = FALSE;
mnCurPage = 0;
mnCurPrintPage = 0;
maJobName.Erase();
- if ( mpPrinter )
- {
- ImplReleaseGraphics();
- mbDevOutput = FALSE;
- mpPrinter->AbortJob();
- Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
- mpPrinter = NULL;
- EndPrint();
- }
- else
- {
- mpQPrinter->AbortQueuePrint();
- mpQPrinter->Destroy();
- mpQPrinter = NULL;
- if ( mpQMtf )
- {
- mpQMtf->Clear();
- delete mpQMtf;
- mpQMtf = NULL;
- }
- EndPrint();
- }
+ ImplReleaseGraphics();
+ mbDevOutput = FALSE;
+ mpPrinter->AbortJob();
+ Application::PostUserEvent( LINK( this, Printer, ImplDestroyPrinterAsync ), mpPrinter );
+ mpPrinter = NULL;
return TRUE;
}
@@ -1532,88 +1397,49 @@ BOOL Printer::AbortJob()
// -----------------------------------------------------------------------
-BOOL Printer::StartPage()
+void Printer::ImplStartPage()
{
if ( !IsJobActive() )
- return FALSE;
+ return;
- if ( mpPrinter || mpQPrinter )
+ if ( mpPrinter )
{
- if ( mpPrinter )
- {
- SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
- if ( pGraphics )
- {
- ImplReleaseGraphics();
- mpJobGraphics = pGraphics;
- }
- mbDevOutput = TRUE;
- }
- else
+ SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
+ if ( pGraphics )
{
- ImplGetGraphics();
- mpJobGraphics = mpGraphics;
+ ImplReleaseGraphics();
+ mpJobGraphics = pGraphics;
}
+ mbDevOutput = TRUE;
// PrintJob not aborted ???
if ( IsJobActive() )
{
mbInPrintPage = TRUE;
mnCurPage++;
- if ( mpQPrinter )
- {
- mpQPrinter->SetPrinterOptions( *mpPrinterOptions );
- mpQMtf = new GDIMetaFile;
- mpQMtf->Record( this );
- mpQMtf->SaveStatus();
- }
- else
- {
- mnCurPrintPage++;
- PrintPage();
- }
+ mnCurPrintPage++;
}
-
- return TRUE;
}
-
- return FALSE;
}
// -----------------------------------------------------------------------
-BOOL Printer::EndPage()
+void Printer::ImplEndPage()
{
if ( !IsJobActive() )
- return FALSE;
+ return;
mbInPrintPage = FALSE;
- if ( mpPrinter || mpQPrinter )
+ if ( mpPrinter )
{
- if ( mpPrinter )
- {
- mpPrinter->EndPage();
- ImplReleaseGraphics();
- mbDevOutput = FALSE;
- }
- else if ( mpQPrinter )
- {
- // Eigentuemeruebergang an QPrinter
- mpQMtf->Stop();
- mpQMtf->WindStart();
- GDIMetaFile* pPage = mpQMtf;
- mpQMtf = NULL;
- mpQPrinter->AddQueuePage( pPage, mnCurPage, mbNewJobSetup );
- }
+ mpPrinter->EndPage();
+ ImplReleaseGraphics();
+ mbDevOutput = FALSE;
mpJobGraphics = NULL;
mbNewJobSetup = FALSE;
-
- return TRUE;
}
-
- return FALSE;
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx
index 685f68fe7af3..9d435af5f4b1 100644
--- a/vcl/source/gdi/print2.cxx
+++ b/vcl/source/gdi/print2.cxx
@@ -31,8 +31,6 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#define _SPOOLPRINTER_EXT
-
#include <functional>
#include <algorithm>
#include <utility>
@@ -648,7 +646,9 @@ static bool ImplIsActionHandlingTransparency( const MetaAction& rAct )
bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf,
long nMaxBmpDPIX, long nMaxBmpDPIY,
bool bReduceTransparency, bool bTransparencyAutoMode,
- bool bDownsampleBitmaps )
+ bool bDownsampleBitmaps,
+ const Color& rBackground
+ )
{
MetaAction* pCurrAct;
bool bTransparent( false );
@@ -737,6 +737,20 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf,
bool bStillBackground=true; // true until first non-bg action
nActionNum=0; nLastBgAction=-1;
pCurrAct=const_cast<GDIMetaFile&>(rInMtf).FirstAction();
+ if( rBackground != Color( COL_TRANSPARENT ) )
+ {
+ aBackgroundComponent.aBgColor = rBackground;
+ if( meOutDevType == OUTDEV_PRINTER )
+ {
+ Printer* pThis = dynamic_cast<Printer*>(this);
+ Point aPageOffset = pThis->GetPageOffsetPixel();
+ aPageOffset = Point( 0, 0 ) - aPageOffset;
+ Size aSize = pThis->GetPaperSizePixel();
+ aBackgroundComponent.aBounds = Rectangle( aPageOffset, aSize );
+ }
+ else
+ aBackgroundComponent.aBounds = Rectangle( Point( 0, 0 ), GetOutputSizePixel() );
+ }
while( pCurrAct && bStillBackground )
{
switch( pCurrAct->GetType() )
@@ -880,7 +894,7 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf,
//
// if aBBCurrAct is empty, it will intersect with no
- // aCCList member. Thus, we can safe us the check.
+ // aCCList member. Thus, we can save the check.
// Furthermore, this ensures that non-output-generating
// actions get their own aCCList entry, which is necessary
// when copying them to the output metafile (see stage 4
@@ -1110,7 +1124,7 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf,
// ====================================================
//
- Point aTmpPoint;
+ Point aPageOffset;
Size aTmpSize( GetOutputSizePixel() );
if( mpPDFWriter )
{
@@ -1120,7 +1134,14 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf,
// also add error code to PDFWriter
mpPDFWriter->insertError( vcl::PDFWriter::Warning_Transparency_Converted );
}
- const Rectangle aOutputRect( aTmpPoint, aTmpSize );
+ else if( meOutDevType == OUTDEV_PRINTER )
+ {
+ Printer* pThis = dynamic_cast<Printer*>(this);
+ aPageOffset = pThis->GetPageOffsetPixel();
+ aPageOffset = Point( 0, 0 ) - aPageOffset;
+ aTmpSize = pThis->GetPaperSizePixel();
+ }
+ const Rectangle aOutputRect( aPageOffset, aTmpSize );
bool bTiling = dynamic_cast<Printer*>(this) != NULL;
// iterate over all aCCList members and generate bitmaps for the special ones
@@ -1228,7 +1249,7 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf,
pCurrAct->Execute( &aPaintVDev );
}
- if( !( nActionNum % 4 ) )
+ if( !( nActionNum % 8 ) )
Application::Reschedule();
}
diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx
new file mode 100644
index 000000000000..6778cfbc867e
--- /dev/null
+++ b/vcl/source/gdi/print3.cxx
@@ -0,0 +1,1765 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: print3.cxx,v $
+ * $Revision: 1.1.2.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_vcl.hxx"
+
+#include "vcl/print.hxx"
+#include "vcl/prndlg.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/salinst.hxx"
+#include "vcl/salprn.hxx"
+#include "vcl/svids.hrc"
+#include "vcl/metaact.hxx"
+#include "vcl/msgbox.hxx"
+
+#include "tools/urlobj.hxx"
+
+#include "com/sun/star/ui/dialogs/XFilePicker.hpp"
+#include "com/sun/star/ui/dialogs/XFilterManager.hpp"
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include "com/sun/star/view/DuplexMode.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/awt/Size.hpp"
+#include "comphelper/processfactory.hxx"
+
+#include <hash_map>
+#include <hash_set>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace vcl;
+
+class ImplPageCache
+{
+ struct CacheEntry
+ {
+ GDIMetaFile aPage;
+ PrinterController::PageSize aSize;
+ };
+
+ std::vector< CacheEntry > maPages;
+ std::vector< sal_Int32 > maPageNumbers;
+ std::vector< sal_Int32 > maCacheRanking;
+
+ static const sal_Int32 nCacheSize = 6;
+
+ void updateRanking( sal_Int32 nLastHit )
+ {
+ if( maCacheRanking[0] != nLastHit )
+ {
+ bool bMove = false;
+ for( sal_Int32 i = nCacheSize-1; i > 0; i-- )
+ {
+ if( maCacheRanking[i] == nLastHit )
+ bMove = true;
+ maCacheRanking[i] = maCacheRanking[i-1];
+ }
+ maCacheRanking[0] = nLastHit;
+ }
+ }
+
+public:
+ ImplPageCache()
+ : maPages( nCacheSize )
+ , maPageNumbers( nCacheSize, -1 )
+ , maCacheRanking( nCacheSize )
+ {
+ for( sal_Int32 i = 0; i < nCacheSize; i++ )
+ maCacheRanking[i] = nCacheSize - i - 1;
+ }
+
+ // caution: does not ensure uniqueness
+ void insert( sal_Int32 i_nPageNo, const GDIMetaFile& i_rPage, const PrinterController::PageSize& i_rSize )
+ {
+ sal_Int32 nReplacePage = maCacheRanking.back();
+ maPages[ nReplacePage ].aPage = i_rPage;
+ maPages[ nReplacePage ].aSize = i_rSize;
+ maPageNumbers[ nReplacePage ] = i_nPageNo;
+ // cache insertion means in our case, the page was just queried
+ // so update the ranking
+ updateRanking( nReplacePage );
+ }
+
+ // caution: bad algorithm; should there ever be reason to increase the cache size beyond 6
+ // this needs to be urgently rewritten. However do NOT increase the cache size lightly,
+ // whole pages can be rather memory intensive
+ bool get( sal_Int32 i_nPageNo, GDIMetaFile& o_rPageFile, PrinterController::PageSize& o_rSize )
+ {
+ for( sal_Int32 i = 0; i < nCacheSize; ++i )
+ {
+ if( maPageNumbers[i] == i_nPageNo )
+ {
+ updateRanking( i );
+ o_rPageFile = maPages[i].aPage;
+ o_rSize = maPages[i].aSize;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void invalidate()
+ {
+ for( sal_Int32 i = 0; i < nCacheSize; ++i )
+ {
+ maPageNumbers[i] = -1;
+ maPages[i].aPage.Clear();
+ maCacheRanking[i] = nCacheSize - i - 1;
+ }
+ }
+};
+
+class vcl::ImplPrinterControllerData
+{
+public:
+ struct ControlDependency
+ {
+ rtl::OUString maDependsOnName;
+ sal_Int32 mnDependsOnEntry;
+
+ ControlDependency() : mnDependsOnEntry( -1 ) {}
+ };
+
+ typedef std::hash_map< rtl::OUString, size_t, rtl::OUStringHash > PropertyToIndexMap;
+ typedef std::hash_map< rtl::OUString, ControlDependency, rtl::OUStringHash > ControlDependencyMap;
+
+ boost::shared_ptr<Printer> mpPrinter;
+ Sequence< PropertyValue > maUIOptions;
+ std::vector< PropertyValue > maUIProperties;
+ std::vector< bool > maUIPropertyEnabled;
+ PropertyToIndexMap maPropertyToIndex;
+ Link maOptionChangeHdl;
+ ControlDependencyMap maControlDependencies;
+ sal_Bool mbFirstPage;
+ sal_Bool mbLastPage;
+ sal_Bool mbReversePageOrder;
+ view::PrintableState meJobState;
+
+ vcl::PrinterController::MultiPageSetup maMultiPage;
+
+ vcl::PrintProgressDialog* mpProgress;
+
+ ImplPageCache maPageCache;
+
+ // set by user through printer config dialog
+ // if set, pages are centered and trimmed onto the fixed page
+ Size maFixedPageSize;
+
+ ImplPrinterControllerData() :
+ mbFirstPage( sal_True ),
+ mbLastPage( sal_False ),
+ mbReversePageOrder( sal_False ),
+ meJobState( view::PrintableState_JOB_STARTED ),
+ mpProgress( NULL )
+ {}
+ ~ImplPrinterControllerData() { delete mpProgress; }
+
+ Size getRealPaperSize( const Size& i_rPageSize ) const
+ {
+ if( maFixedPageSize.Width() > 0 && maFixedPageSize.Height() > 0 )
+ return maFixedPageSize;
+ if( maMultiPage.nRows * maMultiPage.nColumns > 1 )
+ return maMultiPage.aPaperSize;
+ return i_rPageSize;
+ }
+ bool isFixedPageSize() const
+ { return maFixedPageSize.Width() != 0 && maFixedPageSize.Height() != 0; }
+ PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps );
+};
+
+PrinterController::PrinterController()
+ : mpImplData( new ImplPrinterControllerData )
+{
+}
+
+PrinterController::PrinterController( const boost::shared_ptr<Printer>& i_pPrinter )
+ : mpImplData( new ImplPrinterControllerData )
+{
+ mpImplData->mpPrinter = i_pPrinter;
+}
+
+static rtl::OUString queryFile( Printer* pPrinter )
+{
+ rtl::OUString aResult;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ if( xFactory.is() )
+ {
+ uno::Sequence< uno::Any > aTempl( 1 );
+ aTempl.getArray()[0] <<= ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION;
+ uno::Reference< ui::dialogs::XFilePicker > xFilePicker(
+ xFactory->createInstanceWithArguments(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ),
+ aTempl ), uno::UNO_QUERY );
+ DBG_ASSERT( xFilePicker.is(), "could not get FilePicker service" );
+
+ uno::Reference< ui::dialogs::XFilterManager > xFilterMgr( xFilePicker, uno::UNO_QUERY );
+ if( xFilePicker.is() && xFilterMgr.is() )
+ {
+ try
+ {
+#ifdef UNX
+ // add PostScript and PDF
+ bool bPS = true, bPDF = true;
+ if( pPrinter )
+ {
+ if( pPrinter->GetCapabilities( PRINTER_CAPABILITIES_PDF ) )
+ bPS = false;
+ else
+ bPDF = false;
+ }
+ if( bPS )
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PostScript" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.ps" ) ) );
+ if( bPDF )
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Portable Document Format" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.pdf" ) ) );
+#elif defined WNT
+ (void)pPrinter;
+ xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.PRN" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ) );
+#endif
+ // add arbitrary files
+ xFilterMgr->appendFilter( String( VclResId( SV_STDTEXT_ALLFILETYPES ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.*" ) ) );
+ }
+ catch( lang::IllegalArgumentException rExc )
+ {
+ DBG_ERRORFILE( "caught IllegalArgumentException when registering filter\n" );
+ }
+
+ if( xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK )
+ {
+ uno::Sequence< ::rtl::OUString > aPathSeq( xFilePicker->getFiles() );
+ INetURLObject aObj( aPathSeq[0] );
+ aResult = aObj.PathToFileName();
+ }
+ }
+ }
+ return aResult;
+}
+
+struct PrintJobAsync
+{
+ boost::shared_ptr<PrinterController> mpController;
+ JobSetup maInitSetup;
+
+ PrintJobAsync( const boost::shared_ptr<PrinterController>& i_pController,
+ const JobSetup& i_rInitSetup
+ )
+ : mpController( i_pController ), maInitSetup( i_rInitSetup )
+ {}
+
+ DECL_LINK( ExecJob, void* );
+};
+
+IMPL_LINK( PrintJobAsync, ExecJob, void*, EMPTYARG )
+{
+ Printer::ImplPrintJob( mpController, maInitSetup );
+
+ // clean up, do not access members after this
+ delete this;
+
+ return 0;
+}
+
+void Printer::PrintJob( const boost::shared_ptr<PrinterController>& i_pController,
+ const JobSetup& i_rInitSetup
+ )
+{
+ sal_Bool bSynchronous = sal_False;
+ beans::PropertyValue* pVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wait" ) ) );
+ if( pVal )
+ pVal->Value >>= bSynchronous;
+
+ if( bSynchronous )
+ ImplPrintJob( i_pController, i_rInitSetup );
+ else
+ {
+ PrintJobAsync* pAsync = new PrintJobAsync( i_pController, i_rInitSetup );
+ Application::PostUserEvent( LINK( pAsync, PrintJobAsync, ExecJob ) );
+ }
+}
+
+void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pController,
+ const JobSetup& i_rInitSetup
+ )
+{
+ boost::shared_ptr<PrinterController> pController( i_pController );
+
+ // check if there is a default printer; if not, show an error box (if appropriate)
+ if( GetDefaultPrinterName().Len() == 0 )
+ {
+ if( pController->isShowDialogs()
+ // && ! pController->isDirectPrint()
+ )
+ {
+ ErrorBox aBox( NULL, VclResId( SV_PRINT_NOPRINTERWARNING ) );
+ aBox.Execute();
+ }
+ pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ),
+ makeAny( sal_False ) );
+ }
+
+ // setup printer
+
+ // if no specific printer is already set, create one
+ if( ! pController->getPrinter() )
+ {
+ boost::shared_ptr<Printer> pPrinter( new Printer( i_rInitSetup.GetPrinterName() ) );
+ pController->setPrinter( pPrinter );
+ }
+
+ // reset last page property
+ i_pController->setLastPage( sal_False );
+
+ // update "PageRange" property inferring from other properties:
+ // case 1: "Pages" set from UNO API ->
+ // setup "Print Selection" and insert "PageRange" attribute
+ // case 2: "All pages" is selected
+ // update "Page range" attribute to have a sensible default,
+ // but leave "All" as selected
+
+ // "Pages" attribute from API is now equivalent to "PageRange"
+ // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
+ // Argh ! That sure needs cleaning up
+ beans::PropertyValue* pContentVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) ) );
+ if( ! pContentVal )
+ pContentVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ) );
+
+ // case 1: UNO API has set "Pages"
+ beans::PropertyValue* pPagesVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pages" ) ) );
+ if( pPagesVal )
+ {
+ rtl::OUString aPagesVal;
+ pPagesVal->Value >>= aPagesVal;
+ if( aPagesVal.getLength() )
+ {
+ // "Pages" attribute from API is now equivalent to "PageRange"
+ // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
+ // Argh ! That sure needs cleaning up
+ if( pContentVal )
+ {
+ pContentVal->Value = makeAny( sal_Int32( 1 ) );
+ i_pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ), pPagesVal->Value );
+ }
+ }
+ }
+ // case 2: is "All" selected ?
+ else if( pContentVal )
+ {
+ sal_Int32 nContent = -1;
+ if( pContentVal->Value >>= nContent )
+ {
+ if( nContent == 0 )
+ {
+ sal_Int32 nPages = i_pController->getPageCount();
+ if( nPages > 0 )
+ {
+ rtl::OUStringBuffer aBuf( 32 );
+ aBuf.appendAscii( "1" );
+ if( nPages > 1 )
+ {
+ aBuf.appendAscii( "-" );
+ aBuf.append( nPages );
+ }
+ i_pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ), makeAny( aBuf.makeStringAndClear() ) );
+ }
+ }
+ }
+ }
+
+ beans::PropertyValue* pReverseVal = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ) );
+ if( pReverseVal )
+ {
+ sal_Bool bReverse = sal_False;
+ pReverseVal->Value >>= bReverse;
+ pController->setReversePrint( bReverse );
+ }
+
+ // in direct print case check whether there is anything to print.
+ // if not, show an errorbox (if appropriate)
+ if( pController->isShowDialogs() && pController->isDirectPrint() )
+ {
+ if( pController->getFilteredPageCount() == 0 )
+ {
+ ErrorBox aBox( NULL, VclResId( SV_PRINT_NOCONTENT ) );
+ aBox.Execute();
+ return;
+ }
+ }
+
+ // check if the printer brings up its own dialog
+ // in that case leave the work to that dialog
+ if( ! pController->getPrinter()->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) &&
+ ! pController->isDirectPrint() &&
+ pController->isShowDialogs()
+ )
+ {
+ try
+ {
+ PrintDialog aDlg( NULL, i_pController );
+ if( ! aDlg.Execute() )
+ {
+ GDIMetaFile aPageFile;
+ i_pController->setLastPage( sal_True );
+ i_pController->getFilteredPageFile( 0, aPageFile );
+ return;
+ }
+ if( aDlg.isPrintToFile() )
+ {
+ rtl::OUString aFile = queryFile( pController->getPrinter().get() );
+ if( ! aFile.getLength() )
+ {
+ GDIMetaFile aPageFile;
+ i_pController->setLastPage( sal_True );
+ i_pController->getFilteredPageFile( 0, aPageFile );
+ return;
+ }
+ pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ),
+ makeAny( aFile ) );
+ }
+ }
+ catch( std::bad_alloc& )
+ {
+ }
+ }
+
+ pController->pushPropertiesToPrinter();
+
+ rtl::OUString aJobName;
+ beans::PropertyValue* pJobNameVal = pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "JobName" ) ) );
+ if( pJobNameVal )
+ pJobNameVal->Value >>= aJobName;
+
+ pController->getPrinter()->StartJob( String( aJobName ), pController );
+
+ pController->jobFinished( pController->getJobState() );
+}
+
+bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl::PrinterController>& i_pController )
+{
+ mnError = PRINTER_OK;
+
+ if ( IsDisplayPrinter() )
+ return FALSE;
+
+ if ( IsJobActive() || IsPrinting() )
+ return FALSE;
+
+ ULONG nCopies = mnCopyCount;
+ bool bCollateCopy = mbCollateCopy;
+ bool bUserCopy = FALSE;
+
+ if ( nCopies > 1 )
+ {
+ ULONG nDevCopy;
+
+ if ( bCollateCopy )
+ nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
+ else
+ nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );
+
+ // need to do copies by hand ?
+ if ( nCopies > nDevCopy )
+ {
+ bUserCopy = TRUE;
+ nCopies = 1;
+ bCollateCopy = FALSE;
+ }
+ }
+ else
+ bCollateCopy = FALSE;
+
+
+ ImplSVData* pSVData = ImplGetSVData();
+ mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
+
+ if ( !mpPrinter )
+ return FALSE;
+
+ // remark: currently it is still possible to use EnablePrintFile and
+ // SetPrintFileName to redirect printout into file
+ // it can be argued that those methods should be removed in favor
+ // of only using the LocalFileName property
+ beans::PropertyValue* pFileValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ) );
+ if( pFileValue )
+ {
+ rtl::OUString aFile;
+ pFileValue->Value >>= aFile;
+ if( aFile.getLength() )
+ {
+ mbPrintFile = TRUE;
+ maPrintFile = aFile;
+ }
+ }
+
+ XubString* pPrintFile = NULL;
+ if ( mbPrintFile )
+ pPrintFile = &maPrintFile;
+
+ maJobName = i_rJobName;
+ mnCurPage = 1;
+ mnCurPrintPage = 1;
+ mbPrinting = TRUE;
+ if( ImplGetSVData()->maGDIData.mbPrinterPullModel )
+ {
+ mbJobActive = TRUE;
+ // sallayer does all necessary page printing
+ // and also handles showing a dialog
+ // that also means it must call jobStarted when the dialog is finished
+ // it also must set the JobState of the Controller
+ if( mpPrinter->StartJob( pPrintFile,
+ i_rJobName,
+ Application::GetDisplayName(),
+ maJobSetup.ImplGetConstData(),
+ *i_pController ) )
+ {
+ EndJob();
+ }
+ else
+ {
+ mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
+ if ( !mnError )
+ mnError = PRINTER_GENERALERROR;
+ pSVData->mpDefInst->DestroyPrinter( mpPrinter );
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ mbPrinting = FALSE;
+ mpPrinter = NULL;
+
+ return false;
+ }
+ }
+ else
+ {
+ // possibly a dialog has been shown
+ // now the real job starts
+ i_pController->setJobState( view::PrintableState_JOB_STARTED );
+ i_pController->jobStarted();
+
+ if( mpPrinter->StartJob( pPrintFile,
+ i_rJobName,
+ Application::GetDisplayName(),
+ nCopies,
+ bCollateCopy,
+ i_pController->isDirectPrint(),
+ maJobSetup.ImplGetConstData() ) )
+ {
+ mbJobActive = TRUE;
+ i_pController->createProgressDialog();
+ int nPages = i_pController->getFilteredPageCount();
+ int nRepeatCount = bUserCopy ? mnCopyCount : 1;
+ for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ )
+ {
+ for( int nPage = 0; nPage < nPages; nPage++ )
+ {
+ if( nPage == nPages-1 && nIteration == nRepeatCount-1 )
+ i_pController->setLastPage( sal_True );
+ i_pController->printFilteredPage( nPage );
+ }
+ // FIXME: duplex ?
+ }
+ EndJob();
+
+ if( i_pController->getJobState() == view::PrintableState_JOB_STARTED )
+ i_pController->setJobState( view::PrintableState_JOB_SPOOLED );
+ }
+ else
+ {
+ mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() );
+ if ( !mnError )
+ mnError = PRINTER_GENERALERROR;
+ i_pController->setJobState( mnError == PRINTER_ABORT
+ ? view::PrintableState_JOB_ABORTED
+ : view::PrintableState_JOB_FAILED );
+ pSVData->mpDefInst->DestroyPrinter( mpPrinter );
+ mnCurPage = 0;
+ mnCurPrintPage = 0;
+ mbPrinting = FALSE;
+ mpPrinter = NULL;
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+PrinterController::~PrinterController()
+{
+ delete mpImplData;
+}
+
+view::PrintableState PrinterController::getJobState() const
+{
+ return mpImplData->meJobState;
+}
+
+void PrinterController::setJobState( view::PrintableState i_eState )
+{
+ mpImplData->meJobState = i_eState;
+}
+
+const boost::shared_ptr<Printer>& PrinterController::getPrinter() const
+{
+ return mpImplData->mpPrinter;
+}
+
+void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter )
+{
+ mpImplData->mpPrinter = i_rPrinter;
+ setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ),
+ makeAny( rtl::OUString( i_rPrinter->GetName() ) ) );
+}
+
+bool PrinterController::setupPrinter( Window* i_pParent )
+{
+ bool bRet = false;
+ if( mpImplData->mpPrinter.get() )
+ {
+ Size aPaperSize( mpImplData->mpPrinter->PixelToLogic(
+ mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
+ bRet = mpImplData->mpPrinter->Setup( i_pParent );
+ if( bRet )
+ {
+ // was the papersize overridden ? if so we need to take action
+ Size aNewPaperSize( mpImplData->mpPrinter->PixelToLogic(
+ mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
+ if( aNewPaperSize != aPaperSize )
+ {
+ mpImplData->maFixedPageSize = aNewPaperSize;
+ mpImplData->maPageCache.invalidate();
+ awt::Size aOverrideSize;
+ aOverrideSize.Width = aNewPaperSize.Width();
+ aOverrideSize.Height = aNewPaperSize.Height();
+ setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OverridePageSize" ) ),
+ makeAny( aOverrideSize ) );
+ }
+ }
+ }
+ return bRet;
+}
+
+PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps )
+{
+ PrinterController::PageSize aPageSize;
+ aPageSize.aSize = mpPrinter->GetPaperSize();
+ for( sal_Int32 nProperty = 0, nPropertyCount = i_rProps.getLength(); nProperty < nPropertyCount; ++nProperty )
+ {
+ if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) )
+ {
+ awt::Size aSize;
+ i_rProps[ nProperty].Value >>= aSize;
+ aPageSize.aSize.Width() = aSize.Width;
+ aPageSize.aSize.Height() = aSize.Height;
+
+ Size aCurSize( mpPrinter->GetPaperSize() );
+ Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) );
+ if( aRealPaperSize != aCurSize )
+ mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() );
+ }
+ if( i_rProps[ nProperty ].Name.equalsAscii( "PageIncludesNonprintableArea" ) )
+ {
+ sal_Bool bVal = sal_False;
+ i_rProps[ nProperty].Value >>= bVal;
+ aPageSize.bFullPaper = static_cast<bool>(bVal);
+ }
+ }
+ return aPageSize;
+}
+
+int PrinterController::getPageCountProtected() const
+{
+ const MapMode aMapMode( MAP_100TH_MM );
+
+ mpImplData->mpPrinter->Push();
+ mpImplData->mpPrinter->SetMapMode( aMapMode );
+ int nPages = getPageCount();
+ mpImplData->mpPrinter->Pop();
+ return nPages;
+}
+
+Sequence< beans::PropertyValue > PrinterController::getPageParametersProtected( int i_nPage ) const
+{
+ const MapMode aMapMode( MAP_100TH_MM );
+
+ mpImplData->mpPrinter->Push();
+ mpImplData->mpPrinter->SetMapMode( aMapMode );
+ Sequence< beans::PropertyValue > aResult( getPageParameters( i_nPage ) );
+ mpImplData->mpPrinter->Pop();
+ return aResult;
+}
+
+PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
+{
+ // update progress if necessary
+ if( mpImplData->mpProgress )
+ {
+ // do nothing if printing is canceled
+ if( mpImplData->mpProgress->isCanceled() )
+ return PrinterController::PageSize();
+ mpImplData->mpProgress->tick();
+ Application::Reschedule( true );
+ }
+
+ if( i_bMayUseCache )
+ {
+ PrinterController::PageSize aPageSize;
+ if( mpImplData->maPageCache.get( i_nUnfilteredPage, o_rMtf, aPageSize ) )
+ {
+ return aPageSize;
+ }
+ }
+ else
+ mpImplData->maPageCache.invalidate();
+
+ o_rMtf.Clear();
+
+ // get page parameters
+ Sequence< PropertyValue > aPageParm( getPageParametersProtected( i_nUnfilteredPage ) );
+ const MapMode aMapMode( MAP_100TH_MM );
+
+ mpImplData->mpPrinter->Push();
+ mpImplData->mpPrinter->SetMapMode( aMapMode );
+
+ // modify job setup if necessary
+ PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm );
+
+ o_rMtf.SetPrefSize( aPageSize.aSize );
+ o_rMtf.SetPrefMapMode( aMapMode );
+
+ mpImplData->mpPrinter->EnableOutput( FALSE );
+
+ o_rMtf.Record( mpImplData->mpPrinter.get() );
+
+ printPage( i_nUnfilteredPage );
+
+ o_rMtf.Stop();
+ o_rMtf.WindStart();
+ mpImplData->mpPrinter->Pop();
+
+ if( i_bMayUseCache )
+ mpImplData->maPageCache.insert( i_nUnfilteredPage, o_rMtf, aPageSize );
+
+ // reset "FirstPage" property to false now we've gotten at least our first one
+ mpImplData->mbFirstPage = sal_False;
+
+ return aPageSize;
+}
+
+static void appendSubPage( GDIMetaFile& o_rMtf, const Rectangle& i_rClipRect, GDIMetaFile& io_rSubPage, bool i_bDrawBorder )
+{
+ // intersect all clipregion actions with our clip rect
+ io_rSubPage.WindStart();
+ io_rSubPage.Clip( i_rClipRect );
+
+ // save gstate
+ o_rMtf.AddAction( new MetaPushAction( PUSH_ALL ) );
+
+ // clip to page rect
+ o_rMtf.AddAction( new MetaClipRegionAction( Region( i_rClipRect ), TRUE ) );
+
+ // append the subpage
+ io_rSubPage.WindStart();
+ io_rSubPage.Play( o_rMtf );
+
+ // restore gstate
+ o_rMtf.AddAction( new MetaPopAction() );
+
+ // draw a border
+ if( i_bDrawBorder )
+ {
+ // save gstate
+ o_rMtf.AddAction( new MetaPushAction( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_CLIPREGION | PUSH_MAPMODE ) );
+ o_rMtf.AddAction( new MetaMapModeAction( MapMode( MAP_100TH_MM ) ) );
+
+ Rectangle aBorderRect( i_rClipRect );
+ o_rMtf.AddAction( new MetaLineColorAction( Color( COL_BLACK ), TRUE ) );
+ o_rMtf.AddAction( new MetaFillColorAction( Color( COL_TRANSPARENT ), FALSE ) );
+ o_rMtf.AddAction( new MetaRectAction( aBorderRect ) );
+
+ // restore gstate
+ o_rMtf.AddAction( new MetaPopAction() );
+ }
+}
+
+PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
+{
+ const MultiPageSetup& rMPS( mpImplData->maMultiPage );
+ int nSubPages = rMPS.nRows * rMPS.nColumns;
+ if( nSubPages < 1 )
+ nSubPages = 1;
+
+ // reverse sheet order
+ if( mpImplData->mbReversePageOrder )
+ {
+ int nDocPages = getFilteredPageCount();
+ i_nFilteredPage = nDocPages - 1 - i_nFilteredPage;
+ }
+
+ // there is no filtering to be done (and possibly the page size of the
+ // original page is to be set), when N-Up is "neutral" that is there is
+ // only one subpage and the margins are 0
+ if( nSubPages == 1 &&
+ rMPS.nLeftMargin == 0 && rMPS.nRightMargin == 0 &&
+ rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 )
+ {
+ PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache );
+ Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize );
+ mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
+ mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
+ if( aPaperSize != aPageSize.aSize )
+ {
+ // user overridden page size, center Metafile
+ o_rMtf.WindStart();
+ long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2;
+ long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2;
+ o_rMtf.Move( nDX, nDY );
+ o_rMtf.WindStart();
+ o_rMtf.SetPrefSize( aPaperSize );
+ aPageSize.aSize = aPaperSize;
+ }
+ return aPageSize;
+ }
+
+ // set last page property really only on the very last page to be rendered
+ // that is on the last subpage of a NUp run
+ sal_Bool bIsLastPage = mpImplData->mbLastPage;
+ mpImplData->mbLastPage = sal_False;
+
+ Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize ) );
+
+ // multi page area: page size minus margins + one time spacing right and down
+ // the added spacing is so each subpage can be calculated including its spacing
+ Size aMPArea( aPaperSize );
+ aMPArea.Width() -= rMPS.nLeftMargin + rMPS.nRightMargin;
+ aMPArea.Width() += rMPS.nHorizontalSpacing;
+ aMPArea.Height() -= rMPS.nTopMargin + rMPS.nBottomMargin;
+ aMPArea.Height() += rMPS.nVerticalSpacing;
+
+ // determine offsets
+ long nAdvX = aMPArea.Width() / rMPS.nColumns;
+ long nAdvY = aMPArea.Height() / rMPS.nRows;
+
+ // determine size of a "cell" subpage, leave a little space around pages
+ Size aSubPageSize( nAdvX - rMPS.nHorizontalSpacing, nAdvY - rMPS.nVerticalSpacing );
+
+ o_rMtf.Clear();
+ o_rMtf.SetPrefSize( aPaperSize );
+ o_rMtf.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
+ o_rMtf.AddAction( new MetaMapModeAction( MapMode( MAP_100TH_MM ) ) );
+
+ int nDocPages = getPageCountProtected();
+ for( int nSubPage = 0; nSubPage < nSubPages; nSubPage++ )
+ {
+ // map current sub page to real page
+ int nPage = (i_nFilteredPage * nSubPages + nSubPage) / rMPS.nRepeat;
+ if( nSubPage == nSubPages-1 ||
+ nPage == nDocPages-1 )
+ {
+ mpImplData->mbLastPage = bIsLastPage;
+ }
+ if( nPage >= 0 && nPage < nDocPages )
+ {
+ GDIMetaFile aPageFile;
+ PrinterController::PageSize aPageSize = getPageFile( nPage, aPageFile, i_bMayUseCache );
+ if( aPageSize.aSize.Width() && aPageSize.aSize.Height() )
+ {
+ long nCellX = 0, nCellY = 0;
+ switch( rMPS.nOrder )
+ {
+ case PrinterController::LRTB:
+ nCellX = (nSubPage % rMPS.nColumns);
+ nCellY = (nSubPage / rMPS.nColumns);
+ break;
+ case PrinterController::TBLR:
+ nCellX = (nSubPage / rMPS.nRows);
+ nCellY = (nSubPage % rMPS.nRows);
+ break;
+ }
+ // scale the metafile down to a sub page size
+ double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width());
+ double fScaleY = double(aSubPageSize.Height())/double(aPageSize.aSize.Height());
+ double fScale = std::min( fScaleX, fScaleY );
+ aPageFile.Scale( fScale, fScale );
+ aPageFile.WindStart();
+
+ // move the subpage so it is centered in its "cell"
+ long nOffX = (aSubPageSize.Width() - long(double(aPageSize.aSize.Width()) * fScale)) / 2;
+ long nOffY = (aSubPageSize.Height() - long(double(aPageSize.aSize.Height()) * fScale)) / 2;
+ long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX;
+ long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY;
+ aPageFile.Move( nX, nY );
+ aPageFile.WindStart();
+ // calculate border rectangle
+ Rectangle aSubPageRect( Point( nX, nY ),
+ Size( long(double(aPageSize.aSize.Width())*fScale),
+ long(double(aPageSize.aSize.Height())*fScale) ) );
+
+ // append subpage to page
+ appendSubPage( o_rMtf, aSubPageRect, aPageFile, rMPS.bDrawBorder );
+ }
+ }
+ }
+ o_rMtf.WindStart();
+
+ // subsequent getPageFile calls have changed the paper, reset it to current value
+ mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
+ mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
+
+ return PrinterController::PageSize( aPaperSize, true );
+}
+
+int PrinterController::getFilteredPageCount()
+{
+ int nDiv = mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns;
+ if( nDiv < 1 )
+ nDiv = 1;
+ return (getPageCountProtected() * mpImplData->maMultiPage.nRepeat + (nDiv-1)) / nDiv;
+}
+
+ULONG PrinterController::removeTransparencies( GDIMetaFile& i_rIn, GDIMetaFile& o_rOut )
+{
+ ULONG nRestoreDrawMode = mpImplData->mpPrinter->GetDrawMode();
+ sal_Int32 nMaxBmpDPIX = mpImplData->mpPrinter->ImplGetDPIX();
+ sal_Int32 nMaxBmpDPIY = mpImplData->mpPrinter->ImplGetDPIY();
+
+ const PrinterOptions& rPrinterOptions = mpImplData->mpPrinter->GetPrinterOptions();
+
+ static const sal_Int32 OPTIMAL_BMP_RESOLUTION = 300;
+ static const sal_Int32 NORMAL_BMP_RESOLUTION = 200;
+
+
+ if( rPrinterOptions.IsReduceBitmaps() )
+ {
+ // calculate maximum resolution for bitmap graphics
+ if( PRINTER_BITMAP_OPTIMAL == rPrinterOptions.GetReducedBitmapMode() )
+ {
+ nMaxBmpDPIX = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIX );
+ nMaxBmpDPIY = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIY );
+ }
+ else if( PRINTER_BITMAP_NORMAL == rPrinterOptions.GetReducedBitmapMode() )
+ {
+ nMaxBmpDPIX = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIX );
+ nMaxBmpDPIY = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIY );
+ }
+ else
+ {
+ nMaxBmpDPIX = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIX );
+ nMaxBmpDPIY = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIY );
+ }
+ }
+
+ // convert to greysacles
+ if( rPrinterOptions.IsConvertToGreyscales() )
+ {
+ mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() |
+ ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT |
+ DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) );
+ }
+
+ // disable transparency output
+ if( rPrinterOptions.IsReduceTransparency() && ( PRINTER_TRANSPARENCY_NONE == rPrinterOptions.GetReducedTransparencyMode() ) )
+ {
+ mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() | DRAWMODE_NOTRANSPARENCY );
+ }
+
+ Color aBg( COL_TRANSPARENT ); // default: let RemoveTransparenciesFromMetaFile do its own background logic
+ if( mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns > 1 )
+ {
+ // in N-Up printing we have no "page" background operation
+ // we also have no way to determine the paper color
+ // so let's go for white, which will kill 99.9% of the real cases
+ aBg = Color( COL_WHITE );
+ }
+ mpImplData->mpPrinter->RemoveTransparenciesFromMetaFile( i_rIn, o_rOut, nMaxBmpDPIX, nMaxBmpDPIY,
+ rPrinterOptions.IsReduceTransparency(),
+ rPrinterOptions.GetReducedTransparencyMode() == PRINTER_TRANSPARENCY_AUTO,
+ rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency(),
+ aBg
+ );
+ return nRestoreDrawMode;
+}
+
+void PrinterController::printFilteredPage( int i_nPage )
+{
+ if( mpImplData->meJobState != view::PrintableState_JOB_STARTED )
+ return;
+
+ GDIMetaFile aPageFile;
+ PrinterController::PageSize aPageSize = getFilteredPageFile( i_nPage, aPageFile );
+
+ if( mpImplData->mpProgress )
+ {
+ // do nothing if printing is canceled
+ if( mpImplData->mpProgress->isCanceled() )
+ {
+ setJobState( view::PrintableState_JOB_ABORTED );
+ return;
+ }
+ }
+
+ // in N-Up printing set the correct page size
+ mpImplData->mpPrinter->SetMapMode( MAP_100TH_MM );
+ // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile()
+ mpImplData->mpPrinter->SetPaperSizeUser( aPageSize.aSize, ! mpImplData->isFixedPageSize() );
+
+ // if full paper are is meant, move the output to accomodate for pageoffset
+ if( aPageSize.bFullPaper )
+ {
+ Point aPageOffset( mpImplData->mpPrinter->GetPageOffset() );
+ aPageFile.WindStart();
+ aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y() );
+ }
+
+ GDIMetaFile aCleanedFile;
+ ULONG nRestoreDrawMode = removeTransparencies( aPageFile, aCleanedFile );
+
+ mpImplData->mpPrinter->EnableOutput( TRUE );
+
+ // actually print the page
+ mpImplData->mpPrinter->ImplStartPage();
+
+ mpImplData->mpPrinter->Push();
+ aCleanedFile.WindStart();
+ aCleanedFile.Play( mpImplData->mpPrinter.get() );
+ mpImplData->mpPrinter->Pop();
+
+ mpImplData->mpPrinter->ImplEndPage();
+
+ mpImplData->mpPrinter->SetDrawMode( nRestoreDrawMode );
+}
+
+void PrinterController::jobStarted()
+{
+}
+
+void PrinterController::jobFinished( view::PrintableState )
+{
+}
+
+void PrinterController::abortJob()
+{
+ setJobState( view::PrintableState_JOB_ABORTED );
+}
+
+void PrinterController::setLastPage( sal_Bool i_bLastPage )
+{
+ mpImplData->mbLastPage = i_bLastPage;
+}
+
+void PrinterController::setReversePrint( sal_Bool i_bReverse )
+{
+ mpImplData->mbReversePageOrder = i_bReverse;
+}
+
+bool PrinterController::getReversePrint() const
+{
+ return mpImplData->mbReversePageOrder;
+}
+
+Sequence< PropertyValue > PrinterController::getJobProperties( const Sequence< PropertyValue >& i_rMergeList ) const
+{
+ std::hash_set< rtl::OUString, rtl::OUStringHash > aMergeSet;
+ size_t nResultLen = size_t(i_rMergeList.getLength()) + mpImplData->maUIProperties.size() + 3;
+ for( int i = 0; i < i_rMergeList.getLength(); i++ )
+ aMergeSet.insert( i_rMergeList[i].Name );
+
+ Sequence< PropertyValue > aResult( nResultLen );
+ for( int i = 0; i < i_rMergeList.getLength(); i++ )
+ aResult[i] = i_rMergeList[i];
+ int nCur = i_rMergeList.getLength();
+ for( size_t i = 0; i < mpImplData->maUIProperties.size(); i++ )
+ {
+ if( aMergeSet.find( mpImplData->maUIProperties[i].Name ) == aMergeSet.end() )
+ aResult[nCur++] = mpImplData->maUIProperties[i];
+ }
+ // append IsFirstPage
+ if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) ) == aMergeSet.end() )
+ {
+ PropertyValue aVal;
+ aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
+ aVal.Value <<= mpImplData->mbFirstPage;
+ aResult[nCur++] = aVal;
+ }
+ // append IsLastPage
+ if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) ) == aMergeSet.end() )
+ {
+ PropertyValue aVal;
+ aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
+ aVal.Value <<= mpImplData->mbLastPage;
+ aResult[nCur++] = aVal;
+ }
+ // append IsPrinter
+ if( aMergeSet.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) ) ) == aMergeSet.end() )
+ {
+ PropertyValue aVal;
+ aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsPrinter" ) );
+ aVal.Value <<= sal_True;
+ aResult[nCur++] = aVal;
+ }
+ aResult.realloc( nCur );
+ return aResult;
+}
+
+const Sequence< beans::PropertyValue >& PrinterController::getUIOptions() const
+{
+ return mpImplData->maUIOptions;
+}
+
+beans::PropertyValue* PrinterController::getValue( const rtl::OUString& i_rProperty )
+{
+ std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
+ mpImplData->maPropertyToIndex.find( i_rProperty );
+ return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL;
+}
+
+const beans::PropertyValue* PrinterController::getValue( const rtl::OUString& i_rProperty ) const
+{
+ std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
+ mpImplData->maPropertyToIndex.find( i_rProperty );
+ return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL;
+}
+
+Sequence< beans::PropertyValue > PrinterController::getValues( const Sequence< rtl::OUString >& i_rNames ) const
+{
+ Sequence< beans::PropertyValue > aRet( i_rNames.getLength() );
+ sal_Int32 nFound = 0;
+ for( sal_Int32 i = 0; i < i_rNames.getLength(); i++ )
+ {
+ const beans::PropertyValue* pVal = getValue( i_rNames[i] );
+ if( pVal )
+ aRet[ nFound++ ] = *pVal;
+ }
+ aRet.realloc( nFound );
+ return aRet;
+}
+
+void PrinterController::setValue( const rtl::OUString& i_rName, const Any& i_rValue )
+{
+ beans::PropertyValue aVal;
+ aVal.Name = i_rName;
+ aVal.Value = i_rValue;
+
+ setValue( aVal );
+}
+
+void PrinterController::setValue( const beans::PropertyValue& i_rValue )
+{
+ std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
+ mpImplData->maPropertyToIndex.find( i_rValue.Name );
+ if( it != mpImplData->maPropertyToIndex.end() )
+ mpImplData->maUIProperties[ it->second ] = i_rValue;
+ else
+ {
+ // insert correct index into property map
+ mpImplData->maPropertyToIndex[ i_rValue.Name ] = mpImplData->maUIProperties.size();
+ mpImplData->maUIProperties.push_back( i_rValue );
+ mpImplData->maUIPropertyEnabled.push_back( true );
+ }
+}
+
+void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_rOptions )
+{
+ DBG_ASSERT( mpImplData->maUIOptions.getLength() == 0, "setUIOptions called twice !" );
+
+ mpImplData->maUIOptions = i_rOptions;
+
+ for( int i = 0; i < i_rOptions.getLength(); i++ )
+ {
+ Sequence< beans::PropertyValue > aOptProp;
+ i_rOptions[i].Value >>= aOptProp;
+ bool bIsEnabled = true;
+ bool bHaveProperty = false;
+ rtl::OUString aPropName;
+ vcl::ImplPrinterControllerData::ControlDependency aDep;
+ for( int n = 0; n < aOptProp.getLength(); n++ )
+ {
+ const beans::PropertyValue& rEntry( aOptProp[ n ] );
+ if( rEntry.Name.equalsAscii( "Property" ) )
+ {
+ PropertyValue aVal;
+ rEntry.Value >>= aVal;
+ DBG_ASSERT( mpImplData->maPropertyToIndex.find( aVal.Name )
+ == mpImplData->maPropertyToIndex.end(), "duplicate property entry" );
+ setValue( aVal );
+ aPropName = aVal.Name;
+ bHaveProperty = true;
+ }
+ else if( rEntry.Name.equalsAscii( "Enabled" ) )
+ {
+ sal_Bool bValue = sal_True;
+ rEntry.Value >>= bValue;
+ bIsEnabled = bValue;
+ }
+ else if( rEntry.Name.equalsAscii( "DependsOnName" ) )
+ {
+ rEntry.Value >>= aDep.maDependsOnName;
+ }
+ else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) )
+ {
+ rEntry.Value >>= aDep.mnDependsOnEntry;
+ }
+ }
+ if( bHaveProperty )
+ {
+ vcl::ImplPrinterControllerData::PropertyToIndexMap::const_iterator it =
+ mpImplData->maPropertyToIndex.find( aPropName );
+ // sanity check
+ if( it != mpImplData->maPropertyToIndex.end() )
+ {
+ mpImplData->maUIPropertyEnabled[ it->second ] = bIsEnabled;
+ }
+ if( aDep.maDependsOnName.getLength() > 0 )
+ mpImplData->maControlDependencies[ aPropName ] = aDep;
+ }
+ }
+}
+
+void PrinterController::enableUIOption( const rtl::OUString& i_rProperty, bool i_bEnable )
+{
+ std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it =
+ mpImplData->maPropertyToIndex.find( i_rProperty );
+ if( it != mpImplData->maPropertyToIndex.end() )
+ {
+ // call handler only for actual changes
+ if( ( mpImplData->maUIPropertyEnabled[ it->second ] && ! i_bEnable ) ||
+ ( ! mpImplData->maUIPropertyEnabled[ it->second ] && i_bEnable ) )
+ {
+ mpImplData->maUIPropertyEnabled[ it->second ] = i_bEnable;
+ rtl::OUString aPropName( i_rProperty );
+ mpImplData->maOptionChangeHdl.Call( &aPropName );
+ }
+ }
+}
+
+bool PrinterController::isUIOptionEnabled( const rtl::OUString& i_rProperty ) const
+{
+ bool bEnabled = false;
+ std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator prop_it =
+ mpImplData->maPropertyToIndex.find( i_rProperty );
+ if( prop_it != mpImplData->maPropertyToIndex.end() )
+ {
+ bEnabled = mpImplData->maUIPropertyEnabled[prop_it->second];
+
+ if( bEnabled )
+ {
+ // check control dependencies
+ vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
+ mpImplData->maControlDependencies.find( i_rProperty );
+ if( it != mpImplData->maControlDependencies.end() )
+ {
+ // check if the dependency is enabled
+ // if the dependency is disabled, we are too
+ bEnabled = isUIOptionEnabled( it->second.maDependsOnName );
+
+ if( bEnabled )
+ {
+ // does the dependency have the correct value ?
+ const com::sun::star::beans::PropertyValue* pVal = getValue( it->second.maDependsOnName );
+ OSL_ENSURE( pVal, "unknown property in dependency" );
+ if( pVal )
+ {
+ sal_Int32 nDepVal = 0;
+ sal_Bool bDepVal = sal_False;
+ if( pVal->Value >>= nDepVal )
+ {
+ bEnabled = (nDepVal == it->second.mnDependsOnEntry) || (it->second.mnDependsOnEntry == -1);
+ }
+ else if( pVal->Value >>= bDepVal )
+ {
+ // could be a dependency on a checked boolean
+ // in this case the dependency is on a non zero for checked value
+ bEnabled = ( bDepVal && it->second.mnDependsOnEntry != 0) ||
+ ( ! bDepVal && it->second.mnDependsOnEntry == 0);
+ }
+ else
+ {
+ // if the type does not match something is awry
+ OSL_ENSURE( 0, "strange type in control dependency" );
+ bEnabled = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ return bEnabled;
+}
+
+rtl::OUString PrinterController::getDependency( const rtl::OUString& i_rProperty ) const
+{
+ rtl::OUString aDependency;
+
+ vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
+ mpImplData->maControlDependencies.find( i_rProperty );
+ if( it != mpImplData->maControlDependencies.end() )
+ aDependency = it->second.maDependsOnName;
+
+ return aDependency;
+}
+
+rtl::OUString PrinterController::makeEnabled( const rtl::OUString& i_rProperty )
+{
+ rtl::OUString aDependency;
+
+ vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
+ mpImplData->maControlDependencies.find( i_rProperty );
+ if( it != mpImplData->maControlDependencies.end() )
+ {
+ if( isUIOptionEnabled( it->second.maDependsOnName ) )
+ {
+ aDependency = it->second.maDependsOnName;
+ const com::sun::star::beans::PropertyValue* pVal = getValue( aDependency );
+ OSL_ENSURE( pVal, "unknown property in dependency" );
+ if( pVal )
+ {
+ sal_Int32 nDepVal = 0;
+ sal_Bool bDepVal = sal_False;
+ if( pVal->Value >>= nDepVal )
+ {
+ if( it->second.mnDependsOnEntry != -1 )
+ {
+ setValue( aDependency, makeAny( sal_Int32( it->second.mnDependsOnEntry ) ) );
+ }
+ }
+ else if( pVal->Value >>= bDepVal )
+ {
+ setValue( aDependency, makeAny( sal_Bool( it->second.mnDependsOnEntry != 0 ) ) );
+ }
+ else
+ {
+ // if the type does not match something is awry
+ OSL_ENSURE( 0, "strange type in control dependency" );
+ }
+ }
+ }
+ }
+
+ return aDependency;
+}
+
+void PrinterController::setOptionChangeHdl( const Link& i_rHdl )
+{
+ mpImplData->maOptionChangeHdl = i_rHdl;
+}
+
+void PrinterController::createProgressDialog()
+{
+ if( ! mpImplData->mpProgress )
+ {
+ sal_Bool bShow = sal_True;
+ beans::PropertyValue* pMonitor = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MonitorVisible" ) ) );
+ if( pMonitor )
+ pMonitor->Value >>= bShow;
+ else
+ {
+ const com::sun::star::beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ) );
+ if( pVal )
+ {
+ sal_Bool bApi = sal_False;
+ pVal->Value >>= bApi;
+ bShow = ! bApi;
+ }
+ }
+
+ if( bShow && ! Application::IsHeadlessModeEnabled() )
+ {
+ mpImplData->mpProgress = new PrintProgressDialog( NULL, getPageCountProtected() );
+ mpImplData->mpProgress->Show();
+ }
+ }
+}
+
+void PrinterController::setMultipage( const MultiPageSetup& i_rMPS )
+{
+ mpImplData->maMultiPage = i_rMPS;
+}
+
+const PrinterController::MultiPageSetup& PrinterController::getMultipage() const
+{
+ return mpImplData->maMultiPage;
+}
+
+void PrinterController::pushPropertiesToPrinter()
+{
+ sal_Int32 nCopyCount = 1;
+ // set copycount and collate
+ const beans::PropertyValue* pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) );
+ if( pVal )
+ pVal->Value >>= nCopyCount;
+ sal_Bool bCollate = sal_False;
+ pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) );
+ if( pVal )
+ pVal->Value >>= bCollate;
+ mpImplData->mpPrinter->SetCopyCount( static_cast<USHORT>(nCopyCount), bCollate );
+
+ // duplex mode
+ pVal = getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DuplexMode" ) ) );
+ if( pVal )
+ {
+ sal_Int16 nDuplex = view::DuplexMode::UNKNOWN;
+ pVal->Value >>= nDuplex;
+ switch( nDuplex )
+ {
+ case view::DuplexMode::OFF: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_OFF ); break;
+ case view::DuplexMode::LONGEDGE: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_LONGEDGE ); break;
+ case view::DuplexMode::SHORTEDGE: mpImplData->mpPrinter->SetDuplexMode( DUPLEX_SHORTEDGE ); break;
+ }
+ }
+}
+
+bool PrinterController::isShowDialogs() const
+{
+ sal_Bool bApi = getBoolProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsApi" ) ), sal_False );
+ return ! bApi && ! Application::IsHeadlessModeEnabled();
+}
+
+bool PrinterController::isDirectPrint() const
+{
+ sal_Bool bDirect = getBoolProperty( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDirect" ) ), sal_False );
+ return bDirect == sal_True;
+}
+
+sal_Bool PrinterController::getBoolProperty( const rtl::OUString& i_rProperty, sal_Bool i_bFallback ) const
+{
+ sal_Bool bRet = i_bFallback;
+ const com::sun::star::beans::PropertyValue* pVal = getValue( i_rProperty );
+ if( pVal )
+ pVal->Value >>= bRet;
+ return bRet;
+}
+
+/*
+ * PrinterOptionsHelper
+**/
+Any PrinterOptionsHelper::getValue( const rtl::OUString& i_rPropertyName ) const
+{
+ Any aRet;
+ std::hash_map< rtl::OUString, Any, rtl::OUStringHash >::const_iterator it =
+ m_aPropertyMap.find( i_rPropertyName );
+ if( it != m_aPropertyMap.end() )
+ aRet = it->second;
+ return aRet;
+}
+
+void PrinterOptionsHelper::setValue( const rtl::OUString& i_rPropertyName, const Any& i_rValue )
+{
+ m_aPropertyMap[ i_rPropertyName ] = i_rValue;
+}
+
+bool PrinterOptionsHelper::hasProperty( const rtl::OUString& i_rPropertyName ) const
+{
+ Any aRet;
+ std::hash_map< rtl::OUString, Any, rtl::OUStringHash >::const_iterator it =
+ m_aPropertyMap.find( i_rPropertyName );
+ return it != m_aPropertyMap.end();
+}
+
+sal_Bool PrinterOptionsHelper::getBoolValue( const rtl::OUString& i_rPropertyName, sal_Bool i_bDefault ) const
+{
+ sal_Bool bRet = sal_False;
+ Any aVal( getValue( i_rPropertyName ) );
+ return (aVal >>= bRet) ? bRet : i_bDefault;
+}
+
+sal_Int64 PrinterOptionsHelper::getIntValue( const rtl::OUString& i_rPropertyName, sal_Int64 i_nDefault ) const
+{
+ sal_Int64 nRet = 0;
+ Any aVal( getValue( i_rPropertyName ) );
+ return (aVal >>= nRet) ? nRet : i_nDefault;
+}
+
+rtl::OUString PrinterOptionsHelper::getStringValue( const rtl::OUString& i_rPropertyName, const rtl::OUString& i_rDefault ) const
+{
+ rtl::OUString aRet;
+ Any aVal( getValue( i_rPropertyName ) );
+ return (aVal >>= aRet) ? aRet : i_rDefault;
+}
+
+bool PrinterOptionsHelper::processProperties( const Sequence< PropertyValue >& i_rNewProp,
+ std::set< rtl::OUString >* o_pChangeProp )
+{
+ bool bChanged = false;
+
+ // clear the changed set
+ if( o_pChangeProp )
+ o_pChangeProp->clear();
+
+ sal_Int32 nElements = i_rNewProp.getLength();
+ const PropertyValue* pVals = i_rNewProp.getConstArray();
+ for( sal_Int32 i = 0; i < nElements; i++ )
+ {
+ bool bElementChanged = false;
+ std::hash_map< rtl::OUString, Any, rtl::OUStringHash >::iterator it =
+ m_aPropertyMap.find( pVals[ i ].Name );
+ if( it != m_aPropertyMap.end() )
+ {
+ if( it->second != pVals[ i ].Value )
+ bElementChanged = true;
+ }
+ else
+ bElementChanged = true;
+
+ if( bElementChanged )
+ {
+ if( o_pChangeProp )
+ o_pChangeProp->insert( pVals[ i ].Name );
+ m_aPropertyMap[ pVals[i].Name ] = pVals[i].Value;
+ bChanged = true;
+ }
+ }
+ return bChanged;
+}
+
+void PrinterOptionsHelper::appendPrintUIOptions( uno::Sequence< beans::PropertyValue >& io_rProps ) const
+{
+ if( m_aUIProperties.getLength() > 0 )
+ {
+ sal_Int32 nIndex = io_rProps.getLength();
+ io_rProps.realloc( nIndex+1 );
+ PropertyValue aVal;
+ aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ExtraPrintUIOptions" ) );
+ aVal.Value = makeAny( m_aUIProperties );
+ io_rProps[ nIndex ] = aVal;
+ }
+}
+
+Any PrinterOptionsHelper::getUIControlOpt( const rtl::OUString& i_rTitle,
+ const Sequence< rtl::OUString >& i_rHelpTexts,
+ const rtl::OUString& i_rType,
+ const PropertyValue* i_pVal,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ sal_Int32 nElements =
+ 1 // ControlType
+ + (i_rTitle.getLength() ? 1 : 0) // Text
+ + (i_rHelpTexts.getLength() ? 1 : 0) // HelpText
+ + (i_pVal ? 1 : 0) // Property
+ + i_rControlOptions.maAddProps.getLength() // additional props
+ + (i_rControlOptions.maGroupHint.getLength() ? 1 : 0) // grouping
+ + (i_rControlOptions.mbInternalOnly ? 1 : 0) // internal hint
+ + (i_rControlOptions.mbEnabled ? 0 : 1) // enabled
+ ;
+ if( i_rControlOptions.maDependsOnName.getLength() )
+ {
+ nElements += 1;
+ if( i_rControlOptions.mnDependsOnEntry != -1 )
+ nElements += 1;
+ if( i_rControlOptions.mbAttachToDependency )
+ nElements += 1;
+ }
+
+ Sequence< PropertyValue > aCtrl( nElements );
+ sal_Int32 nUsed = 0;
+ if( i_rTitle.getLength() )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rTitle );
+ }
+ if( i_rHelpTexts.getLength() )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rHelpTexts );
+ }
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlType" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rType );
+ if( i_pVal )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Property" ) );
+ aCtrl[nUsed++].Value = makeAny( *i_pVal );
+ }
+ if( i_rControlOptions.maDependsOnName.getLength() )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DependsOnName" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rControlOptions.maDependsOnName );
+ if( i_rControlOptions.mnDependsOnEntry != -1 )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DependsOnEntry" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rControlOptions.mnDependsOnEntry );
+ }
+ if( i_rControlOptions.mbAttachToDependency )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AttachToDependency" ) );
+ aCtrl[nUsed++].Value = makeAny( i_rControlOptions.mbAttachToDependency );
+ }
+ }
+ if( i_rControlOptions.maGroupHint.getLength() )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GroupingHint" ) );
+ aCtrl[nUsed++].Value <<= i_rControlOptions.maGroupHint;
+ }
+ if( i_rControlOptions.mbInternalOnly )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InternalUIOnly" ) );
+ aCtrl[nUsed++].Value <<= sal_True;
+ }
+ if( ! i_rControlOptions.mbEnabled )
+ {
+ aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enabled" ) );
+ aCtrl[nUsed++].Value <<= sal_False;
+ }
+
+ sal_Int32 nAddProps = i_rControlOptions.maAddProps.getLength();
+ for( sal_Int32 i = 0; i < nAddProps; i++ )
+ aCtrl[ nUsed++ ] = i_rControlOptions.maAddProps[i];
+
+ DBG_ASSERT( nUsed == nElements, "nUsed != nElements, probable heap corruption" );
+
+ return makeAny( aCtrl );
+}
+
+Any PrinterOptionsHelper::getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpText )
+{
+ Sequence< rtl::OUString > aHelpText;
+ if( i_rHelpText.getLength() > 0 )
+ {
+ aHelpText.realloc( 1 );
+ *aHelpText.getArray() = i_rHelpText;
+ }
+ return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) );
+}
+
+Any PrinterOptionsHelper::getSubgroupControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ Sequence< rtl::OUString > aHelpText;
+ if( i_rHelpText.getLength() > 0 )
+ {
+ aHelpText.realloc( 1 );
+ *aHelpText.getArray() = i_rHelpText;
+ }
+ return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Subgroup" ) ),
+ NULL, i_rControlOptions );
+}
+
+Any PrinterOptionsHelper::getBoolControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ sal_Bool i_bValue,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ Sequence< rtl::OUString > aHelpText;
+ if( i_rHelpText.getLength() > 0 )
+ {
+ aHelpText.realloc( 1 );
+ *aHelpText.getArray() = i_rHelpText;
+ }
+ PropertyValue aVal;
+ aVal.Name = i_rProperty;
+ aVal.Value = makeAny( i_bValue );
+ return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bool" ) ), &aVal, i_rControlOptions );
+}
+
+Any PrinterOptionsHelper::getChoiceControlOpt( const rtl::OUString& i_rTitle,
+ const Sequence< rtl::OUString >& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ const Sequence< rtl::OUString >& i_rChoices,
+ sal_Int32 i_nValue,
+ const rtl::OUString& i_rType,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ UIControlOptions aOpt( i_rControlOptions );
+ sal_Int32 nUsed = aOpt.maAddProps.getLength();
+ aOpt.maAddProps.realloc( nUsed + 1 );
+ aOpt.maAddProps[nUsed].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Choices" ) );
+ aOpt.maAddProps[nUsed].Value = makeAny( i_rChoices );
+
+ PropertyValue aVal;
+ aVal.Name = i_rProperty;
+ aVal.Value = makeAny( i_nValue );
+ return getUIControlOpt( i_rTitle, i_rHelpText, i_rType, &aVal, aOpt );
+}
+
+Any PrinterOptionsHelper::getRangeControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ sal_Int32 i_nValue,
+ sal_Int32 i_nMinValue,
+ sal_Int32 i_nMaxValue,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ UIControlOptions aOpt( i_rControlOptions );
+ if( i_nMaxValue >= i_nMinValue )
+ {
+ sal_Int32 nUsed = aOpt.maAddProps.getLength();
+ aOpt.maAddProps.realloc( nUsed + 2 );
+ aOpt.maAddProps[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MinValue" ) );
+ aOpt.maAddProps[nUsed++].Value = makeAny( i_nMinValue );
+ aOpt.maAddProps[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxValue" ) );
+ aOpt.maAddProps[nUsed++].Value = makeAny( i_nMaxValue );
+ }
+
+ Sequence< rtl::OUString > aHelpText;
+ if( i_rHelpText.getLength() > 0 )
+ {
+ aHelpText.realloc( 1 );
+ *aHelpText.getArray() = i_rHelpText;
+ }
+ PropertyValue aVal;
+ aVal.Name = i_rProperty;
+ aVal.Value = makeAny( i_nValue );
+ return getUIControlOpt( i_rTitle,
+ aHelpText,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Range" ) ),
+ &aVal,
+ aOpt
+ );
+}
+
+Any PrinterOptionsHelper::getEditControlOpt( const rtl::OUString& i_rTitle,
+ const rtl::OUString& i_rHelpText,
+ const rtl::OUString& i_rProperty,
+ const rtl::OUString& i_rValue,
+ const PrinterOptionsHelper::UIControlOptions& i_rControlOptions
+ )
+{
+ Sequence< rtl::OUString > aHelpText;
+ if( i_rHelpText.getLength() > 0 )
+ {
+ aHelpText.realloc( 1 );
+ *aHelpText.getArray() = i_rHelpText;
+ }
+ PropertyValue aVal;
+ aVal.Name = i_rProperty;
+ aVal.Value = makeAny( i_rValue );
+ return getUIControlOpt( i_rTitle,
+ aHelpText,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Edit" ) ),
+ &aVal,
+ i_rControlOptions
+ );
+}
diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx
index 642690a8d32d..0eb25bdfa130 100644
--- a/vcl/source/gdi/region.cxx
+++ b/vcl/source/gdi/region.cxx
@@ -50,6 +50,7 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
// =======================================================================
//
@@ -1304,9 +1305,7 @@ void Region::Move( long nHorzMove, long nVertMove )
mpImplRegion->mpPolyPoly->Move( nHorzMove, nVertMove );
else if( mpImplRegion->mpB2DPolyPoly )
{
- ::basegfx::B2DHomMatrix aTransform;
- aTransform.translate( nHorzMove, nVertMove );
- mpImplRegion->mpB2DPolyPoly->transform( aTransform );
+ mpImplRegion->mpB2DPolyPoly->transform(basegfx::tools::createTranslateB2DHomMatrix(nHorzMove, nVertMove));
}
else
{
@@ -1347,9 +1346,7 @@ void Region::Scale( double fScaleX, double fScaleY )
mpImplRegion->mpPolyPoly->Scale( fScaleX, fScaleY );
else if( mpImplRegion->mpB2DPolyPoly )
{
- ::basegfx::B2DHomMatrix aTransform;
- aTransform.scale( fScaleX, fScaleY );
- mpImplRegion->mpB2DPolyPoly->transform( aTransform );
+ mpImplRegion->mpB2DPolyPoly->transform(basegfx::tools::createScaleB2DHomMatrix(fScaleX, fScaleY));
}
else
{
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index e71c47d61c54..9934e2f39873 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -52,7 +52,6 @@
#include <vcl/gdimtf.hxx>
#include <vcl/outdata.hxx>
#include <vcl/print.hxx>
-#include <implncvt.hxx>
#include <vcl/outdev.h>
#include <vcl/outdev.hxx>
#include <vcl/unowrap.hxx>
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index d937d15ce7df..cb823fc912cd 100755
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -41,6 +41,7 @@
#include <vcl/sallayout.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <i18npool/lang.h>
#ifndef _TL_DEBUG_HXX
@@ -890,10 +891,8 @@ bool SalLayout::GetOutline( SalGraphics& rSalGraphics,
{
if( aPos.X() || aPos.Y() )
{
- ::basegfx::B2DHomMatrix aMatrix;
- aMatrix.translate( aPos.X(), aPos.Y() );
- aGlyphOutline.transform( aMatrix );
- }
+ aGlyphOutline.transform(basegfx::tools::createTranslateB2DHomMatrix(aPos.X(), aPos.Y()));
+ }
// insert outline at correct position
rVector.push_back( aGlyphOutline );
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
index f1c532a9295f..a13e272e368b 100644
--- a/vcl/source/gdi/virdev.cxx
+++ b/vcl/source/gdi/virdev.cxx
@@ -359,27 +359,40 @@ BOOL VirtualDevice::SetOutputSizePixel( const Size& rNewSize, BOOL bErase )
// -----------------------------------------------------------------------
-void VirtualDevice::SetReferenceDevice( RefDevMode eRefDevMode )
+void VirtualDevice::SetReferenceDevice( RefDevMode i_eRefDevMode )
{
- switch( eRefDevMode )
+ sal_Int32 nDPIX = 600, nDPIY = 600;
+ switch( i_eRefDevMode )
{
case REFDEV_NONE:
default:
DBG_ASSERT( FALSE, "VDev::SetRefDev illegal argument!" );
- // fall through
+ break;
case REFDEV_MODE06:
- mnDPIX = mnDPIY = 600;
+ nDPIX = nDPIY = 600;
break;
case REFDEV_MODE48:
- mnDPIX = mnDPIY = 4800;
+ nDPIX = nDPIY = 4800;
break;
case REFDEV_MODE_MSO1:
- mnDPIX = mnDPIY = 6*1440;
+ nDPIX = nDPIY = 6*1440;
break;
case REFDEV_MODE_PDF1:
- mnDPIX = mnDPIY = 720;
+ nDPIX = nDPIY = 720;
break;
}
+ ImplSetReferenceDevice( i_eRefDevMode, nDPIX, nDPIY );
+}
+
+void VirtualDevice::SetReferenceDevice( sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
+{
+ ImplSetReferenceDevice( REFDEV_CUSTOM, i_nDPIX, i_nDPIY );
+}
+
+void VirtualDevice::ImplSetReferenceDevice( RefDevMode i_eRefDevMode, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
+{
+ mnDPIX = i_nDPIX;
+ mnDPIY = i_nDPIY;
EnableOutput( FALSE ); // prevent output on reference device
mbScreenComp = FALSE;
@@ -391,7 +404,7 @@ void VirtualDevice::SetReferenceDevice( RefDevMode eRefDevMode )
// avoid adjusting font lists when already in refdev mode
BYTE nOldRefDevMode = meRefDevMode;
BYTE nOldCompatFlag = (BYTE)meRefDevMode & REFDEV_FORCE_ZERO_EXTLEAD;
- meRefDevMode = (BYTE)(eRefDevMode | nOldCompatFlag);
+ meRefDevMode = (BYTE)(i_eRefDevMode | nOldCompatFlag);
if( (nOldRefDevMode ^ nOldCompatFlag) != REFDEV_NONE )
return;
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
index 18857b94af8f..b92bea929c51 100644
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ b/vcl/source/glyphs/gcach_ftyp.cxx
@@ -43,6 +43,7 @@
#include "tools/poly.hxx"
#include "basegfx/matrix/b2dhommatrix.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include "basegfx/polygon/b2dpolypolygon.hxx"
#include "osl/file.hxx"
@@ -2282,9 +2283,7 @@ bool FreetypeServerFont::GetGlyphOutline( int nGlyphIndex,
// convert to basegfx polypolygon
// TODO: get rid of the intermediate tools polypolygon
rB2DPolyPoly = aToolPolyPolygon.getB2DPolyPolygon();
- ::basegfx::B2DHomMatrix aMatrix;
- aMatrix.scale( +1.0/(1<<6), -1.0/(1<<6) );
- rB2DPolyPoly.transform( aMatrix );
+ rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix( +1.0/(1<<6), -1.0/(1<<6) ));
return true;
}
diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx
index e3e840e40730..17e70c539254 100644
--- a/vcl/source/glyphs/glyphcache.cxx
+++ b/vcl/source/glyphs/glyphcache.cxx
@@ -79,9 +79,7 @@ GlyphCache::~GlyphCache()
// -----------------------------------------------------------------------
-#ifndef IRIX
inline
-#endif
size_t GlyphCache::IFSD_Hash::operator()( const ImplFontSelectData& rFontSelData ) const
{
// TODO: is it worth to improve this hash function?
diff --git a/vcl/source/helper/xconnection.cxx b/vcl/source/helper/xconnection.cxx
index 477ff5fb9902..489e3cf9340e 100644
--- a/vcl/source/helper/xconnection.cxx
+++ b/vcl/source/helper/xconnection.cxx
@@ -30,10 +30,31 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#include <svsys.h>
-#include <vcl/xconnection.hxx>
-#include <vcl/svdata.hxx>
-#include <vcl/salinst.hxx>
+
+#include "svsys.h"
+#include "vcl/xconnection.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/salinst.hxx"
+#include "vcl/svapp.hxx"
+
+namespace vcl
+{
+ class SolarMutexReleaser
+ {
+ ULONG mnReleased;
+ public:
+ SolarMutexReleaser()
+ {
+ mnReleased = Application::ReleaseSolarMutex();
+ }
+
+ ~SolarMutexReleaser()
+ {
+ if( mnReleased )
+ Application::AcquireSolarMutex( mnReleased );
+ }
+ };
+}
using namespace rtl;
using namespace osl;
@@ -41,6 +62,7 @@ using namespace vcl;
using namespace com::sun::star::uno;
using namespace com::sun::star::awt;
+
DisplayConnection::DisplayConnection()
{
ImplSVData* pSVData = ImplGetSVData();
@@ -108,6 +130,8 @@ Any SAL_CALL DisplayConnection::getIdentifier() throw()
void DisplayConnection::dispatchDowningEvent()
{
+ SolarMutexReleaser aRel;
+
MutexGuard aGuard( m_aMutex );
Any aEvent;
std::list< Reference< XEventHandler > > aLocalList( m_aHandlers );
@@ -117,6 +141,8 @@ void DisplayConnection::dispatchDowningEvent()
bool DisplayConnection::dispatchEvent( void* pThis, void* pData, int nBytes )
{
+ SolarMutexReleaser aRel;
+
DisplayConnection* This = (DisplayConnection*)pThis;
MutexGuard aGuard( This->m_aMutex );
@@ -131,6 +157,8 @@ bool DisplayConnection::dispatchEvent( void* pThis, void* pData, int nBytes )
bool DisplayConnection::dispatchErrorEvent( void* pThis, void* pData, int nBytes )
{
+ SolarMutexReleaser aRel;
+
DisplayConnection* This = (DisplayConnection*)pThis;
MutexGuard aGuard( This->m_aMutex );
diff --git a/vcl/source/src/images.src b/vcl/source/src/images.src
index a2b057c8d234..5a0e7b412a58 100644
--- a/vcl/source/src/images.src
+++ b/vcl/source/src/images.src
@@ -833,3 +833,23 @@ Bitmap (SV_ICON_SMALL_HC_START + SV_ICON_ID_PRINTERADMIN)
File = "printeradmin_16_h.png" ;
};
+Bitmap SV_DISCLOSURE_PLUS
+{
+ File = "plus.png";
+};
+
+Bitmap SV_DISCLOSURE_PLUS_HC
+{
+ File = "plus_sch.png";
+};
+
+Bitmap SV_DISCLOSURE_MINUS
+{
+ File = "minus.png";
+};
+
+Bitmap SV_DISCLOSURE_MINUS_HC
+{
+ File = "minus_sch.png";
+};
+
diff --git a/vcl/source/src/makefile.mk b/vcl/source/src/makefile.mk
index cf01c74b977d..7772af5a0978 100644
--- a/vcl/source/src/makefile.mk
+++ b/vcl/source/src/makefile.mk
@@ -8,7 +8,7 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.8 $
+# $Revision: 1.8.114.1 $
#
# This file is part of OpenOffice.org.
#
@@ -47,7 +47,8 @@ SRC1FILES= images.src \
stdtext.src \
helptext.src \
units.src \
- btntext.src
+ btntext.src \
+ print.src
RESLIB1NAME= $(RESTARGET)
RESLIB1IMAGES= $(PRJ)$/source/src
diff --git a/vcl/source/src/print.src b/vcl/source/src/print.src
new file mode 100644
index 000000000000..0125c0dfbeb3
--- /dev/null
+++ b/vcl/source/src/print.src
@@ -0,0 +1,495 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: print.src,v $
+ * $Revision: 1.1.2.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vcl/svids.hrc"
+
+ModalDialog SV_DLG_PRINT
+{
+ Text [en-US] = "Print";
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Moveable = TRUE;
+ Maxable = TRUE;
+ SVLook = TRUE;
+
+ Size = MAP_APPFONT( 350, 215 );
+
+ OKButton SV_PRINT_OK
+ {
+ DefButton = TRUE;
+ Pos = MAP_APPFONT( 240, 195 );
+ Size = MAP_APPFONT( 50, 15 );
+ Text [en-US] = "~Print";
+ };
+ CancelButton SV_PRINT_CANCEL
+ {
+ Pos = MAP_APPFONT( 295, 195 );
+ Size = MAP_APPFONT( 50, 15 );
+ };
+ HelpButton SV_PRINT_HELP
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 50, 15 );
+ };
+
+ Window SV_PRINT_PAGE_PREVIEW
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 130, 130 );
+ Border = FALSE;
+ };
+ NumericField SV_PRINT_PAGE_EDIT
+ {
+ Pos = MAP_APPFONT( 5, 140 );
+ Size = MAP_APPFONT( 30, 12 );
+ SVLook = TRUE;
+ Spin = FALSE;
+ Border = TRUE;
+ HelpText [en-US] = "Select page to display in preview.";
+ };
+ FixedText SV_PRINT_PAGE_TXT
+ {
+ Pos = MAP_APPFONT( 40,142 );
+ Size = MAP_APPFONT( 30, 12 );
+ Text [ en-US ] = "/ %n";
+ VCenter = TRUE;
+ };
+ PushButton SV_PRINT_PAGE_FORWARD
+ {
+ Pos = MAP_APPFONT( 95, 140 );
+ Size = MAP_APPFONT( 15, 12 );
+ HelpText [en-US] = "Scroll one page forward.";
+ };
+ PushButton SV_PRINT_PAGE_BACKWARD
+ {
+ Pos = MAP_APPFONT( 80, 140 );
+ Size = MAP_APPFONT( 15, 12 );
+ HelpText [en-US] = "Scroll one page backward.";
+ };
+ TabControl SV_PRINT_TABCTRL
+ {
+ Pos = MAP_APPFONT( 140, 5 );
+ Size = MAP_APPFONT( 205, 175 );
+ };
+ FixedLine SV_PRINT_BUTTONLINE
+ {
+ Pos = MAP_APPFONT( 0, 185 );
+ Size = MAP_APPFONT( 350, 8 );
+ };
+ String SV_PRINT_NOPAGES
+ {
+ Text [en-US] = "No pages";
+ };
+
+ String SV_PRINT_TOFILE_TXT
+ {
+ Text [en-US] = "Print to File...";
+ };
+
+ String SV_PRINT_DEFPRT_TXT
+ {
+ Text [en-US] = "Default printer";
+ };
+
+
+ String SV_PRINT_PRINTPREVIEW_TXT
+ {
+ Text [en-US] = "Print preview";
+ };
+
+ TabPage SV_PRINT_TAB_NUP
+ {
+ Text [en-US] = "Page Layout";
+ Hide = TRUE;
+
+ FixedLine SV_PRINT_PRT_NUP_LAYOUT_FL
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 150, 10 );
+ Text [en-US] = "Layout";
+ };
+ RadioButton SV_PRINT_PRT_NUP_DEFAULT_BTN
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text [en-US] = "~Default";
+ HelpText [en-US] = "Print one page per sheet of paper.";
+ };
+ RadioButton SV_PRINT_PRT_NUP_BROCHURE_BTN
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text = "";
+ };
+ RadioButton SV_PRINT_PRT_NUP_PAGES_BTN
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text [en-US] = "Pa~ges per sheet";
+ HelpText [en-US] = "Print multiple pages per sheet of paper.";
+ };
+ ListBox SV_PRINT_PRT_NUP_PAGES_BOX
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 80 );
+ Border = TRUE;
+ DropDown = TRUE;
+ CurPos = 0;
+ HelpText [en-US] = "Select how many pages to print per sheet of paper.";
+ StringList [en-US] =
+ {
+ < "1"; 1; >;
+ < "2"; 2; >;
+ < "4"; 4; >;
+ < "6"; 6; >;
+ < "9"; 9; >;
+ < "16"; 16; >;
+ < "Custom"; 0xffff; >;
+ };
+ };
+ FixedText SV_PRINT_PRT_NUP_NUM_PAGES_TXT
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text [en-US] = "P~ages";
+ VCenter = TRUE;
+ };
+ NumericField SV_PRINT_PRT_NUP_COLS_EDT
+ {
+ Pos = MAP_APPFONT( 55, 20 );
+ Size = MAP_APPFONT( 40, 12 );
+ Border = TRUE;
+ Spin = TRUE;
+ Minimum = 1;
+ Maximum = 32;
+ Value = 1;
+ HelpText [en-US] = "Select number of columns.";
+ };
+ FixedText SV_PRINT_PRT_NUP_TIMES_TXT
+ {
+ Pos = MAP_APPFONT( 10, 35 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text [en-US] = "b~y";
+ VCenter = TRUE;
+ };
+ NumericField SV_PRINT_PRT_NUP_ROWS_EDT
+ {
+ Pos = MAP_APPFONT( 55, 35 );
+ Size = MAP_APPFONT( 40, 12 );
+ Border = TRUE;
+ Spin = TRUE;
+ Minimum = 1;
+ Maximum = 32;
+ Value = 1;
+ HelpText [en-US] = "Select number of rows.";
+ };
+ FixedText SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT
+ {
+ Pos = MAP_APPFONT( 10, 95 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text [en-US] = "~Distance";
+ };
+ MetricField SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT
+ {
+ Pos = MAP_APPFONT( 55, 95 );
+ Size = MAP_APPFONT( 40, 12 );
+ Spin = TRUE;
+ Border = TRUE;
+ Value = 0;
+ Unit = FUNIT_MM;
+ HelpText [en-US] = "Select margin between individual pages on each sheet of paper.";
+ };
+ FixedText SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT
+ {
+ Pos = MAP_APPFONT( 10, 95 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text [en-US] = "between pages";
+ };
+ FixedText SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT
+ {
+ Pos = MAP_APPFONT( 110, 95 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text [en-US] = "~Margin";
+ };
+ MetricField SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT
+ {
+ Pos = MAP_APPFONT( 155, 95 );
+ Size = MAP_APPFONT( 40, 12 );
+ Spin = TRUE;
+ Border = TRUE;
+ Value = 0;
+ Unit = FUNIT_MM;
+ HelpText [en-US] = "Select margin between the printed pages and paper edge.";
+ };
+ FixedText SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT
+ {
+ Pos = MAP_APPFONT( 110, 95 );
+ Size = MAP_APPFONT( 40, 10 );
+ Text [en-US] = "to sheet border";
+ };
+ FixedText SV_PRINT_PRT_NUP_ORIENTATION_TXT
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text [en-US] = "~Orientation";
+ };
+ ListBox SV_PRINT_PRT_NUP_ORIENTATION_BOX
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 40 );
+ Border = TRUE;
+ DropDown = TRUE;
+ CurPos = 0;
+ StringList [en-US] =
+ {
+ < "Automatic"; SV_PRINT_PRT_NUP_ORIENTATION_AUTOMATIC; >;
+ < "Portrait"; SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT; >;
+ < "Landscape"; SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE; >;
+ };
+ HelpText [en-US] = "Select the orientation of the paper.";
+ };
+ FixedText SV_PRINT_PRT_NUP_ORDER_TXT
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 10 );
+ Text [en-US] = "Order";
+ };
+ ListBox SV_PRINT_PRT_NUP_ORDER_BOX
+ {
+ Pos = MAP_APPFONT( 0, 0 );
+ Size = MAP_APPFONT( 10, 20 );
+ DropDown = TRUE;
+ Border = TRUE;
+ CurPos = 0;
+ StringList [en-US] =
+ {
+ < "left to right, then down"; SV_PRINT_PRT_NUP_ORDER_LRTD; >;
+ < "top to bottom, then right"; SV_PRINT_PRT_NUP_ORDER_TDLR; >;
+ };
+ HelpText [en-US] = "Select order in which pages are to be printed.";
+ };
+ CheckBox SV_PRINT_PRT_NUP_BORDER_CB
+ {
+ Pos = MAP_APPFONT( 10, 65 );
+ Size = MAP_APPFONT( 150, 12 );
+ Text [en-US] = "Draw a border around each page";
+ HelpText [en-US] = "Check to draw a border around each page.";
+ };
+ };
+
+ TabPage SV_PRINT_TAB_JOB
+ {
+ Text [en-US] = "General";
+ Hide = TRUE;
+
+ FixedLine SV_PRINT_PRINTERS_FL
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 100, 10 );
+ Text [ en-US ] = "Prin~ter";
+ };
+ ListBox SV_PRINT_PRINTERS
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 100, 80 );
+ Border = TRUE;
+ Sort = TRUE;
+ HelpText [en-US] = "Select the printer to print on.";
+ };
+ CheckBox SV_PRINT_DETAILS_BTN
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 5, 5 );
+ Text [en-US] = "Details";
+ HelpText [en-US] = "Show/Hide detailed information of the selected printer.";
+ };
+ FixedText SV_PRINT_STATUS_TXT
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 100, 10 );
+ Text [en-US] = "Status:";
+ };
+ FixedText SV_PRINT_LOCATION_TXT
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 100, 10 );
+ Text [en-US] = "Location:";
+ };
+ FixedText SV_PRINT_COMMENT_TXT
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 100, 10 );
+ Text [en-US] = "Comment:";
+ };
+ PushButton SV_PRINT_PRT_SETUP
+ {
+ Pos = MAP_APPFONT( 115, 5 );
+ Size = MAP_APPFONT( 50, 15 );
+ Text [en-US] = "Properties...";
+ HelpText [en-US] = "Call the setup dialog of the selected printer.";
+ };
+ FixedLine SV_PRINT_COPIES
+ {
+ Pos = MAP_APPFONT( 5, 35 );
+ Size = MAP_APPFONT( 150, 10 );
+ Text [en-US] = "Range and Copies";
+ };
+ FixedText SV_PRINT_COPYCOUNT
+ {
+ Pos = MAP_APPFONT( 10, 45 );
+ Size = MAP_APPFONT( 80, 10 );
+ Text [en-US] = "Number of copies";
+ };
+ NumericField SV_PRINT_COPYCOUNT_FIELD
+ {
+ Pos = MAP_APPFONT( 10, 56 );
+ Size = MAP_APPFONT( 40, 12 );
+ Border = TRUE;
+ Spin = TRUE;
+ Minimum = 1;
+ Maximum = 16384;
+ Value = 1;
+ HelpText [en-US] = "Select the number of copies to be produced.";
+ };
+ FixedImage SV_PRINT_COLLATE_IMAGE
+ {
+ Pos = MAP_APPFONT( 95, 60 );
+ Size = MAP_PIXEL( 80, 30 );
+ };
+ CheckBox SV_PRINT_COLLATE
+ {
+ Pos = MAP_APPFONT( 95, 45 );
+ Size = MAP_APPFONT( 70, 10 );
+ Text [en-US] = "Collate";
+ HelpText [en-US] = "Select whether copies should be collated or not.";
+ };
+
+ Image SV_PRINT_COLLATE_IMG
+ {
+ ImageBitmap = Bitmap { File = "collate.png" ; };
+ };
+
+ Image SV_PRINT_NOCOLLATE_IMG
+ {
+ ImageBitmap = Bitmap { File = "ncollate.png" ; };
+ };
+
+ Image SV_PRINT_COLLATE_HC_IMG
+ {
+ ImageBitmap = Bitmap { File = "collate_h.png" ; };
+ };
+
+ Image SV_PRINT_NOCOLLATE_HC_IMG
+ {
+ ImageBitmap = Bitmap { File = "ncollate_h.png" ; };
+ };
+ };
+
+ TabPage SV_PRINT_TAB_OPT
+ {
+ Text [en-US] = "Options";
+ Hide = TRUE;
+
+ FixedLine SV_PRINT_OPT_PRINT_FL
+ {
+ Pos = MAP_APPFONT( 5, 5 );
+ Size = MAP_APPFONT( 150, 10 );
+ Text [en-US] = "Options";
+ };
+ CheckBox SV_PRINT_OPT_TOFILE
+ {
+ Pos = MAP_APPFONT( 10, 20 );
+ Size = MAP_APPFONT( 200, 12 );
+ Text [en-US] = "Print to ~file";
+ HelpText [en-US] = "Check to send output to a file instead of the actual printer.";
+ };
+ CheckBox SV_PRINT_OPT_SINGLEJOBS
+ {
+ Pos = MAP_APPFONT( 10, 35 );
+ Size = MAP_APPFONT( 200, 12 );
+ Text [en-US] = "~Create single print jobs for collated output";
+ HelpText [en-US] = "Check to not rely on the printer to create collated copies but create a print job for each copy instead.";
+ };
+ CheckBox SV_PRINT_OPT_REVERSE
+ {
+ Pos = MAP_APPFONT( 10, 50 );
+ Size = MAP_APPFONT( 200, 12 );
+ Text [en-US] = "Print in ~reverse page order";
+ HelpText [en-US] = "Check to print pages in reverse order.";
+ };
+ };
+};
+
+ModelessDialog SV_DLG_PRINT_PROGRESS
+{
+ Text [en-US] = "Printing";
+ Closeable = FALSE;
+ Sizeable = FALSE;
+ Moveable = TRUE;
+ SVLook = TRUE;
+
+ Size = MAP_APPFONT( 120, 70 );
+
+ CancelButton SV_PRINT_PROGRESS_CANCEL
+ {
+ Pos = MAP_APPFONT( 35, 50 );
+ Size = MAP_APPFONT( 50, 15 );
+ };
+ FixedText SV_PRINT_PROGRESS_TEXT
+ {
+ Pos = MAP_APPFONT( 5,10 );
+ Size = MAP_APPFONT( 110, 10 );
+ Text [ en-US ] = "Page %p of %n";
+ Center = TRUE;
+ };
+};
+
+ErrorBox SV_PRINT_NOPRINTERWARNING
+{
+ Title = "%PRODUCTNAME";
+ Message [en-US] = "No default printer found.\nPlease choose a printer and try again.";
+};
+
+ErrorBox SV_PRINT_NOCONTENT
+{
+ Title = "%PRODUCTNAME";
+ Message [en-US] = "There are no pages to be printed. Please check your document for ranges relevant to printing.";
+};
+
+StringArray SV_PRINT_NATIVE_STRINGS
+{
+ ItemList [en-US] =
+ {
+ < "Preview"; >;
+ < "Page number"; >;
+ < "Number of pages"; >;
+ < "More"; >;
+ };
+};
diff --git a/vcl/source/src/stdtext.src b/vcl/source/src/stdtext.src
index 5ad1cdceeb61..d4dca4915b6b 100644
--- a/vcl/source/src/stdtext.src
+++ b/vcl/source/src/stdtext.src
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: stdtext.src,v $
- * $Revision: 1.53 $
+ * $Revision: 1.53.84.1 $
*
* This file is part of OpenOffice.org.
*
@@ -123,3 +123,8 @@ String SV_MAC_SCREENNNAME
{
Text [en-US] = "Screen %d";
};
+
+String SV_STDTEXT_ALLFILETYPES
+{
+ Text [en-US] = "Any type";
+};
diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx
new file mode 100644
index 000000000000..0199af7ed50d
--- /dev/null
+++ b/vcl/source/window/arrange.cxx
@@ -0,0 +1,906 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accel.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_vcl.hxx"
+
+#include "vcl/arrange.hxx"
+#include "vcl/edit.hxx"
+
+#include "osl/diagnose.h"
+
+using namespace vcl;
+
+// ----------------------------------------
+// vcl::WindowArranger
+//-----------------------------------------
+
+WindowArranger::~WindowArranger()
+{}
+
+void WindowArranger::setParent( WindowArranger* i_pParent )
+{
+ OSL_VERIFY( i_pParent->m_pParentWindow == m_pParentWindow || m_pParentWindow == NULL );
+
+ m_pParentArranger = i_pParent;
+ m_pParentWindow = i_pParent->m_pParentWindow;
+ setParentWindow( m_pParentWindow );
+}
+
+void WindowArranger::setParentWindow( Window* i_pNewParent )
+{
+ m_pParentWindow = i_pNewParent;
+
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ Element* pEle = getElement( i );
+ if( pEle ) // sanity check
+ {
+ #if OSL_DEBUG_LEVEL > 0
+ if( pEle->m_pElement )
+ {
+ OSL_VERIFY( pEle->m_pElement->GetParent() == i_pNewParent );
+ }
+ #endif
+ if( pEle->m_pChild )
+ pEle->m_pChild->setParentWindow( i_pNewParent );
+ }
+ }
+}
+
+void WindowArranger::show( bool i_bShow, bool i_bImmediateUpdate )
+{
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ Element* pEle = getElement( i );
+ if( pEle ) // sanity check
+ {
+ pEle->m_bHidden = ! i_bShow;
+ if( pEle->m_pElement )
+ pEle->m_pElement->Show( i_bShow );
+ if( pEle->m_pChild.get() )
+ pEle->m_pChild->show( i_bShow, false );
+ }
+ }
+ if( m_pParentArranger )
+ {
+ nEle = m_pParentArranger->countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ Element* pEle = m_pParentArranger->getElement( i );
+ if( pEle && pEle->m_pChild.get() == this )
+ {
+ pEle->m_bHidden = ! i_bShow;
+ break;
+ }
+ }
+ }
+ if( i_bImmediateUpdate )
+ {
+ // find the topmost parent
+ WindowArranger* pResize = this;
+ while( pResize->m_pParentArranger )
+ pResize = pResize->m_pParentArranger;
+ pResize->resize();
+ }
+}
+
+bool WindowArranger::isVisible() const
+{
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ const Element* pEle = getConstElement( i );
+ if( pEle->isVisible() )
+ return true;
+ }
+ return false;
+}
+
+bool WindowArranger::Element::isVisible() const
+{
+ bool bVisible = false;
+ if( ! m_bHidden )
+ {
+ if( m_pElement )
+ bVisible = m_pElement->IsVisible();
+ else if( m_pChild )
+ bVisible = m_pChild->isVisible();
+ }
+ return bVisible;
+}
+
+sal_Int32 WindowArranger::Element::getExpandPriority() const
+{
+ sal_Int32 nPrio = m_nExpandPriority;
+ if( m_pChild && m_nExpandPriority >= 0 )
+ {
+ size_t nElements = m_pChild->countElements();
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ sal_Int32 nCPrio = m_pChild->getExpandPriority( i );
+ if( nCPrio > nPrio )
+ nPrio = nCPrio;
+ }
+ }
+ return nPrio;
+}
+
+Size WindowArranger::Element::getOptimalSize( WindowSizeType i_eType ) const
+{
+ Size aResult;
+ if( ! m_bHidden )
+ {
+ if( m_pElement && m_pElement->IsVisible() )
+ aResult = m_pElement->GetOptimalSize( i_eType );
+ else if( m_pChild )
+ aResult = m_pChild->getOptimalSize( i_eType );
+ if( aResult.Width() < m_aMinSize.Width() )
+ aResult.Width() = m_aMinSize.Width();
+ if( aResult.Height() < m_aMinSize.Height() )
+ aResult.Height() = m_aMinSize.Height();
+ aResult.Width() += m_nLeftBorder + m_nRightBorder;
+ aResult.Height() += m_nTopBorder + m_nBottomBorder;
+ }
+
+ return aResult;
+}
+
+void WindowArranger::Element::setPosSize( const Point& i_rPos, const Size& i_rSize )
+{
+ Point aPoint( i_rPos );
+ Size aSize( i_rSize );
+ aPoint.X() += m_nLeftBorder;
+ aPoint.Y() += m_nTopBorder;
+ aSize.Width() -= m_nLeftBorder + m_nRightBorder;
+ aSize.Height() -= m_nTopBorder + m_nBottomBorder;
+ if( m_pElement )
+ m_pElement->SetPosSizePixel( aPoint, aSize );
+ else if( m_pChild )
+ m_pChild->setManagedArea( Rectangle( aPoint, aSize ) );
+}
+
+// ----------------------------------------
+// vcl::RowOrColumn
+//-----------------------------------------
+
+RowOrColumn::~RowOrColumn()
+{
+ for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ it->deleteChild();
+ }
+}
+
+Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const
+{
+ Size aRet( 0, 0 );
+ for( std::vector< WindowArranger::Element >::const_iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->isVisible() )
+ {
+ // get the size of type of the managed element
+ Size aElementSize( it->getOptimalSize( i_eType ) );
+ if( m_bColumn )
+ {
+ // add the distance between elements
+ aRet.Height() += m_nBorderWidth;
+ // check if the width needs adjustment
+ if( aRet.Width() < aElementSize.Width() )
+ aRet.Width() = aElementSize.Width();
+ aRet.Height() += aElementSize.Height();
+ }
+ else
+ {
+ // add the distance between elements
+ aRet.Width() += m_nBorderWidth;
+ // check if the height needs adjustment
+ if( aRet.Height() < aElementSize.Height() )
+ aRet.Height() = aElementSize.Height();
+ aRet.Width() += aElementSize.Width();
+ }
+ }
+ }
+
+ if( aRet.Width() != 0 || aRet.Height() != 0 )
+ {
+ // subtract the border for the first element
+ if( m_bColumn )
+ aRet.Height() -= m_nBorderWidth;
+ else
+ aRet.Width() -= m_nBorderWidth;
+
+ // add the outer border
+ aRet.Width() += 2*m_nOuterBorder;
+ aRet.Height() += 2*m_nOuterBorder;
+ }
+
+ return aRet;
+}
+
+void RowOrColumn::distributeRowWidth( std::vector<Size>& io_rSizes, long /*i_nUsedWidth*/, long i_nExtraWidth )
+{
+ if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() )
+ {
+ // find all elements with the highest expand priority
+ size_t nElements = m_aElements.size();
+ std::vector< size_t > aIndices;
+ sal_Int32 nHighPrio = 0;
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ if( m_aElements[ i ].isVisible() )
+ {
+ sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority();
+ if( nCurPrio > nHighPrio )
+ {
+ aIndices.clear();
+ nHighPrio = nCurPrio;
+ }
+ if( nCurPrio == nHighPrio )
+ aIndices.push_back( i );
+ }
+ }
+
+ // distribute extra space evenly among collected elements
+ nElements = aIndices.size();
+ if( nElements > 0 )
+ {
+ long nDelta = i_nExtraWidth / nElements;
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ io_rSizes[ aIndices[i] ].Width() += nDelta;
+ i_nExtraWidth -= nDelta;
+ }
+ // add the last pixels to the last row element
+ if( i_nExtraWidth > 0 && nElements > 0 )
+ io_rSizes[aIndices.back()].Width() += i_nExtraWidth;
+ }
+ }
+}
+
+void RowOrColumn::distributeColumnHeight( std::vector<Size>& io_rSizes, long /*i_nUsedHeight*/, long i_nExtraHeight )
+{
+ if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() )
+ {
+ // find all elements with the highest expand priority
+ size_t nElements = m_aElements.size();
+ std::vector< size_t > aIndices;
+ sal_Int32 nHighPrio = 3;
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ if( m_aElements[ i ].isVisible() )
+ {
+ sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority();
+ if( nCurPrio > nHighPrio )
+ {
+ aIndices.clear();
+ nHighPrio = nCurPrio;
+ }
+ if( nCurPrio == nHighPrio )
+ aIndices.push_back( i );
+ }
+ }
+
+ // distribute extra space evenly among collected elements
+ nElements = aIndices.size();
+ if( nElements > 0 )
+ {
+ long nDelta = i_nExtraHeight / nElements;
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ io_rSizes[ aIndices[i] ].Height() += nDelta;
+ i_nExtraHeight -= nDelta;
+ }
+ // add the last pixels to the last row element
+ if( i_nExtraHeight > 0 && nElements > 0 )
+ io_rSizes[aIndices.back()].Height() += i_nExtraHeight;
+ }
+ }
+}
+
+void RowOrColumn::resize()
+{
+ // check if we can get optimal size, else fallback to minimal size
+ Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED ) );
+ WindowSizeType eType = WINDOWSIZE_PREFERRED;
+ if( m_bColumn )
+ {
+ if( aOptSize.Height() > m_aManagedArea.GetHeight() )
+ eType = WINDOWSIZE_MINIMUM;
+ }
+ else
+ {
+ if( aOptSize.Width() > m_aManagedArea.GetWidth() )
+ eType = WINDOWSIZE_MINIMUM;
+ }
+
+ size_t nElements = m_aElements.size();
+ // get all element sizes for sizing
+ std::vector<Size> aElementSizes( nElements );
+ long nUsedWidth = 2*m_nOuterBorder - (nElements ? m_nBorderWidth : 0);
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ if( m_aElements[i].isVisible() )
+ {
+ aElementSizes[i] = m_aElements[i].getOptimalSize( eType );
+ if( m_bColumn )
+ {
+ aElementSizes[i].Width() = m_aManagedArea.GetWidth() - 2* m_nOuterBorder;
+ nUsedWidth += aElementSizes[i].Height() + m_nBorderWidth;
+ }
+ else
+ {
+ aElementSizes[i].Height() = m_aManagedArea.GetHeight() - 2* m_nOuterBorder;
+ nUsedWidth += aElementSizes[i].Width() + m_nBorderWidth;
+ }
+ }
+ }
+
+ long nExtraWidth = (m_bColumn ? m_aManagedArea.GetHeight() : m_aManagedArea.GetWidth()) - nUsedWidth;
+ if( nExtraWidth > 0 )
+ {
+ if( m_bColumn )
+ distributeColumnHeight( aElementSizes, nUsedWidth, nExtraWidth );
+ else
+ distributeRowWidth( aElementSizes, nUsedWidth, nExtraWidth );
+ }
+
+ // get starting position
+ Point aElementPos( m_aManagedArea.TopLeft() );
+ // outer border
+ aElementPos.X() += m_nOuterBorder;
+ aElementPos.Y() += m_nOuterBorder;
+
+ // position managed windows
+ for( size_t i = 0; i < nElements; i++ )
+ {
+ // get the size of type of the managed element
+ if( m_aElements[i].isVisible() )
+ {
+ m_aElements[i].setPosSize( aElementPos, aElementSizes[i] );
+ if( m_bColumn )
+ aElementPos.Y() += m_nBorderWidth + aElementSizes[i].Height();
+ else
+ aElementPos.X() += m_nBorderWidth + aElementSizes[i].Width();
+ }
+ }
+}
+
+size_t RowOrColumn::addWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio, size_t i_nIndex )
+{
+ size_t nIndex = i_nIndex;
+ if( i_nIndex >= m_aElements.size() )
+ {
+ nIndex = m_aElements.size();
+ m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio ) );
+ }
+ else
+ {
+ std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
+ while( i_nIndex-- )
+ ++it;
+ m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio ) );
+ }
+ return nIndex;
+}
+
+size_t RowOrColumn::addChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio, size_t i_nIndex )
+{
+ size_t nIndex = i_nIndex;
+ if( i_nIndex >= m_aElements.size() )
+ {
+ nIndex = m_aElements.size();
+ m_aElements.push_back( WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) );
+ }
+ else
+ {
+ std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
+ while( i_nIndex-- )
+ ++it;
+ m_aElements.insert( it, WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) );
+ }
+ return nIndex;
+}
+
+void RowOrColumn::remove( Window* i_pWindow )
+{
+ if( i_pWindow )
+ {
+ for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->m_pElement == i_pWindow )
+ {
+ m_aElements.erase( it );
+ return;
+ }
+ }
+ }
+}
+
+void RowOrColumn::remove( boost::shared_ptr<WindowArranger> const & i_pChild )
+{
+ if( i_pChild )
+ {
+ for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->m_pChild == i_pChild )
+ {
+ m_aElements.erase( it );
+ return;
+ }
+ }
+ }
+}
+
+// ----------------------------------------
+// vcl::LabeledElement
+//-----------------------------------------
+
+LabeledElement::~LabeledElement()
+{
+ m_aLabel.deleteChild();
+ m_aElement.deleteChild();
+}
+
+Size LabeledElement::getOptimalSize( WindowSizeType i_eType ) const
+{
+ Size aRet( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) );
+ if( aRet.Width() != 0 )
+ {
+ if( m_nLabelColumnWidth != 0 )
+ aRet.Width() = m_nLabelColumnWidth;
+ else
+ aRet.Width() += m_nDistance;
+ }
+ Size aElementSize( m_aElement.getOptimalSize( i_eType ) );
+ aRet.Width() += aElementSize.Width();
+ if( aElementSize.Height() > aRet.Height() )
+ aRet.Height() = aElementSize.Height();
+ if( aRet.Height() != 0 )
+ aRet.Height() += 2*m_nOuterBorder;
+
+ return aRet;
+}
+
+void LabeledElement::resize()
+{
+ Size aLabelSize( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) );
+ Size aElementSize( m_aElement.getOptimalSize( WINDOWSIZE_PREFERRED ) );
+ if( m_nDistance + aLabelSize.Width() + aElementSize.Width() > m_aManagedArea.GetWidth() )
+ aElementSize = m_aElement.getOptimalSize( WINDOWSIZE_MINIMUM );
+
+ // align label and element vertically in LabeledElement
+ long nYOff = (m_aManagedArea.GetHeight() - 2*m_nOuterBorder - aLabelSize.Height()) / 2;
+ Point aPos( m_aManagedArea.Left(),
+ m_aManagedArea.Top() + m_nOuterBorder + nYOff );
+ Size aSize( aLabelSize );
+ if( m_nLabelColumnWidth != 0 )
+ aSize.Width() = m_nLabelColumnWidth;
+ m_aLabel.setPosSize( aPos, aSize );
+
+ aPos.X() += aSize.Width() + m_nDistance;
+ nYOff = (m_aManagedArea.GetHeight() - 2*m_nOuterBorder - aElementSize.Height()) / 2;
+ aPos.Y() = m_aManagedArea.Top() + m_nOuterBorder + nYOff;
+ aSize.Width() = aElementSize.Width();
+ aSize.Height() = m_aManagedArea.GetHeight() - 2*m_nOuterBorder;
+
+ // label style
+ // 0: position left and right
+ // 1: keep the element close to label and grow it
+ // 2: keep the element close and don't grow it
+ if( m_nLabelStyle == 0)
+ {
+ if( aPos.X() + aSize.Width() < m_aManagedArea.Right() )
+ aPos.X() = m_aManagedArea.Right() - aSize.Width();
+ }
+ else if( m_nLabelStyle == 1 )
+ {
+ if( aPos.X() + aSize.Width() < m_aManagedArea.Right() )
+ aSize.Width() = m_aManagedArea.Right() - aPos.X();
+ }
+ m_aElement.setPosSize( aPos, aSize );
+}
+
+void LabeledElement::setLabel( Window* i_pLabel )
+{
+ m_aLabel.m_pElement = i_pLabel;
+ m_aLabel.m_pChild.reset();
+}
+
+void LabeledElement::setLabel( boost::shared_ptr<WindowArranger> const & i_pLabel )
+{
+ m_aLabel.m_pElement = NULL;
+ m_aLabel.m_pChild = i_pLabel;
+}
+
+void LabeledElement::setElement( Window* i_pElement )
+{
+ m_aElement.m_pElement = i_pElement;
+ m_aElement.m_pChild.reset();
+}
+
+void LabeledElement::setElement( boost::shared_ptr<WindowArranger> const & i_pElement )
+{
+ m_aElement.m_pElement = NULL;
+ m_aElement.m_pChild = i_pElement;
+}
+
+// ----------------------------------------
+// vcl::LabelColumn
+//-----------------------------------------
+LabelColumn::~LabelColumn()
+{
+}
+
+long LabelColumn::getLabelWidth() const
+{
+ long nWidth = 0;
+
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ const Element* pEle = getConstElement( i );
+ if( pEle && pEle->m_pChild.get() )
+ {
+ const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get());
+ if( pLabel )
+ {
+ Window* pLW = pLabel->getWindow( 0 );
+ if( pLW )
+ {
+ Size aLabSize( pLW->GetOptimalSize( WINDOWSIZE_MINIMUM ) );
+ if( aLabSize.Width() > nWidth )
+ nWidth = aLabSize.Width();
+ }
+ }
+ }
+ }
+ return nWidth + getBorderWidth();
+}
+
+Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const
+{
+ long nWidth = getLabelWidth();
+ Size aColumnSize;
+
+ // every child is a LabeledElement
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ Size aElementSize;
+ const Element* pEle = getConstElement( i );
+ if( pEle && pEle->m_pChild.get() )
+ {
+ const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get());
+ if( pLabel ) // we have a label
+ {
+ aElementSize = pLabel->getLabelSize( WINDOWSIZE_MINIMUM );
+ if( aElementSize.Width() )
+ aElementSize.Width() = nWidth;
+ Size aSize( pLabel->getElementSize( i_eType ) );
+ aElementSize.Width() += aSize.Width();
+ if( aSize.Height() > aElementSize.Height() )
+ aElementSize.Height() = aSize.Height();
+ }
+ else // a non label, just treat it as a row
+ {
+ aElementSize = pEle->getOptimalSize( i_eType );
+ }
+ }
+ else if( pEle && pEle->m_pElement ) // a general window, treat is as a row
+ {
+ aElementSize = pEle->getOptimalSize( i_eType );
+ }
+ if( aElementSize.Width() )
+ {
+ aElementSize.Width() += 2*m_nOuterBorder;
+ if( aElementSize.Width() > aColumnSize.Width() )
+ aColumnSize.Width() = aElementSize.Width();
+ }
+ if( aElementSize.Height() )
+ {
+ aColumnSize.Height() += getBorderWidth() + aElementSize.Height();
+ }
+ }
+ if( nEle > 0 && aColumnSize.Height() )
+ {
+ aColumnSize.Height() -= getBorderWidth(); // for the first element
+ aColumnSize.Height() += 2*m_nOuterBorder;
+ }
+ return aColumnSize;
+}
+
+void LabelColumn::resize()
+{
+ long nWidth = getLabelWidth();
+ size_t nEle = countElements();
+ for( size_t i = 0; i < nEle; i++ )
+ {
+ Element* pEle = getElement( i );
+ if( pEle && pEle->m_pChild.get() )
+ {
+ LabeledElement* pLabel = dynamic_cast< LabeledElement* >(pEle->m_pChild.get());
+ if( pLabel )
+ pLabel->setLabelColumnWidth( nWidth );
+ }
+ }
+ RowOrColumn::resize();
+}
+
+size_t LabelColumn::addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent )
+{
+ boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) );
+ xLabel->setLabel( i_pLabel );
+ xLabel->setBorders( 0, i_nIndent, 0, 0, 0 );
+ xLabel->setElement( i_rElement );
+ size_t nIndex = addChild( xLabel );
+ resize();
+ return nIndex;
+}
+
+size_t LabelColumn::addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent )
+{
+ boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) );
+ xLabel->setLabel( i_pLabel );
+ xLabel->setBorders( 0, i_nIndent, 0, 0, 0 );
+ xLabel->setElement( i_pElement );
+ size_t nIndex = addChild( xLabel );
+ resize();
+ return nIndex;
+}
+
+// ----------------------------------------
+// vcl::Indenter
+//-----------------------------------------
+
+Indenter::~Indenter()
+{
+ m_aElement.deleteChild();
+}
+
+Size Indenter::getOptimalSize( WindowSizeType i_eType ) const
+{
+ Size aSize( m_aElement.getOptimalSize( i_eType ) );
+ aSize.Width() += 2*m_nOuterBorder + m_nIndent;
+ aSize.Height() += 2*m_nOuterBorder;
+ return aSize;
+}
+
+void Indenter::resize()
+{
+ Point aPt( m_aManagedArea.TopLeft() );
+ aPt.X() += m_nOuterBorder + m_nIndent;
+ aPt.Y() += m_nOuterBorder;
+ Size aSz( m_aManagedArea.GetSize() );
+ aSz.Width() -= 2*m_nOuterBorder + m_nIndent;
+ aSz.Height() -= 2*m_nOuterBorder;
+ m_aElement.setPosSize( aPt, aSz );
+}
+
+void Indenter::setWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio )
+{
+ OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0) || i_pWindow == 0 );
+ OSL_VERIFY( i_pWindow == 0 || i_pWindow->GetParent() == m_pParentWindow );
+ m_aElement.m_pElement = i_pWindow;
+ m_aElement.m_nExpandPriority = i_nExpandPrio;
+}
+
+void Indenter::setChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio )
+{
+ OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0 ) || i_pChild == 0 );
+ m_aElement.m_pChild = i_pChild;
+ m_aElement.m_nExpandPriority = i_nExpandPrio;
+}
+
+// ----------------------------------------
+// vcl::MatrixArranger
+//-----------------------------------------
+MatrixArranger::~MatrixArranger()
+{
+}
+
+Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights ) const
+{
+ Size aMatrixSize( 2*m_nOuterBorder, 2*m_nOuterBorder );
+
+ // first find out the current number of rows and columns
+ sal_uInt32 nRows = 0, nColumns = 0;
+ for( std::vector< MatrixElement >::const_iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->m_nX >= nColumns )
+ nColumns = it->m_nX+1;
+ if( it->m_nY >= nRows )
+ nRows = it->m_nY+1;
+ }
+
+ // now allocate row and column depth vectors
+ o_rColumnWidths = std::vector< long >( nColumns, 0 );
+ o_rRowHeights = std::vector< long >( nRows, 0 );
+
+ // get sizes an allocate them into rows/columns
+ for( std::vector< MatrixElement >::const_iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ Size aSize( it->getOptimalSize( i_eType ) );
+ if( aSize.Width() > o_rColumnWidths[ it->m_nX ] )
+ o_rColumnWidths[ it->m_nX ] = aSize.Width();
+ if( aSize.Height() > o_rRowHeights[ it->m_nY ] )
+ o_rRowHeights[ it->m_nY ] = aSize.Height();
+ }
+
+ // add up sizes
+ for( sal_uInt32 i = 0; i < nColumns; i++ )
+ aMatrixSize.Width() += o_rColumnWidths[i] + m_nBorderX;
+ if( nColumns > 0 )
+ aMatrixSize.Width() -= m_nBorderX;
+
+ for( sal_uInt32 i = 0; i < nRows; i++ )
+ aMatrixSize.Height() += o_rRowHeights[i] + m_nBorderY;
+ if( nRows > 0 )
+ aMatrixSize.Height() -= m_nBorderY;
+
+ return aMatrixSize;
+}
+
+Size MatrixArranger::getOptimalSize( WindowSizeType i_eType ) const
+{
+ std::vector<long> aColumnWidths, aRowHeights;
+ return getOptimalSize( i_eType, aColumnWidths, aRowHeights );
+}
+
+void MatrixArranger::resize()
+{
+ // assure that we have at least one row and column
+ if( m_aElements.empty() )
+ return;
+
+ // check if we can get optimal size, else fallback to minimal size
+ std::vector<long> aColumnWidths, aRowHeights;
+ Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED, aColumnWidths, aRowHeights ) );
+ if( aOptSize.Height() > m_aManagedArea.GetHeight() ||
+ aOptSize.Width() > m_aManagedArea.GetWidth() )
+ {
+ std::vector<long> aMinColumnWidths, aMinRowHeights;
+ getOptimalSize( WINDOWSIZE_MINIMUM, aMinColumnWidths, aMinRowHeights );
+ if( aOptSize.Height() > m_aManagedArea.GetHeight() )
+ aRowHeights = aMinRowHeights;
+ if( aOptSize.Width() > m_aManagedArea.GetWidth() )
+ aColumnWidths = aMinColumnWidths;
+ }
+
+ // FIXME: distribute extra space available
+
+ // prepare offsets
+ std::vector<long> aColumnX( aColumnWidths.size() );
+ aColumnX[0] = m_aManagedArea.Left() + m_nOuterBorder;
+ for( size_t i = 1; i < aColumnX.size(); i++ )
+ aColumnX[i] = aColumnX[i-1] + aColumnWidths[i-1] + m_nBorderX;
+
+ std::vector<long> aRowY( aRowHeights.size() );
+ aRowY[0] = m_aManagedArea.Top() + m_nOuterBorder;
+ for( size_t i = 1; i < aRowY.size(); i++ )
+ aRowY[i] = aRowY[i-1] + aRowHeights[i-1] + m_nBorderY;
+
+ // now iterate over the elements and assign their positions
+ for( std::vector< MatrixElement >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ Point aCellPos( aColumnX[it->m_nX], aRowY[it->m_nY] );
+ Size aCellSize( aColumnWidths[it->m_nX], aRowHeights[it->m_nY] );
+ it->setPosSize( aCellPos, aCellSize );
+ }
+}
+
+size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio )
+{
+ sal_uInt64 nMapValue = getMap( i_nX, i_nY );
+ std::map< sal_uInt64, size_t >::const_iterator it = m_aMatrixMap.find( nMapValue );
+ size_t nIndex = 0;
+ if( it == m_aMatrixMap.end() )
+ {
+ m_aMatrixMap[ nMapValue ] = nIndex = m_aElements.size();
+ m_aElements.push_back( MatrixElement( i_pWindow, i_nX, i_nY, boost::shared_ptr<WindowArranger>(), i_nExpandPrio ) );
+ }
+ else
+ {
+ MatrixElement& rEle( m_aElements[ it->second ] );
+ rEle.m_pElement = i_pWindow;
+ rEle.m_pChild.reset();
+ rEle.m_nExpandPriority = i_nExpandPrio;
+ rEle.m_nX = i_nX;
+ rEle.m_nY = i_nY;
+ nIndex = it->second;
+ }
+ return nIndex;
+}
+
+void MatrixArranger::remove( Window* i_pWindow )
+{
+ if( i_pWindow )
+ {
+ for( std::vector< MatrixElement >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->m_pElement == i_pWindow )
+ {
+ m_aMatrixMap.erase( getMap( it->m_nX, it->m_nY ) );
+ m_aElements.erase( it );
+ return;
+ }
+ }
+ }
+}
+
+size_t MatrixArranger::addChild( boost::shared_ptr<WindowArranger> const &i_pChild, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio )
+{
+ sal_uInt64 nMapValue = getMap( i_nX, i_nY );
+ std::map< sal_uInt64, size_t >::const_iterator it = m_aMatrixMap.find( nMapValue );
+ size_t nIndex = 0;
+ if( it == m_aMatrixMap.end() )
+ {
+ m_aMatrixMap[ nMapValue ] = nIndex = m_aElements.size();
+ m_aElements.push_back( MatrixElement( NULL, i_nX, i_nY, i_pChild, i_nExpandPrio ) );
+ }
+ else
+ {
+ MatrixElement& rEle( m_aElements[ it->second ] );
+ rEle.m_pElement = 0;
+ rEle.m_pChild = i_pChild;
+ rEle.m_nExpandPriority = i_nExpandPrio;
+ rEle.m_nX = i_nX;
+ rEle.m_nY = i_nY;
+ nIndex = it->second;
+ }
+ return nIndex;
+}
+
+void MatrixArranger::remove( boost::shared_ptr<WindowArranger> const &i_pChild )
+{
+ if( i_pChild )
+ {
+ for( std::vector< MatrixElement >::iterator it = m_aElements.begin();
+ it != m_aElements.end(); ++it )
+ {
+ if( it->m_pChild == i_pChild )
+ {
+ m_aMatrixMap.erase( getMap( it->m_nX, it->m_nY ) );
+ m_aElements.erase( it );
+ return;
+ }
+ }
+ }
+}
+
diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk
index 169cf44b2b13..21b8efe4c586 100644
--- a/vcl/source/window/makefile.mk
+++ b/vcl/source/window/makefile.mk
@@ -8,7 +8,7 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.25 $
+# $Revision: 1.25.114.1 $
#
# This file is part of OpenOffice.org.
#
@@ -45,6 +45,7 @@ ENABLE_EXCEPTIONS=TRUE
# --- Files --------------------------------------------------------
SLOFILES= \
+ $(SLO)$/arrange.obj \
$(SLO)$/abstdlg.obj \
$(SLO)$/accel.obj \
$(SLO)$/accmgr.obj \
@@ -70,6 +71,7 @@ SLOFILES= \
$(SLO)$/mnemonicengine.obj \
$(SLO)$/msgbox.obj \
$(SLO)$/scrwnd.obj \
+ $(SLO)$/printdlg.obj \
$(SLO)$/seleng.obj \
$(SLO)$/split.obj \
$(SLO)$/splitwin.obj \
diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx
new file mode 100644
index 000000000000..649ca21a32b8
--- /dev/null
+++ b/vcl/source/window/printdlg.cxx
@@ -0,0 +1,2489 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: printdlg.cxx,v $
+ * $Revision: 1.1.2.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_vcl.hxx"
+
+#include "vcl/print.hxx"
+#include "vcl/prndlg.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/svids.hrc"
+#include "vcl/wall.hxx"
+#include "vcl/jobset.h"
+#include "vcl/status.hxx"
+#include "vcl/decoview.hxx"
+#include "vcl/arrange.hxx"
+#include "vcl/configsettings.hxx"
+#include "vcl/help.hxx"
+#include "vcl/decoview.hxx"
+#include "vcl/svapp.hxx"
+
+#include "unotools/localedatawrapper.hxx"
+
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/awt/Size.hpp"
+
+using namespace vcl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+
+#define HELPID_PREFIX ".HelpId:vcl:PrintDialog"
+#define SMHID2( a, b ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ":" b ) ), HID_PRINTDLG ) )
+#define SMHID1( a ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ) ), HID_PRINTDLG ) )
+
+PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId )
+ : Window( i_pParent, i_rId )
+ , maOrigSize( 10, 10 )
+ , maPageVDev( *this )
+ , maToolTipString( String( VclResId( SV_PRINT_PRINTPREVIEW_TXT ) ) )
+{
+ SetPaintTransparent( TRUE );
+ SetBackground();
+ if( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
+ else
+ maPageVDev.SetBackground( Color( COL_WHITE ) );
+}
+
+PrintDialog::PrintPreviewWindow::~PrintPreviewWindow()
+{
+}
+
+void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt )
+{
+ // react on settings changed
+ if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS )
+ {
+ if( GetSettings().GetStyleSettings().GetHighContrastMode() )
+ maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
+ else
+ maPageVDev.SetBackground( Color( COL_WHITE ) );
+ }
+ Window::DataChanged( i_rDCEvt );
+}
+
+void PrintDialog::PrintPreviewWindow::Resize()
+{
+ Size aNewSize( GetSizePixel() );
+ // leave small space for decoration
+ aNewSize.Width() -= 2;
+ aNewSize.Height() -= 2;
+ Size aScaledSize;
+ double fScale = 1.0;
+
+ // #i106435# catch corner case of Size(0,0)
+ Size aOrigSize( maOrigSize );
+ if( aOrigSize.Width() < 1 )
+ aOrigSize.Width() = aNewSize.Width();
+ if( aOrigSize.Height() < 1 )
+ aOrigSize.Height() = aNewSize.Height();
+ if( aOrigSize.Width() > aOrigSize.Height() )
+ {
+ aScaledSize = Size( aNewSize.Width(), aNewSize.Width() * aOrigSize.Height() / aOrigSize.Width() );
+ if( aScaledSize.Height() > aNewSize.Height() )
+ fScale = double(aNewSize.Height())/double(aScaledSize.Height());
+ }
+ else
+ {
+ aScaledSize = Size( aNewSize.Height() * aOrigSize.Width() / aOrigSize.Height(), aNewSize.Height() );
+ if( aScaledSize.Width() > aNewSize.Width() )
+ fScale = double(aNewSize.Width())/double(aScaledSize.Width());
+ }
+ aScaledSize.Width() = long(aScaledSize.Width()*fScale);
+ aScaledSize.Height() = long(aScaledSize.Height()*fScale);
+ maPageVDev.SetOutputSizePixel( aScaledSize, FALSE );
+}
+
+void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& )
+{
+ Size aSize( GetSizePixel() );
+ if( maReplacementString.getLength() != 0 )
+ {
+ // replacement is active
+ Push();
+ Rectangle aTextRect( Point( 0, 0 ), aSize );
+ Font aFont( GetSettings().GetStyleSettings().GetFieldFont() );
+ aFont.SetSize( Size( 0, aSize.Height()/12 ) );
+ SetFont( aFont );
+ DrawText( aTextRect, maReplacementString,
+ TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE
+ );
+ Pop();
+ }
+ else
+ {
+ GDIMetaFile aMtf( maMtf );
+
+ Size aPreviewSize = maPageVDev.GetOutputSizePixel();
+ Point aOffset( (aSize.Width() - aPreviewSize.Width()) / 2,
+ (aSize.Height() - aPreviewSize.Height()) / 2 );
+
+ const Size aLogicSize( maPageVDev.PixelToLogic( aPreviewSize, MapMode( MAP_100TH_MM ) ) );
+ Size aOrigSize( maOrigSize );
+ if( aOrigSize.Width() < 1 )
+ aOrigSize.Width() = aLogicSize.Width();
+ if( aOrigSize.Height() < 1 )
+ aOrigSize.Height() = aLogicSize.Height();
+ double fScale = double(aLogicSize.Width())/double(aOrigSize.Width());
+
+
+ maPageVDev.Erase();
+ maPageVDev.Push();
+ maPageVDev.SetMapMode( MAP_100TH_MM );
+ aMtf.WindStart();
+ aMtf.Scale( fScale, fScale );
+ aMtf.WindStart();
+ aMtf.Play( &maPageVDev, Point( 0, 0 ), aLogicSize );
+ maPageVDev.Pop();
+
+ SetMapMode( MAP_PIXEL );
+ maPageVDev.SetMapMode( MAP_PIXEL );
+ DrawOutDev( aOffset, aPreviewSize, Point( 0, 0 ), aPreviewSize, maPageVDev );
+
+ DecorationView aVw( this );
+ aOffset.X() -= 1; aOffset.Y() -=1; aPreviewSize.Width() += 2; aPreviewSize.Height() += 2;
+ aVw.DrawFrame( Rectangle( aOffset, aPreviewSize ), FRAME_DRAW_GROUP );
+ }
+}
+
+void PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt )
+{
+ if( rEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pWheelData = rEvt.GetWheelData();
+ PrintDialog* pDlg = dynamic_cast<PrintDialog*>(GetParent());
+ if( pDlg )
+ {
+ if( pWheelData->GetDelta() > 0 )
+ pDlg->previewForward();
+ else if( pWheelData->GetDelta() < 0 )
+ pDlg->previewBackward();
+ /*
+ else
+ huh ?
+ */
+ }
+ }
+}
+
+void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview,
+ const Size& i_rOrigSize,
+ const rtl::OUString& i_rReplacement,
+ sal_Int32 i_nDPIX,
+ sal_Int32 i_nDPIY
+ )
+{
+ rtl::OUStringBuffer aBuf( 256 );
+ aBuf.append( maToolTipString );
+ #if OSL_DEBUG_LEVEL > 0
+ aBuf.appendAscii( "\n---\nPageSize: " );
+ aBuf.append( sal_Int32( i_rOrigSize.Width()/100) );
+ aBuf.appendAscii( "mm x " );
+ aBuf.append( sal_Int32( i_rOrigSize.Height()/100) );
+ aBuf.appendAscii( "mm" );
+ #endif
+ SetQuickHelpText( aBuf.makeStringAndClear() );
+ maMtf = i_rNewPreview;
+ if( GetSettings().GetStyleSettings().GetHighContrastMode() &&
+ GetSettings().GetStyleSettings().GetWindowColor().IsDark()
+ )
+ {
+ maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 );
+ }
+
+ maOrigSize = i_rOrigSize;
+ maReplacementString = i_rReplacement;
+ maPageVDev.SetReferenceDevice( i_nDPIX, i_nDPIY );
+ maPageVDev.EnableOutput( TRUE );
+ Resize();
+ Invalidate();
+}
+
+PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow( Window* i_pParent )
+ : Window( i_pParent, WB_NOBORDER )
+ , mnOrderMode( 0 )
+ , mnRows( 1 )
+ , mnColumns( 1 )
+{
+ ImplInitSettings();
+}
+
+PrintDialog::ShowNupOrderWindow::~ShowNupOrderWindow()
+{
+}
+
+void PrintDialog::ShowNupOrderWindow::ImplInitSettings()
+{
+ SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
+}
+
+void PrintDialog::ShowNupOrderWindow::Paint( const Rectangle& i_rRect )
+{
+ Window::Paint( i_rRect );
+ SetMapMode( MAP_PIXEL );
+ SetTextColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
+
+ int nPages = mnRows * mnColumns;
+ Font aFont( GetSettings().GetStyleSettings().GetFieldFont() );
+ aFont.SetSize( Size( 0, 24 ) );
+ SetFont( aFont );
+ Size aSampleTextSize( GetTextWidth( rtl::OUString::valueOf( sal_Int32(nPages+1) ) ), GetTextHeight() );
+
+ Size aOutSize( GetOutputSizePixel() );
+ Size aSubSize( aOutSize.Width() / mnColumns, aOutSize.Height() / mnRows );
+ // calculate font size: shrink the sample text so it fits
+ double fX = double(aSubSize.Width())/double(aSampleTextSize.Width());
+ double fY = double(aSubSize.Height())/double(aSampleTextSize.Height());
+ double fScale = (fX < fY) ? fX : fY;
+ long nFontHeight = long(24.0*fScale) - 3;
+ if( nFontHeight < 5 )
+ nFontHeight = 5;
+ aFont.SetSize( Size( 0, nFontHeight ) );
+ SetFont( aFont );
+ long nTextHeight = GetTextHeight();
+ for( int i = 0; i < nPages; i++ )
+ {
+ rtl::OUString aPageText( rtl::OUString::valueOf( sal_Int32(i+1) ) );
+ int nX = 0, nY = 0;
+ switch( mnOrderMode )
+ {
+ case SV_PRINT_PRT_NUP_ORDER_LRTD:
+ nX = (i % mnColumns); nY = (i / mnColumns);
+ break;
+ case SV_PRINT_PRT_NUP_ORDER_TDLR:
+ nX = (i / mnRows); nY = (i % mnRows);
+ break;
+ }
+ Size aTextSize( GetTextWidth( aPageText ), nTextHeight );
+ int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2;
+ int nDeltaY = (aSubSize.Height() - aTextSize.Height()) / 2;
+ DrawText( Point( nX * aSubSize.Width() + nDeltaX,
+ nY * aSubSize.Height() + nDeltaY ),
+ aPageText );
+ }
+ DecorationView aVw( this );
+ aVw.DrawFrame( Rectangle( Point( 0, 0), aOutSize ), FRAME_DRAW_GROUP );
+}
+
+PrintDialog::NUpTabPage::NUpTabPage( Window* i_pParent, const ResId& rResId )
+ : TabPage( i_pParent, rResId )
+ , maNupLine( this, VclResId( SV_PRINT_PRT_NUP_LAYOUT_FL ) )
+ , maPagesBtn( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BTN ) )
+ , maBrochureBtn( this, VclResId( SV_PRINT_PRT_NUP_BROCHURE_BTN ) )
+ , maPagesBoxTitleTxt( this, 0 )
+ , maNupPagesBox( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BOX ) )
+ , maNupNumPagesTxt( this, VclResId( SV_PRINT_PRT_NUP_NUM_PAGES_TXT ) )
+ , maNupColEdt( this, VclResId( SV_PRINT_PRT_NUP_COLS_EDT ) )
+ , maNupTimesTxt( this, VclResId( SV_PRINT_PRT_NUP_TIMES_TXT ) )
+ , maNupRowsEdt( this, VclResId( SV_PRINT_PRT_NUP_ROWS_EDT ) )
+ , maPageMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT ) )
+ , maPageMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT ) )
+ , maPageMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT ) )
+ , maSheetMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT ) )
+ , maSheetMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT ) )
+ , maSheetMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT ) )
+ , maNupOrientationTxt( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_TXT ) )
+ , maNupOrientationBox( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_BOX ) )
+ , maNupOrderTxt( this, VclResId( SV_PRINT_PRT_NUP_ORDER_TXT ) )
+ , maNupOrderBox( this, VclResId( SV_PRINT_PRT_NUP_ORDER_BOX ) )
+ , maNupOrderWin( this )
+ , maBorderCB( this, VclResId( SV_PRINT_PRT_NUP_BORDER_CB ) )
+{
+ FreeResource();
+
+ maNupOrderWin.Show();
+ maPagesBtn.Check( TRUE );
+ maBrochureBtn.Show( FALSE );
+
+ // setup field units for metric fields
+ const LocaleDataWrapper& rLocWrap( maPageMarginEdt.GetLocaleDataWrapper() );
+ FieldUnit eUnit = FUNIT_MM;
+ USHORT nDigits = 0;
+ if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US )
+ {
+ eUnit = FUNIT_INCH;
+ nDigits = 2;
+ }
+ // set units
+ maPageMarginEdt.SetUnit( eUnit );
+ maSheetMarginEdt.SetUnit( eUnit );
+
+ // set precision
+ maPageMarginEdt.SetDecimalDigits( nDigits );
+ maSheetMarginEdt.SetDecimalDigits( nDigits );
+
+ SMHID1( "NUpPage" );
+ maNupLine.SMHID2("NUpPage", "Layout");
+ maBrochureBtn.SMHID2("NUpPage", "Brochure" );
+ maPagesBtn.SMHID2( "NUpPage", "PagesPerSheet" );
+ maPagesBoxTitleTxt.SMHID2( "NUpPage", "PagesPerSheetLabel" );
+ maNupPagesBox.SMHID2( "NUpPage", "PagesPerSheetBox" );
+ maNupNumPagesTxt.SMHID2( "NUpPage", "Columns" );
+ maNupColEdt.SMHID2( "NUpPage", "ColumnsBox" );
+ maNupTimesTxt.SMHID2( "NUpPage", "Rows" );
+ maNupRowsEdt.SMHID2( "NUpPage", "RowsBox" );
+ maPageMarginTxt1.SMHID2( "NUpPage", "PageMargin" );
+ maPageMarginEdt.SMHID2( "NUpPage", "PageMarginBox" );
+ maPageMarginTxt2.SMHID2( "NUpPage", "PageMarginCont" );
+ maSheetMarginTxt1.SMHID2( "NUpPage", "SheetMargin" );
+ maSheetMarginEdt.SMHID2( "NUpPage", "SheetMarginBox" );
+ maSheetMarginTxt2.SMHID2( "NUpPage", "SheetMarginCont" );
+ maNupOrientationTxt.SMHID2( "NUpPage", "Orientation" );
+ maNupOrientationBox.SMHID2( "NUpPage", "OrientationBox" );
+ maNupOrderTxt.SMHID2( "NUpPage", "Order" );
+ maNupOrderBox.SMHID2( "NUpPage", "OrderBox" );
+ maBorderCB.SMHID2( "NUpPage", "BorderBox" );
+
+ setupLayout();
+}
+
+PrintDialog::NUpTabPage::~NUpTabPage()
+{
+}
+
+void PrintDialog::NUpTabPage::enableNupControls( bool bEnable )
+{
+ maNupPagesBox.Enable( TRUE );
+ maNupNumPagesTxt.Enable( bEnable );
+ maNupColEdt.Enable( bEnable );
+ maNupTimesTxt.Enable( bEnable );
+ maNupRowsEdt.Enable( bEnable );
+ maPageMarginTxt1.Enable( bEnable );
+ maPageMarginEdt.Enable( bEnable );
+ maPageMarginTxt2.Enable( bEnable );
+ maSheetMarginTxt1.Enable( bEnable );
+ maSheetMarginEdt.Enable( bEnable );
+ maSheetMarginTxt2.Enable( bEnable );
+ maNupOrientationTxt.Enable( bEnable );
+ maNupOrientationBox.Enable( bEnable );
+ maNupOrderTxt.Enable( bEnable );
+ maNupOrderBox.Enable( bEnable );
+ maNupOrderWin.Enable( bEnable );
+ maBorderCB.Enable( bEnable );
+}
+
+void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow )
+{
+ maNupNumPagesTxt.Show( i_bShow );
+ maNupColEdt.Show( i_bShow );
+ maNupTimesTxt.Show( i_bShow );
+ maNupRowsEdt.Show( i_bShow );
+ maPageMarginTxt1.Show( i_bShow );
+ maPageMarginEdt.Show( i_bShow );
+ maPageMarginTxt2.Show( i_bShow );
+ maSheetMarginTxt1.Show( i_bShow );
+ maSheetMarginEdt.Show( i_bShow );
+ maSheetMarginTxt2.Show( i_bShow );
+ maNupOrientationTxt.Show( i_bShow );
+ maNupOrientationBox.Show( i_bShow );
+ maLayout.resize();
+}
+
+void PrintDialog::NUpTabPage::setupLayout()
+{
+ Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) );
+ long nIndent = 3*aBorder.Width();
+
+ maLayout.setParentWindow( this );
+ maLayout.setOuterBorder( aBorder.Width() );
+
+ maLayout.addWindow( &maNupLine );
+ boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( &maLayout, false ) );
+ maLayout.addChild( xRow );
+ boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xRow.get() ) );
+ xRow->addChild( xIndent );
+
+ boost::shared_ptr< vcl::RowOrColumn > xShowNupCol( new vcl::RowOrColumn( xRow.get() ) );
+ xRow->addChild( xShowNupCol, -1 );
+ xShowNupCol->setMinimumSize( xShowNupCol->addWindow( &maNupOrderWin ), Size( 70, 70 ) );
+ boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( xShowNupCol.get() ) );
+ xShowNupCol->addChild( xSpacer );
+
+ boost::shared_ptr< vcl::LabelColumn > xMainCol( new vcl::LabelColumn( xIndent.get() ) );
+ xIndent->setChild( xMainCol );
+
+ size_t nPagesIndex = xMainCol->addRow( &maPagesBtn, &maNupPagesBox );
+ mxPagesBtnLabel = boost::dynamic_pointer_cast<vcl::LabeledElement>( xMainCol->getChild( nPagesIndex ) );
+
+ xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) );
+ xMainCol->addRow( &maNupNumPagesTxt, xRow, nIndent );
+ xRow->addWindow( &maNupColEdt );
+ xRow->addWindow( &maNupTimesTxt );
+ xRow->addWindow( &maNupRowsEdt );
+
+ boost::shared_ptr< vcl::LabeledElement > xLab( new vcl::LabeledElement( xMainCol.get(), 2 ) );
+ xLab->setLabel( &maPageMarginEdt );
+ xLab->setElement( &maPageMarginTxt2 );
+ xMainCol->addRow( &maPageMarginTxt1, xLab, nIndent );
+
+ xLab.reset( new vcl::LabeledElement( xMainCol.get(), 2 ) );
+ xLab->setLabel( &maSheetMarginEdt );
+ xLab->setElement( &maSheetMarginTxt2 );
+ xMainCol->addRow( &maSheetMarginTxt1, xLab, nIndent );
+
+ xMainCol->addRow( &maNupOrientationTxt, &maNupOrientationBox, nIndent );
+ xMainCol->addRow( &maNupOrderTxt, &maNupOrderBox, nIndent );
+ xMainCol->setBorders( xMainCol->addWindow( &maBorderCB ), nIndent, 0, 0, 0 );
+
+ xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, aBorder.Width() ) ) );
+ xMainCol->addChild( xSpacer );
+
+ xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) );
+ xMainCol->addRow( &maBrochureBtn, xRow );
+ // remember brochure row for dependencies
+ mxBrochureDep = xRow;
+
+ // initially advanced controls are not shown, rows=columns=1
+ showAdvancedControls( false );
+}
+
+void PrintDialog::NUpTabPage::Resize()
+{
+ maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
+}
+
+void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS )
+{
+ maSheetMarginEdt.SetValue( maSheetMarginEdt.Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM );
+ maPageMarginEdt.SetValue( maPageMarginEdt.Normalize( i_rMPS.nHorizontalSpacing ), FUNIT_100TH_MM );
+ maBorderCB.Check( i_rMPS.bDrawBorder );
+ maNupRowsEdt.SetValue( i_rMPS.nRows );
+ maNupColEdt.SetValue( i_rMPS.nColumns );
+}
+
+void PrintDialog::NUpTabPage::readFromSettings()
+{
+}
+
+void PrintDialog::NUpTabPage::storeToSettings()
+{
+}
+
+PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId )
+ : TabPage( i_pParent, rResId )
+ , maPrinterFL( this, VclResId( SV_PRINT_PRINTERS_FL ) )
+ , maPrinters( this, VclResId( SV_PRINT_PRINTERS ) )
+ , maDetailsBtn( this, VclResId( SV_PRINT_DETAILS_BTN ) )
+ , maStatusLabel( this, VclResId( SV_PRINT_STATUS_TXT ) )
+ , maStatusTxt( this, 0 )
+ , maLocationLabel( this, VclResId( SV_PRINT_LOCATION_TXT ) )
+ , maLocationTxt( this, 0 )
+ , maCommentLabel( this, VclResId( SV_PRINT_COMMENT_TXT ) )
+ , maCommentTxt( this, 0 )
+ , maSetupButton( this, VclResId( SV_PRINT_PRT_SETUP ) )
+ , maCopies( this, VclResId( SV_PRINT_COPIES ) )
+ , maCopySpacer( this, WB_VERT )
+ , maCopyCount( this, VclResId( SV_PRINT_COPYCOUNT ) )
+ , maCopyCountField( this, VclResId( SV_PRINT_COPYCOUNT_FIELD ) )
+ , maCollateBox( this, VclResId( SV_PRINT_COLLATE ) )
+ , maCollateImage( this, VclResId( SV_PRINT_COLLATE_IMAGE ) )
+ , maCollateImg( VclResId( SV_PRINT_COLLATE_IMG ) )
+ , maCollateHCImg( VclResId( SV_PRINT_COLLATE_HC_IMG ) )
+ , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) )
+ , maNoCollateHCImg( VclResId( SV_PRINT_NOCOLLATE_HC_IMG ) )
+ , mnCollateUIMode( 0 )
+ , maLayout( NULL, true )
+{
+ FreeResource();
+
+ SMHID1( "JobPage" );
+ maPrinterFL.SMHID2( "JobPage", "Printer" );
+ maPrinters.SMHID2( "JobPage", "PrinterList" );
+ maDetailsBtn.SMHID2( "JobPage", "DetailsBtn" );
+ maStatusLabel.SMHID2( "JobPage", "StatusLabel" );
+ maStatusTxt.SMHID2( "JobPage", "StatusText" );
+ maLocationLabel.SMHID2( "JobPage", "LocationLabel" );
+ maLocationTxt.SMHID2( "JobPage", "LocationText" );
+ maCommentLabel.SMHID2( "JobPage", "CommentLabel" );
+ maCommentTxt.SMHID2( "JobPage", "CommentText" );
+ maSetupButton.SMHID2( "JobPage", "Properties" );
+ maCopies.SMHID2( "JobPage", "CopiesLine" );
+ maCopySpacer.SMHID2( "JobPage", "CopySpacer" );
+ maCopyCount.SMHID2( "JobPage", "CopiesText" );
+ maCopyCountField.SMHID2( "JobPage", "Copies" );
+ maCollateBox.SMHID2( "JobPage", "Collate" );
+ maCollateImage.SMHID2( "JobPage", "CollateImage" );
+
+ maCopySpacer.Show();
+ maStatusTxt.Show();
+ maCommentTxt.Show();
+ maLocationTxt.Show();
+
+ setupLayout();
+}
+
+PrintDialog::JobTabPage::~JobTabPage()
+{
+}
+
+void PrintDialog::JobTabPage::setupLayout()
+{
+ // HACK: this is not a dropdown box, but the dropdown line count
+ // sets the results of GetOptimalSize in a normal ListBox
+ maPrinters.SetDropDownLineCount( 4 );
+
+ Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) );
+
+ maLayout.setParentWindow( this );
+ maLayout.setOuterBorder( aBorder.Width() );
+
+ // add printer fixed line
+ maLayout.addWindow( &maPrinterFL );
+ // add print LB
+ maLayout.addWindow( &maPrinters );
+
+ // create a row for details button/text and properties button
+ boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( &maLayout, false ) );
+ maLayout.addChild( xDetRow );
+ xDetRow->addWindow( &maDetailsBtn );
+ xDetRow->addChild( new vcl::Spacer( xDetRow.get(), 2 ) );
+ xDetRow->addWindow( &maSetupButton );
+
+ // create an indent for details
+ boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( &maLayout ) );
+ maLayout.addChild( xIndent );
+ // remember details controls
+ mxDetails = xIndent;
+ // create a column for the details
+ boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get(), aBorder.Height() ) );
+ xIndent->setChild( xLabelCol );
+ xLabelCol->addRow( &maStatusLabel, &maStatusTxt );
+ xLabelCol->addRow( &maLocationLabel, &maLocationTxt );
+ xLabelCol->addRow( &maCommentLabel, &maCommentTxt );
+
+ // add print range and copies columns
+ maLayout.addWindow( &maCopies );
+ boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false, aBorder.Width() ) );
+ maLayout.addChild( xRangeRow );
+
+ // create print range and add to range row
+ mxPrintRange.reset( new vcl::RowOrColumn( xRangeRow.get() ) );
+ xRangeRow->addChild( mxPrintRange );
+ xRangeRow->addWindow( &maCopySpacer );
+
+ boost::shared_ptr< vcl::RowOrColumn > xCopyCollateCol( new vcl::RowOrColumn( xRangeRow.get() ) );
+ xRangeRow->addChild( xCopyCollateCol );
+
+ // add copies row to copy/collate column
+ boost::shared_ptr< vcl::LabeledElement > xCopiesRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) );
+ xCopyCollateCol->addChild( xCopiesRow );
+ xCopiesRow->setLabel( &maCopyCount );
+ xCopiesRow->setElement( &maCopyCountField );
+ boost::shared_ptr< vcl::LabeledElement > xCollateRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) );
+ xCopyCollateCol->addChild( xCollateRow );
+ xCollateRow->setLabel( &maCollateBox );
+ xCollateRow->setElement( &maCollateImage );
+
+ // maDetailsBtn.SetStyle( maDetailsBtn.GetStyle() | (WB_SMALLSTYLE | WB_BEVELBUTTON) );
+ mxDetails->show( false, false );
+}
+
+void PrintDialog::JobTabPage::readFromSettings()
+{
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ rtl::OUString aValue;
+
+ #if 0
+ // do not actually make copy count persistent
+ // the assumption is that this would lead to a lot of unwanted copies
+ aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) );
+ sal_Int32 nVal = aValue.toInt32();
+ maCopyCountField.SetValue( sal_Int64(nVal > 1 ? nVal : 1) );
+ #endif
+
+ aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CollateBox" ) ) );
+ if( aValue.equalsIgnoreAsciiCaseAscii( "alwaysoff" ) )
+ {
+ mnCollateUIMode = 1;
+ maCollateBox.Check( FALSE );
+ maCollateBox.Enable( FALSE );
+ }
+ else
+ {
+ mnCollateUIMode = 0;
+ aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) );
+ maCollateBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) );
+ }
+ Resize();
+}
+
+void PrintDialog::JobTabPage::storeToSettings()
+{
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ),
+ maCopyCountField.GetText() );
+ pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
+ rtl::OUString::createFromAscii( maCollateBox.IsChecked() ? "true" : "false" ) );
+}
+
+void PrintDialog::JobTabPage::Resize()
+{
+ maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
+}
+
+PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rResId )
+ : TabPage( i_pParent, i_rResId )
+ , maOptionsLine( this, VclResId( SV_PRINT_OPT_PRINT_FL ) )
+ , maToFileBox( this, VclResId( SV_PRINT_OPT_TOFILE ) )
+ , maCollateSingleJobsBox( this, VclResId( SV_PRINT_OPT_SINGLEJOBS ) )
+ , maReverseOrderBox( this, VclResId( SV_PRINT_OPT_REVERSE ) )
+{
+ FreeResource();
+ SMHID1( "OptPage" );
+ maOptionsLine.SMHID2( "OptPage", "Options" );
+ maToFileBox.SMHID2( "OptPage", "ToFile" );
+ maCollateSingleJobsBox.SMHID2( "OptPage", "SingleJobs" );
+ maReverseOrderBox.SMHID2( "OptPage", "Reverse" );
+
+ setupLayout();
+}
+
+PrintDialog::OutputOptPage::~OutputOptPage()
+{
+}
+
+void PrintDialog::OutputOptPage::setupLayout()
+{
+ Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) );
+
+ maLayout.setParentWindow( this );
+ maLayout.setOuterBorder( aBorder.Width() );
+
+ maLayout.addWindow( &maOptionsLine );
+ boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( &maLayout, aBorder.Width() ) );
+ maLayout.addChild( xIndent );
+ boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get(), aBorder.Height() ) );
+ xIndent->setChild( xCol );
+ mxOptGroup = xCol;
+ xCol->addWindow( &maToFileBox );
+ xCol->addWindow( &maCollateSingleJobsBox );
+ xCol->addWindow( &maReverseOrderBox );
+}
+
+void PrintDialog::OutputOptPage::readFromSettings()
+{
+ #if 0
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ rtl::OUString aValue;
+
+ aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ) );
+ maToFileBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) );
+ #endif
+}
+
+void PrintDialog::OutputOptPage::storeToSettings()
+{
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ),
+ rtl::OUString::createFromAscii( maToFileBox.IsChecked() ? "true" : "false" ) );
+}
+
+void PrintDialog::OutputOptPage::Resize()
+{
+ maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
+}
+
+
+PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterController>& i_rController )
+ : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) )
+ , maOKButton( this, VclResId( SV_PRINT_OK ) )
+ , maCancelButton( this, VclResId( SV_PRINT_CANCEL ) )
+ , maHelpButton( this, VclResId( SV_PRINT_HELP ) )
+ , maPreviewWindow( this, VclResId( SV_PRINT_PAGE_PREVIEW ) )
+ , maPageEdit( this, VclResId( SV_PRINT_PAGE_EDIT ) )
+ , maNumPagesText( this, VclResId( SV_PRINT_PAGE_TXT ) )
+ , maBackwardBtn( this, VclResId( SV_PRINT_PAGE_BACKWARD ) )
+ , maForwardBtn( this, VclResId( SV_PRINT_PAGE_FORWARD ) )
+ , maTabCtrl( this, VclResId( SV_PRINT_TABCTRL ) )
+ , maNUpPage( &maTabCtrl, VclResId( SV_PRINT_TAB_NUP ) )
+ , maJobPage( &maTabCtrl, VclResId( SV_PRINT_TAB_JOB ) )
+ , maOptionsPage( &maTabCtrl, VclResId( SV_PRINT_TAB_OPT ) )
+ , maButtonLine( this, VclResId( SV_PRINT_BUTTONLINE ) )
+ , maPController( i_rController )
+ , maNoPageStr( String( VclResId( SV_PRINT_NOPAGES ) ) )
+ , mnCurPage( 0 )
+ , mnCachedPages( 0 )
+ , maPrintToFileText( String( VclResId( SV_PRINT_TOFILE_TXT ) ) )
+ , maDefPrtText( String( VclResId( SV_PRINT_DEFPRT_TXT ) ) )
+ , mbShowLayoutPage( sal_True )
+{
+ FreeResource();
+
+ // save printbutton text, gets exchanged occasionally with print to file
+ maPrintText = maOKButton.GetText();
+
+ // setup preview controls
+ maForwardBtn.SetStyle( maForwardBtn.GetStyle() | WB_BEVELBUTTON );
+ maBackwardBtn.SetStyle( maBackwardBtn.GetStyle() | WB_BEVELBUTTON );
+
+ // insert the job (general) tab page first
+ maTabCtrl.InsertPage( SV_PRINT_TAB_JOB, maJobPage.GetText() );
+ maTabCtrl.SetTabPage( SV_PRINT_TAB_JOB, &maJobPage );
+
+ // set symbols on forward and backward button
+ maBackwardBtn.SetSymbol( SYMBOL_PREV );
+ maForwardBtn.SetSymbol( SYMBOL_NEXT );
+ maBackwardBtn.ImplSetSmallSymbol( TRUE );
+ maForwardBtn.ImplSetSmallSymbol( TRUE );
+
+ maPageStr = maNumPagesText.GetText();
+
+ // init reverse print
+ maOptionsPage.maReverseOrderBox.Check( maPController->getReversePrint() );
+
+ // get the first page
+ preparePreview( true, true );
+
+ // fill printer listbox
+ const std::vector< rtl::OUString >& rQueues( Printer::GetPrinterQueues() );
+ for( std::vector< rtl::OUString >::const_iterator it = rQueues.begin();
+ it != rQueues.end(); ++it )
+ {
+ maJobPage.maPrinters.InsertEntry( *it );
+ }
+ // select current printer
+ if( maJobPage.maPrinters.GetEntryPos( maPController->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND )
+ {
+ maJobPage.maPrinters.SelectEntry( maPController->getPrinter()->GetName() );
+ }
+ else
+ {
+ // fall back to last printer
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ String aValue( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ) ) );
+ if( maJobPage.maPrinters.GetEntryPos( aValue ) != LISTBOX_ENTRY_NOTFOUND )
+ {
+ maJobPage.maPrinters.SelectEntry( aValue );
+ maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aValue ) ) );
+ }
+ else
+ {
+ // fall back to default printer
+ maJobPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() );
+ maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) );
+ }
+ }
+ // update the text fields for the printer
+ updatePrinterText();
+
+ // set a select handler
+ maJobPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
+
+ // setup sizes for N-Up
+ Size aNupSize( maPController->getPrinter()->PixelToLogic(
+ maPController->getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
+ if( maPController->getPrinter()->GetOrientation() == ORIENTATION_LANDSCAPE )
+ {
+ maNupLandscapeSize = aNupSize;
+ maNupPortraitSize = Size( aNupSize.Height(), aNupSize.Width() );
+ }
+ else
+ {
+ maNupPortraitSize = aNupSize;
+ maNupLandscapeSize = Size( aNupSize.Height(), aNupSize.Width() );
+ }
+ maNUpPage.initFromMultiPageSetup( maPController->getMultipage() );
+
+
+ // setup click handler on the various buttons
+ maOKButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ #if OSL_DEBUG_LEVEL > 1
+ maCancelButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ #endif
+ maHelpButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maForwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maBackwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maJobPage.maCollateBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maJobPage.maSetupButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maJobPage.maDetailsBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maOptionsPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+ maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+
+ // setup modify hdl
+ maPageEdit.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+ maJobPage.maCopyCountField.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+ maNUpPage.maNupRowsEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+ maNUpPage.maNupColEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+ maNUpPage.maPageMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+ maNUpPage.maSheetMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
+
+ // setup select hdl
+ maNUpPage.maNupPagesBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
+ maNUpPage.maNupOrientationBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
+ maNUpPage.maNupOrderBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
+
+ // setup the layout
+ setupLayout();
+
+ // setup optional UI options set by application
+ setupOptionalUI();
+
+ // set change handler for UI options
+ maPController->setOptionChangeHdl( LINK( this, PrintDialog, UIOptionsChanged ) );
+
+ // set min size pixel to current size
+ Size aOutSize( GetOutputSizePixel() );
+ SetMinOutputSizePixel( aOutSize );
+
+ // if there is space enough, enlarge the preview so it gets roughly as
+ // high as the tab control
+ if( aOutSize.Width() < 768 )
+ {
+ Size aJobPageSize( getJobPageSize() );
+ Size aTabSize( maTabCtrl.GetSizePixel() );
+ if( aJobPageSize.Width() < 1 )
+ aJobPageSize.Width() = aTabSize.Width();
+ if( aJobPageSize.Height() < 1 )
+ aJobPageSize.Height() = aTabSize.Height();
+ long nOptPreviewWidth = aTabSize.Height() * aJobPageSize.Width() / aJobPageSize.Height();
+ // add space for borders
+ nOptPreviewWidth += 15;
+ if( aOutSize.Width() - aTabSize.Width() < nOptPreviewWidth )
+ {
+ aOutSize.Width() = aTabSize.Width() + nOptPreviewWidth;
+ if( aOutSize.Width() > 768 ) // don't enlarge the dialog too much
+ aOutSize.Width() = 768;
+ SetOutputSizePixel( aOutSize );
+ }
+ }
+
+ // set HelpIDs
+ SMHID1( "Dialog" );
+ maOKButton.SMHID1( "OK" );
+ maCancelButton.SMHID1( "Cancel" );
+ maHelpButton.SMHID1( "Help" );
+ maPreviewWindow.SMHID1( "Preview" );
+ maNumPagesText.SMHID1( "NumPagesText" );
+ maPageEdit.SMHID1( "PageEdit" );
+ maForwardBtn.SMHID1( "ForwardBtn" );
+ maBackwardBtn.SMHID1( "BackwardBtn" );
+ maTabCtrl.SMHID1( "TabPages" );
+
+ // append further tab pages
+ if( mbShowLayoutPage )
+ {
+ maTabCtrl.InsertPage( SV_PRINT_TAB_NUP, maNUpPage.GetText() );
+ maTabCtrl.SetTabPage( SV_PRINT_TAB_NUP, &maNUpPage );
+ }
+ maTabCtrl.InsertPage( SV_PRINT_TAB_OPT, maOptionsPage.GetText() );
+ maTabCtrl.SetTabPage( SV_PRINT_TAB_OPT, &maOptionsPage );
+
+ // restore settings from last run
+ readFromSettings();
+
+ // setup dependencies
+ checkControlDependencies();
+
+}
+
+PrintDialog::~PrintDialog()
+{
+ while( ! maControls.empty() )
+ {
+ delete maControls.front();
+ maControls.pop_front();
+ }
+}
+
+void PrintDialog::setupLayout()
+{
+ Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) );
+
+ maLayout.setParentWindow( this );
+
+ boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( &maLayout, false ) );
+ size_t nIndex = maLayout.addChild( xPreviewAndTab, 5 );
+ maLayout.setBorders( nIndex, aBorder.Width(), aBorder.Width(), aBorder.Width(), 0 );
+
+ // setup column for preview and sub controls
+ boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) );
+ xPreviewAndTab->addChild( xPreview, 5 );
+ xPreview->addWindow( &maPreviewWindow, 5 );
+ // get a row for the preview controls
+ mxPreviewCtrls.reset( new vcl::RowOrColumn( xPreview.get(), false ) );
+ nIndex = xPreview->addChild( mxPreviewCtrls );
+ boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
+ mxPreviewCtrls->addChild( xSpacer );
+ mxPreviewCtrls->addWindow( &maPageEdit );
+ mxPreviewCtrls->addWindow( &maNumPagesText );
+ xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
+ mxPreviewCtrls->addChild( xSpacer );
+ mxPreviewCtrls->addWindow( &maBackwardBtn );
+ mxPreviewCtrls->addWindow( &maForwardBtn );
+ xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
+ mxPreviewCtrls->addChild( xSpacer );
+
+ // continue with the tab ctrl
+ xPreviewAndTab->addWindow( &maTabCtrl );
+
+ // add the button line
+ maLayout.addWindow( &maButtonLine );
+
+ // add the row for the buttons
+ boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( &maLayout, false ) );
+ nIndex = maLayout.addChild( xButtons );
+ maLayout.setBorders( nIndex, aBorder.Width(), 0, aBorder.Width(), aBorder.Width() );
+
+ Size aMinSize( maCancelButton.GetSizePixel() );
+ // insert help button
+ xButtons->setMinimumSize( xButtons->addWindow( &maHelpButton ), aMinSize );
+ // insert a spacer, cancel and OK buttons are right aligned
+ xSpacer.reset( new vcl::Spacer( xButtons.get(), 2 ) );
+ xButtons->addChild( xSpacer );
+ xButtons->setMinimumSize( xButtons->addWindow( &maOKButton ), aMinSize );
+ xButtons->setMinimumSize( xButtons->addWindow( &maCancelButton ), aMinSize );
+}
+
+void PrintDialog::readFromSettings()
+{
+ maJobPage.readFromSettings();
+ maNUpPage.readFromSettings();
+ maOptionsPage.readFromSettings();
+
+ // read last selected tab page; if it exists, actiavte it
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ rtl::OUString aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ) );
+ USHORT nCount = maTabCtrl.GetPageCount();
+ for( USHORT i = 0; i < nCount; i++ )
+ {
+ USHORT nPageId = maTabCtrl.GetPageId( i );
+ if( aValue.equals( maTabCtrl.GetPageText( nPageId ) ) )
+ {
+ maTabCtrl.SelectTabPage( nPageId );
+ break;
+ }
+ }
+ maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText );
+}
+
+void PrintDialog::storeToSettings()
+{
+ maJobPage.storeToSettings();
+ maNUpPage.storeToSettings();
+ maOptionsPage.storeToSettings();
+
+ // store last selected printer
+ SettingsConfigItem* pItem = SettingsConfigItem::get();
+ pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ),
+ maJobPage.maPrinters.GetSelectEntry() );
+
+ pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ),
+ maTabCtrl.GetPageText( maTabCtrl.GetCurPageId() ) );
+ pItem->Commit();
+}
+
+bool PrintDialog::isPrintToFile()
+{
+ return maOptionsPage.maToFileBox.IsChecked();
+}
+
+int PrintDialog::getCopyCount()
+{
+ return static_cast<int>(maJobPage.maCopyCountField.GetValue());
+}
+
+bool PrintDialog::isCollate()
+{
+ return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : FALSE;
+}
+
+static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId = -1, const rtl::OUString& i_rPropName = rtl::OUString() )
+{
+ rtl::OUStringBuffer aBuf( 256 );
+ aBuf.appendAscii( HELPID_PREFIX );
+ if( i_rPropName.getLength() )
+ {
+ aBuf.append( sal_Unicode( ':' ) );
+ aBuf.append( i_rPropName );
+ }
+ if( i_pType )
+ {
+ aBuf.append( sal_Unicode( ':' ) );
+ aBuf.appendAscii( i_pType );
+ }
+ if( i_nId >= 0 )
+ {
+ aBuf.append( sal_Unicode( ':' ) );
+ aBuf.append( i_nId );
+ }
+ i_pWindow->SetSmartHelpId( SmartId( aBuf.makeStringAndClear(), HID_PRINTDLG ) );
+}
+
+static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex )
+{
+ if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() )
+ i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] );
+}
+
+void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize )
+{
+ if( i_rCheckSize.Width() > o_rMaxSize.Width() )
+ o_rMaxSize.Width() = i_rCheckSize.Width();
+ if( i_rCheckSize.Height() > o_rMaxSize.Height() )
+ o_rMaxSize.Height() = i_rCheckSize.Height();
+}
+
+void PrintDialog::setupOptionalUI()
+{
+ Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) );
+
+ std::vector<vcl::RowOrColumn*> aDynamicColumns;
+ vcl::RowOrColumn* pCurColumn = 0;
+
+ Window* pCurParent = 0, *pDynamicPageParent = 0;
+ USHORT nOptPageId = 9, nCurSubGroup = 0;
+ bool bOnStaticPage = false;
+ bool bSubgroupOnStaticPage = false;
+
+ std::multimap< rtl::OUString, vcl::RowOrColumn* > aPropertyToDependencyRowMap;
+
+ const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() );
+ for( int i = 0; i < rOptions.getLength(); i++ )
+ {
+ Sequence< beans::PropertyValue > aOptProp;
+ rOptions[i].Value >>= aOptProp;
+
+ // extract ui element
+ bool bEnabled = true;
+ rtl::OUString aCtrlType;
+ rtl::OUString aText;
+ rtl::OUString aPropertyName;
+ Sequence< rtl::OUString > aChoices;
+ Sequence< rtl::OUString > aHelpTexts;
+ sal_Int64 nMinValue = 0, nMaxValue = 0;
+ sal_Int32 nCurHelpText = 0;
+ rtl::OUString aGroupingHint;
+ rtl::OUString aDependsOnName;
+ sal_Int32 nDependsOnValue = 0;
+ sal_Bool bUseDependencyRow = sal_False;
+
+ for( int n = 0; n < aOptProp.getLength(); n++ )
+ {
+ const beans::PropertyValue& rEntry( aOptProp[ n ] );
+ if( rEntry.Name.equalsAscii( "Text" ) )
+ {
+ rEntry.Value >>= aText;
+ }
+ else if( rEntry.Name.equalsAscii( "ControlType" ) )
+ {
+ rEntry.Value >>= aCtrlType;
+ }
+ else if( rEntry.Name.equalsAscii( "Choices" ) )
+ {
+ rEntry.Value >>= aChoices;
+ }
+ else if( rEntry.Name.equalsAscii( "Property" ) )
+ {
+ PropertyValue aVal;
+ rEntry.Value >>= aVal;
+ aPropertyName = aVal.Name;
+ }
+ else if( rEntry.Name.equalsAscii( "Enabled" ) )
+ {
+ sal_Bool bValue = sal_True;
+ rEntry.Value >>= bValue;
+ bEnabled = bValue;
+ }
+ else if( rEntry.Name.equalsAscii( "GroupingHint" ) )
+ {
+ rEntry.Value >>= aGroupingHint;
+ }
+ else if( rEntry.Name.equalsAscii( "DependsOnName" ) )
+ {
+ rEntry.Value >>= aDependsOnName;
+ }
+ else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) )
+ {
+ rEntry.Value >>= nDependsOnValue;
+ }
+ else if( rEntry.Name.equalsAscii( "AttachToDependency" ) )
+ {
+ rEntry.Value >>= bUseDependencyRow;
+ }
+ else if( rEntry.Name.equalsAscii( "MinValue" ) )
+ {
+ rEntry.Value >>= nMinValue;
+ }
+ else if( rEntry.Name.equalsAscii( "MaxValue" ) )
+ {
+ rEntry.Value >>= nMaxValue;
+ }
+ else if( rEntry.Name.equalsAscii( "HelpText" ) )
+ {
+ if( ! (rEntry.Value >>= aHelpTexts) )
+ {
+ rtl::OUString aHelpText;
+ if( (rEntry.Value >>= aHelpText) )
+ {
+ aHelpTexts.realloc( 1 );
+ *aHelpTexts.getArray() = aHelpText;
+ }
+ }
+ }
+ else if( rEntry.Name.equalsAscii( "HintNoLayoutPage" ) )
+ {
+ sal_Bool bNoLayoutPage = sal_False;
+ rEntry.Value >>= bNoLayoutPage;
+ mbShowLayoutPage = ! bNoLayoutPage;
+ }
+ }
+
+ // bUseDependencyRow should only be true if a dependency exists
+ bUseDependencyRow = bUseDependencyRow && (aDependsOnName.getLength() != 0);
+
+ // is it necessary to switch between static and dynamic pages ?
+ bool bSwitchPage = false;
+ if( aGroupingHint.getLength() )
+ bSwitchPage = true;
+ else if( aCtrlType.equalsAscii( "Subgroup" ) || (bOnStaticPage && ! bSubgroupOnStaticPage ) )
+ bSwitchPage = true;
+ if( bSwitchPage )
+ {
+ // restore to dynamic
+ pCurParent = pDynamicPageParent;
+ pCurColumn = aDynamicColumns.empty() ? NULL : aDynamicColumns.back();
+ bOnStaticPage = false;
+ bSubgroupOnStaticPage = false;
+
+ if( aGroupingHint.equalsAscii( "PrintRange" ) )
+ {
+ pCurColumn = maJobPage.mxPrintRange.get();
+ pCurParent = &maJobPage; // set job page as current parent
+ bOnStaticPage = true;
+ }
+ else if( aGroupingHint.equalsAscii( "OptionsPage" ) )
+ {
+ pCurColumn = &maOptionsPage.maLayout;
+ pCurParent = &maOptionsPage; // set options page as current parent
+ bOnStaticPage = true;
+ }
+ else if( aGroupingHint.equalsAscii( "OptionsPageOptGroup" ) )
+ {
+ pCurColumn = maOptionsPage.mxOptGroup.get();
+ pCurParent = &maOptionsPage; // set options page as current parent
+ bOnStaticPage = true;
+ }
+ else if( aGroupingHint.equalsAscii( "LayoutPage" ) )
+ {
+ pCurColumn = &maNUpPage.maLayout;
+ pCurParent = &maNUpPage; // set layout page as current parent
+ bOnStaticPage = true;
+ }
+ else if( aGroupingHint.getLength() )
+ {
+ pCurColumn = &maJobPage.maLayout;
+ pCurParent = &maJobPage; // set job page as current parent
+ bOnStaticPage = true;
+ }
+ }
+
+ if( aCtrlType.equalsAscii( "Group" ) ||
+ ( ! pCurParent && ! (bOnStaticPage || aGroupingHint.getLength() ) ) )
+ {
+ // add new tab page
+ TabPage* pNewGroup = new TabPage( &maTabCtrl );
+ maControls.push_front( pNewGroup );
+ pDynamicPageParent = pCurParent = pNewGroup;
+ pNewGroup->SetText( aText );
+ maTabCtrl.InsertPage( ++nOptPageId, aText );
+ maTabCtrl.SetTabPage( nOptPageId, pNewGroup );
+
+ // set help id
+ setSmartId( pNewGroup, "TabPage", nOptPageId );
+ // set help text
+ setHelpText( pNewGroup, aHelpTexts, 0 );
+
+ // reset subgroup counter
+ nCurSubGroup = 0;
+
+ aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true, aBorder.Width() ) );
+ pCurColumn = aDynamicColumns.back();
+ pCurColumn->setParentWindow( pNewGroup );
+ pCurColumn->setOuterBorder( aBorder.Width() );
+ bSubgroupOnStaticPage = false;
+ bOnStaticPage = false;
+ }
+ else if( aCtrlType.equalsAscii( "Subgroup" ) && (pCurParent || aGroupingHint.getLength() ) )
+ {
+ bSubgroupOnStaticPage = (aGroupingHint.getLength() != 0);
+ // create group FixedLine
+ if( ! aGroupingHint.equalsAscii( "PrintRange" ) ||
+ ! pCurColumn->countElements() == 0
+ )
+ {
+ Window* pNewSub = NULL;
+ if( aGroupingHint.equalsAscii( "PrintRange" ) )
+ pNewSub = new FixedText( pCurParent, WB_VCENTER );
+ else
+ pNewSub = new FixedLine( pCurParent );
+ maControls.push_front( pNewSub );
+ pNewSub->SetText( aText );
+ pNewSub->Show();
+
+ // set help id
+ setSmartId( pNewSub, "FixedLine", sal_Int32( nCurSubGroup++ ) );
+ // set help text
+ setHelpText( pNewSub, aHelpTexts, 0 );
+ // add group to current column
+ pCurColumn->addWindow( pNewSub );
+ }
+
+ // add an indent to the current column
+ vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, aBorder.Width() );
+ pCurColumn->addChild( pIndent );
+ // and create a column inside the indent
+ pCurColumn = new vcl::RowOrColumn( pIndent );
+ pIndent->setChild( pCurColumn );
+ }
+ // EVIL
+ else if( aCtrlType.equalsAscii( "Bool" ) &&
+ aGroupingHint.equalsAscii( "LayoutPage" ) &&
+ aPropertyName.equalsAscii( "PrintProspect" )
+ )
+ {
+ maNUpPage.maBrochureBtn.SetText( aText );
+ maNUpPage.maBrochureBtn.Show();
+ setHelpText( &maNUpPage.maBrochureBtn, aHelpTexts, 0 );
+
+ sal_Bool bVal = sal_False;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal )
+ pVal->Value >>= bVal;
+ maNUpPage.maBrochureBtn.Check( bVal );
+ maNUpPage.maBrochureBtn.Enable( maPController->isUIOptionEnabled( aPropertyName ) && pVal != NULL );
+ maNUpPage.maBrochureBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
+
+ maPropertyToWindowMap[ aPropertyName ].push_back( &maNUpPage.maBrochureBtn );
+ maControlToPropertyMap[&maNUpPage.maBrochureBtn] = aPropertyName;
+
+ aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, maNUpPage.mxBrochureDep.get() ) );
+ }
+ else
+ {
+ vcl::RowOrColumn* pSaveCurColumn = pCurColumn;
+
+ if( bUseDependencyRow )
+ {
+ // find the correct dependency row (if any)
+ std::pair< std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator,
+ std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator > aDepRange;
+ aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName );
+ if( aDepRange.first != aDepRange.second )
+ {
+ while( nDependsOnValue && aDepRange.first != aDepRange.second )
+ {
+ nDependsOnValue--;
+ ++aDepRange.first;
+ }
+ if( aDepRange.first != aPropertyToDependencyRowMap.end() )
+ {
+ pCurColumn = aDepRange.first->second;
+ maReverseDependencySet.insert( aPropertyName );
+ }
+ }
+ }
+ if( aCtrlType.equalsAscii( "Bool" ) && pCurParent )
+ {
+ // add a check box
+ CheckBox* pNewBox = new CheckBox( pCurParent );
+ maControls.push_front( pNewBox );
+ pNewBox->SetText( aText );
+ pNewBox->Show();
+
+ sal_Bool bVal = sal_False;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal )
+ pVal->Value >>= bVal;
+ pNewBox->Check( bVal );
+ pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) );
+
+ maPropertyToWindowMap[ aPropertyName ].push_back( pNewBox );
+ maControlToPropertyMap[pNewBox] = aPropertyName;
+
+ // set help id
+ setSmartId( pNewBox, "CheckBox", -1, aPropertyName );
+ // set help text
+ setHelpText( pNewBox, aHelpTexts, 0 );
+
+ vcl::RowOrColumn* pDependencyRow = new vcl::RowOrColumn( pCurColumn, false );
+ pCurColumn->addChild( pDependencyRow );
+ aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow ) );
+
+ // add checkbox to current column
+ pDependencyRow->addWindow( pNewBox );
+ }
+ else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent )
+ {
+ vcl::RowOrColumn* pRadioColumn = pCurColumn;
+ if( aText.getLength() )
+ {
+ // add a FixedText:
+ FixedText* pHeading = new FixedText( pCurParent );
+ maControls.push_front( pHeading );
+ pHeading->SetText( aText );
+ pHeading->Show();
+
+ // set help id
+ setSmartId( pHeading, "FixedText", -1, aPropertyName );
+ // set help text
+ setHelpText( pHeading, aHelpTexts, nCurHelpText++ );
+ // add fixed text to current column
+ pCurColumn->addWindow( pHeading );
+ // add an indent to the current column
+ vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, 15 );
+ pCurColumn->addChild( pIndent );
+ // and create a column inside the indent
+ pRadioColumn = new vcl::RowOrColumn( pIndent );
+ pIndent->setChild( pRadioColumn );
+ }
+ // iterate options
+ sal_Int32 nSelectVal = 0;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= nSelectVal;
+ for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
+ {
+ boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn, 1 ) );
+ pRadioColumn->addChild( pLabel );
+ boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pLabel.get(), false ) );
+ pLabel->setElement( pDependencyRow );
+ aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow.get() ) );
+
+ RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 );
+ maControls.push_front( pBtn );
+ pBtn->SetText( aChoices[m] );
+ pBtn->Check( m == nSelectVal );
+ pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) );
+ pBtn->Show();
+ maPropertyToWindowMap[ aPropertyName ].push_back( pBtn );
+ maControlToPropertyMap[pBtn] = aPropertyName;
+ maControlToNumValMap[pBtn] = m;
+
+ // set help id
+ setSmartId( pBtn, "RadioButton", m, aPropertyName );
+ // set help text
+ setHelpText( pBtn, aHelpTexts, nCurHelpText++ );
+ // add the radio button to the column
+ pLabel->setLabel( pBtn );
+ }
+ }
+ else if( ( aCtrlType.equalsAscii( "List" ) ||
+ aCtrlType.equalsAscii( "Range" ) ||
+ aCtrlType.equalsAscii( "Edit" )
+ ) && pCurParent )
+ {
+ // create a row in the current column
+ vcl::RowOrColumn* pFieldColumn = new vcl::RowOrColumn( pCurColumn, false );
+ pCurColumn->addChild( pFieldColumn );
+ aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pFieldColumn ) );
+
+ vcl::LabeledElement* pLabel = NULL;
+ if( aText.getLength() )
+ {
+ // add a FixedText:
+ FixedText* pHeading = new FixedText( pCurParent, WB_VCENTER );
+ maControls.push_front( pHeading );
+ pHeading->SetText( aText );
+ pHeading->Show();
+
+ // set help id
+ setSmartId( pHeading, "FixedText", -1, aPropertyName );
+
+ // add to row
+ pLabel = new vcl::LabeledElement( pFieldColumn, 2 );
+ pFieldColumn->addChild( pLabel );
+ pLabel->setLabel( pHeading );
+ }
+
+ if( aCtrlType.equalsAscii( "List" ) )
+ {
+ ListBox* pList = new ListBox( pCurParent, WB_DROPDOWN | WB_BORDER );
+ maControls.push_front( pList );
+
+ // iterate options
+ for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
+ {
+ pList->InsertEntry( aChoices[m] );
+ }
+ sal_Int32 nSelectVal = 0;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= nSelectVal;
+ pList->SelectEntryPos( static_cast<USHORT>(nSelectVal) );
+ pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) );
+ pList->SetDropDownLineCount( static_cast<USHORT>(aChoices.getLength()) );
+ pList->Show();
+
+ // set help id
+ setSmartId( pList, "ListBox", -1, aPropertyName );
+ // set help text
+ setHelpText( pList, aHelpTexts, 0 );
+
+ maPropertyToWindowMap[ aPropertyName ].push_back( pList );
+ maControlToPropertyMap[pList] = aPropertyName;
+
+ // finish the pair
+ if( pLabel )
+ pLabel->setElement( pList );
+ else
+ pFieldColumn->addWindow( pList );
+ }
+ else if( aCtrlType.equalsAscii( "Range" ) )
+ {
+ NumericField* pField = new NumericField( pCurParent, WB_BORDER | WB_SPIN );
+ maControls.push_front( pField );
+
+ // set min/max and current value
+ if( nMinValue != nMaxValue )
+ {
+ pField->SetMin( nMinValue );
+ pField->SetMax( nMaxValue );
+ }
+ sal_Int64 nCurVal = 0;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= nCurVal;
+ pField->SetValue( nCurVal );
+ pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
+ pField->Show();
+
+ // set help id
+ setSmartId( pField, "NumericField", -1, aPropertyName );
+ // set help text
+ setHelpText( pField, aHelpTexts, 0 );
+
+ maPropertyToWindowMap[ aPropertyName ].push_back( pField );
+ maControlToPropertyMap[pField] = aPropertyName;
+
+ // add to row
+ if( pLabel )
+ pLabel->setElement( pField );
+ else
+ pFieldColumn->addWindow( pField );
+ }
+ else if( aCtrlType.equalsAscii( "Edit" ) )
+ {
+ Edit* pField = new Edit( pCurParent, WB_BORDER );
+ maControls.push_front( pField );
+
+ rtl::OUString aCurVal;
+ PropertyValue* pVal = maPController->getValue( aPropertyName );
+ if( pVal && pVal->Value.hasValue() )
+ pVal->Value >>= aCurVal;
+ pField->SetText( aCurVal );
+ pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
+ pField->Show();
+
+ // set help id
+ setSmartId( pField, "Edit", -1, aPropertyName );
+ // set help text
+ setHelpText( pField, aHelpTexts, 0 );
+
+ maPropertyToWindowMap[ aPropertyName ].push_back( pField );
+ maControlToPropertyMap[pField] = aPropertyName;
+
+ // add to row
+ if( pLabel )
+ pLabel->setElement( pField );
+ else
+ pFieldColumn->addWindow( pField, 2 );
+ }
+ }
+ else
+ {
+ DBG_ERROR( "Unsupported UI option" );
+ }
+
+ pCurColumn = pSaveCurColumn;
+ }
+ }
+
+ // #i106506# if no brochure button, then the singular Pages radio button
+ // makes no sense, so replace it by a FixedText label
+ if( ! maNUpPage.maBrochureBtn.IsVisible() )
+ {
+ if( maNUpPage.mxPagesBtnLabel.get() )
+ {
+ maNUpPage.maPagesBoxTitleTxt.SetText( maNUpPage.maPagesBtn.GetText() );
+ maNUpPage.maPagesBoxTitleTxt.Show( TRUE );
+ maNUpPage.mxPagesBtnLabel->setLabel( &maNUpPage.maPagesBoxTitleTxt );
+ maNUpPage.maPagesBtn.Show( FALSE );
+ }
+ }
+
+ // update enable states
+ checkOptionalControlDependencies();
+
+ // print range empty (currently math only) -> hide print range and spacer line
+ if( maJobPage.mxPrintRange->countElements() == 0 )
+ {
+ maJobPage.mxPrintRange->show( false, false );
+ maJobPage.maCopySpacer.Show( FALSE );
+ }
+
+#ifdef WNT
+ // FIXME: the GetNativeControlRegion call on Windows has some issues
+ // (which skew the results of GetOptimalSize())
+ // however fixing this thoroughly needs to take interaction with paint into
+ // acoount, making the right fix less simple. Fix this the right way
+ // at some point. For now simply add some space at the lowest element
+ size_t nIndex = maJobPage.maLayout.countElements();
+ if( nIndex > 0 ) // sanity check
+ maJobPage.maLayout.setBorders( nIndex-1, 0, 0, 0, aBorder.Width() );
+#endif
+
+ // calculate job page
+ Size aMaxSize = maJobPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED );
+ // and layout page
+ updateMaxSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize );
+ // and options page
+ updateMaxSize( maOptionsPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize );
+
+ for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin();
+ it != aDynamicColumns.end(); ++it )
+ {
+ Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) );
+ updateMaxSize( aPageSize, aMaxSize );
+ }
+
+ // resize dialog if necessary
+ Size aTabSize = maTabCtrl.GetTabPageSizePixel();
+ maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() );
+ if( aMaxSize.Height() > aTabSize.Height() || aMaxSize.Width() > aTabSize.Width() )
+ {
+ Size aCurSize( GetOutputSizePixel() );
+ if( aMaxSize.Height() > aTabSize.Height() )
+ {
+ aCurSize.Height() += aMaxSize.Height() - aTabSize.Height();
+ aTabSize.Height() = aMaxSize.Height();
+ }
+ if( aMaxSize.Width() > aTabSize.Width() )
+ {
+ aCurSize.Width() += aMaxSize.Width() - aTabSize.Width();
+ // and the tab ctrl needs more space, too
+ aTabSize.Width() = aMaxSize.Width();
+ }
+ maTabCtrl.SetTabPageSizePixel( aTabSize );
+ maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() );
+ }
+
+ // and finally arrange controls
+ for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin();
+ it != aDynamicColumns.end(); ++it )
+ {
+ (*it)->setManagedArea( Rectangle( Point(), aTabSize ) );
+ delete *it;
+ *it = NULL;
+ }
+ maJobPage.Resize();
+ maNUpPage.Resize();
+ maOptionsPage.Resize();
+
+ Size aSz = maLayout.getOptimalSize( WINDOWSIZE_PREFERRED );
+ SetOutputSizePixel( aSz );
+}
+
+void PrintDialog::DataChanged( const DataChangedEvent& i_rDCEvt )
+{
+ // react on settings changed
+ if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS )
+ checkControlDependencies();
+ ModalDialog::DataChanged( i_rDCEvt );
+}
+
+void PrintDialog::checkControlDependencies()
+{
+ if( maJobPage.maCopyCountField.GetValue() > 1 )
+ maJobPage.maCollateBox.Enable( maJobPage.mnCollateUIMode == 0 );
+ else
+ maJobPage.maCollateBox.Enable( FALSE );
+
+ Image aImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg );
+ Image aHCImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateHCImg : maJobPage.maNoCollateHCImg );
+ bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ Size aImgSize( aImg.GetSizePixel() );
+ Size aHCImgSize( aHCImg.GetSizePixel() );
+
+ if( aHCImgSize.Width() > aImgSize.Width() )
+ aImgSize.Width() = aHCImgSize.Width();
+ if( aHCImgSize.Height() > aImgSize.Height() )
+ aImgSize.Height() = aHCImgSize.Height();
+
+ // adjust size of image
+ maJobPage.maCollateImage.SetSizePixel( aImgSize );
+ maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg );
+ maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST );
+
+ // enable setup button only for printers that can be setup
+ bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG );
+ maJobPage.maSetupButton.Enable( bHaveSetup );
+ if( bHaveSetup )
+ {
+ if( ! maJobPage.maSetupButton.IsVisible() )
+ {
+ Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() );
+ Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() );
+ Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() );
+ aPrinterSize.Width() = aSetupPos.X() - aPrinterPos.X() - LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ).Width();
+ maJobPage.maPrinters.SetSizePixel( aPrinterSize );
+ maJobPage.maSetupButton.Show();
+ maLayout.resize();
+ }
+ }
+ else
+ {
+ if( maJobPage.maSetupButton.IsVisible() )
+ {
+ Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() );
+ Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() );
+ Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() );
+ Size aSetupSize( maJobPage.maSetupButton.GetSizePixel() );
+ aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X();
+ maJobPage.maPrinters.SetSizePixel( aPrinterSize );
+ maJobPage.maSetupButton.Hide();
+ maLayout.resize();
+ }
+ }
+}
+
+void PrintDialog::checkOptionalControlDependencies()
+{
+ for( std::map< Window*, rtl::OUString >::iterator it = maControlToPropertyMap.begin();
+ it != maControlToPropertyMap.end(); ++it )
+ {
+ bool bShouldbeEnabled = maPController->isUIOptionEnabled( it->second );
+ if( ! bShouldbeEnabled )
+ {
+ // enable controls that are directly attached to a dependency anyway
+ // if the normally disabled controls get modified, change the dependency
+ // so the control would be enabled
+ // example: in print range "Print All" is selected, "Page Range" is then of course
+ // not selected and the Edit for the Page Range would be disabled
+ // as a convenience we should enable the Edit anyway and automatically select
+ // "Page Range" instead of "Print All" if the Edit gets modified
+ if( maReverseDependencySet.find( it->second ) != maReverseDependencySet.end() )
+ {
+ rtl::OUString aDep( maPController->getDependency( it->second ) );
+ // if the dependency is at least enabled, then enable this control anyway
+ if( aDep.getLength() && maPController->isUIOptionEnabled( aDep ) )
+ bShouldbeEnabled = true;
+ }
+ }
+
+ bool bIsEnabled = it->first->IsEnabled();
+ // Enable does not do a change check first, so can be less cheap than expected
+ if( bShouldbeEnabled != bIsEnabled )
+ it->first->Enable( bShouldbeEnabled );
+ }
+}
+
+static rtl::OUString searchAndReplace( const rtl::OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, const rtl::OUString& i_rRepl )
+{
+ sal_Int32 nPos = i_rOrig.indexOfAsciiL( i_pRepl, i_nReplLen );
+ if( nPos != -1 )
+ {
+ rtl::OUStringBuffer aBuf( i_rOrig.getLength() );
+ aBuf.append( i_rOrig.getStr(), nPos );
+ aBuf.append( i_rRepl );
+ if( nPos + i_nReplLen < i_rOrig.getLength() )
+ aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen );
+ return aBuf.makeStringAndClear();
+ }
+ return i_rOrig;
+}
+
+void PrintDialog::updatePrinterText()
+{
+ String aDefPrt( Printer::GetDefaultPrinterName() );
+ const QueueInfo* pInfo = Printer::GetQueueInfo( maJobPage.maPrinters.GetSelectEntry(), true );
+ if( pInfo )
+ {
+ maJobPage.maLocationTxt.SetText( pInfo->GetLocation() );
+ maJobPage.maCommentTxt.SetText( pInfo->GetComment() );
+ // FIXME: status text
+ rtl::OUString aStatus;
+ if( aDefPrt == pInfo->GetPrinterName() )
+ aStatus = maDefPrtText;
+ maJobPage.maStatusTxt.SetText( aStatus );
+ }
+ else
+ {
+ maJobPage.maLocationTxt.SetText( String() );
+ maJobPage.maCommentTxt.SetText( String() );
+ maJobPage.maStatusTxt.SetText( String() );
+ }
+}
+
+void PrintDialog::setPreviewText( sal_Int32 )
+{
+ rtl::OUString aNewText( searchAndReplace( maPageStr, "%n", 2, rtl::OUString::valueOf( mnCachedPages ) ) );
+ maNumPagesText.SetText( aNewText );
+
+ // if layout is already established the refresh layout of
+ // preview controls since text length may have changes
+ if( mxPreviewCtrls.get() )
+ mxPreviewCtrls->setManagedArea( mxPreviewCtrls->getManagedArea() );
+}
+
+void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache )
+{
+ // page range may have changed depending on options
+ sal_Int32 nPages = maPController->getFilteredPageCount();
+ mnCachedPages = nPages;
+
+ if( mnCurPage >= nPages )
+ mnCurPage = nPages-1;
+ if( mnCurPage < 0 )
+ mnCurPage = 0;
+
+ setPreviewText( mnCurPage );
+
+ maPageEdit.SetMin( 1 );
+ maPageEdit.SetMax( nPages );
+
+ if( i_bNewPage )
+ {
+ const MapMode aMapMode( MAP_100TH_MM );
+ GDIMetaFile aMtf;
+ boost::shared_ptr<Printer> aPrt( maPController->getPrinter() );
+ if( nPages > 0 )
+ {
+ PrinterController::PageSize aPageSize =
+ maPController->getFilteredPageFile( mnCurPage, aMtf, i_bMayUseCache );
+ if( ! aPageSize.bFullPaper )
+ {
+ Point aOff( aPrt->PixelToLogic( aPrt->GetPageOffsetPixel(), aMapMode ) );
+ aMtf.Move( aOff.X(), aOff.Y() );
+ }
+ }
+
+ Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) );
+ maPreviewWindow.setPreview( aMtf, aCurPageSize, nPages > 0 ? rtl::OUString() : maNoPageStr,
+ aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY()
+ );
+
+ maForwardBtn.Enable( mnCurPage < nPages-1 );
+ maBackwardBtn.Enable( mnCurPage != 0 );
+ maPageEdit.Enable( nPages > 1 );
+ }
+}
+
+Size PrintDialog::getJobPageSize()
+{
+ if( maFirstPageSize.Width() == 0 && maFirstPageSize.Height() == 0)
+ {
+ maFirstPageSize = maNupPortraitSize;
+ GDIMetaFile aMtf;
+ if( maPController->getPageCountProtected() > 0 )
+ {
+ PrinterController::PageSize aPageSize = maPController->getPageFile( 0, aMtf, true );
+ maFirstPageSize = aPageSize.aSize;
+ }
+ }
+ return maFirstPageSize;
+}
+
+void PrintDialog::updateNupFromPages()
+{
+ long nPages = long(maNUpPage.maNupPagesBox.GetEntryData(maNUpPage.maNupPagesBox.GetSelectEntryPos()));
+ int nRows = int(maNUpPage.maNupRowsEdt.GetValue());
+ int nCols = int(maNUpPage.maNupColEdt.GetValue());
+ long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM )));
+ long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM )));
+ bool bCustom = false;
+
+ if( nPages == 1 )
+ {
+ nRows = nCols = 1;
+ nSheetMargin = 0;
+ nPageMargin = 0;
+ }
+ else if( nPages == 2 || nPages == 4 || nPages == 6 || nPages == 9 || nPages == 16 )
+ {
+ Size aJobPageSize( getJobPageSize() );
+ bool bPortrait = aJobPageSize.Width() < aJobPageSize.Height();
+ if( nPages == 2 )
+ {
+ if( bPortrait )
+ nRows = 1, nCols = 2;
+ else
+ nRows = 2, nCols = 1;
+ }
+ else if( nPages == 4 )
+ nRows = nCols = 2;
+ else if( nPages == 6 )
+ {
+ if( bPortrait )
+ nRows = 2, nCols = 3;
+ else
+ nRows = 3, nCols = 2;
+ }
+ else if( nPages == 9 )
+ nRows = nCols = 3;
+ else if( nPages == 16 )
+ nRows = nCols = 4;
+ nPageMargin = 0;
+ nSheetMargin = 0;
+ }
+ else
+ bCustom = true;
+
+ if( nPages > 1 )
+ {
+ // set upper limits for margins based on job page size and rows/columns
+ Size aSize( getJobPageSize() );
+
+ // maximum sheet distance: 1/2 sheet
+ long nHorzMax = aSize.Width()/2;
+ long nVertMax = aSize.Height()/2;
+ if( nSheetMargin > nHorzMax )
+ nSheetMargin = nHorzMax;
+ if( nSheetMargin > nVertMax )
+ nSheetMargin = nVertMax;
+
+ maNUpPage.maSheetMarginEdt.SetMax(
+ maNUpPage.maSheetMarginEdt.Normalize(
+ nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
+
+ // maximum page distance
+ nHorzMax = (aSize.Width() - 2*nSheetMargin);
+ if( nCols > 1 )
+ nHorzMax /= (nCols-1);
+ nVertMax = (aSize.Height() - 2*nSheetMargin);
+ if( nRows > 1 )
+ nHorzMax /= (nRows-1);
+
+ if( nPageMargin > nHorzMax )
+ nPageMargin = nHorzMax;
+ if( nPageMargin > nVertMax )
+ nPageMargin = nVertMax;
+
+ maNUpPage.maPageMarginEdt.SetMax(
+ maNUpPage.maSheetMarginEdt.Normalize(
+ nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
+ }
+
+ maNUpPage.maNupRowsEdt.SetValue( nRows );
+ maNUpPage.maNupColEdt.SetValue( nCols );
+ maNUpPage.maPageMarginEdt.SetValue( maNUpPage.maPageMarginEdt.Normalize( nPageMargin ), FUNIT_100TH_MM );
+ maNUpPage.maSheetMarginEdt.SetValue( maNUpPage.maSheetMarginEdt.Normalize( nSheetMargin ), FUNIT_100TH_MM );
+
+ maNUpPage.showAdvancedControls( bCustom );
+ if( bCustom )
+ {
+ // see if we have to enlarge the dialog to make the tab page fit
+ Size aCurSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ) );
+ Size aTabSize( maTabCtrl.GetTabPageSizePixel() );
+ if( aTabSize.Height() < aCurSize.Height() )
+ {
+ Size aDlgSize( GetSizePixel() );
+ aDlgSize.Height() += aCurSize.Height() - aTabSize.Height();
+ SetSizePixel( aDlgSize );
+ }
+ }
+
+ updateNup();
+}
+
+void PrintDialog::updateNup()
+{
+ int nRows = int(maNUpPage.maNupRowsEdt.GetValue());
+ int nCols = int(maNUpPage.maNupColEdt.GetValue());
+ long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM )));
+ long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM )));
+
+ PrinterController::MultiPageSetup aMPS;
+ aMPS.nRows = nRows;
+ aMPS.nColumns = nCols;
+ aMPS.nRepeat = 1;
+ aMPS.nLeftMargin =
+ aMPS.nTopMargin =
+ aMPS.nRightMargin =
+ aMPS.nBottomMargin = nSheetMargin;
+
+ aMPS.nHorizontalSpacing =
+ aMPS.nVerticalSpacing = nPageMargin;
+
+ aMPS.bDrawBorder = maNUpPage.maBorderCB.IsChecked();
+
+ int nOrderMode = int(sal_IntPtr(maNUpPage.maNupOrderBox.GetEntryData(
+ maNUpPage.maNupOrderBox.GetSelectEntryPos() )));
+ if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTD )
+ aMPS.nOrder = PrinterController::LRTB;
+ else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TDLR )
+ aMPS.nOrder = PrinterController::TBLR;
+
+ int nOrientationMode = int(sal_IntPtr(maNUpPage.maNupOrientationBox.GetEntryData(
+ maNUpPage.maNupOrientationBox.GetSelectEntryPos() )));
+ if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE )
+ aMPS.aPaperSize = maNupLandscapeSize;
+ else if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT )
+ aMPS.aPaperSize = maNupPortraitSize;
+ else // automatic mode
+ {
+ // get size of first real page to see if it is portrait or landscape
+ // we assume same page sizes for all the pages for this
+ Size aPageSize = getJobPageSize();
+
+ Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows );
+ if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape
+ aMPS.aPaperSize = maNupLandscapeSize;
+ else
+ aMPS.aPaperSize = maNupPortraitSize;
+ }
+
+ maPController->setMultipage( aMPS );
+
+ maNUpPage.maNupOrderWin.setValues( nOrderMode, nCols, nRows );
+
+ preparePreview( true, true );
+}
+
+IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox )
+{
+ if( pBox == &maJobPage.maPrinters )
+ {
+ String aNewPrinter( pBox->GetSelectEntry() );
+ // set new printer
+ maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) );
+ // update text fields
+ updatePrinterText();
+ }
+ else if( pBox == &maNUpPage.maNupOrientationBox || pBox == &maNUpPage.maNupOrderBox )
+ {
+ updateNup();
+ }
+ else if( pBox == &maNUpPage.maNupPagesBox )
+ {
+ if( !maNUpPage.maPagesBtn.IsChecked() )
+ maNUpPage.maPagesBtn.Check();
+ updateNupFromPages();
+ }
+
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton )
+{
+ if( pButton == &maOKButton || pButton == &maCancelButton )
+ {
+ storeToSettings();
+ EndDialog( pButton == &maOKButton );
+ }
+ else if( pButton == &maHelpButton )
+ {
+ // start help system
+ Help* pHelp = Application::GetHelp();
+ if( pHelp )
+ {
+ // FIXME: find out proper help URL and use here
+ pHelp->Start( HID_PRINTDLG, GetParent() );
+ }
+ }
+ else if( pButton == &maForwardBtn )
+ {
+ previewForward();
+ }
+ else if( pButton == &maBackwardBtn )
+ {
+ previewBackward();
+ }
+ else if( pButton == &maOptionsPage.maToFileBox )
+ {
+ maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText );
+ maLayout.resize();
+ }
+ else if( pButton == &maNUpPage.maBrochureBtn )
+ {
+ PropertyValue* pVal = getValueForWindow( pButton );
+ if( pVal )
+ {
+ sal_Bool bVal = maNUpPage.maBrochureBtn.IsChecked();
+ pVal->Value <<= bVal;
+
+ checkOptionalControlDependencies();
+
+ // update preview and page settings
+ preparePreview();
+ }
+ if( maNUpPage.maBrochureBtn.IsChecked() )
+ {
+ maNUpPage.maNupPagesBox.SelectEntryPos( 0 );
+ updateNupFromPages();
+ maNUpPage.showAdvancedControls( false );
+ maNUpPage.enableNupControls( false );
+ }
+ }
+ else if( pButton == &maNUpPage.maPagesBtn )
+ {
+ maNUpPage.enableNupControls( true );
+ updateNupFromPages();
+ }
+ else if( pButton == &maJobPage.maDetailsBtn )
+ {
+ bool bShow = maJobPage.maDetailsBtn.IsChecked();
+ maJobPage.mxDetails->show( bShow );
+ if( bShow )
+ {
+ maDetailsCollapsedSize = GetOutputSizePixel();
+ // enlarge dialog if necessary
+ Size aMinSize( maJobPage.maLayout.getOptimalSize( WINDOWSIZE_MINIMUM ) );
+ Size aCurSize( maJobPage.GetSizePixel() );
+ if( aCurSize.Height() < aMinSize.Height() )
+ {
+ Size aDlgSize( GetOutputSizePixel() );
+ aDlgSize.Height() += aMinSize.Height() - aCurSize.Height();
+ SetOutputSizePixel( aDlgSize );
+ }
+ maDetailsExpandedSize = GetOutputSizePixel();
+ }
+ else if( maDetailsCollapsedSize.Width() > 0 &&
+ maDetailsCollapsedSize.Height() > 0 )
+ {
+ // if the user did not resize the dialog
+ // make it smaller again on collapsing the details
+ Size aDlgSize( GetOutputSizePixel() );
+ if( aDlgSize == maDetailsExpandedSize &&
+ aDlgSize.Height() > maDetailsCollapsedSize.Height() )
+ {
+ SetOutputSizePixel( maDetailsCollapsedSize );
+ }
+ }
+ }
+ else if( pButton == &maJobPage.maCollateBox )
+ {
+ maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
+ makeAny( sal_Bool(isCollate()) ) );
+ checkControlDependencies();
+ }
+ else if( pButton == &maOptionsPage.maReverseOrderBox )
+ {
+ sal_Bool bChecked = maOptionsPage.maReverseOrderBox.IsChecked();
+ maPController->setReversePrint( bChecked );
+ maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ),
+ makeAny( bChecked ) );
+ preparePreview( true, true );
+ }
+ else if( pButton == &maNUpPage.maBorderCB )
+ {
+ updateNup();
+ }
+ else
+ {
+ if( pButton == &maJobPage.maSetupButton )
+ {
+ maPController->setupPrinter( this );
+ preparePreview( true, true );
+ }
+ checkControlDependencies();
+ }
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, ModifyHdl, Edit*, pEdit )
+{
+ checkControlDependencies();
+ if( pEdit == &maNUpPage.maNupRowsEdt || pEdit == &maNUpPage.maNupColEdt ||
+ pEdit == &maNUpPage.maSheetMarginEdt || pEdit == &maNUpPage.maPageMarginEdt
+ )
+ {
+ updateNupFromPages();
+ }
+ else if( pEdit == &maPageEdit )
+ {
+ mnCurPage = sal_Int32( maPageEdit.GetValue() - 1 );
+ preparePreview( true, true );
+ }
+ else if( pEdit == &maJobPage.maCopyCountField )
+ {
+ maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ),
+ makeAny( sal_Int32(maJobPage.maCopyCountField.GetValue()) ) );
+ maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
+ makeAny( sal_Bool(isCollate()) ) );
+ }
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, UIOptionsChanged, void*, EMPTYARG )
+{
+ checkOptionalControlDependencies();
+ return 0;
+}
+
+PropertyValue* PrintDialog::getValueForWindow( Window* i_pWindow ) const
+{
+ PropertyValue* pVal = NULL;
+ std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow );
+ if( it != maControlToPropertyMap.end() )
+ {
+ pVal = maPController->getValue( it->second );
+ DBG_ASSERT( pVal, "property value not found" );
+ }
+ else
+ {
+ DBG_ERROR( "changed control not in property map" );
+ }
+ return pVal;
+}
+
+void PrintDialog::updateWindowFromProperty( const rtl::OUString& i_rProperty )
+{
+ beans::PropertyValue* pValue = maPController->getValue( i_rProperty );
+ std::map< rtl::OUString, std::vector< Window* > >::const_iterator it = maPropertyToWindowMap.find( i_rProperty );
+ if( pValue && it != maPropertyToWindowMap.end() )
+ {
+ const std::vector< Window* >& rWindows( it->second );
+ if( ! rWindows.empty() )
+ {
+ sal_Bool bVal = sal_False;
+ sal_Int32 nVal = -1;
+ if( pValue->Value >>= bVal )
+ {
+ // we should have a CheckBox for this one
+ CheckBox* pBox = dynamic_cast< CheckBox* >( rWindows.front() );
+ if( pBox )
+ {
+ pBox->Check( bVal );
+ }
+ else if( i_rProperty.equalsAscii( "PrintProspect" ) )
+ {
+ // EVIL special case
+ if( bVal )
+ maNUpPage.maBrochureBtn.Check();
+ else
+ maNUpPage.maPagesBtn.Check();
+ }
+ else
+ {
+ DBG_ASSERT( 0, "missing a checkbox" );
+ }
+ }
+ else if( pValue->Value >>= nVal )
+ {
+ // this could be a ListBox or a RadioButtonGroup
+ ListBox* pList = dynamic_cast< ListBox* >( rWindows.front() );
+ if( pList )
+ {
+ pList->SelectEntryPos( static_cast< USHORT >(nVal) );
+ }
+ else if( nVal >= 0 && nVal < sal_Int32(rWindows.size() ) )
+ {
+ RadioButton* pBtn = dynamic_cast< RadioButton* >( rWindows[nVal] );
+ DBG_ASSERT( pBtn, "unexpected control for property" );
+ if( pBtn )
+ pBtn->Check();
+ }
+ }
+ }
+ }
+}
+
+void PrintDialog::makeEnabled( Window* i_pWindow )
+{
+ std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow );
+ if( it != maControlToPropertyMap.end() )
+ {
+ rtl::OUString aDependency( maPController->makeEnabled( it->second ) );
+ if( aDependency.getLength() )
+ updateWindowFromProperty( aDependency );
+ }
+}
+
+IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox*, i_pBox )
+{
+ PropertyValue* pVal = getValueForWindow( i_pBox );
+ if( pVal )
+ {
+ makeEnabled( i_pBox );
+
+ sal_Bool bVal = i_pBox->IsChecked();
+ pVal->Value <<= bVal;
+
+ checkOptionalControlDependencies();
+
+ // update preview and page settings
+ preparePreview();
+ }
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, UIOption_RadioHdl, RadioButton*, i_pBtn )
+{
+ // this handler gets called for all radiobuttons that get unchecked, too
+ // however we only want one notificaction for the new value (that is for
+ // the button that gets checked)
+ if( i_pBtn->IsChecked() )
+ {
+ PropertyValue* pVal = getValueForWindow( i_pBtn );
+ std::map< Window*, sal_Int32 >::const_iterator it = maControlToNumValMap.find( i_pBtn );
+ if( pVal && it != maControlToNumValMap.end() )
+ {
+ makeEnabled( i_pBtn );
+
+ sal_Int32 nVal = it->second;
+ pVal->Value <<= nVal;
+
+ checkOptionalControlDependencies();
+
+ // update preview and page settings
+ preparePreview();
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, UIOption_SelectHdl, ListBox*, i_pBox )
+{
+ PropertyValue* pVal = getValueForWindow( i_pBox );
+ if( pVal )
+ {
+ makeEnabled( i_pBox );
+
+ sal_Int32 nVal( i_pBox->GetSelectEntryPos() );
+ pVal->Value <<= nVal;
+
+ checkOptionalControlDependencies();
+
+ // update preview and page settings
+ preparePreview();
+ }
+ return 0;
+}
+
+IMPL_LINK( PrintDialog, UIOption_ModifyHdl, Edit*, i_pBox )
+{
+ PropertyValue* pVal = getValueForWindow( i_pBox );
+ if( pVal )
+ {
+ makeEnabled( i_pBox );
+
+ NumericField* pNum = dynamic_cast<NumericField*>(i_pBox);
+ MetricField* pMetric = dynamic_cast<MetricField*>(i_pBox);
+ if( pNum )
+ {
+ sal_Int64 nVal = pNum->GetValue();
+ pVal->Value <<= nVal;
+ }
+ else if( pMetric )
+ {
+ sal_Int64 nVal = pMetric->GetValue();
+ pVal->Value <<= nVal;
+ }
+ else
+ {
+ rtl::OUString aVal( i_pBox->GetText() );
+ pVal->Value <<= aVal;
+ }
+
+ checkOptionalControlDependencies();
+
+ // update preview and page settings
+ preparePreview();
+ }
+ return 0;
+}
+
+void PrintDialog::Command( const CommandEvent& rEvt )
+{
+ if( rEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pWheelData = rEvt.GetWheelData();
+ if( pWheelData->GetDelta() > 0 )
+ previewForward();
+ else if( pWheelData->GetDelta() < 0 )
+ previewBackward();
+ /*
+ else
+ huh ?
+ */
+ }
+}
+
+void PrintDialog::Resize()
+{
+ maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
+ // and do the preview; however the metafile does not need to be gotten anew
+ preparePreview( false );
+
+ // do an invalidate for the benefit of the grouping elements
+ Invalidate();
+}
+
+void PrintDialog::previewForward()
+{
+ maPageEdit.Up();
+}
+
+void PrintDialog::previewBackward()
+{
+ maPageEdit.Down();
+}
+
+// -----------------------------------------------------------------------------
+//
+// PrintProgressDialog
+//
+// -----------------------------------------------------------------------------
+
+PrintProgressDialog::PrintProgressDialog( Window* i_pParent, int i_nMax ) :
+ ModelessDialog( i_pParent, VclResId( SV_DLG_PRINT_PROGRESS ) ),
+ maText( this, VclResId( SV_PRINT_PROGRESS_TEXT ) ),
+ maButton( this, VclResId( SV_PRINT_PROGRESS_CANCEL ) ),
+ mbCanceled( false ),
+ mnCur( 0 ),
+ mnMax( i_nMax ),
+ mnProgressHeight( 15 ),
+ mbNativeProgress( false )
+{
+ FreeResource();
+
+ if( mnMax < 1 )
+ mnMax = 1;
+
+ maStr = maText.GetText();
+
+ maButton.SetClickHdl( LINK( this, PrintProgressDialog, ClickHdl ) );
+
+}
+
+PrintProgressDialog::~PrintProgressDialog()
+{
+}
+
+IMPL_LINK( PrintProgressDialog, ClickHdl, Button*, pButton )
+{
+ if( pButton == &maButton )
+ mbCanceled = true;
+
+ return 0;
+}
+
+void PrintProgressDialog::implCalcProgressRect()
+{
+ if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aValue;
+ Region aControlRegion( Rectangle( Point(), Size( 100, mnProgressHeight ) ) );
+ Region aNativeControlRegion, aNativeContentRegion;
+ if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) )
+ {
+ mnProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight();
+ }
+ mbNativeProgress = true;
+ }
+ maProgressRect = Rectangle( Point( 10, maText.GetPosPixel().Y() + maText.GetSizePixel().Height() + 8 ),
+ Size( GetSizePixel().Width() - 20, mnProgressHeight ) );
+}
+
+void PrintProgressDialog::setProgress( int i_nCurrent, int i_nMax )
+{
+ if( maProgressRect.IsEmpty() )
+ implCalcProgressRect();
+
+ mnCur = i_nCurrent;
+ if( i_nMax != -1 )
+ mnMax = i_nMax;
+
+ if( mnMax < 1 )
+ mnMax = 1;
+
+ rtl::OUString aNewText( searchAndReplace( maStr, "%p", 2, rtl::OUString::valueOf( mnCur ) ) );
+ aNewText = searchAndReplace( aNewText, "%n", 2, rtl::OUString::valueOf( mnMax ) );
+ maText.SetText( aNewText );
+
+ // update progress
+ Invalidate( maProgressRect, INVALIDATE_UPDATE );
+}
+
+void PrintProgressDialog::tick()
+{
+ if( mnCur < mnMax )
+ setProgress( ++mnCur );
+}
+
+void PrintProgressDialog::Paint( const Rectangle& )
+{
+ if( maProgressRect.IsEmpty() )
+ implCalcProgressRect();
+
+ Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aPrgsColor = rStyleSettings.GetHighlightColor();
+ if ( aPrgsColor == rStyleSettings.GetFaceColor() )
+ aPrgsColor = rStyleSettings.GetDarkShadowColor();
+ SetLineColor();
+ SetFillColor( aPrgsColor );
+
+ const long nOffset = 3;
+ const long nWidth = 3*mnProgressHeight/2;
+ const long nFullWidth = nWidth + nOffset;
+ const long nMaxCount = maProgressRect.GetWidth() / nFullWidth;
+ DrawProgress( this, maProgressRect.TopLeft(),
+ nOffset,
+ nWidth,
+ mnProgressHeight,
+ static_cast<USHORT>(0),
+ static_cast<USHORT>(10000*mnCur/mnMax),
+ static_cast<USHORT>(10000/nMaxCount),
+ maProgressRect
+ );
+ Pop();
+
+ if( ! mbNativeProgress )
+ {
+ DecorationView aDecoView( this );
+ Rectangle aFrameRect( maProgressRect );
+ aFrameRect.Left() -= nOffset;
+ aFrameRect.Right() += nOffset;
+ aFrameRect.Top() -= nOffset;
+ aFrameRect.Bottom() += nOffset;
+ aDecoView.DrawFrame( aFrameRect );
+ }
+}
+
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index 8aa4926f5e1a..ef58ea9e6bc6 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -229,6 +229,22 @@ int ToolBox::ImplGetDragWidth( ToolBox* pThis )
}
return width;
}
+
+ButtonType determineButtonType( ImplToolItem* pItem, ButtonType defaultType )
+{
+ ButtonType tmpButtonType = defaultType;
+ ToolBoxItemBits nBits( pItem->mnBits & 0x300 );
+ if ( nBits & TIB_TEXTICON ) // item has custom setting
+ {
+ tmpButtonType = BUTTON_SYMBOLTEXT;
+ if ( nBits == TIB_TEXT_ONLY )
+ tmpButtonType = BUTTON_TEXT;
+ else if ( nBits == TIB_ICON_ONLY )
+ tmpButtonType = BUTTON_SYMBOL;
+ }
+ return tmpButtonType;
+}
+
// -----------------------------------------------------------------------
void ToolBox::ImplUpdateDragArea( ToolBox *pThis )
@@ -1992,12 +2008,13 @@ BOOL ToolBox::ImplCalcItem()
bText = FALSE;
else
bText = TRUE;
-
+ ButtonType tmpButtonType = determineButtonType( &(*it), meButtonType ); // default to toolbox setting
if ( bImage || bText )
{
+
it->mbEmptyBtn = FALSE;
- if ( meButtonType == BUTTON_SYMBOL )
+ if ( tmpButtonType == BUTTON_SYMBOL )
{
// we're drawing images only
if ( bImage || !bText )
@@ -2011,7 +2028,7 @@ BOOL ToolBox::ImplCalcItem()
it->mbVisibleText = TRUE;
}
}
- else if ( meButtonType == BUTTON_TEXT )
+ else if ( tmpButtonType == BUTTON_TEXT )
{
// we're drawing text only
if ( bText || !bImage )
@@ -3625,7 +3642,8 @@ void ToolBox::ImplDrawItem( USHORT nPos, BOOL bHighlight, BOOL bPaint, BOOL bLay
// determine what has to be drawn on the button: image, text or both
BOOL bImage;
BOOL bText;
- pItem->DetermineButtonDrawStyle( meButtonType, bImage, bText );
+ ButtonType tmpButtonType = determineButtonType( pItem, meButtonType ); // default to toolbox setting
+ pItem->DetermineButtonDrawStyle( tmpButtonType, bImage, bText );
// compute output values
long nBtnWidth = aBtnSize.Width()-SMALLBUTTON_HSIZE;
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index bcf86c749673..ca0ebb10a4e9 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -698,6 +698,7 @@ void Window::ImplInitWindowData( WindowType nType )
mpWindowImpl->mbCallHandlersDuringInputDisabled = FALSE; // TRUE: call event handlers even if input is disabled
mpWindowImpl->mbDisableAccessibleLabelForRelation = FALSE; // TRUE: do not set LabelFor relation on accessible objects
mpWindowImpl->mbDisableAccessibleLabeledByRelation = FALSE; // TRUE: do not set LabeledBy relation on accessible objects
+ mpWindowImpl->mbHelpTextDynamic = FALSE; // TRUE: append help id in HELP_DEBUG case
mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // TRUE: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
}
@@ -1279,7 +1280,10 @@ void Window::ImplLoadRes( const ResId& rResId )
if ( nObjMask & WINDOW_TEXT )
SetText( ReadStringRes() );
if ( nObjMask & WINDOW_HELPTEXT )
+ {
SetHelpText( ReadStringRes() );
+ mpWindowImpl->mbHelpTextDynamic = TRUE;
+ }
if ( nObjMask & WINDOW_QUICKTEXT )
SetQuickHelpText( ReadStringRes() );
if ( nObjMask & WINDOW_EXTRALONG )
@@ -8109,9 +8113,26 @@ const XubString& Window::GetHelpText() const
((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this );
else
((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( nNumHelpId, this );
+ mpWindowImpl->mbHelpTextDynamic = FALSE;
}
}
}
+ else if( mpWindowImpl->mbHelpTextDynamic && (nNumHelpId || bStrHelpId) )
+ {
+ static const char* pEnv = getenv( "HELP_DEBUG" );
+ if( pEnv && *pEnv )
+ {
+ rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() );
+ aTxt.append( mpWindowImpl->maHelpText );
+ aTxt.appendAscii( "\n+++++++++++++++\n" );
+ if( bStrHelpId )
+ aTxt.append( rtl::OUString( aStrHelpId ) );
+ else
+ aTxt.append( sal_Int32( nNumHelpId ) );
+ mpWindowImpl->maHelpText = aTxt.makeStringAndClear();
+ }
+ mpWindowImpl->mbHelpTextDynamic = FALSE;
+ }
return mpWindowImpl->maHelpText;
}
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index d70f607a6cc6..a9bc93863829 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -1459,7 +1459,6 @@ ULONG Window::GetHelpId() const
void Window::SetSmartHelpId( const SmartId& aId, SmartIdUpdateMode aMode )
{
- mpWindowImpl->maHelpText = String();
// create SmartId if required
if ( (aMode == SMART_SET_STR) || (aMode == SMART_SET_ALL) || ( (aMode == SMART_SET_SMART) && aId.HasString() ) )
{
@@ -2000,6 +1999,7 @@ BOOL Window::IsZoom() const
void Window::SetHelpText( const XubString& rHelpText )
{
mpWindowImpl->maHelpText = rHelpText;
+ mpWindowImpl->mbHelpTextDynamic = TRUE;
}
void Window::SetQuickHelpText( const XubString& rHelpText )
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 278ac0e61d92..d0b9ae5c7561 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -1105,6 +1105,19 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType,
rNativeContentRegion = Region( aIndicatorRect );
returnVal = TRUE;
}
+ if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX) && nPart == PART_ENTIRE_CONTROL )
+ {
+ NWEnsureGTKEditBox( m_nScreen );
+ GtkWidget* widget = gWidgetData[m_nScreen].gEditBoxWidget;
+ GtkRequisition aReq;
+ gtk_widget_size_request( widget, &aReq );
+ Rectangle aEditRect = rControlRegion.GetBoundRect();
+ aEditRect = Rectangle( aEditRect.TopLeft(),
+ Size( aEditRect.GetWidth(), aReq.height+1 ) );
+ rNativeBoundingRegion = Region( aEditRect );
+ rNativeContentRegion = rNativeBoundingRegion;
+ returnVal = TRUE;
+ }
if( (nType == CTRL_SLIDER) && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
{
NWEnsureGTKSlider( m_nScreen );
diff --git a/vcl/unx/headless/svpprn.cxx b/vcl/unx/headless/svpprn.cxx
index 1882b50e6ad7..75d86959b2b5 100644
--- a/vcl/unx/headless/svpprn.cxx
+++ b/vcl/unx/headless/svpprn.cxx
@@ -123,6 +123,32 @@ static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData )
pJobSetup->mnPaperBin = 0xffff;
}
+ // copy duplex
+ pKey = NULL;
+ pValue = NULL;
+
+ pJobSetup->meDuplexMode = DUPLEX_UNKNOWN;
+ if( rData.m_pParser )
+ pKey = rData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
+ if( pKey )
+ pValue = rData.m_aContext.getValue( pKey );
+ if( pKey && pValue )
+ {
+ if( pValue->m_aOption.EqualsIgnoreCaseAscii( "None" ) ||
+ pValue->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 )
+ )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_OFF;
+ }
+ else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexNoTumble" ) )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_LONGEDGE;
+ }
+ else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexTumble" ) )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_SHORTEDGE;
+ }
+ }
// copy the whole context
if( pJobSetup->mpDriverData )
@@ -455,34 +481,6 @@ void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* )
// -----------------------------------------------------------------------
-DuplexMode PspSalInfoPrinter::GetDuplexMode( const ImplJobSetup* pJobSetup )
-{
- DuplexMode aRet = DUPLEX_UNKNOWN;
- PrinterInfo aInfo( PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ) );
- if ( pJobSetup->mpDriverData )
- JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo );
- if( aInfo.m_pParser )
- {
- const PPDKey * pKey = aInfo.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
- if( pKey )
- {
- const PPDValue* pVal = aInfo.m_aContext.getValue( pKey );
- if( pVal && (
- pVal->m_aOption.EqualsIgnoreCaseAscii( "None" ) ||
- pVal->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 )
- ) )
- {
- aRet = DUPLEX_OFF;
- }
- else
- aRet = DUPLEX_ON;
- }
- }
- return aRet;
-}
-
-// -----------------------------------------------------------------------
-
int PspSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* )
{
return 900;
@@ -624,6 +622,37 @@ BOOL PspSalInfoPrinter::SetData(
if( nSetDataFlags & SAL_JOBSET_ORIENTATION )
aData.m_eOrientation = pJobSetup->meOrientation == ORIENTATION_LANDSCAPE ? orientation::Landscape : orientation::Portrait;
+ // merge duplex if necessary
+ if( nSetDataFlags & SAL_JOBSET_DUPLEXMODE )
+ {
+ pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
+ if( pKey )
+ {
+ pValue = NULL;
+ switch( pJobSetup->meDuplexMode )
+ {
+ case DUPLEX_OFF:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ if( pValue == NULL )
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "SimplexNoTumble" ) ) );
+ break;
+ case DUPLEX_SHORTEDGE:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "DuplexTumble" ) ) );
+ break;
+ case DUPLEX_LONGEDGE:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "DuplexNoTumble" ) ) );
+ break;
+ case DUPLEX_UNKNOWN:
+ default:
+ pValue = 0;
+ break;
+ }
+ if( ! pValue )
+ pValue = pKey->getDefaultValue();
+ aData.m_aContext.setValue( pKey, pValue );
+ }
+ }
+
m_aJobData = aData;
copyJobDataToJobSetup( pJobSetup, aData );
return TRUE;
@@ -725,9 +754,22 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT
case PRINTER_CAPABILITIES_COPIES:
return 0xffff;
case PRINTER_CAPABILITIES_COLLATECOPIES:
- return 0;
+ {
+ // see if the PPD contains a value to set Collate to True
+ JobData aData;
+ JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
+
+ const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) ) : NULL;
+ const PPDValue* pVal = pKey ? pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "True" ) ) ) : NULL;
+
+ // PPDs don't mention the number of possible collated copies.
+ // so let's guess as many as we want ?
+ return pVal ? 0xffff : 0;
+ }
case PRINTER_CAPABILITIES_SETORIENTATION:
return 1;
+ case PRINTER_CAPABILITIES_SETDUPLEX:
+ return 1;
case PRINTER_CAPABILITIES_SETPAPERBIN:
return 1;
case PRINTER_CAPABILITIES_SETPAPERSIZE:
@@ -777,6 +819,7 @@ PspSalPrinter::PspSalPrinter( SalInfoPrinter* pInfoPrinter )
m_bSwallowFaxNo( false ),
m_pGraphics( NULL ),
m_nCopies( 1 ),
+ m_bCollate( false ),
m_pInfoPrinter( pInfoPrinter )
{
}
@@ -802,7 +845,9 @@ BOOL PspSalPrinter::StartJob(
const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL /*bCollate*/,
+ ULONG nCopies,
+ bool bCollate,
+ bool /*bDirect*/,
ImplJobSetup* pJobSetup )
{
vcl_sal::PrinterUpdate::jobStarted();
@@ -811,13 +856,17 @@ BOOL PspSalPrinter::StartJob(
m_bPdf = false;
m_aFileName = pFileName ? *pFileName : String();
m_aTmpFile = String();
- m_nCopies = nCopies;
+ m_nCopies = nCopies;
+ m_bCollate = bCollate;
JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData );
if( m_nCopies > 1 )
+ {
// in case user did not do anything (m_nCopies=1)
// take the default from jobsetup
m_aJobData.m_nCopies = m_nCopies;
+ m_aJobData.setCollate( bCollate );
+ }
// check wether this printer is configured as fax
int nMode = 0;
@@ -917,9 +966,12 @@ SalGraphics* PspSalPrinter::StartPage( ImplJobSetup* pJobSetup, BOOL )
m_pGraphics = new PspGraphics( &m_aJobData, &m_aPrinterGfx, m_bFax ? &m_aFaxNr : NULL, m_bSwallowFaxNo, m_pInfoPrinter );
m_pGraphics->SetLayout( 0 );
if( m_nCopies > 1 )
+ {
// in case user did not do anything (m_nCopies=1)
// take the default from jobsetup
m_aJobData.m_nCopies = m_nCopies;
+ m_aJobData.setCollate( m_nCopies > 1 && m_bCollate );
+ }
m_aPrintJob.StartPage( m_aJobData );
m_aPrinterGfx.Init( m_aPrintJob );
diff --git a/vcl/unx/headless/svpprn.hxx b/vcl/unx/headless/svpprn.hxx
index c2d85c054fce..8f5a47fed118 100644
--- a/vcl/unx/headless/svpprn.hxx
+++ b/vcl/unx/headless/svpprn.hxx
@@ -63,7 +63,6 @@ public:
virtual String GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin );
virtual void InitPaperFormats( const ImplJobSetup* pSetupData );
virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData );
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData );
};
class PspSalPrinter : public SalPrinter
@@ -80,6 +79,7 @@ public:
psp::JobData m_aJobData;
psp::PrinterGfx m_aPrinterGfx;
ULONG m_nCopies;
+ bool m_bCollate;
SalInfoPrinter* m_pInfoPrinter;
PspSalPrinter( SalInfoPrinter* );
@@ -90,7 +90,9 @@ public:
virtual BOOL StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData );
virtual BOOL EndJob();
virtual BOOL AbortJob();
diff --git a/vcl/unx/inc/salprn.h b/vcl/unx/inc/salprn.h
index 452fa5a89387..59a5c3eef56a 100644
--- a/vcl/unx/inc/salprn.h
+++ b/vcl/unx/inc/salprn.h
@@ -63,7 +63,6 @@ public:
virtual String GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin );
virtual void InitPaperFormats( const ImplJobSetup* pSetupData );
virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData );
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData );
};
class PspSalPrinter : public SalPrinter
@@ -80,6 +79,7 @@ public:
psp::JobData m_aJobData;
psp::PrinterGfx m_aPrinterGfx;
ULONG m_nCopies;
+ bool m_bCollate;
SalInfoPrinter* m_pInfoPrinter;
PspSalPrinter( SalInfoPrinter* );
@@ -90,7 +90,9 @@ public:
virtual BOOL StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData );
virtual BOOL EndJob();
virtual BOOL AbortJob();
diff --git a/vcl/unx/inc/salunx.h b/vcl/unx/inc/salunx.h
index cdf45fd30867..c1fee6c68d94 100644
--- a/vcl/unx/inc/salunx.h
+++ b/vcl/unx/inc/salunx.h
@@ -38,12 +38,6 @@
#include <time.h>
#include <sys/time.h>
#include <strings.h>
-#elif defined IRIX
-#ifdef __cplusplus
-#include <ctime>
-#endif
-#include <sys/time.h>
-#include <unistd.h>
#endif
#include <svunx.h>
#include <salstd.hxx>
diff --git a/vcl/unx/source/app/i18n_ic.cxx b/vcl/unx/source/app/i18n_ic.cxx
index cacffbcfdbb1..bb8f86d93e01 100644
--- a/vcl/unx/source/app/i18n_ic.cxx
+++ b/vcl/unx/source/app/i18n_ic.cxx
@@ -340,7 +340,7 @@ SalI18N_InputContext::SalI18N_InputContext ( SalFrame *pFrame ) :
if ( mnPreeditStyle != XIMPreeditNone )
{
-#if defined LINUX || defined FREEBSD || defined NETBSD || defined IRIX
+#if defined LINUX || defined FREEBSD || defined NETBSD
if ( mpPreeditAttributes != NULL )
#endif
mpAttributes = XVaAddToNestedList( mpAttributes,
@@ -348,7 +348,7 @@ SalI18N_InputContext::SalI18N_InputContext ( SalFrame *pFrame ) :
}
if ( mnStatusStyle != XIMStatusNone )
{
-#if defined LINUX || defined FREEBSD || defined NETBSD || defined IRIX
+#if defined LINUX || defined FREEBSD || defined NETBSD
if ( mpStatusAttributes != NULL )
#endif
mpAttributes = XVaAddToNestedList( mpAttributes,
diff --git a/vcl/unx/source/app/i18n_im.cxx b/vcl/unx/source/app/i18n_im.cxx
index ae472d6323f4..0a48c054167f 100644
--- a/vcl/unx/source/app/i18n_im.cxx
+++ b/vcl/unx/source/app/i18n_im.cxx
@@ -59,7 +59,7 @@
using namespace vcl;
#include "i18n_cb.hxx"
-#if defined(SOLARIS) || defined(LINUX) || defined(IRIX)
+#if defined(SOLARIS) || defined(LINUX)
extern "C" char * XSetIMValues(XIM im, ...);
#endif
diff --git a/vcl/unx/source/app/randrwrapper.cxx b/vcl/unx/source/app/randrwrapper.cxx
index 8d01b64d4680..4fbe5db97ab9 100644
--- a/vcl/unx/source/app/randrwrapper.cxx
+++ b/vcl/unx/source/app/randrwrapper.cxx
@@ -161,7 +161,13 @@ RandRWrapper::RandRWrapper( Display* pDisplay ) :
if( ! m_bValid )
{
rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
- m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT );
+ // load and resolve dependencies immediately
+ // rationale: there are older distributions where libXrandr.so.2 is not linked
+ // with libXext.so, resulting in a missing symbol and terminating the office
+ // obviously they expected libXext to be linked in global symbolspace (that is
+ // linked by the application), which is not the case with us (because we want
+ // to be able to run in headless mode even without an installed X11 library)
+ m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT | SAL_LOADMODULE_NOW );
initFromModule();
}
if( m_bValid )
diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx
index 07955d426b8c..558ae3714358 100644
--- a/vcl/unx/source/app/saldisp.cxx
+++ b/vcl/unx/source/app/saldisp.cxx
@@ -38,16 +38,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
-#if defined(IRIX)
-#include <ctime>
-#endif
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
-#if defined(SOLARIS) || defined(IRIX)
+#if defined(SOLARIS)
#include <sal/alloca.h>
#include <osl/module.h>
#endif
@@ -898,7 +895,7 @@ void SalDisplay::Init()
sscanf( pProperties, "%li", &nProperties_ );
else
{
-#if defined DBG_UTIL || defined SUN || defined LINUX || defined FREEBSD || defined IRIX
+#if defined DBG_UTIL || defined SUN || defined LINUX || defined FREEBSD
nProperties_ |= PROPERTY_FEATURE_Maximize;
#endif
// Server Bugs & Properties
@@ -2307,11 +2304,7 @@ long SalX11Display::Dispatch( XEvent *pEvent )
return 0;
SalInstance* pInstance = GetSalData()->m_pInstance;
- if( pInstance->GetEventCallback() )
- {
- YieldMutexReleaser aReleaser;
- pInstance->CallEventCallback( pEvent, sizeof( XEvent ) );
- }
+ pInstance->CallEventCallback( pEvent, sizeof( XEvent ) );
switch( pEvent->type )
{
diff --git a/vcl/unx/source/app/saltimer.cxx b/vcl/unx/source/app/saltimer.cxx
index bf8aa202b066..afcecc0d0667 100644
--- a/vcl/unx/source/app/saltimer.cxx
+++ b/vcl/unx/source/app/saltimer.cxx
@@ -32,9 +32,6 @@
#include "precompiled_vcl.hxx"
#include <stdio.h>
-#if defined(IRIX)
-#include <ctime>
-#endif
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx
index cb554bccea21..5fe2295a8fed 100644
--- a/vcl/unx/source/gdi/salgdi.cxx
+++ b/vcl/unx/source/gdi/salgdi.cxx
@@ -50,6 +50,7 @@
#include "basegfx/polygon/b2dpolygonclipper.hxx"
#include "basegfx/polygon/b2dlinegeometry.hxx"
#include "basegfx/matrix/b2dhommatrix.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
#include <vector>
@@ -1567,6 +1568,9 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
// the used basegfx::tools::createAreaGeometry is simply too
// expensive with very big polygons; fallback to caller (who
// should use ImplLineConverter normally)
+ // AW: ImplLineConverter had to be removed since it does not even
+ // know LineJoins, so the fallback will now prepare the line geometry
+ // the same way.
return false;
}
const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
@@ -1579,9 +1583,7 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
&& !basegfx::fTools::equalZero( rLineWidth.getY() ) )
{
// prepare for createAreaGeometry() with anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() );
- aPolygon.transform( aAnisoMatrix );
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
}
// special handling for hairlines to improve the drawing performance
@@ -1603,9 +1605,7 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const :
&& !basegfx::fTools::equalZero( rLineWidth.getX() ) )
{
// postprocess createAreaGeometry() for anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() );
- aPolygon.transform( aAnisoMatrix );
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
}
// temporarily adjust brush color to pen color
diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx
index 2cf4e3baedd3..d47e30a89633 100644
--- a/vcl/unx/source/gdi/salprnpsp.cxx
+++ b/vcl/unx/source/gdi/salprnpsp.cxx
@@ -177,6 +177,32 @@ static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData )
pJobSetup->mnPaperBin = 0;
}
+ // copy duplex
+ pKey = NULL;
+ pValue = NULL;
+
+ pJobSetup->meDuplexMode = DUPLEX_UNKNOWN;
+ if( rData.m_pParser )
+ pKey = rData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
+ if( pKey )
+ pValue = rData.m_aContext.getValue( pKey );
+ if( pKey && pValue )
+ {
+ if( pValue->m_aOption.EqualsIgnoreCaseAscii( "None" ) ||
+ pValue->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 )
+ )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_OFF;
+ }
+ else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexNoTumble" ) )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_LONGEDGE;
+ }
+ else if( pValue->m_aOption.EqualsIgnoreCaseAscii( "DuplexTumble" ) )
+ {
+ pJobSetup->meDuplexMode = DUPLEX_SHORTEDGE;
+ }
+ }
// copy the whole context
if( pJobSetup->mpDriverData )
@@ -525,34 +551,6 @@ void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* )
// -----------------------------------------------------------------------
-DuplexMode PspSalInfoPrinter::GetDuplexMode( const ImplJobSetup* pJobSetup )
-{
- DuplexMode aRet = DUPLEX_UNKNOWN;
- PrinterInfo aInfo( PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ) );
- if ( pJobSetup->mpDriverData )
- JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo );
- if( aInfo.m_pParser )
- {
- const PPDKey * pKey = aInfo.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
- if( pKey )
- {
- const PPDValue* pVal = aInfo.m_aContext.getValue( pKey );
- if( pVal && (
- pVal->m_aOption.EqualsIgnoreCaseAscii( "None" ) ||
- pVal->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 )
- ) )
- {
- aRet = DUPLEX_OFF;
- }
- else
- aRet = DUPLEX_ON;
- }
- }
- return aRet;
-}
-
-// -----------------------------------------------------------------------
-
int PspSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* )
{
return 900;
@@ -727,6 +725,37 @@ BOOL PspSalInfoPrinter::SetData(
if( nSetDataFlags & SAL_JOBSET_ORIENTATION )
aData.m_eOrientation = pJobSetup->meOrientation == ORIENTATION_LANDSCAPE ? orientation::Landscape : orientation::Portrait;
+ // merge duplex if necessary
+ if( nSetDataFlags & SAL_JOBSET_DUPLEXMODE )
+ {
+ pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
+ if( pKey )
+ {
+ pValue = NULL;
+ switch( pJobSetup->meDuplexMode )
+ {
+ case DUPLEX_OFF:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ if( pValue == NULL )
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "SimplexNoTumble" ) ) );
+ break;
+ case DUPLEX_SHORTEDGE:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "DuplexTumble" ) ) );
+ break;
+ case DUPLEX_LONGEDGE:
+ pValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "DuplexNoTumble" ) ) );
+ break;
+ case DUPLEX_UNKNOWN:
+ default:
+ pValue = 0;
+ break;
+ }
+ if( ! pValue )
+ pValue = pKey->getDefaultValue();
+ aData.m_aContext.setValue( pKey, pValue );
+ }
+ }
+
m_aJobData = aData;
copyJobDataToJobSetup( pJobSetup, aData );
return TRUE;
@@ -828,9 +857,22 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT
case PRINTER_CAPABILITIES_COPIES:
return 0xffff;
case PRINTER_CAPABILITIES_COLLATECOPIES:
- return 0;
+ {
+ // see if the PPD contains a value to set Collate to True
+ JobData aData;
+ JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
+
+ const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) ) : NULL;
+ const PPDValue* pVal = pKey ? pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "True" ) ) ) : NULL;
+
+ // PPDs don't mention the number of possible collated copies.
+ // so let's guess as many as we want ?
+ return pVal ? 0xffff : 0;
+ }
case PRINTER_CAPABILITIES_SETORIENTATION:
return 1;
+ case PRINTER_CAPABILITIES_SETDUPLEX:
+ return 1;
case PRINTER_CAPABILITIES_SETPAPERBIN:
return 1;
case PRINTER_CAPABILITIES_SETPAPERSIZE:
@@ -860,6 +902,7 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT
m_bSwallowFaxNo( false ),
m_pGraphics( NULL ),
m_nCopies( 1 ),
+ m_bCollate( false ),
m_pInfoPrinter( pInfoPrinter )
{
}
@@ -885,7 +928,9 @@ BOOL PspSalPrinter::StartJob(
const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL /*bCollate*/,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pJobSetup )
{
vcl_sal::PrinterUpdate::jobStarted();
@@ -894,13 +939,17 @@ BOOL PspSalPrinter::StartJob(
m_bPdf = false;
m_aFileName = pFileName ? *pFileName : String();
m_aTmpFile = String();
- m_nCopies = nCopies;
+ m_nCopies = nCopies;
+ m_bCollate = bCollate;
JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData );
if( m_nCopies > 1 )
+ {
// in case user did not do anything (m_nCopies=1)
// take the default from jobsetup
m_aJobData.m_nCopies = m_nCopies;
+ m_aJobData.setCollate( bCollate );
+ }
// check wether this printer is configured as fax
int nMode = 0;
@@ -943,15 +992,6 @@ BOOL PspSalPrinter::StartJob(
}
m_aPrinterGfx.Init( m_aJobData );
- bool bIsQuickJob = false;
- std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator quick_it =
- pJobSetup->maValueMap.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ) );
- if( quick_it != pJobSetup->maValueMap.end() )
- {
- if( quick_it->second.equalsIgnoreAsciiCaseAscii( "true" ) )
- bIsQuickJob = true;
- }
-
// set/clear backwards compatibility flag
bool bStrictSO52Compatibility = false;
std::hash_map<rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator compat_it =
@@ -964,7 +1004,7 @@ BOOL PspSalPrinter::StartJob(
}
m_aPrinterGfx.setStrictSO52Compatibility( bStrictSO52Compatibility );
- return m_aPrintJob.StartJob( m_aTmpFile.Len() ? m_aTmpFile : m_aFileName, nMode, rJobName, rAppName, m_aJobData, &m_aPrinterGfx, bIsQuickJob ) ? TRUE : FALSE;
+ return m_aPrintJob.StartJob( m_aTmpFile.Len() ? m_aTmpFile : m_aFileName, nMode, rJobName, rAppName, m_aJobData, &m_aPrinterGfx, bDirect ) ? TRUE : FALSE;
}
// -----------------------------------------------------------------------
@@ -1010,9 +1050,12 @@ SalGraphics* PspSalPrinter::StartPage( ImplJobSetup* pJobSetup, BOOL )
m_pGraphics = new PspGraphics( &m_aJobData, &m_aPrinterGfx, m_bFax ? &m_aFaxNr : NULL, m_bSwallowFaxNo, m_pInfoPrinter );
m_pGraphics->SetLayout( 0 );
if( m_nCopies > 1 )
+ {
// in case user did not do anything (m_nCopies=1)
// take the default from jobsetup
m_aJobData.m_nCopies = m_nCopies;
+ m_aJobData.setCollate( m_nCopies > 1 && m_bCollate );
+ }
m_aPrintJob.StartPage( m_aJobData );
m_aPrinterGfx.Init( m_aPrintJob );
diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx
index f1c63b8abee7..08820b2cb7f9 100644
--- a/vcl/unx/source/plugadapt/salplug.cxx
+++ b/vcl/unx/source/plugadapt/salplug.cxx
@@ -219,8 +219,10 @@ SalInstance *CreateSalInstance()
if( !(pUsePlugin && *pUsePlugin) )
pInst = check_headless_plugin();
+ else
+ pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );
- if( ! pInst && !(pUsePlugin && *pUsePlugin) )
+ if( ! pInst )
pInst = autodetect_plugin();
// fallback to gen
diff --git a/vcl/unx/source/printer/jobdata.cxx b/vcl/unx/source/printer/jobdata.cxx
index 51e171d578d9..0410b349c93b 100644
--- a/vcl/unx/source/printer/jobdata.cxx
+++ b/vcl/unx/source/printer/jobdata.cxx
@@ -64,6 +64,28 @@ JobData& JobData::operator=(const JobData& rRight)
return *this;
}
+void JobData::setCollate( bool bCollate )
+{
+ const PPDParser* pParser = m_aContext.getParser();
+ if( pParser )
+ {
+ const PPDKey* pKey = pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) );
+ if( pKey )
+ {
+ const PPDValue* pVal = NULL;
+ if( bCollate )
+ pVal = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "True" ) ) );
+ else
+ {
+ pVal = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "False" ) ) );
+ if( ! pVal )
+ pVal = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
+ }
+ m_aContext.setValue( pKey, pVal );
+ }
+ }
+}
+
bool JobData::getStreamBuffer( void*& pData, int& bytes )
{
// consistency checks
diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx
index b3e5b4667a6a..53cd662db8e0 100644
--- a/vcl/unx/source/printer/printerinfomanager.cxx
+++ b/vcl/unx/source/printer/printerinfomanager.cxx
@@ -441,7 +441,7 @@ void PrinterInfoManager::initialize()
* porters: please append your platform to the Solaris
* case if your platform has SystemV printing per default.
*/
- #if defined SOLARIS || defined(IRIX)
+ #if defined SOLARIS
aValue = "lp";
#else
aValue = "lpr";
diff --git a/vcl/unx/source/printergfx/printerjob.cxx b/vcl/unx/source/printergfx/printerjob.cxx
index 783dd5ff2b47..1c42cafa4cb9 100644
--- a/vcl/unx/source/printergfx/printerjob.cxx
+++ b/vcl/unx/source/printergfx/printerjob.cxx
@@ -681,14 +681,6 @@ PrinterJob::StartPage (const JobData& rJobSetup)
if( ! (pPageHeader && pPageBody) )
return sal_False;
- /* #i7262# write setup only before first page
- * don't do this in StartJob since the jobsetup there may be
- * different.
- */
- bool bSuccess = true;
- if( 1 == maPageList.size() )
- m_aDocumentJobData = rJobSetup;
-
// write page header according to Document Structuring Conventions (DSC)
WritePS (pPageHeader, "%%Page: ");
WritePS (pPageHeader, aPageNo);
@@ -722,13 +714,25 @@ PrinterJob::StartPage (const JobData& rJobSetup)
WritePS (pPageHeader, pBBox);
- if (bSuccess)
- bSuccess = writePageSetup ( pPageHeader, rJobSetup );
- if(bSuccess)
- m_aLastJobData = rJobSetup;
+ /* #i7262# #i65491# write setup only before first page
+ * (to %%Begin(End)Setup, instead of %%Begin(End)PageSetup)
+ * don't do this in StartJob since the jobsetup there may be
+ * different.
+ */
+ bool bWriteFeatures = true;
+ if( 1 == maPageList.size() )
+ {
+ m_aDocumentJobData = rJobSetup;
+ bWriteFeatures = false;
+ }
+ if ( writePageSetup( pPageHeader, rJobSetup, bWriteFeatures ) )
+ {
+ m_aLastJobData = rJobSetup;
+ return true;
+ }
- return bSuccess;
+ return false;
}
sal_Bool
@@ -828,12 +832,9 @@ bool PrinterJob::writeFeatureList( osl::File* pFile, const JobData& rJob, bool b
if( pKey->getSetupType() == PPDKey::DocumentSetup )
bEmit = true;
}
- else
- {
- if( pKey->getSetupType() == PPDKey::PageSetup ||
- pKey->getSetupType() == PPDKey::AnySetup )
- bEmit = true;
- }
+ if( pKey->getSetupType() == PPDKey::PageSetup ||
+ pKey->getSetupType() == PPDKey::AnySetup )
+ bEmit = true;
if( bEmit )
{
const PPDValue* pValue = rJob.m_aContext.getValue( pKey );
@@ -866,13 +867,13 @@ bool PrinterJob::writeFeatureList( osl::File* pFile, const JobData& rJob, bool b
return bSuccess;
}
-bool PrinterJob::writePageSetup( osl::File* pFile, const JobData& rJob )
+bool PrinterJob::writePageSetup( osl::File* pFile, const JobData& rJob, bool bWriteFeatures )
{
bool bSuccess = true;
WritePS (pFile, "%%BeginPageSetup\n%\n");
-
- bSuccess = writeFeatureList( pFile, rJob, false );
+ if ( bWriteFeatures )
+ bSuccess = writeFeatureList( pFile, rJob, false );
WritePS (pFile, "%%EndPageSetup\n");
sal_Char pTranslate [128];
diff --git a/vcl/util/hidother.src b/vcl/util/hidother.src
new file mode 100644
index 000000000000..ab10a1e4c4ea
--- /dev/null
+++ b/vcl/util/hidother.src
@@ -0,0 +1,34 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hidother.src,v $
+ * $Revision: 1.20 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "vcl/svids.hrc"
+
+hidspecial HID_PRINTDLG { HelpID = HID_PRINTDLG; };
+
diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk
index ef4f13301ecd..c5a99d47c709 100644
--- a/vcl/util/makefile.mk
+++ b/vcl/util/makefile.mk
@@ -31,6 +31,7 @@ PRJNAME=vcl
TARGET=vcl
TARGETTYPE=GUI
USE_DEFFILE=TRUE
+GEN_HID_OTHER=TRUE
.IF "$(SNDFILE_LIBS)"!=""
SNDFILELIB=$(SNDFILE_LIBS)
diff --git a/vcl/win/inc/salprn.h b/vcl/win/inc/salprn.h
index 58d721fd043a..890ff70bc3d6 100644
--- a/vcl/win/inc/salprn.h
+++ b/vcl/win/inc/salprn.h
@@ -88,7 +88,6 @@ public:
virtual String GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin );
virtual void InitPaperFormats( const ImplJobSetup* pSetupData );
virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData );
- virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData );
};
// -----------------
@@ -117,7 +116,9 @@ public:
virtual BOOL StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString& rAppName,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool bDirect,
ImplJobSetup* pSetupData );
virtual BOOL EndJob();
virtual BOOL AbortJob();
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index d82830a9022f..12fdad65dfb1 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -65,6 +65,7 @@
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolypolygon.hxx"
#include "basegfx/matrix/b2dhommatrix.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include "sft.hxx"
@@ -2480,9 +2481,8 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex,
// rescaling needed for the PolyPolygon conversion
if( rB2DPolyPoly.count() )
{
- ::basegfx::B2DHomMatrix aMatrix;
- aMatrix.scale( mfFontScale/256, mfFontScale/256 );
- rB2DPolyPoly.transform( aMatrix );
+ const double fFactor(mfFontScale/256);
+ rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor));
}
return bRet;
diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx
index 5c00c786e22d..29e4ff1d801e 100644
--- a/vcl/win/source/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx
@@ -62,9 +62,9 @@
// -----------------------------------------------------------------------
-void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon)
+void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
{
- const sal_uInt32 nCount(rPolygon.count());
+ sal_uInt32 nCount(rPolygon.count());
if(nCount)
{
@@ -97,8 +97,58 @@ void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const b
if(a + 1 < nEdgeCount)
{
- aCurr = aNext;
aFCurr = aFNext;
+
+ if(bNoLineJoin)
+ {
+ rPath.StartFigure();
+ }
+ }
+ }
+ }
+}
+
+void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
+{
+ sal_uInt32 nCount(rPolygon.count());
+
+ if(nCount)
+ {
+ const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
+ const bool bControls(rPolygon.areControlPointsUsed());
+ basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
+ Gdiplus::Point aICurr(INT(aCurr.getX()), INT(aCurr.getY()));
+
+ for(sal_uInt32 a(0); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex((a + 1) % nCount);
+ const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
+ const Gdiplus::Point aINext(INT(aNext.getX()), INT(aNext.getY()));
+
+ if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
+ {
+ const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
+ const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
+
+ rPath.AddBezier(
+ aICurr,
+ Gdiplus::Point(INT(aCa.getX()), INT(aCa.getY())),
+ Gdiplus::Point(INT(aCb.getX()), INT(aCb.getY())),
+ aINext);
+ }
+ else
+ {
+ rPath.AddLine(aICurr, aINext);
+ }
+
+ if(a + 1 < nEdgeCount)
+ {
+ aICurr = aINext;
+
+ if(bNoLineJoin)
+ {
+ rPath.StartFigure();
+ }
}
}
}
@@ -123,7 +173,7 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly
aPath.StartFigure(); // #i101491# not needed for first run
}
- impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolyPolygon.getB2DPolygon(a));
+ impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolyPolygon.getB2DPolygon(a), false);
aPath.CloseFigure();
}
@@ -152,11 +202,16 @@ bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const bas
Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
Gdiplus::GraphicsPath aPath;
+ bool bNoLineJoin(false);
switch(eLineJoin)
{
default : // basegfx::B2DLINEJOIN_NONE :
{
+ if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
+ {
+ bNoLineJoin = true;
+ }
break;
}
case basegfx::B2DLINEJOIN_BEVEL :
@@ -179,9 +234,16 @@ bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const bas
}
}
- impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolygon);
+ if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
+ {
+ impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath, rPolygon, bNoLineJoin);
+ }
+ else
+ {
+ impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolygon, bNoLineJoin);
+ }
- if(rPolygon.isClosed())
+ if(rPolygon.isClosed() && !bNoLineJoin)
{
// #i101491# needed to create the correct line joins
aPath.CloseFigure();
diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx
index 07bfe3c20695..819ae7b70253 100644
--- a/vcl/win/source/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx
@@ -341,7 +341,7 @@ BOOL ImplDrawTheme( HTHEME hTheme, HDC hDC, int iPart, int iState, RECT rc, cons
}
-Rectangle ImplGetThemeRect( HTHEME hTheme, HDC hDC, int iPart, int iState, const Rectangle& aRect )
+Rectangle ImplGetThemeRect( HTHEME hTheme, HDC hDC, int iPart, int iState, const Rectangle& aRect, THEMESIZE eTS = TS_TRUE )
{
SIZE aSz;
RECT rc;
@@ -349,7 +349,7 @@ Rectangle ImplGetThemeRect( HTHEME hTheme, HDC hDC, int iPart, int iState, const
rc.right = aRect.nRight;
rc.top = aRect.nTop;
rc.bottom = aRect.nBottom;
- HRESULT hr = vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, NULL, TS_TRUE, &aSz ); // TS_TRUE returns optimal size
+ HRESULT hr = vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, NULL, eTS, &aSz ); // TS_TRUE returns optimal size
if( hr == S_OK )
return Rectangle( 0, 0, aSz.cx, aSz.cy );
else
@@ -1149,6 +1149,61 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType,
bRet = TRUE;
}
}
+ if( (nType == CTRL_LISTBOX || nType == CTRL_COMBOBOX ) && nPart == PART_ENTIRE_CONTROL )
+ {
+ HTHEME hTheme = getThemeHandle( mhWnd, L"Combobox");
+ if( hTheme )
+ {
+ Rectangle aBoxRect( rControlRegion.GetBoundRect() );
+ Rectangle aRect( ImplGetThemeRect( hTheme, hDC, CP_DROPDOWNBUTTON,
+ CBXS_NORMAL, aBoxRect ) );
+ Rectangle aBrdRect( ImplGetThemeRect( hTheme, hDC, CP_BORDER,
+ CBB_HOT, aBoxRect ) );
+ aRect.Top() -= aBrdRect.GetHeight();
+ if( aRect.GetHeight() > aBoxRect.GetHeight() )
+ aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight();
+ if( aRect.GetWidth() > aBoxRect.GetWidth() )
+ aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth();
+ rNativeContentRegion = aBoxRect;
+ rNativeBoundingRegion = rNativeContentRegion;
+ if( !aRect.IsEmpty() )
+ bRet = TRUE;
+ }
+ }
+
+ if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX) && nPart == PART_ENTIRE_CONTROL )
+ {
+ HTHEME hTheme = getThemeHandle( mhWnd, L"Edit");
+ if( hTheme )
+ {
+ // get borderr size
+ Rectangle aBoxRect( rControlRegion.GetBoundRect() );
+ Rectangle aRect( ImplGetThemeRect( hTheme, hDC, EP_BACKGROUNDWITHBORDER,
+ EBWBS_HOT, aBoxRect ) );
+ // ad app font height
+ NONCLIENTMETRICSW aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ long nFontHeight = aNonClientMetrics.lfMessageFont.lfHeight;
+ if( nFontHeight < 0 )
+ nFontHeight = -nFontHeight;
+
+ if( aRect.GetHeight() && nFontHeight )
+ {
+ aRect.Bottom() += aRect.GetHeight();
+ aRect.Bottom() += nFontHeight;
+ if( aRect.GetHeight() > aBoxRect.GetHeight() )
+ aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight();
+ if( aRect.GetWidth() > aBoxRect.GetWidth() )
+ aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth();
+ rNativeContentRegion = aBoxRect;
+ rNativeBoundingRegion = rNativeContentRegion;
+ bRet = TRUE;
+ }
+ }
+ }
+ }
if( nType == CTRL_SLIDER && ( (nPart == PART_THUMB_HORZ) || (nPart == PART_THUMB_VERT) ) )
{
HTHEME hTheme = getThemeHandle( mhWnd, L"Trackbar");
@@ -1173,8 +1228,10 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType,
rNativeContentRegion = aRect;
rNativeBoundingRegion = rNativeContentRegion;
}
+ bRet = TRUE;
}
}
+
ReleaseDC( mhWnd, hDC );
return( bRet );
}
diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx
index ecf91aea7c1b..f4f55dd0adbf 100644
--- a/vcl/win/source/gdi/salprn.cxx
+++ b/vcl/win/source/gdi/salprn.cxx
@@ -1059,6 +1059,21 @@ static void ImplDevModeToJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS
break;
}
}
+
+ if( nFlags & SAL_JOBSET_DUPLEXMODE )
+ {
+ DuplexMode eDuplex = DUPLEX_UNKNOWN;
+ if( (CHOOSE_DEVMODE(dmFields) & DM_DUPLEX) )
+ {
+ if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_SIMPLEX )
+ eDuplex = DUPLEX_OFF;
+ else if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_VERTICAL )
+ eDuplex = DUPLEX_LONGEDGE;
+ else if( CHOOSE_DEVMODE(dmDuplex) == DMDUP_HORIZONTAL )
+ eDuplex = DUPLEX_SHORTEDGE;
+ }
+ pSetupData->meDuplexMode = eDuplex;
+ }
}
// -----------------------------------------------------------------------
@@ -1326,6 +1341,26 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS
}
}
}
+ if( (nFlags & SAL_JOBSET_DUPLEXMODE) )
+ {
+ switch( pSetupData->meDuplexMode )
+ {
+ case DUPLEX_OFF:
+ CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
+ CHOOSE_DEVMODE(dmDuplex) = DMDUP_SIMPLEX;
+ break;
+ case DUPLEX_SHORTEDGE:
+ CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
+ CHOOSE_DEVMODE(dmDuplex) = DMDUP_HORIZONTAL;
+ break;
+ case DUPLEX_LONGEDGE:
+ CHOOSE_DEVMODE(dmFields) |= DM_DUPLEX;
+ CHOOSE_DEVMODE(dmDuplex) = DMDUP_VERTICAL;
+ break;
+ case DUPLEX_UNKNOWN:
+ break;
+ }
+ }
}
// -----------------------------------------------------------------------
@@ -1559,39 +1594,6 @@ void WinSalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData )
// -----------------------------------------------------------------------
-DuplexMode WinSalInfoPrinter::GetDuplexMode( const ImplJobSetup* pSetupData )
-{
- DuplexMode nRet = DUPLEX_UNKNOWN;
- if ( pSetupData &&pSetupData->mpDriverData )
- {
- if( aSalShlData.mbWPrinter )
- {
- DEVMODEW* pDevMode = SAL_DEVMODE_W( pSetupData );
- if ( pDevMode && (pDevMode->dmFields & DM_DUPLEX ))
- {
- if ( pDevMode->dmDuplex == DMDUP_SIMPLEX )
- nRet = DUPLEX_OFF;
- else
- nRet = DUPLEX_ON;
- }
- }
- else
- {
- DEVMODEA* pDevMode = SAL_DEVMODE_A( pSetupData );
- if ( pDevMode && (pDevMode->dmFields & DM_DUPLEX ))
- {
- if ( pDevMode->dmDuplex == DMDUP_SIMPLEX )
- nRet = DUPLEX_OFF;
- else
- nRet = DUPLEX_ON;
- }
- }
- }
- return nRet;
-}
-
-// -----------------------------------------------------------------------
-
int WinSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData )
{
int nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
@@ -1964,7 +1966,9 @@ static int lcl_StartDocA( HDC hDC, DOCINFOA* pInfo, WinSalPrinter* pPrt )
BOOL WinSalPrinter::StartJob( const XubString* pFileName,
const XubString& rJobName,
const XubString&,
- ULONG nCopies, BOOL bCollate,
+ ULONG nCopies,
+ bool bCollate,
+ bool /*bDirect*/,
ImplJobSetup* pSetupData )
{
mnError = 0;