xref: /aoo42x/main/sc/source/ui/view/drawvie4.cxx (revision b3f79822)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
27 
28 
29 
30 // INCLUDE ---------------------------------------------------------------
31 #include <svx/svditer.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdogrp.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svx/svdundo.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <tools/urlobj.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 
41 #include "drawview.hxx"
42 #include "global.hxx"
43 #include "drwlayer.hxx"
44 #include "viewdata.hxx"
45 #include "document.hxx"
46 #include "docsh.hxx"
47 #include "drwtrans.hxx"
48 #include "transobj.hxx"		// SetDrawClipDoc
49 #include "drawutil.hxx"
50 #include "scmod.hxx"
51 #include "globstr.hrc"
52 #include "chartarr.hxx"
53 
54 using namespace com::sun::star;
55 
56 // STATIC DATA -----------------------------------------------------------
57 
58 Point aDragStartDiff;
59 
60 // -----------------------------------------------------------------------
61 
62 //!	welche Funktionen aus drawview/drawvie4 muessen wirklich ohne Optimierung sein?
63 
64 #ifdef _MSC_VER
65 #pragma optimize ( "", off )
66 #endif
67 
68 // -----------------------------------------------------------------------
69 
lcl_CheckOle(const SdrMarkList & rMarkList,sal_Bool & rAnyOle,sal_Bool & rOneOle)70 void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle )
71 {
72 	rAnyOle = rOneOle = sal_False;
73 	sal_uLong nCount = rMarkList.GetMarkCount();
74     for (sal_uLong i=0; i<nCount; i++)
75     {
76         SdrMark* pMark = rMarkList.GetMark(i);
77         SdrObject* pObj = pMark->GetMarkedSdrObj();
78         sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
79         if (nSdrObjKind == OBJ_OLE2)
80         {
81             rAnyOle = sal_True;
82             rOneOle = (nCount == 1);
83             break;
84         }
85 		else if ( pObj->ISA(SdrObjGroup) )
86 		{
87 			SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
88 			SdrObject* pSubObj = aIter.Next();
89 			while (pSubObj)
90 			{
91 				if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
92 				{
93 		            rAnyOle = sal_True;
94 		            // rOneOle remains sal_False - a group isn't treated like a single OLE object
95 		            return;
96 				}
97 				pSubObj = aIter.Next();
98 			}
99 		}
100     }
101 }
102 
103 #if 0
104 void lcl_RefreshChartData( SdrModel* pModel, ScDocument* pSourceDoc )
105 {
106 	sal_uInt16 nPages = pModel->GetPageCount();
107 	for (SCTAB nTab=0; nTab<nPages; nTab++)
108 	{
109 		SdrPage* pPage = pModel->GetPage(nTab);
110 		SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
111 		SdrObject* pObject = aIter.Next();
112 		while (pObject)
113 		{
114 			if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
115 			{
116 				SvInPlaceObjectRef aIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
117 				if ( aIPObj.Is() && SotExchange::IsChart( aIPObj->GetStorage()->GetClassName() ) )
118 				{
119 					SchMemChart* pOldData = SchDLL::GetChartData(aIPObj);
120 					if ( pOldData )
121 					{
122 						//	create data from source document
123 						ScChartArray aArray( pSourceDoc, *pOldData );
124 						if ( aArray.IsValid() )
125 						{
126 							SchMemChart* pNewData = aArray.CreateMemChart();
127 							SchDLL::Update( aIPObj, pNewData );
128 							delete pNewData;
129                 			((SdrOle2Obj*)pObject)->GetNewReplacement();
130 						}
131 					}
132 				}
133 			}
134 			pObject = aIter.Next();
135 		}
136 	}
137 }
138 #endif
139 
140 
BeginDrag(Window * pWindow,const Point & rStartPos)141 sal_Bool ScDrawView::BeginDrag( Window* pWindow, const Point& rStartPos )
142 {
143 	sal_Bool bReturn = sal_False;
144 
145 	if ( AreObjectsMarked() )
146 	{
147 		BrkAction();
148 
149 		Rectangle aMarkedRect = GetAllMarkedRect();
150 		Region aRegion( aMarkedRect );
151 
152 		aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
153 
154 		sal_Bool bAnyOle, bOneOle;
155 		const SdrMarkList& rMarkList = GetMarkedObjectList();
156 		lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
157 
158 		ScDocShellRef aDragShellRef;
159 		if (bAnyOle)
160 		{
161 			aDragShellRef = new ScDocShell;		// DocShell needs a Ref immediately
162 			aDragShellRef->DoInitNew(NULL);
163 		}
164 		ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
165 		SdrModel* pModel = GetAllMarkedModel();
166 		ScDrawLayer::SetGlobalDrawPersist(NULL);
167 
168 		//	Charts now always copy their data in addition to the source reference, so
169 		//	there's no need to call SchDLL::Update for the charts in the clipboard doc.
170 		//	Update with the data (including NumberFormatter) from the live document would
171 		//	also store the NumberFormatter in the clipboard chart (#88749#)
172 		// lcl_RefreshChartData( pModel, pViewData->GetDocument() );
173 
174 		ScDocShell* pDocSh = pViewData->GetDocShell();
175 
176 		TransferableObjectDescriptor aObjDesc;
177 		pDocSh->FillTransferableObjectDescriptor( aObjDesc );
178 		aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
179 		// maSize is set in ScDrawTransferObj ctor
180 
181 		ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
182 		uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
183 
184         pTransferObj->SetDrawPersist( &aDragShellRef );    // keep persist for ole objects alive
185 		pTransferObj->SetDragSource( this );			// copies selection
186 
187 		SC_MOD()->SetDragObject( NULL, pTransferObj );		// for internal D&D
188 		pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
189 	}
190 
191 	return bReturn;
192 }
193 
DoCopy()194 void ScDrawView::DoCopy()
195 {
196 	sal_Bool bAnyOle, bOneOle;
197 	const SdrMarkList& rMarkList = GetMarkedObjectList();
198 	lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
199 
200 	// update ScGlobal::pDrawClipDocShellRef
201 	ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
202 	SdrModel* pModel = GetAllMarkedModel();
203 	ScDrawLayer::SetGlobalDrawPersist(NULL);
204 
205 	//	Charts now always copy their data in addition to the source reference, so
206 	//	there's no need to call SchDLL::Update for the charts in the clipboard doc.
207 	//	Update with the data (including NumberFormatter) from the live document would
208 	//	also store the NumberFormatter in the clipboard chart (#88749#)
209 	// lcl_RefreshChartData( pModel, pViewData->GetDocument() );
210 
211 	ScDocShell* pDocSh = pViewData->GetDocShell();
212 
213 	TransferableObjectDescriptor aObjDesc;
214 	pDocSh->FillTransferableObjectDescriptor( aObjDesc );
215 	aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
216 	// maSize is set in ScDrawTransferObj ctor
217 
218 	ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
219 	uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
220 
221 	if ( ScGlobal::pDrawClipDocShellRef )
222 	{
223         pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) );    // keep persist for ole objects alive
224 	}
225 
226 	pTransferObj->CopyToClipboard( pViewData->GetActiveWin() );		// system clipboard
227 	SC_MOD()->SetClipObject( NULL, pTransferObj );					// internal clipboard
228 }
229 
CopyToTransferable()230 uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
231 {
232 	sal_Bool bAnyOle, bOneOle;
233 	const SdrMarkList& rMarkList = GetMarkedObjectList();
234 	lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
235 
236 	// update ScGlobal::pDrawClipDocShellRef
237 	ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
238 	SdrModel* pModel = GetAllMarkedModel();
239 	ScDrawLayer::SetGlobalDrawPersist(NULL);
240 
241 	//	Charts now always copy their data in addition to the source reference, so
242 	//	there's no need to call SchDLL::Update for the charts in the clipboard doc.
243 	//	Update with the data (including NumberFormatter) from the live document would
244 	//	also store the NumberFormatter in the clipboard chart (#88749#)
245 	// lcl_RefreshChartData( pModel, pViewData->GetDocument() );
246 
247 	ScDocShell* pDocSh = pViewData->GetDocShell();
248 
249 	TransferableObjectDescriptor aObjDesc;
250 	pDocSh->FillTransferableObjectDescriptor( aObjDesc );
251 	aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
252 	// maSize is set in ScDrawTransferObj ctor
253 
254 	ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
255 	uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
256 
257 	if ( ScGlobal::pDrawClipDocShellRef )
258 	{
259         pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) );    // keep persist for ole objects alive
260 	}
261 
262     return xTransferable;
263 }
264 
265 //	Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
266 
CalcNormScale(Fraction & rFractX,Fraction & rFractY) const267 void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
268 {
269 	Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
270 	double nPPTX = ScGlobal::nScreenPPTX;
271 	double nPPTY = ScGlobal::nScreenPPTY;
272 
273 	if (pViewData)
274 		nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
275 
276 	SCCOL nEndCol = 0;
277 	SCROW nEndRow = 0;
278 	pDoc->GetTableArea( nTab, nEndCol, nEndRow );
279 	if (nEndCol<20)
280 		nEndCol = 20;
281 	if (nEndRow<20)
282         nEndRow = 20;
283 
284 	Fraction aZoom(1,1);
285 	ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
286 							nPPTX, nPPTY, rFractX,rFractY );
287 }
288 
SetMarkedOriginalSize()289 void ScDrawView::SetMarkedOriginalSize()
290 {
291 	SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
292 
293 	const SdrMarkList& rMarkList = GetMarkedObjectList();
294 	long nDone = 0;
295 	sal_uLong nCount = rMarkList.GetMarkCount();
296 	for (sal_uLong i=0; i<nCount; i++)
297 	{
298 		SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
299 		sal_uInt16 nIdent = pObj->GetObjIdentifier();
300 		sal_Bool bDo = sal_False;
301 		Size aOriginalSize;
302 		if (nIdent == OBJ_OLE2)
303 		{
304             // TODO/LEAN: working with visual area can switch object to running state
305             uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), uno::UNO_QUERY );
306             if ( xObj.is() )    // #121612# NULL for an invalid object that couldn't be loaded
307             {
308 				sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect();
309 
310 				if ( nAspect == embed::Aspects::MSOLE_ICON )
311 				{
312 					MapMode aMapMode( MAP_100TH_MM );
313 					aOriginalSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMapMode );
314 					bDo = sal_True;
315 				}
316 				else
317 				{
318 					MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( ((SdrOle2Obj*)pObj)->GetAspect() ) );
319 					awt::Size aSz;
320 					try
321 					{
322 						aSz = xObj->getVisualAreaSize( ((SdrOle2Obj*)pObj)->GetAspect() );
323 						aOriginalSize = OutputDevice::LogicToLogic(
324 											Size( aSz.Width, aSz.Height ),
325 											aUnit, MAP_100TH_MM );
326 						bDo = sal_True;
327 					} catch( embed::NoVisualAreaSizeException& )
328 					{
329 						OSL_ENSURE( sal_False, "Can't get the original size of the object!" );
330 					}
331 				}
332             }
333 		}
334 		else if (nIdent == OBJ_GRAF)
335 		{
336 			const Graphic& rGraphic = ((SdrGrafObj*)pObj)->GetGraphic();
337 
338 			MapMode aSourceMap = rGraphic.GetPrefMapMode();
339 			MapMode aDestMap( MAP_100TH_MM );
340 			if (aSourceMap.GetMapUnit() == MAP_PIXEL)
341 			{
342 				//	Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
343 
344 				Fraction aNormScaleX, aNormScaleY;
345 				CalcNormScale( aNormScaleX, aNormScaleY );
346 				aDestMap.SetScaleX(aNormScaleX);
347 				aDestMap.SetScaleY(aNormScaleY);
348 			}
349 			if (pViewData)
350 			{
351 				Window* pActWin = pViewData->GetActiveWin();
352 				if (pActWin)
353 				{
354 					aOriginalSize = pActWin->LogicToLogic(
355 									rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
356 					bDo = sal_True;
357 				}
358 			}
359 		}
360 
361 		if ( bDo )
362 		{
363 			Rectangle aDrawRect = pObj->GetLogicRect();
364 
365 			pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
366 			pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
367 												 Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
368 			++nDone;
369 		}
370 	}
371 
372 	if (nDone)
373 	{
374 		pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
375         ScDocShell* pDocSh = pViewData->GetDocShell();
376         pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
377         pDocSh->SetDrawModified();
378 	}
379 	else
380 		delete pUndoGroup;
381 }
382 
383 
384 #ifdef _MSC_VER
385 #pragma optimize ( "", on )
386 #endif
387 
388 
389 
390 
391