1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/sdr/contact/viewobjectcontactofsdrole2obj.hxx>
32 #include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx>
33 #include <svx/sdr/contact/viewcontactofsdrole2obj.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/sdr/contact/objectcontact.hxx>
36 #include <svx/svdview.hxx>
37 #include <drawinglayer/primitive2d/chartprimitive2d.hxx>
38 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
39 #include <basegfx/polygon/b2dpolygontools.hxx>
40 #include <com/sun/star/embed/EmbedMisc.hpp>
41 #include <com/sun/star/embed/EmbedStates.hpp>
42 #include <basegfx/polygon/b2dpolygon.hxx>
43 
44 //////////////////////////////////////////////////////////////////////////////
45 
46 using namespace com::sun::star;
47 
48 //////////////////////////////////////////////////////////////////////////////
49 
50 namespace sdr
51 {
52 	namespace contact
53 	{
54 		const SdrOle2Obj& ViewObjectContactOfSdrOle2Obj::getSdrOle2Object() const
55 		{
56 			return static_cast< ViewContactOfSdrOle2Obj& >(GetViewContact()).GetOle2Obj();
57 		}
58 
59 		drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrOle2Obj::createPrimitive2DSequence(
60             const DisplayInfo& /*rDisplayInfo*/) const
61 		{
62 			// this method is overloaded to do some things the old SdrOle2Obj::DoPaintObject did.
63 		    // In the future, some of these may be solved different, but ATM try to stay compatible
64 		    // with the old behaviour
65 		    drawinglayer::primitive2d::Primitive2DSequence xRetval;
66 		    const SdrOle2Obj& rSdrOle2 = getSdrOle2Object();
67             sal_Int32 nState(-1);
68 
69             {
70                 const svt::EmbeddedObjectRef& xObjRef  = rSdrOle2.getEmbeddedObjectRef();
71                 if ( xObjRef.is() )
72                     nState = xObjRef->getCurrentState();
73             }
74 
75             const bool bIsOutplaceActive(nState == embed::EmbedStates::ACTIVE);
76             const bool bIsInplaceActive((nState == embed::EmbedStates::INPLACE_ACTIVE) || (nState == embed::EmbedStates::UI_ACTIVE));
77             const bool bIsChart(rSdrOle2.IsChart());
78             bool bDone(false);
79 
80             if(!bDone && bIsInplaceActive)
81             {
82                 if( !GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile() )
83                 {
84                     //no need to create a primitive sequence here as the OLE object does render itself
85                     //in case of charts the superfluous creation of a metafile is strongly performance relevant!
86                     bDone = true;
87                 }
88             }
89 
90             if( !bDone )
91             {
92                 const Rectangle& rObjectRectangle(rSdrOle2.GetGeoRect());
93 		        const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom());
94 
95 		        // create object transform
96 		        basegfx::B2DHomMatrix aObjectTransform;
97 		        aObjectTransform.set(0, 0, aObjectRange.getWidth());
98 		        aObjectTransform.set(1, 1, aObjectRange.getHeight());
99 		        aObjectTransform.set(0, 2, aObjectRange.getMinX());
100 		        aObjectTransform.set(1, 2, aObjectRange.getMinY());
101 
102                 if(bIsChart)
103 		        {
104                     //charts must be painted resolution dependent!! #i82893#, #i75867#
105 
106 			        // for chart, to not lose the current better quality visualisation which
107 			        // uses a direct paint, use a primtive wrapper for that exceptional case. The renderers
108 			        // will then ATM paint it to an OutputDevice directly.
109 			        // In later versions this should be replaced by getting the Primitive2DSequnce from
110 			        // the chart and using it.
111 			        // to be able to render something in non-VCL using renderers, the wrapper is a
112 			        // GroupPrimitive2D which automatically decomposes to the already created Metafile
113 			        // content.
114 			        // For being completely compatible, ATM Window and VDEV PrettyPrinting is suppressed.
115 			        // It works in the VCL renderers, though. So for activating again with VCL primitive
116 			        // renderers, change conditions here.
117 
118 			        // determine if embedding and PrettyPrinting shall be done at all
119 			        uno::Reference< frame::XModel > xChartModel;
120 			        bool bDoChartPrettyPrinting(true);
121 
122 			        // the original ChartPrettyPainter does not do it for Window
123 			        if(bDoChartPrettyPrinting && GetObjectContact().isOutputToWindow())
124 			        {
125 				        bDoChartPrettyPrinting = false;
126 			        }
127 
128 			        // the original ChartPrettyPainter does not do it for VDEV
129 			        if(bDoChartPrettyPrinting && GetObjectContact().isOutputToVirtualDevice())
130 			        {
131 				        if(GetObjectContact().isOutputToPDFFile())
132 				        {
133 					        // #i97982#
134 					        // For PDF files, allow PrettyPrinting
135 				        }
136 				        else
137 				        {
138 					        bDoChartPrettyPrinting = false;
139 				        }
140 			        }
141 
142 			        // the chart model is needed. Check if it's available
143 			        if(bDoChartPrettyPrinting)
144 			        {
145 				        // get chart model
146 				        xChartModel = rSdrOle2.getXModel();
147 
148 				        if(!xChartModel.is())
149 				        {
150 					        bDoChartPrettyPrinting = false;
151 				        }
152 			        }
153 
154 			        if(bDoChartPrettyPrinting)
155 			        {
156 				        // embed MetaFile data in a specialized Wrapper Primitive which holds also the ChartModel needed
157 				        // for PrettyPrinting
158 				        const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ChartPrimitive2D(
159 					        xChartModel, aObjectTransform, xRetval));
160 				        xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
161                         bDone = true;
162 			        }
163 		        }
164 
165                 if( !bDone )
166                 {
167                     //old stuff that should be reworked
168                     {
169                         //if no replacement image is available load the OLE object
170                         if(!rSdrOle2.GetGraphic()) //try to fetch the metafile - this can lead to the actual creation of the metafile what can be extremely expensive (e.g. for big charts)!!! #i101925#
171                         {
172 	                        // try to create embedded object
173                             rSdrOle2.GetObjRef(); //this loads the OLE object if it is not loaded already
174                         }
175                         const svt::EmbeddedObjectRef& xObjRef  = rSdrOle2.getEmbeddedObjectRef();
176                         if(xObjRef.is())
177                         {
178                             const sal_Int64 nMiscStatus(xObjRef->getStatus(rSdrOle2.GetAspect()));
179 
180                             // this hack (to change model data during PAINT argh(!)) should be reworked
181                             if(!rSdrOle2.IsResizeProtect() && (nMiscStatus & embed::EmbedMisc::EMBED_NEVERRESIZE))
182                             {
183 	                            const_cast< SdrOle2Obj* >(&rSdrOle2)->SetResizeProtect(true);
184                             }
185 
186                             SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView();
187 	                        if(pPageView && (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE))
188 	                        {
189 		                        // connect plugin object
190 		                        pPageView->GetView().DoConnect(const_cast< SdrOle2Obj* >(&rSdrOle2));
191 	                        }
192                         }
193                     }//end old stuff to rework
194 
195                     // create OLE primitive stuff directly at VC with HC as parameter
196 		            const ViewContactOfSdrOle2Obj& rVC = static_cast< const ViewContactOfSdrOle2Obj& >(GetViewContact());
197                     xRetval = rVC.createPrimitive2DSequenceWithParameters(GetObjectContact().isDrawModeHighContrast());
198                 }
199 
200                 if(bIsOutplaceActive)
201 		        {
202 			        // do not shade when printing or PDF exporting
203 			        if(!GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile())
204 			        {
205 				        // shade the representation if the object is activated outplace
206 				        basegfx::B2DPolygon aObjectOutline(basegfx::tools::createUnitPolygon());
207 				        aObjectOutline.transform(aObjectTransform);
208 
209 				        // Use a FillHatchPrimitive2D with necessary attributes
210 				        const drawinglayer::attribute::FillHatchAttribute aFillHatch(
211 					        drawinglayer::attribute::HATCHSTYLE_SINGLE, // single hatch
212 					        125.0, // 1.25 mm
213 					        45.0 * F_PI180, // 45 degree diagonal
214 					        Color(COL_BLACK).getBColor(), // black color
215 					        false); // no filling
216 
217 				        const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D(
218 					        basegfx::B2DPolyPolygon(aObjectOutline),
219 					        Color(COL_BLACK).getBColor(),
220 					        aFillHatch));
221 
222 				        drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference);
223 			        }
224 		        }
225 
226             }
227 
228 		    return xRetval;
229 		}
230 
231 		ViewObjectContactOfSdrOle2Obj::ViewObjectContactOfSdrOle2Obj(ObjectContact& rObjectContact, ViewContact& rViewContact)
232 		:	ViewObjectContactOfSdrObj(rObjectContact, rViewContact)
233 		{
234 		}
235 
236 		ViewObjectContactOfSdrOle2Obj::~ViewObjectContactOfSdrOle2Obj()
237 		{
238 		}
239 	} // end of namespace contact
240 } // end of namespace sdr
241 
242 //////////////////////////////////////////////////////////////////////////////
243 // eof
244