[ooo-build-commit] Branch 'ooo/OOO310' - 2 commits - drawinglayer/source fpicker/source sfx2/inc sfx2/source svx/inc svx/source xmloff/source

Jan Holesovsky kendy at kemper.freedesktop.org
Mon Jul 20 18:01:10 PDT 2009


 drawinglayer/source/processor2d/canvasprocessor.cxx        |    5 
 drawinglayer/source/processor2d/helperchartrenderer.cxx    |   70 ++
 drawinglayer/source/processor2d/helperchartrenderer.hxx    |   13 
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |  103 +++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx    |    5 
 drawinglayer/source/processor2d/vclprocessor2d.cxx         |  242 ++++-----
 fpicker/source/win32/filepicker/VistaFilePicker.cxx        |   20 
 fpicker/source/win32/filepicker/VistaFilePicker.hxx        |    2 
 fpicker/source/win32/filepicker/asyncrequests.cxx          |    2 
 sfx2/inc/sfx2/docfile.hxx                                  |    3 
 sfx2/source/doc/docfile.cxx                                |   25 
 sfx2/source/doc/objstor.cxx                                |    9 
 sfx2/source/toolbox/tbxitem.cxx                            |   19 
 svx/inc/svx/sdr/attribute/sdrtextattribute.hxx             |    4 
 svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx           |   19 
 svx/inc/svx/sdr/primitive2d/sdrpathprimitive2d.hxx         |   12 
 svx/inc/svx/sdr/properties/properties.hxx                  |    5 
 svx/inc/svx/sdr/properties/textproperties.hxx              |    7 
 svx/inc/svx/svdograf.hxx                                   |    3 
 svx/source/outliner/outliner.cxx                           |    2 
 svx/source/sdr/attribute/sdrtextattribute.cxx              |    7 
 svx/source/sdr/contact/viewcontactofgraphic.cxx            |  335 +++++++++++--
 svx/source/sdr/contact/viewcontactofsdrpathobj.cxx         |  119 ++--
 svx/source/sdr/contact/viewobjectcontactofgraphic.cxx      |   29 +
 svx/source/sdr/contact/viewobjectcontactofpageobj.cxx      |    3 
 svx/source/sdr/properties/properties.cxx                   |    5 
 svx/source/sdr/properties/textproperties.cxx               |   23 
 svx/source/svdraw/svdcrtv.cxx                              |   14 
 svx/source/svdraw/svdobj.cxx                               |    5 
 svx/source/svdraw/svdograf.cxx                             |   25 
 xmloff/source/text/txtparae.cxx                            |   36 -
 31 files changed, 887 insertions(+), 284 deletions(-)

New commits:
commit 2898b672166d3304c2e3c06e2e3d5e7a6f49f1c7
Author: Oliver Bolte <obo at openoffice.org>
Date:   Fri Jul 17 06:24:42 2009 +0000

    CWS-TOOLING: integrate CWS aw074
    2009-07-06 13:21:50 +0200 aw  r273737 : CWS-TOOLING: rebase CWS aw074 to branches/OOO310 at 273700 (milestone: OOO310:m15)
    2009-07-06 11:12:35 +0200 aw  r273728 : #i102637# corrected condition to add gray frame to page visualisation objects
    2009-07-03 14:43:00 +0200 aw  r273702 : #i102380# always swap n GrafObjects on MasterPages synchronously
    2009-07-03 12:14:57 +0200 aw  r273686 : #i102548# corrected SdrPathPrimitive2D's usage of unit polygon
    2009-07-02 16:06:16 +0200 aw  r273662 : #i103255# added control when to show the draft graphic visualisation (in VOC, of course) and when not. Changed text visualisation to BlockText
    2009-07-01 17:36:55 +0200 aw  r273609 : #i103116# clear GaphicLink for interaction clone of graphic objets
    2009-07-01 16:42:09 +0200 aw  r273601 : #i101491# corrected some minor glitches in line geometry creation
    2009-06-30 18:47:44 +0200 aw  r273532 : #i102380# committed the cleanups/additions for the fix
    2009-06-26 13:16:17 +0200 aw  r273404 : #i101491# finetuning changes
    2009-06-26 13:15:57 +0200 aw  r273403 : #i101491# finetuning changes
    2009-06-25 16:31:26 +0200 aw  r273387 : #i101491# first version checkin for linux/mac tests
    2009-06-25 16:31:04 +0200 aw  r273386 : #i101491# first version checkin for linux/mac tests
    2009-06-24 15:35:05 +0200 aw  r273350 : #i101734# corrected VclMetafileProcessor2D::impTryToCreateSvtGraphicStroke to use the current ObjectTransformation
    2009-06-24 15:01:58 +0200 aw  r273348 : #i101811# added ViewInformation2D to renderChartPrimitive2D to allow embedding of object transformation to target MapMode
    2009-06-24 12:27:05 +0200 aw  r273328 : #i101980# use a hairline LineWitdth for SdrObject::TakeContour() calculation (like the old implementation did)
    2009-06-24 11:29:43 +0200 aw  r273321 : #i101781# corrected creation fallback for FullDrag for circle objects
    2009-06-23 17:26:58 +0200 aw  r273300 : #i101556# made primitive text attributes take versioned base text attribute sets into account

diff --git a/drawinglayer/source/processor2d/canvasprocessor.cxx b/drawinglayer/source/processor2d/canvasprocessor.cxx
index 4fd65b5..77cb2b3 100644
--- a/drawinglayer/source/processor2d/canvasprocessor.cxx
+++ b/drawinglayer/source/processor2d/canvasprocessor.cxx
@@ -2106,7 +2106,10 @@ namespace drawinglayer
                        mpOutputDevice->Push(PUSH_MAPMODE);
                     mpOutputDevice->SetMapMode(maOriginalMapMode);
                     
-                    if(!renderChartPrimitive2D(rChartPrimitive, *mpOutputDevice))
+                    if(!renderChartPrimitive2D(
+                        rChartPrimitive, 
+                        *mpOutputDevice,
+                        getViewInformation2D()))
                     {
                         // fallback to decomposition (MetaFile)
                         process(rChartPrimitive.get2DDecomposition(getViewInformation2D()));
diff --git a/drawinglayer/source/processor2d/helperchartrenderer.cxx b/drawinglayer/source/processor2d/helperchartrenderer.cxx
index 3d1f6a1..383f678 100644
--- a/drawinglayer/source/processor2d/helperchartrenderer.cxx
+++ b/drawinglayer/source/processor2d/helperchartrenderer.cxx
@@ -41,6 +41,7 @@
 #include <svtools/chartprettypainter.hxx>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -50,7 +51,10 @@ using namespace com::sun::star;
 
 namespace drawinglayer
 {
-    bool renderChartPrimitive2D(const primitive2d::ChartPrimitive2D& rChartCandidate, OutputDevice& rOutputDevice)
+    bool renderChartPrimitive2D(
+        const primitive2d::ChartPrimitive2D& rChartCandidate, 
+        OutputDevice& rOutputDevice,
+        const geometry::ViewInformation2D& rViewInformation2D)
     {
         bool bChartRendered(false);
 
@@ -73,14 +77,74 @@ namespace drawinglayer
                 
                     if( pPrettyPainter )
                     {
-                        // create logic object range
+                        // create logic object range; do NOT use ObjectTransformation for this 
+                        // (rViewInformation2D.getObjectTransformation()), only the logic object 
+                        // size is wanted
                         basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
                         aObjectRange.transform(rChartCandidate.getTransformation());
                         const Rectangle aRectangle(
                                 (sal_Int32)aObjectRange.getMinX(), (sal_Int32)aObjectRange.getMinY(), 
                                 (sal_Int32)aObjectRange.getMaxX(), (sal_Int32)aObjectRange.getMaxY());
 
-                        bChartRendered = pPrettyPainter->DoPaint(&rOutputDevice, aRectangle);
+                        // #i101811#
+                        if(rViewInformation2D.getObjectTransformation().isIdentity())
+                        {
+                            // no embedding in another transfromation, just paint with existing
+                            // MapMode. This is just a shortcut; using the below code will also
+                            // work; it has just a neutral ObjectTransformation
+                            bChartRendered = pPrettyPainter->DoPaint(&rOutputDevice, aRectangle);
+                        }
+                        else
+                        {
+                            // rViewInformation2D.getObjectTransformation() is used and
+                            // needs to be expressed in the MapMode for the PrettyPainter;
+                            // else it would call ChartModelHelper::setPageSize(...) with the
+                            // changed size what really will change the chart model and leads
+                            // to re-layouts and re-formattings
+                            const MapMode aOldMapMode(rOutputDevice.GetMapMode());
+                            basegfx::B2DVector aVTScale, aScale, aTranslate;
+                            double fRotate, fShearX;
+
+                            // get basic scaling with current MapMode (aVTScale), containing
+                            // mapping for set MapUnit (e.g. for 100th mm, the basic scale is
+                            // not 1.0, 1.0). This is needed since this scale is included in
+                            // the ObjectToView Transformation and needs to be removed (see
+                            // correction below) to re-create a MapMode
+                            rOutputDevice.SetMapMode(aOldMapMode.GetMapUnit());
+                            rOutputDevice.GetViewTransformation().decompose(aVTScale, aTranslate, fRotate, fShearX);
+
+                            // get complete ObjectToView Transformation scale and translate from current
+                            // transformation chain (combined view and object transform)
+                            rViewInformation2D.getObjectToViewTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+
+                            // assert when shear and/or rotation is used
+                            OSL_ENSURE(basegfx::fTools::equalZero(fRotate), "Chart PrettyPrinting with unsupportable rotation (!)");
+                            OSL_ENSURE(basegfx::fTools::equalZero(fShearX), "Chart PrettyPrinting with unsupportable shear (!)");
+
+                            // clean scale and translate from basic scaling (DPI, etc...)
+                            // since this will implicitely be part of the to-be-created MapMode
+                            const basegfx::B2DTuple aBasicCleaner(
+                                basegfx::fTools::equalZero(aVTScale.getX()) ? 1.0 : 1.0 / aVTScale.getX(),
+                                basegfx::fTools::equalZero(aVTScale.getY()) ? 1.0 : 1.0 / aVTScale.getY());
+                            aScale *= aBasicCleaner;
+                            aTranslate *= aBasicCleaner;
+
+                            // for MapMode, take scale out of translation
+                            const basegfx::B2DTuple aScaleRemover(
+                                basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(),
+                                basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY());
+                            aTranslate *= aScaleRemover;
+
+                            // build new MapMode
+                            const MapMode aNewMapMode(aOldMapMode.GetMapUnit(),
+                                Point(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())),
+                                Fraction(aScale.getX()), Fraction(aScale.getY()));
+
+                            // use, paint, restore
+                            rOutputDevice.SetMapMode(aNewMapMode);
+                            bChartRendered = pPrettyPainter->DoPaint(&rOutputDevice, aRectangle);
+                            rOutputDevice.SetMapMode(aOldMapMode);
+                        }
                     }
                 }
             }
diff --git a/drawinglayer/source/processor2d/helperchartrenderer.hxx b/drawinglayer/source/processor2d/helperchartrenderer.hxx
index de13431..e670ccc 100644
--- a/drawinglayer/source/processor2d/helperchartrenderer.hxx
+++ b/drawinglayer/source/processor2d/helperchartrenderer.hxx
@@ -43,16 +43,21 @@
 
 class OutputDevice;
 
-namespace drawinglayer { namespace primitive2d {
-    class ChartPrimitive2D;
-}}
+namespace drawinglayer { namespace primitive2d { class ChartPrimitive2D; }}
+namespace drawinglayer { namespace geometry { class ViewInformation2D; }}
 
 //////////////////////////////////////////////////////////////////////////////
 // support chart PrettyPrinter usage from primitives
 
 namespace drawinglayer
 {
-    bool renderChartPrimitive2D(const primitive2d::ChartPrimitive2D& rChartCandidate, OutputDevice& rOutputDevice);
+    // #i101811#
+    // Added current ViewInformation2D to take evtl. changed
+    // ObjectTransformation into account
+    bool renderChartPrimitive2D(
+        const primitive2d::ChartPrimitive2D& rChartCandidate, 
+        OutputDevice& rOutputDevice,
+        const geometry::ViewInformation2D& rViewInformation2D);
 
 } // end of namespace drawinglayer
 
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index f940012..c75e500 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -247,8 +247,8 @@ namespace drawinglayer
             if(rB2DPolygon.count() && !mnSvtGraphicStrokeCount)
             {
                 basegfx::BColor aStrokeColor;
-                PolyPolygon aStartPolyPolygon;
-                PolyPolygon aEndPolyPolygon;
+                basegfx::B2DPolyPolygon aStartArrow;
+                basegfx::B2DPolyPolygon aEndArrow;
                 
                 if(pColor)
                 {
@@ -271,11 +271,9 @@ namespace drawinglayer
                     {
                         fPolyLength = basegfx::tools::getLength(rB2DPolygon);
                         
-                        const basegfx::B2DPolyPolygon aStartArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
+                        aStartArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
                             rB2DPolygon, pStart->getB2DPolyPolygon(), true, pStart->getWidth(), 
-                            fPolyLength, pStart->isCentered() ? 0.5 : 0.0, 0));
-                        
-                        aStartPolyPolygon = PolyPolygon(aStartArrow);
+                            fPolyLength, pStart->isCentered() ? 0.5 : 0.0, 0);
                     }
 
                     if(pEnd && pEnd->isActive())
@@ -285,11 +283,9 @@ namespace drawinglayer
                             fPolyLength = basegfx::tools::getLength(rB2DPolygon);
                         }
 
-                        const basegfx::B2DPolyPolygon aEndArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
+                        aEndArrow = basegfx::tools::createAreaGeometryForLineStartEnd(
                             rB2DPolygon, pEnd->getB2DPolyPolygon(), false, pEnd->getWidth(), 
-                            fPolyLength, pEnd->isCentered() ? 0.5 : 0.0, 0));
-                        
-                        aEndPolyPolygon = PolyPolygon(aEndArrow);
+                            fPolyLength, pEnd->isCentered() ? 0.5 : 0.0, 0);
                     }
                 }
 
@@ -341,10 +337,23 @@ namespace drawinglayer
                     aDashArray = pStrokeAttribute->getDotDashArray();
                 }
 
+                // #i101734# apply current object transformation to created geometry.
+                // This is a partial fix. When a object transformation is used which
+                // e.g. contains a scaleX != scaleY, an unproportional scaling would
+                // have to be applied to the evtl. existing fat line. The current
+                // concept of PDF export and SvtGraphicStroke usage does simply not 
+                // allow handling such definitions. The only clean way would be to
+                // add the transformation to SvtGraphicStroke and to handle it there
+                basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
+
+                aB2DPolygon.transform(maCurrentTransformation);
+                aStartArrow.transform(maCurrentTransformation);
+                aEndArrow.transform(maCurrentTransformation);
+
                 pRetval = new SvtGraphicStroke(
-                    Polygon(rB2DPolygon),
-                    aStartPolyPolygon,
-                    aEndPolyPolygon,
+                    Polygon(aB2DPolygon),
+                    PolyPolygon(aStartArrow),
+                    PolyPolygon(aEndArrow),
                     mfCurrentUnifiedTransparence,
                     fLineWidth,
                     SvtGraphicStroke::capButt,
@@ -1001,7 +1010,68 @@ namespace drawinglayer
                     adaptLineToFillDrawMode();
 
                     impStartSvtGraphicStroke(pSvtGraphicStroke);
-                    process(rCandidate.get2DDecomposition(getViewInformation2D()));
+
+                    // #i101491#
+                    // Change default of fat line generation for MetaFiles: Create MetaPolyLineAction
+                    // instead of decomposing all geometries when the polygon has more than given amount of
+                    // points; else the decomposition will get too expensive quiclky. OTOH
+                    // the decomposition provides the better quality e.g. taking edge roundings
+                    // into account which will NOT be taken into account with LineInfo-based actions
+                    const sal_uInt32 nSubPolygonCount(rStrokePrimitive.getB2DPolygon().count());
+                    bool bDone(0 == nSubPolygonCount);
+
+                    if(!bDone && nSubPolygonCount > 1000)
+                    {
+                        // create MetaPolyLineActions, but without LINE_DASH
+                        const attribute::LineAttribute& rLine = rStrokePrimitive.getLineAttribute();
+
+                        if(basegfx::fTools::more(rLine.getWidth(), 0.0))
+                        {
+                            const attribute::StrokeAttribute& rStroke = rStrokePrimitive.getStrokeAttribute();
+                            basegfx::B2DPolyPolygon aHairLinePolyPolygon;
+
+                            if(0.0 == rStroke.getFullDotDashLen())
+                            {
+                                aHairLinePolyPolygon.append(rStrokePrimitive.getB2DPolygon());
+                            }
+                            else
+                            {
+                                basegfx::tools::applyLineDashing(
+                                    rStrokePrimitive.getB2DPolygon(), rStroke.getDotDashArray(), 
+                                    &aHairLinePolyPolygon, 0, rStroke.getFullDotDashLen());
+                            }
+
+                            const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLine.getColor()));
+                            mpOutputDevice->SetLineColor(Color(aHairlineColor));
+                            mpOutputDevice->SetFillColor();
+
+                            aHairLinePolyPolygon.transform(maCurrentTransformation);
+
+                            const LineInfo aLineInfo(LINE_SOLID, basegfx::fround(rLine.getWidth()));
+
+                            for(sal_uInt32 a(0); a < aHairLinePolyPolygon.count(); a++)
+                            {
+                                const basegfx::B2DPolygon aCandidate(aHairLinePolyPolygon.getB2DPolygon(a));
+
+                                if(aCandidate.count() > 1)
+                                {
+                                    const Polygon aToolsPolygon(aCandidate);
+
+                                    mrMetaFile.AddAction(new MetaPolyLineAction(aToolsPolygon, aLineInfo));
+                                }
+                            }
+
+                            bDone = true;
+                        }
+                    }
+
+                    if(!bDone)
+                    {
+                        // use decomposition (creates line geometry as filled polygon
+                        // geometry)
+                        process(rCandidate.get2DDecomposition(getViewInformation2D()));
+                    }
+
                     impEndSvtGraphicStroke(pSvtGraphicStroke);
                     
                     // restore DrawMode
@@ -1623,7 +1693,10 @@ namespace drawinglayer
                     // ChartPrimitive2D
                     const primitive2d::ChartPrimitive2D& rChartPrimitive = static_cast< const primitive2d::ChartPrimitive2D& >(rCandidate);
 
-                    if(!renderChartPrimitive2D(rChartPrimitive, *mpOutputDevice))
+                    if(!renderChartPrimitive2D(
+                        rChartPrimitive, 
+                        *mpOutputDevice,
+                        getViewInformation2D()))
                     {
                         // fallback to decomposition (MetaFile)
                         process(rChartPrimitive.get2DDecomposition(getViewInformation2D()));
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 7e7a909..73424a2 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -425,7 +425,10 @@ namespace drawinglayer
                        mpOutputDevice->Push(PUSH_MAPMODE);
                     mpOutputDevice->SetMapMode(maOriginalMapMode);
                     
-                    if(!renderChartPrimitive2D(rChartPrimitive, *mpOutputDevice))
+                    if(!renderChartPrimitive2D(
+                        rChartPrimitive, 
+                        *mpOutputDevice,
+                        getViewInformation2D()))
                     {
                         // fallback to decomposition (MetaFile)
                         process(rChartPrimitive.get2DDecomposition(getViewInformation2D()));
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 8407968..2e740f4 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -1012,6 +1012,8 @@ namespace drawinglayer
 
         void VclProcessor2D::RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate)
         {
+            // #i101491# method restructured to clearly use the DrawPolyLine
+            // calls starting from a deined line width
             const attribute::LineAttribute& rLineAttribute = rPolygonStrokeCandidate.getLineAttribute();
             const double fLineWidth(rLineAttribute.getWidth());
             bool bDone(false);
@@ -1020,157 +1022,163 @@ namespace drawinglayer
             {
                 const basegfx::B2DVector aDiscreteUnit(maCurrentTransformation * basegfx::B2DVector(fLineWidth, 0.0));
                 const double fDiscreteLineWidth(aDiscreteUnit.getLength());
-                const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing());
-                const double fAllowedUpperBound(bAntiAliased ? 3.0 : 2.5);
+                const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokeCandidate.getStrokeAttribute();
+                const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
+                basegfx::B2DPolyPolygon aHairlinePolyPolygon;
 
-                if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, fAllowedUpperBound))
+                mpOutputDevice->SetLineColor(Color(aHairlineColor));
+                mpOutputDevice->SetFillColor();
+
+                if(0.0 == rStrokeAttribute.getFullDotDashLen())
+                {
+                    // no line dashing, just copy
+                    aHairlinePolyPolygon.append(rPolygonStrokeCandidate.getB2DPolygon());
+                }
+                else
                 {
-                    // force to hairline
-                    const attribute::StrokeAttribute& rStrokeAttribute = rPolygonStrokeCandidate.getStrokeAttribute();
-                    const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rLineAttribute.getColor()));
-                    basegfx::B2DPolyPolygon aHairlinePolyPolygon;
+                    // else apply LineStyle
+                    basegfx::tools::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(),
+                        rStrokeAttribute.getDotDashArray(),
+                        &aHairlinePolyPolygon, 0, rStrokeAttribute.getFullDotDashLen());
+                }
 
-                    mpOutputDevice->SetLineColor(Color(aHairlineColor));
-                    mpOutputDevice->SetFillColor();
+                const sal_uInt32 nCount(aHairlinePolyPolygon.count());
 
-                    if(0.0 == rStrokeAttribute.getFullDotDashLen())
-                    {
-                        // no line dashing, just copy
-                        aHairlinePolyPolygon.append(rPolygonStrokeCandidate.getB2DPolygon());
-                    }
-                    else
-                    {
-                        // else apply LineStyle
-                        basegfx::tools::applyLineDashing(rPolygonStrokeCandidate.getB2DPolygon(),
-                            rStrokeAttribute.getDotDashArray(),
-                            &aHairlinePolyPolygon, 0, rStrokeAttribute.getFullDotDashLen());
-                    }
-
-                    const sal_uInt32 nCount(aHairlinePolyPolygon.count());
+                if(nCount)
+                {
+                    const bool bAntiAliased(getOptionsDrawinglayer().IsAntiAliasing());
+                    aHairlinePolyPolygon.transform(maCurrentTransformation);
 
-                    if(nCount)
+                    for(sal_uInt32 a(0); a < nCount; a++)
                     {
-                        aHairlinePolyPolygon.transform(maCurrentTransformation);
+                        basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
 
                         if(bAntiAliased)
                         {
-                            for(sal_uInt32 a(0); a < nCount; a++)
+                            if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0))
+                            {
+                                // line in range ]0.0 .. 1.0[
+                                // paint as simple hairline
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                bDone = true;
+                            }
+                            else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0))
                             {
-                                basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
+                                // line in range [1.0 .. 2.0[
+                                // paint as 2x2 with dynamic line distance
+                                basegfx::B2DHomMatrix aMat;
+                                const double fDistance(fDiscreteLineWidth - 1.0);
+                                const double fHalfDistance(fDistance * 0.5);
+
+                                aMat.set(0, 2, -fHalfDistance);
+                                aMat.set(1, 2, -fHalfDistance);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+                                aMat.set(0, 2, fDistance);
+                                aMat.set(1, 2, 0.0);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+                                aMat.set(0, 2, 0.0);
+                                aMat.set(1, 2, fDistance);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+
+                                aMat.set(0, 2, -fDistance);
+                                aMat.set(1, 2, 0.0);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                bDone = true;
+                            }
+                            else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 3.0))
+                            {
+                                // line in range [2.0 .. 3.0]
+                                // paint as cross in a 3x3  with dynamic line distance
+                                basegfx::B2DHomMatrix aMat;
+                                const double fDistance((fDiscreteLineWidth - 1.0) * 0.5);
 
-                                if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.0))
-                                {
-                                    // line in range ]0.0 .. 1.0[
-                                    // paint as simple hairline
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                }
-                                else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.0))
-                                {
-                                    // line in range [1.0 .. 2.0[
-                                    // paint as 2x2 with dynamic line distance
-                                    basegfx::B2DHomMatrix aMat;
-                                    const double fDistance(fDiscreteLineWidth - 1.0);
-                                    const double fHalfDistance(fDistance * 0.5);
-
-                                    aMat.set(0, 2, -fHalfDistance);
-                                    aMat.set(1, 2, -fHalfDistance);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
-                                    aMat.set(0, 2, fDistance);
-                                    aMat.set(1, 2, 0.0);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
-                                    aMat.set(0, 2, 0.0);
-                                    aMat.set(1, 2, fDistance);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
-                                    aMat.set(0, 2, -fDistance);
-                                    aMat.set(1, 2, 0.0);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                }
-                                else
-                                {
-                                    // line in range [2.0 .. 3.0]
-                                    // paint as cross in a 3x3  with dynamic line distance
-                                    basegfx::B2DHomMatrix aMat;
-                                    const double fDistance((fDiscreteLineWidth - 1.0) * 0.5);
-
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                    
-                                    aMat.set(0, 2, -fDistance);
-                                    aMat.set(1, 2, 0.0);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                
-                                    aMat.set(0, 2, fDistance);
-                                    aMat.set(1, 2, -fDistance);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
                                 
-                                    aMat.set(0, 2, fDistance);
-                                    aMat.set(1, 2, fDistance);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                
-                                    aMat.set(0, 2, -fDistance);
-                                    aMat.set(1, 2, fDistance);
-                                    aCandidate.transform(aMat);
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                }
+                                aMat.set(0, 2, -fDistance);
+                                aMat.set(1, 2, 0.0);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                            
+                                aMat.set(0, 2, fDistance);
+                                aMat.set(1, 2, -fDistance);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                            
+                                aMat.set(0, 2, fDistance);
+                                aMat.set(1, 2, fDistance);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                            
+                                aMat.set(0, 2, -fDistance);
+                                aMat.set(1, 2, fDistance);
+                                aCandidate.transform(aMat);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                bDone = true;
+                            }
+                            else
+                            {
+                                // #i101491# line width above 3.0
                             }
                         }
                         else
                         {
-                            if(basegfx::fTools::more(fDiscreteLineWidth, 1.5))
+                            if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 1.5))
+                            {
+                                // line width below 1.5, draw the basic hairline polygon
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                bDone = true;
+                            }
+                            else if(basegfx::fTools::lessOrEqual(fDiscreteLineWidth, 2.5))
                             {
                                 // line width is in range ]1.5 .. 2.5], use four hairlines
                                 // drawn in a square
                                 basegfx::B2DHomMatrix aMat;
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
 
-                                for(sal_uInt32 a(0); a < nCount; a++)
-                                {
-                                    basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-
-                                    aMat.set(0, 2, 1.0);
-                                    aMat.set(1, 2, 0.0);
-                                    aCandidate.transform(aMat);
+                                aMat.set(0, 2, 1.0);
+                                aMat.set(1, 2, 0.0);
+                                aCandidate.transform(aMat);
 
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
 
-                                    aMat.set(0, 2, 0.0);
-                                    aMat.set(1, 2, 1.0);
-                                    aCandidate.transform(aMat);
+                                aMat.set(0, 2, 0.0);
+                                aMat.set(1, 2, 1.0);
+                                aCandidate.transform(aMat);
 
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
 
-                                    aMat.set(0, 2, -1.0);
-                                    aMat.set(1, 2, 0.0);
-                                    aCandidate.transform(aMat);
+                                aMat.set(0, 2, -1.0);
+                                aMat.set(1, 2, 0.0);
+                                aCandidate.transform(aMat);
 
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                }
+                                mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
+                                bDone = true;
                             }
                             else
                             {
-                                for(sal_uInt32 a(0); a < nCount; a++)
-                                {
-                                    // draw the basic hairline polygon
-                                    const basegfx::B2DPolygon aCandidate(aHairlinePolyPolygon.getB2DPolygon(a));
-                                    mpOutputDevice->DrawPolyLine(aCandidate, 0.0);
-                                }
+                                // #i101491# line width is above 2.5
                             }
                         }
-                    }
 
-                    bDone = true;
+                        if(!bDone && rPolygonStrokeCandidate.getB2DPolygon().count() > 1000)
+                        {
+                            // #i101491# If the polygon complexity uses more than a given amount, do
+                            // use OuputDevice::DrawPolyLine directly; this will avoid buffering all
+                            // decompositions in primtives (memory) and fallback to old line painting
+                            // for very complex polygons, too
+                            mpOutputDevice->DrawPolyLine(aCandidate, fDiscreteLineWidth, rLineAttribute.getLineJoin());
+                            bDone = true;
+                        }
+                    }
                 }
             }
-
+            
             if(!bDone)
             {
                 // remeber that we enter a PolygonStrokePrimitive2D decomposition,
diff --git a/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx b/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx
index 6193488..8046708 100644
--- a/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx
+++ b/svx/inc/svx/sdr/attribute/sdrtextattribute.hxx
@@ -62,6 +62,9 @@ namespace drawinglayer
             sal_Int32								maTextRightDistance;
             sal_Int32								maTextLowerDistance;
 
+            // #i101556# use versioning from text attributes to detect changes
+            sal_uInt32                              maPropertiesVersion;
+
             // bitfield
             unsigned								mbContour : 1;
             unsigned								mbFitToSize : 1;
@@ -102,6 +105,7 @@ namespace drawinglayer
             sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; }
             sal_Int32 getTextRightDistance() const { return maTextRightDistance; }
             sal_Int32 getTextLowerDistance() const { return maTextLowerDistance; }
+            sal_uInt32 getPropertiesVersion() const { return maPropertiesVersion; }
 
             // animation timing generation
             void getBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const;
diff --git a/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx b/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
index f977de5..322b55b 100644
--- a/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
+++ b/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
@@ -38,6 +38,8 @@
 // predeclarations
 
 class SdrGrafObj;
+namespace drawinglayer { namespace attribute { class SdrLineFillShadowTextAttribute; }}
+class GraphicAttr;
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -47,6 +49,16 @@ namespace sdr
     {
         class ViewContactOfGraphic : public ViewContactOfTextObj
         {
+        private:
+            // helpers for constructing various primitive visualisations in various states
+            drawinglayer::primitive2d::Primitive2DSequence createVIP2DSForPresObj(
+                const basegfx::B2DHomMatrix& rObjectMatrix,
+                const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute,
+                const GraphicAttr& rLocalGrafInfo) const;
+            drawinglayer::primitive2d::Primitive2DSequence createVIP2DSForDraft(
+                const basegfx::B2DHomMatrix& rObjectMatrix,
+                const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const;
+
         protected:
             // Create a Object-Specific ViewObjectContact, set ViewContact and
             // ObjectContact. Always needs to return something.
@@ -63,6 +75,13 @@ namespace sdr
             ViewContactOfGraphic(SdrGrafObj& rGrafObj);
             virtual ~ViewContactOfGraphic();
 
+            // #i102380#
+            void flushGraphicObjects();
+
+            // helpers for viusualisation state
+            bool visualisationUsesPresObj() const;
+            bool visualisationUsesDraft() const;
+
         protected:
             // This method is responsible for creating the graphical visualisation data
             // ONLY based on model data
diff --git a/svx/inc/svx/sdr/primitive2d/sdrpathprimitive2d.hxx b/svx/inc/svx/sdr/primitive2d/sdrpathprimitive2d.hxx
index defaa73..199f3c4 100644
--- a/svx/inc/svx/sdr/primitive2d/sdrpathprimitive2d.hxx
+++ b/svx/inc/svx/sdr/primitive2d/sdrpathprimitive2d.hxx
@@ -49,9 +49,9 @@ namespace drawinglayer
         class SdrPathPrimitive2D : public BasePrimitive2D
         {
         private:
-            ::basegfx::B2DHomMatrix						maTransform;
+            basegfx::B2DHomMatrix						maTransform;
             attribute::SdrLineFillShadowTextAttribute	maSdrLFSTAttribute;
-            ::basegfx::B2DPolyPolygon					maUnitPolyPolygon;
+            basegfx::B2DPolyPolygon						maUnitPolyPolygon;
 
         protected:
             // local decomposition.
@@ -59,14 +59,14 @@ namespace drawinglayer
 
         public:
             SdrPathPrimitive2D(
-                const ::basegfx::B2DHomMatrix& rTransform, 
+                const basegfx::B2DHomMatrix& rTransform, 
                 const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute,
-                const ::basegfx::B2DPolyPolygon& rUnitPolyPolygon);
+                const basegfx::B2DPolyPolygon& rUnitPolyPolygon);
 
             // data access
-            const ::basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
+            const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
             const attribute::SdrLineFillShadowTextAttribute& getSdrLFSTAttribute() const { return maSdrLFSTAttribute; }
-            const ::basegfx::B2DPolyPolygon& getUnitPolyPolygon() const { return maUnitPolyPolygon; }
+            const basegfx::B2DPolyPolygon& getUnitPolyPolygon() const { return maUnitPolyPolygon; }
 
             // compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/svx/inc/svx/sdr/properties/properties.hxx b/svx/inc/svx/sdr/properties/properties.hxx
index 855b8a2..2b8928e 100644
--- a/svx/inc/svx/sdr/properties/properties.hxx
+++ b/svx/inc/svx/sdr/properties/properties.hxx
@@ -184,6 +184,11 @@ namespace sdr
             // ClearItemAndBroadcast() and SetItemSetAndBroadcast(), see above.
             // But also from inside SdrObjects.
             void BroadcastItemChange(const ItemChangeBroadcaster& rChange);
+            
+            // #i101556# add versioning mechanism; used from e.g. text attribute set to
+            // allow detection of e.g. style sheet or single text attribute changes. The
+            // default implementation returns 0 (zero)
+            virtual sal_uInt32 getVersion() const;
         };
     } // end of namespace properties
 } // end of namespace sdr
diff --git a/svx/inc/svx/sdr/properties/textproperties.hxx b/svx/inc/svx/sdr/properties/textproperties.hxx
index 5dcc8f5..08f2603 100644
--- a/svx/inc/svx/sdr/properties/textproperties.hxx
+++ b/svx/inc/svx/sdr/properties/textproperties.hxx
@@ -42,6 +42,10 @@ namespace sdr
     {
         class SVX_DLLPUBLIC TextProperties : public AttributeProperties
         {
+        private:
+            // #i101556# versioning support
+            sal_uInt32                  maVersion;
+
         protected:
             // create a new itemset
             virtual SfxItemSet& CreateObjectSpecificItemSet(SfxItemPool& rPool);
@@ -82,6 +86,9 @@ namespace sdr
             // Set single item at the local ItemSet. *Does not use* AllowItemChange(),
             // ItemChange(), PostItemChange() and ItemSetChanged() calls.
             void SetObjectItemNoBroadcast(const SfxPoolItem& rItem);
+
+            // #i101556# versioning support
+            virtual sal_uInt32 getVersion() const;
         };
     } // end of namespace properties
 } // end of namespace sdr
diff --git a/svx/inc/svx/svdograf.hxx b/svx/inc/svx/svdograf.hxx
index 8c7b47c..f542818 100644
--- a/svx/inc/svx/svdograf.hxx
+++ b/svx/inc/svx/svdograf.hxx
@@ -227,6 +227,9 @@ public:
     sal_Bool IsObjectTransparent() const;
     
     ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > getInputStream();
+
+    // #i103116# FullDrag support
+    virtual SdrObject* getFullDragClone() const;
 };
 
 #endif //_SVDOGRAF_HXX
diff --git a/svx/source/outliner/outliner.cxx b/svx/source/outliner/outliner.cxx
index 7a298c4..f46dedf 100644
--- a/svx/source/outliner/outliner.cxx
+++ b/svx/source/outliner/outliner.cxx
@@ -1526,7 +1526,7 @@ void Outliner::ImplCheckParagraphs( USHORT nStart, USHORT nEnd )
                 if (pPara)
                 {
                     pPara->Invalidate();
-                    ImplCalcBulletText( n, FALSE, FALSE );
+                    ImplCalcBulletText( (USHORT)n, FALSE, FALSE );
                 }
     }
 }
diff --git a/svx/source/sdr/attribute/sdrtextattribute.cxx b/svx/source/sdr/attribute/sdrtextattribute.cxx
index 591fcb0..020ec57 100644
--- a/svx/source/sdr/attribute/sdrtextattribute.cxx
+++ b/svx/source/sdr/attribute/sdrtextattribute.cxx
@@ -35,6 +35,7 @@
 #include <svx/outlobj.hxx>
 #include <svx/editobj.hxx>
 #include <svx/flditem.hxx>
+#include <svx/sdr/properties/properties.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -63,6 +64,7 @@ namespace drawinglayer
             maTextUpperDistance(aTextUpperDistance),
             maTextRightDistance(aTextRightDistance),
             maTextLowerDistance(aTextLowerDistance),
+            maPropertiesVersion(0),
             mbContour(bContour),
             mbFitToSize(bFitToSize),
             mbHideContour(bHideContour),
@@ -70,6 +72,10 @@ namespace drawinglayer
             mbScroll(bScroll),
             mbInEditMode(bInEditMode)
         {
+            // #i101556# init with version number to detect changes of single text
+            // attribute and/or style sheets in primitive data without having to
+            // copy that data locally (which would be better from principle)
+            maPropertiesVersion = rSdrText.GetObject().GetProperties().getVersion();
         }
 
         bool SdrTextAttribute::operator==(const SdrTextAttribute& rCandidate) const
@@ -80,6 +86,7 @@ namespace drawinglayer
                 && getTextUpperDistance() == rCandidate.getTextUpperDistance()
                 && getTextRightDistance() == rCandidate.getTextRightDistance()
                 && getTextLowerDistance() == rCandidate.getTextLowerDistance()
+                && getPropertiesVersion() == rCandidate.getPropertiesVersion()
                 && isContour() == rCandidate.isContour()
                 && isFitToSize() == rCandidate.isFitToSize()
                 && isHideContour() == rCandidate.isHideContour()
diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx
index 3f6ac13..40f005d 100644
--- a/svx/source/sdr/contact/viewcontactofgraphic.cxx
+++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx
@@ -53,6 +53,18 @@
 #include <svdglob.hxx>
 #include <vcl/svapp.hxx>
 
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+
+#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
+#include <svx/eeitem.hxx>
+#include <svx/colritem.hxx>
+//#include <svx/xtable.hxx>
+
 //////////////////////////////////////////////////////////////////////////////
 
 namespace sdr
@@ -78,6 +90,238 @@ namespace sdr
         {
         }
 
+        void ViewContactOfGraphic::flushGraphicObjects()
+        {
+            // #i102380# The graphic is swapped out. To let that have an effect ist is necessary to
+            // delete copies of the GraphicObject which are not swapped out and have no SwapHandler set
+            // (this is what happnes when the GraphicObject gets copied to a SdrGrafPrimitive2D). This
+            // is best achieved for the VC by clearing the local decomposition cache. It would be possible
+            // to also do this for the VOC cache, but that VOCs exist exactly expresss that the object
+            // gets visualised, so this would be wrong.
+            flushViewIndependentPrimitive2DSequence();
+        }
+
+        drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj(
+            const basegfx::B2DHomMatrix& rObjectMatrix,
+            const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute,
+            const GraphicAttr& rLocalGrafInfo) const
+        {
+            drawinglayer::primitive2d::Primitive2DSequence xRetval;
+            GraphicObject aEmptyGraphicObject;
+            GraphicAttr	aEmptyGraphicAttr;
+            
+            // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts
+            const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
+                rObjectMatrix, 
+                rAttribute, 
+                aEmptyGraphicObject, 
+                aEmptyGraphicAttr));
+            xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1);
+
+            // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and
+            // without attributes
+            basegfx::B2DHomMatrix aSmallerMatrix;
+            
+            // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic
+            // into account. Since EmptyPresObj's are only used in Draw/Impress, it is
+            // safe to assume 100th mm as target.
+            Size aPrefSize(GetGrafObject().GetGrafPrefSize());
+
+            if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit())
+            {
+                aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM);
+            }
+            else
+            {
+                aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM);
+            }
+            
+            // decompose object matrix to get single values
+            basegfx::B2DVector aScale, aTranslate;
+            double fRotate, fShearX;
+            rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+            
+            const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0);
+            const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0);
+
+            if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0))
+            {
+                // create the EmptyPresObj fallback visualisation. The fallback graphic
+                // is already provided in rGraphicObject in this case, use it
+                aSmallerMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight());
+                aSmallerMatrix.translate(fOffsetX, fOffsetY);
+                aSmallerMatrix.shearX(fShearX);
+                aSmallerMatrix.rotate(fRotate);
+                aSmallerMatrix.translate(aTranslate.getX(), aTranslate.getY());
+
+                const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
+                const drawinglayer::attribute::SdrLineFillShadowTextAttribute aEmptyAttributes(0, 0, 0, 0, 0, 0);
+                const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
+                    aSmallerMatrix, 
+                    aEmptyAttributes, 
+                    rGraphicObject, 
+                    rLocalGrafInfo));
+
+                drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB);
+            }
+
+            return xRetval;
+        }
+
+        drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForDraft(
+            const basegfx::B2DHomMatrix& rObjectMatrix,
+            const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const
+        {
+            drawinglayer::primitive2d::Primitive2DSequence xRetval;
+            GraphicObject aEmptyGraphicObject;
+            GraphicAttr	aEmptyGraphicAttr;
+            
+            // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts
+            const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
+                rObjectMatrix, 
+                rAttribute, 
+                aEmptyGraphicObject, 
+                aEmptyGraphicAttr));
+            xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1);
+
+            if(!rAttribute.getLine())
+            {
+                // create a surrounding frame when no linestyle given
+                const Color aColor(Application::GetSettings().GetStyleSettings().GetShadowColor());
+                const basegfx::BColor aBColor(aColor.getBColor());
+                const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+
+                basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aUnitRange));
+                aOutline.transform(rObjectMatrix);
+
+                drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
+                    drawinglayer::primitive2d::Primitive2DReference(
+                        new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+                            aOutline,
+                            aBColor)));
+            }
+
+            // decompose object matrix to get single values
+            basegfx::B2DVector aScale, aTranslate;
+            double fRotate, fShearX;
+            rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+            // define a distance value, used for distance from bitmap to borders and from bitmap
+            // to text, too (2 mm)
+            const double fDistance(200.0);
+
+            // consume borders from values
+            aScale.setX(std::max(0.0, aScale.getX() - (2.0 * fDistance)));
+            aScale.setY(std::max(0.0, aScale.getY() - (2.0 * fDistance)));
+            aTranslate.setX(aTranslate.getX() + fDistance);
+            aTranslate.setY(aTranslate.getY() + fDistance);
+
+            // draw a draft bitmap
+            const Bitmap aDraftBitmap(ResId(BMAP_GrafikEi, *ImpGetResMgr()));
+
+            if(!aDraftBitmap.IsEmpty())
+            {
+                Size aPrefSize(aDraftBitmap.GetPrefSize());
+
+                if(MAP_PIXEL == aDraftBitmap.GetPrefMapMode().GetMapUnit())
+                {
+                    aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aDraftBitmap.GetSizePixel(), MAP_100TH_MM);
+                }
+                else
+                {
+                    aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aDraftBitmap.GetPrefMapMode(), MAP_100TH_MM);
+                }
+                
+                const double fBitmapScaling(2.0);
+                const double fWidth(aPrefSize.getWidth() * fBitmapScaling);
+                const double fHeight(aPrefSize.getHeight() * fBitmapScaling);
+                
+                if(basegfx::fTools::more(fWidth, 1.0) 
+                    && basegfx::fTools::more(fHeight, 1.0)
+                    && basegfx::fTools::lessOrEqual(fWidth, aScale.getX())
+                    && basegfx::fTools::lessOrEqual(fHeight, aScale.getY()))
+                {
+                    basegfx::B2DHomMatrix aBitmapMatrix;
+
+                    aBitmapMatrix.scale(fWidth, fHeight);
+                    aBitmapMatrix.shearX(fShearX);
+                    aBitmapMatrix.rotate(fRotate);
+                    aBitmapMatrix.translate(aTranslate.getX(), aTranslate.getY());
+                    
+                    drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
+                        drawinglayer::primitive2d::Primitive2DReference(
+                            new drawinglayer::primitive2d::BitmapPrimitive2D(
+                                BitmapEx(aDraftBitmap),
+                                aBitmapMatrix)));
+
+                    // consume bitmap size in X
+                    aScale.setX(std::max(0.0, aScale.getX() - (fWidth + fDistance)));
+                    aTranslate.setX(aTranslate.getX() + fWidth + fDistance);
+                }
+            }
+
+            // Build the text for the draft object
+            XubString aDraftText = GetGrafObject().GetFileName();
+            
+            if(!aDraftText.Len())
+            {
+                aDraftText = GetGrafObject().GetName();
+                aDraftText.AppendAscii(" ...");
+            }
+            
+            if(aDraftText.Len() && GetGrafObject().GetModel())
+            {
+                // #i103255# Goal is to produce TextPrimitives which hold the given text as
+                // BlockText in the available space. It would be very tricky to do
+                // an own word wrap/line layout here.
+                // Using SdrBlockTextPrimitive2D OTOH is critical since it internally
+                // uses the SdrObject it references. To solve this, create a temp
+                // SdrObject with Attributes and Text, generate a SdrBlockTextPrimitive2D
+                // directly and immediately decompose it. After that, it is no longer
+                // needed and can be deleted.
+
+                // create temp RectObj as TextObj and set needed attributes
+                SdrRectObj aRectObj(OBJ_TEXT);
+                aRectObj.SetModel(GetGrafObject().GetModel());
+                aRectObj.NbcSetText(aDraftText);
+                aRectObj.SetMergedItem(SvxColorItem(Color(COL_LIGHTRED), EE_CHAR_COLOR));
+
+                // get SdrText and OPO
+                SdrText* pSdrText = aRectObj.getText(0);
+                OutlinerParaObject* pOPO = aRectObj.GetOutlinerParaObject();
+
+                if(pSdrText && pOPO)
+                {
+                    // directly use the remaining space as TextRangeTransform
+                    basegfx::B2DHomMatrix aTextRangeTransform;
+                    
+                    aTextRangeTransform.scale(aScale.getX(), aScale.getY());
+                    aTextRangeTransform.shearX(fShearX);
+                    aTextRangeTransform.rotate(fRotate);
+                    aTextRangeTransform.translate(aTranslate.getX(), aTranslate.getY());
+
+                    // directly create temp SdrBlockTextPrimitive2D
+                    drawinglayer::primitive2d::SdrBlockTextPrimitive2D aBlockTextPrimitive(
+                        *pSdrText,
+                        *pOPO,
+                        aTextRangeTransform,
+                        false,
+                        false,
+                        false);
+
+                    // decompose immediately with neutral ViewInformation. This will
+                    // layout the text to more simple TextPrimitives from drawinglayer
+                    const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0);
+
+                    drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(
+                        xRetval, 
+                        aBlockTextPrimitive.get2DDecomposition(aViewInformation2D));
+                }
+            }
+
+            return xRetval;
+        }
+
         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createViewIndependentPrimitive2DSequence() const
         {
             drawinglayer::primitive2d::Primitive2DSequence xRetval;
@@ -86,7 +330,8 @@ namespace sdr
             if(pSdrText)
             {
                 const SfxItemSet& rItemSet = GetGrafObject().GetMergedItemSet();
-                drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText);
+                drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = 
+                    drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText);
                 bool bVisible(pAttribute && pAttribute->isVisible());
 
                 // create and fill GraphicAttr
@@ -131,7 +376,7 @@ namespace sdr
                         // which will use the primitive data we just create in the near future
                         const Rectangle& rRectangle = GetGrafObject().GetGeoRect();
                         const ::basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom());
-                        ::basegfx::B2DHomMatrix aObjectMatrix;
+                        basegfx::B2DHomMatrix aObjectMatrix;
 
                         // look for mirroring
                         const GeoStat& rGeoStat(GetGrafObject().GetGeoStat());
@@ -170,60 +415,25 @@ namespace sdr
                         // get the current, unchenged graphic obect from SdrGrafObj
                         const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
 
-                        if(GetGrafObject().IsEmptyPresObj())
+                        if(visualisationUsesPresObj())
                         {
                             // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one
                             // with the content which is the placeholder graphic
-                            GraphicObject aEmptyGraphicObject;
-                            GraphicAttr	aEmptyGraphicAttr;
-                            drawinglayer::attribute::SdrLineFillShadowTextAttribute aEmptyAttributes(0, 0, 0, 0, 0, 0);
-                            
-                            // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts
-                            const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
-                                aObjectMatrix, *pAttribute, aEmptyGraphicObject, aEmptyGraphicAttr));
-                            xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1);
-
-                            // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and
-                            // without attributes
-                            basegfx::B2DHomMatrix aSmallerMatrix;
-                            
-                            // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic
-                            // into account. Since EmptyPresObj's are only used in Draw/Impress, it is
-                            // safe to assume 100th mm as target.
-                            Size aPrefSize(GetGrafObject().GetGrafPrefSize());
-
-                            if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit())
-                            {
-                                aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM);
-                            }
-                            else
-                            {
-                                aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM);
-                            }
-                            
-                            const double fOffsetX((aObjectRange.getWidth() - aPrefSize.getWidth()) / 2.0);
-                            const double fOffsetY((aObjectRange.getHeight() - aPrefSize.getHeight()) / 2.0);
-
-                            if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0))
-                            {
-                                aSmallerMatrix.scale(aPrefSize.getWidth(), aPrefSize.getHeight());
-                                aSmallerMatrix.translate(fOffsetX, fOffsetY);
-                                aSmallerMatrix.shearX(fShearX);
-                                aSmallerMatrix.rotate(fRotate);
-                                aSmallerMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY());
-                             
-                                const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
-                                    aSmallerMatrix, 
-                                    aEmptyAttributes, 
-                                    rGraphicObject, 
-                                    aLocalGrafInfo));
-
-                                drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB);
-                            }
+                            xRetval = createVIP2DSForPresObj(aObjectMatrix, *pAttribute, aLocalGrafInfo);
+                        }
+                        else if(visualisationUsesDraft())
+                        {
+                            // #i102380# The graphic is swapped out. To not force a swap-in here, there is a mechanism
+                            // which shows a swapped-out-visualisation (which gets created here now) and an asynchronious
+                            // visual update mechanism for swapped-out grapgics when they were loaded (see AsynchGraphicLoadingEvent
+                            // and ViewObjectContactOfGraphic implementation). Not forcing the swap-in here allows faster
+                            // (non-blocking) processing here and thus in the effect e.g. fast scrolling through pages
+                            xRetval = createVIP2DSForDraft(aObjectMatrix, *pAttribute);
                         }
                         else
                         {
-                            // create primitive
+                            // create primitive. Info: Calling the copy-constructor of GraphicObject in this
+                            // SdrGrafPrimitive2D constructor will force a full swap-in of the graphic
                             const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
                                 aObjectMatrix, 
                                 *pAttribute, 
@@ -241,6 +451,31 @@ namespace sdr
             return xRetval;
         }
 
+        bool ViewContactOfGraphic::visualisationUsesPresObj() const
+        {
+            return GetGrafObject().IsEmptyPresObj();
+        }
+
+        bool ViewContactOfGraphic::visualisationUsesDraft() const
+        {
+            // no draft when already PresObj
+            if(visualisationUsesPresObj())
+                return false;
+
+            // draft when swapped out
+            const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
+            static bool bAllowReplacements(true);
+
+            if(rGraphicObject.IsSwappedOut() && bAllowReplacements)
+                return true;
+
+            // draft when no graphic
+            if(GRAPHIC_NONE == rGraphicObject.GetType() || GRAPHIC_DEFAULT == rGraphicObject.GetType())
+               return true;
+
+            return false;
+        }
+
     } // end of namespace contact
 } // end of namespace sdr
 
diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
index da467f8..1cb99de 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
@@ -62,59 +62,86 @@ namespace sdr
 
             if(pSdrText)
             {
-                drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(rItemSet, *pSdrText);
+                drawinglayer::attribute::SdrLineFillShadowTextAttribute* pAttribute = 
+                    drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(
+                        rItemSet, 
+                        *pSdrText);
 
                 if(pAttribute)
                 {
                     if(pAttribute->isVisible())
                     {
-                        // prepare object transformation and unit polygon (direct model data)
-                        ::basegfx::B2DHomMatrix aObjectMatrix;
-                        ::basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly());
-                        const bool bIsLine(
-                            !aUnitPolyPolygon.areControlPointsUsed()
-                            && 1L == aUnitPolyPolygon.count() 
-                            && 2L == aUnitPolyPolygon.getB2DPolygon(0L).count());
-
-                        if(bIsLine)
-                        {
-                            // special handling for single line mode (2 points)
-                            const ::basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0L));
-                            const ::basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0L));
-                            const ::basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1L));
-                            const ::basegfx::B2DVector aLine(aEnd - aStart);
-
-                            // create new polygon
-                            ::basegfx::B2DPolygon aNewPolygon;
-                            aNewPolygon.append(::basegfx::B2DPoint(0.0, 0.0));
-                            aNewPolygon.append(::basegfx::B2DPoint(aLine.getLength(), 0.0));
-                            aUnitPolyPolygon.setB2DPolygon(0L, aNewPolygon);
-
-                            // fill objectMatrix with rotation and offset (no shear for lines, scale in polygon)
-                            aObjectMatrix.rotate(atan2(aLine.getY(), aLine.getX()));
-                            aObjectMatrix.translate(aStart.getX(), aStart.getY());
-                        }
-                        else
+                        basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly());
+                        const sal_uInt32 nPolyCount(aUnitPolyPolygon.count());
+
+                        if(nPolyCount)
                         {
-                            // create scaled, but unsheared, unrotated and untranslated polygon
-                            // by creating the object matrix and back-transforming the polygon
-                            const ::basegfx::B2DRange aObjectRange(::basegfx::tools::getRange(aUnitPolyPolygon));
-                            const GeoStat& rGeoStat(GetPathObj().GetGeoStat());
-
-                            aObjectMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000));
-                            aObjectMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000);
-                            aObjectMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY());
-
-                            // ceate scaled unit polygon from object's absolute path
-                            ::basegfx::B2DHomMatrix aInverse(aObjectMatrix);
-                            aInverse.invert();
-                            aUnitPolyPolygon.transform(aInverse);
+                            // prepare object transformation and unit polygon (direct model data)
+                            basegfx::B2DHomMatrix aObjectMatrix;
+                            const bool bIsLine(
+                                !aUnitPolyPolygon.areControlPointsUsed()
+                                && 1 == nPolyCount 
+                                && 2 == aUnitPolyPolygon.getB2DPolygon(0).count());
+
+                            if(bIsLine)
+                            {
+                                // special handling for single line mode (2 points)
+                                const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0));
+                                const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0));
+                                const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1));
+                                const basegfx::B2DVector aLine(aEnd - aStart);
+
+                                // #i102548# create new unit polygon for line (horizontal)
+                                basegfx::B2DPolygon aNewPolygon;
+                                aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0));
+                                aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0));
+                                aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon);
+
+                                // #i102548# fill objectMatrix with rotation and offset (no shear for lines)
+                                aObjectMatrix.scale(aLine.getLength(), 1.0);
+                                aObjectMatrix.rotate(atan2(aLine.getY(), aLine.getX()));
+                                aObjectMatrix.translate(aStart.getX(), aStart.getY());
+                            }
+                            else
+                            {
+                                // #i102548# create unscaled, unsheared, unrotated and untranslated polygon
+                                // (unit polygon) by creating the object matrix and back-transforming the polygon
+                                const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon));
+                                const GeoStat& rGeoStat(GetPathObj().GetGeoStat());
+                                const double fWidth(aObjectRange.getWidth());
+                                const double fHeight(aObjectRange.getHeight());
+
+                                aObjectMatrix.scale(
+                                    basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth,
+                                    basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight);
+
+                                if(rGeoStat.nShearWink)
+                                {
+                                    aObjectMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000));
+                                }
+
+                                if(rGeoStat.nDrehWink)
+                                {
+                                    aObjectMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000);
+                                }
+
+                                aObjectMatrix.translate(aObjectRange.getMinX(), aObjectRange.getMinY());
+
+                                // ceate unit polygon from object's absolute path
+                                basegfx::B2DHomMatrix aInverse(aObjectMatrix);
+                                aInverse.invert();
+                                aUnitPolyPolygon.transform(aInverse);
+                            }
+
+                            // create primitive
+                            const drawinglayer::primitive2d::Primitive2DReference xReference(
+                                new drawinglayer::primitive2d::SdrPathPrimitive2D(
+                                    aObjectMatrix, 
+                                    *pAttribute, 
+                                    aUnitPolyPolygon));
+
+                            xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
                         }
-
-                        // create primitive
-                        const drawinglayer::primitive2d::Primitive2DReference xReference(
-                            new drawinglayer::primitive2d::SdrPathPrimitive2D(aObjectMatrix, *pAttribute, aUnitPolyPolygon));
-                        xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
                     }
 
                     delete pAttribute;
diff --git a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx
index 7a6e115..4b3f2b6 100644
--- a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx
@@ -38,6 +38,7 @@
 #include <svx/svdograf.hxx>
 #include <svx/sdr/contact/objectcontact.hxx>
 #include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -245,10 +246,19 @@ namespace sdr
         {
             // prepare primitive generation with evtl. loading the graphic when it's swapped out
             SdrGrafObj& rGrafObj = const_cast< ViewObjectContactOfGraphic* >(this)->getSdrGrafObj();
-            const bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics());
+            bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics());
             static bool bSuppressAsynchLoading(false);
             bool bSwapInDone(false);
 
+            if(bDoAsynchronGraphicLoading 
+                && rGrafObj.IsSwappedOut() 
+                && rGrafObj.GetPage() 
+                && rGrafObj.GetPage()->IsMasterPage())
+            {
+                // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation
+                bDoAsynchronGraphicLoading = false;
+            }
+
             if(bDoAsynchronGraphicLoading && !bSuppressAsynchLoading)
             {
                 bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithAsynchroniousLoading();
@@ -261,6 +271,23 @@ namespace sdr
             // get return value by calling parent
             drawinglayer::primitive2d::Primitive2DSequence xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo);
 
+            if(xRetval.hasElements())
+            {
+                // #i103255# suppress when graphic needs draft visualisation and output
+                // is for PDF export/Printer
+                const ViewContactOfGraphic& rVCOfGraphic = static_cast< const ViewContactOfGraphic& >(GetViewContact());
+
+                if(rVCOfGraphic.visualisationUsesDraft())
+                {
+                    const ObjectContact& rObjectContact = GetObjectContact();
+
+                    if(rObjectContact.isOutputToPDFFile() || rObjectContact.isOutputToPrinter())
+                    {
+                        xRetval = drawinglayer::primitive2d::Primitive2DSequence();
+                    }
+                }
+            }
+
             // if swap in was forced only for printing, swap out again
             const bool bSwapInExclusiveForPrinting(bSwapInDone && GetObjectContact().isOutputToPrinter());
 
diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
index f69f4d5..87ba0b8 100644
--- a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx
@@ -291,7 +291,8 @@ namespace sdr
             }
 
             // add a gray outline frame, except not when printing
-            if(!GetObjectContact().isOutputToPrinter())
+            // #i102637# add frame also when printing and page exists (handout pages)
+            if(!GetObjectContact().isOutputToPrinter() || pPage)
             {
                 const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor);
                 basegfx::B2DPolygon aOwnOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
diff --git a/svx/source/sdr/properties/properties.cxx b/svx/source/sdr/properties/properties.cxx
index 0d6cb3b..fe317a4 100644
--- a/svx/source/sdr/properties/properties.cxx
+++ b/svx/source/sdr/properties/properties.cxx
@@ -180,6 +180,11 @@ namespace sdr
                 GetSdrObject().SendUserCall(SDRUSERCALL_CHGATTR, rChange.GetRectangle(a));
             }
         }
+
+        sal_uInt32 BaseProperties::getVersion() const
+        {
+            return 0;
+        }
     } // end of namespace properties
 } // end of namespace sdr
 
diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx
index 22ddd79..06e151d 100644
--- a/svx/source/sdr/properties/textproperties.cxx
+++ b/svx/source/sdr/properties/textproperties.cxx
@@ -72,12 +72,14 @@ namespace sdr
         }
 
         TextProperties::TextProperties(SdrObject& rObj)
-        :	AttributeProperties(rObj)
+        :	AttributeProperties(rObj),
+            maVersion(0)
         {
         }
 
         TextProperties::TextProperties(const TextProperties& rProps, SdrObject& rObj)
-        :	AttributeProperties(rProps, rObj)
+        :	AttributeProperties(rProps, rObj),
+            maVersion(rProps.getVersion())
         {
         }
 
@@ -93,10 +95,11 @@ namespace sdr
         void TextProperties::ItemSetChanged(const SfxItemSet& rSet)
         {
             SdrTextObj& rObj = (SdrTextObj&)GetSdrObject();
-
-
             sal_Int32 nText = rObj.getTextCount();
 
+            // #i101556# ItemSet has changed -> new version
+            maVersion++;
+
             while( --nText >= 0 )
             {
                 SdrText* pText = rObj.getText( nText );
@@ -237,6 +240,9 @@ namespace sdr
             // call parent
             AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
 
+            // #i101556# StyleSheet has changed -> new version
+            maVersion++;
+
             if( rObj.GetModel() && !rObj.IsTextEditActive() && !rObj.IsLinkedText() )
             {
                 SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner();
@@ -577,6 +583,9 @@ namespace sdr
                             rObj.ActionChanged();
                             //rObj.BroadcastObjectChange();
                         }
+
+                        // #i101556# content of StyleSheet has changed -> new version
+                        maVersion++;
                     }
 
                     if(SFX_HINT_DYING == nId)
@@ -616,6 +625,12 @@ namespace sdr
                 }
             }
         }
+        
+        // #i101556# Handout version information
+        sal_uInt32 TextProperties::getVersion() const
+        {
+            return maVersion;
+        }
     } // end of namespace properties
 } // end of namespace sdr
 
diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx
index d0d2cd0..2ef952a 100644
--- a/svx/source/svdraw/svdcrtv.cxx
+++ b/svx/source/svdraw/svdcrtv.cxx
@@ -821,13 +821,15 @@ void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, BOOL bFull*/)
                 }
             }
 
-            // #i68562# Force to non-solid dragging when not creating a full circle and up to step three
-            if(bUseSolidDragging 
-                && pAktCreate->ISA(SdrCircObj) 
-                && OBJ_CIRC != (SdrObjKind)(static_cast< SdrCircObj* >(pAktCreate)->GetObjIdentifier())
-                && aDragStat.GetPointAnz() < 4L)
+              // #i101781# force to non-solid dragging when not creating a full circle
+            if(bUseSolidDragging)
             {
-                bUseSolidDragging = false;
+                SdrCircObj* pCircObj = dynamic_cast< SdrCircObj* >(pAktCreate);
+
+                if(pCircObj && OBJ_CIRC != pCircObj->GetObjIdentifier())
+                {
+                    bUseSolidDragging = false;
+                }
             }
 
             if(bUseSolidDragging)
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 7aa3835..fecc430 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1167,6 +1167,11 @@ basegfx::B2DPolyPolygon SdrObject::TakeContour() const
 
         SfxItemSet aNewSet(*GetObjectItemPool());
 
+        // #i101980# ignore LineWidth; that's what the old implementation
+        // did. With linewidth, the result may be huge due to fat/thick
+        // line decompositions
+        aNewSet.Put(XLineWidthItem(0));
+
         // solid black lines and no fill
         aNewSet.Put(XLineStyleItem(XLINE_SOLID));
         aNewSet.Put(XLineColorItem(String(), Color(COL_BLACK)));
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index a7e9d7e..1bf8ceb 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -666,6 +666,23 @@ void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
 
 // -----------------------------------------------------------------------------
 
+SdrObject* SdrGrafObj::getFullDragClone() const
+{
+    // call parent
+    SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
+
+    // #i103116# the full drag clone leads to problems
+    // with linked graphics, so reset the link in this
+    // temporary interaction object and load graphic
+    if(pRetval && IsLinkedGraphic())
+    {
+        pRetval->ForceSwapIn();
+        pRetval->ReleaseGraphicLink();
+    }
+
+    return pRetval;
+}
+
 void SdrGrafObj::operator=( const SdrObject& rObj )
 {
     SdrRectObj::operator=( rObj );
@@ -1097,6 +1114,14 @@ IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
                     pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
                     pGraphic->SetUserData();
                 }
+
+                // #i102380#
+                sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
+
+                if(pVC)
+                {
+                    pVC->flushGraphicObjects();
+                }
             }
         }
     }
commit d346cdf3fdffb422571dcf11248c10b788adacfe
Author: Oliver Bolte <obo at openoffice.org>
Date:   Fri Jul 17 04:31:21 2009 +0000

    CWS-TOOLING: integrate CWS mav53
    2009-06-29 13:42:56 +0200 hbrinkm  r273471 : #i101593# switched off optimization in table layout, that caused frames to be layouted incorrectly
    2009-06-25 12:29:11 +0200 cd  r273376 : #i101774# Don't rely on initialize call for VistaFilePicker
    2009-06-25 11:48:33 +0200 tl  r273373 : #i101420# Gnome accessibility fix
    2009-06-24 18:16:49 +0200 od  r273361 : #i97309 method <XMLTextParagraphExport::exportListChange(..)>
    	- export text:start-value at correct list item.
    2009-06-23 14:11:44 +0200 b_michaelsen  r273281 : #i103032#: cutting of URL-parameters for usage tracking
    2009-06-22 11:49:12 +0200 b_michaelsen  r273207 : #i102805#: Added usage tracking to SfxToolboxControl
    2009-06-22 11:46:00 +0200 b_michaelsen  r273205 : whitespace fixes
    2009-06-05 14:21:12 +0200 mav  r272683 : #i101741# check the file date only in document file locking context

diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.cxx b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
index b5f9d4b..fe6ebbf 100644
--- a/fpicker/source/win32/filepicker/VistaFilePicker.cxx
+++ b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
@@ -165,6 +165,7 @@ VistaFilePicker::VistaFilePicker(const css::uno::Reference< css::lang::XMultiSer
     , m_rDialog             (new VistaFilePickerImpl())
     , m_aAsyncExecute       (m_rDialog                )
     , m_nFilePickerThreadId (0                        )
+    , m_bInitialized		(false					  )
 {
 }
 
@@ -345,6 +346,20 @@ css::uno::Sequence< ::rtl::OUString > SAL_CALL VistaFilePicker::getSelectedFiles
 ::sal_Int16 SAL_CALL VistaFilePicker::execute()
     throw(css::uno::RuntimeException)
 {
+    bool bInitialized(false);
+    {
+        osl::MutexGuard aGuard(m_aMutex);
+        bInitialized = m_bInitialized;
+    }
+
+    if ( !bInitialized )
+    {
+        sal_Int16 nTemplateDescription = css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
+        css::uno::Sequence < css::uno::Any > aInitArguments(1);
+        aInitArguments[0] <<= nTemplateDescription;
+        initialize(aInitArguments);
+    }
+
     RequestRef rRequest(new Request());
     rRequest->setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL);
     
@@ -640,6 +655,11 @@ void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::An
     if ( ! m_aAsyncExecute.isRunning())
         m_aAsyncExecute.create();
     m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED);
+    
+    {
+        osl::MutexGuard aGuard(m_aMutex);
+        m_bInitialized = true;
+    }
 }
 
 //------------------------------------------------------------------------------------
diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.hxx b/fpicker/source/win32/filepicker/VistaFilePicker.hxx
index b398fd1..11ef555 100644
--- a/fpicker/source/win32/filepicker/VistaFilePicker.hxx
+++ b/fpicker/source/win32/filepicker/VistaFilePicker.hxx
@@ -305,6 +305,8 @@ public:
     
         //---------------------------------------------------------------------
         oslThreadIdentifier m_nFilePickerThreadId;
+
+        bool m_bInitialized;
 }; 
 
 } // namespace vista
diff --git a/fpicker/source/win32/filepicker/asyncrequests.cxx b/fpicker/source/win32/filepicker/asyncrequests.cxx
index 486d86a..704ffd9 100644
--- a/fpicker/source/win32/filepicker/asyncrequests.cxx
+++ b/fpicker/source/win32/filepicker/asyncrequests.cxx
@@ -53,7 +53,7 @@ void lcl_sleep(::osl::Condition& aCondition   ,
     {
         TimeValue aTime;
         aTime.Seconds = (nMilliSeconds / 1000);
-        aTime.Nanosec = (nMilliSeconds % 1000);
+        aTime.Nanosec = (nMilliSeconds % 1000) * 1000000;
         aCondition.wait(&aTime);
     }
 
diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx
index ab6cc60..71a188f 100644
--- a/sfx2/inc/sfx2/docfile.hxx
+++ b/sfx2/inc/sfx2/docfile.hxx
@@ -183,7 +183,8 @@ public:
 #endif
 
     void                CheckFileDate( const ::com::sun::star::util::DateTime& aInitDate );
-    ::com::sun::star::util::DateTime GetInitFileDate();
+    sal_Bool            DocNeedsFileDateCheck();
+    ::com::sun::star::util::DateTime GetInitFileDate( sal_Bool bIgnoreOldValue );
 
     ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > GetContent() const;
     const String&       GetPhysicalName() const;
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 2ca8a68..e41cb91 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -471,7 +471,7 @@ long SfxMedium::GetFileVersion() const
 //------------------------------------------------------------------
 void SfxMedium::CheckFileDate( const util::DateTime& aInitDate )
 {
-    GetInitFileDate();
+    GetInitFileDate( sal_True );
     if ( pImp->m_aDateTime.Seconds != aInitDate.Seconds
       || pImp->m_aDateTime.Minutes != aInitDate.Minutes
       || pImp->m_aDateTime.Hours != aInitDate.Hours
@@ -531,9 +531,15 @@ void SfxMedium::CheckFileDate( const util::DateTime& aInitDate )
 }
 
 //------------------------------------------------------------------
-util::DateTime SfxMedium::GetInitFileDate()
+sal_Bool SfxMedium::DocNeedsFileDateCheck()
 {
-    if ( !pImp->m_bGotDateTime && GetContent().is() )
+    return ( !IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) );
+}
+
+//------------------------------------------------------------------
+util::DateTime SfxMedium::GetInitFileDate( sal_Bool bIgnoreOldValue )
+{
+    if ( ( bIgnoreOldValue || !pImp->m_bGotDateTime ) && GetContent().is() )
     {
         try
         {
@@ -790,11 +796,8 @@ sal_Bool SfxMedium::Commit()
 
     sal_Bool bResult = ( GetError() == SVSTREAM_OK );
 
-    if ( bResult )
-    {
-        pImp->m_bGotDateTime = sal_False;
-        GetInitFileDate();
-    }
+    if ( bResult && DocNeedsFileDateCheck() )
+        GetInitFileDate( sal_True );
 
     // remove truncation mode from the flags
     nStorOpenMode &= (~STREAM_TRUNC);
@@ -1321,6 +1324,10 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI )
             GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
     }
 
+    // when the file is locked, get the current file date
+    if ( bResult && DocNeedsFileDateCheck() )
+        GetInitFileDate( sal_True );
+
     return bResult;
 }
 
@@ -2583,8 +2590,6 @@ void SfxMedium::GetMedium_Impl()
                 pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream );
         }
 
-        GetInitFileDate();
-
         pImp->bDownloadDone = sal_True;
         pImp->aDoneLink.ClearPendingCall();
         pImp->aDoneLink.Call( (void*) GetError() );
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 37259eb..45fbd18 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -1222,7 +1222,8 @@ sal_Bool SfxObjectShell::SaveTo_Impl
     {
         bStoreToSameLocation = sal_True;
 
-        rMedium.CheckFileDate( pMedium->GetInitFileDate() );
+        if ( pMedium->DocNeedsFileDateCheck() )
+            rMedium.CheckFileDate( pMedium->GetInitFileDate( sal_False ) );
 
         if ( bCopyTo && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
         {
@@ -2041,6 +2042,12 @@ sal_Bool SfxObjectShell::DoSaveCompleted( SfxMedium* pNewMed )
                 InvalidateName();
             SetModified(sal_False); // nur bei gesetztem Medium zur"ucksetzen
             Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
+
+            // this is the end of the saving process, it is possible that the file was changed
+            // between medium commit and this step ( attributes change and so on )
+            // so get the file date again
+            if ( pNewMed->DocNeedsFileDateCheck() )
+                pNewMed->GetInitFileDate( sal_True );
         }
     }
 
diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx
index 7058e86..7d3e79c 100644
--- a/sfx2/source/toolbox/tbxitem.cxx
+++ b/sfx2/source/toolbox/tbxitem.cxx
@@ -1029,6 +1029,25 @@ void SfxToolBoxControl::Select( USHORT nModifier )
 
 void SfxToolBoxControl::Select( BOOL /*bMod1*/ )
 {
+    if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# #i102805#
+    {
+        ::rtl::OUString sAppName;
+        try
+        {
+            static ::rtl::OUString our_aModuleManagerName = ::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager");
+            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager =
+                ::comphelper::getProcessServiceFactory();
+            ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleManager(
+                xServiceManager->createInstance(our_aModuleManagerName)
+                , ::com::sun::star::uno::UNO_QUERY_THROW);
+            sAppName = xModuleManager->identify(m_xFrame);
+        } catch(::com::sun::star::uno::Exception&) {}
+        Sequence<PropertyValue> vSource;
+        ::comphelper::UiEventsLogger::appendDispatchOrigin(vSource, sAppName, ::rtl::OUString::createFromAscii("SfxToolBoxControl"));
+        URL aURL;
+        aURL.Complete = m_aCommandURL;
+        ::comphelper::UiEventsLogger::logDispatch(aURL, vSource);
+    }
     svt::ToolboxController::execute( pImpl->nSelectModifier );
 }
 
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index ed001cb..c90b495 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -798,23 +798,29 @@ void XMLTextParagraphExport::exportListChange(
                 // <text:list-header> or <text:list-item>
                 GetExport().CheckAttrList();
 
-                if ( nListLevelsToBeOpened == 1 &&
-                     rNextInfo.HasStartValue() )
+                // --> OD 2009-06-24 #i97309#
+                // export start value in case of <bRestartNumberingAtContinuedRootList>
+                // at correct list item
+                if ( nListLevelsToBeOpened == 1 )
                 {
-                    OUStringBuffer aBuffer;
-                    aBuffer.append( (sal_Int32)rNextInfo.GetStartValue() );
-                    GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE,
-                                  aBuffer.makeStringAndClear() );
-                }
-                else if ( bRestartNumberingAtContinuedRootList )
-                {
-                    OUStringBuffer aBuffer;
-                    aBuffer.append( (sal_Int32)nRestartValueForContinuedRootList );
-                    GetExport().AddAttribute( XML_NAMESPACE_TEXT,
-                                              XML_START_VALUE,
-                                              aBuffer.makeStringAndClear() );
-                    bRestartNumberingAtContinuedRootList = false;
+                    if ( rNextInfo.HasStartValue() )
+                    {
+                        OUStringBuffer aBuffer;
+                        aBuffer.append( (sal_Int32)rNextInfo.GetStartValue() );
+                        GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE,
+                                      aBuffer.makeStringAndClear() );
+                    }
+                    else if ( bRestartNumberingAtContinuedRootList )
+                    {
+                        OUStringBuffer aBuffer;
+                        aBuffer.append( (sal_Int32)nRestartValueForContinuedRootList );
+                        GetExport().AddAttribute( XML_NAMESPACE_TEXT,
+                                                  XML_START_VALUE,
+                                                  aBuffer.makeStringAndClear() );
+                        bRestartNumberingAtContinuedRootList = false;
+                    }
                 }
+                // <--
 
                 eLName = ( rNextInfo.IsNumbered() || nListLevelsToBeOpened > 1 )
                          ? XML_LIST_ITEM


More information about the ooo-build-commit mailing list