Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/uno/Reference.hxx>
30 : : #include <com/sun/star/chart/XChartDocument.hpp>
31 : : #include <com/sun/star/embed/XEmbeddedObject.hpp>
32 : : #include <com/sun/star/embed/XVisualObject.hpp>
33 : : #include <com/sun/star/embed/XClassifiedObject.hpp>
34 : : #include <com/sun/star/embed/XComponentSupplier.hpp>
35 : : #include <com/sun/star/embed/EmbedStates.hpp>
36 : : #include <com/sun/star/embed/ElementModes.hpp>
37 : : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
38 : : #include <com/sun/star/datatransfer/XTransferable.hpp>
39 : :
40 : : #include "scitems.hxx"
41 : : #include <editeng/eeitem.hxx>
42 : : #include <editeng/frmdiritem.hxx>
43 : : #include <sot/exchange.hxx>
44 : : #include <svx/objfac3d.hxx>
45 : : #include <svx/xtable.hxx>
46 : : #include <svx/svdoutl.hxx>
47 : : #include <svx/svditer.hxx>
48 : : #include <svx/svdocapt.hxx>
49 : : #include <svx/svdocirc.hxx>
50 : : #include <svx/svdoedge.hxx>
51 : : #include <svx/svdograf.hxx>
52 : : #include <svx/svdoole2.hxx>
53 : : #include <svx/svdundo.hxx>
54 : : #include <i18npool/mslangid.hxx>
55 : : #include <editeng/unolingu.hxx>
56 : : #include <svx/drawitem.hxx>
57 : : #include <editeng/fhgtitem.hxx>
58 : : #include <editeng/scriptspaceitem.hxx>
59 : : #include <svx/shapepropertynotifier.hxx>
60 : : #include <sfx2/viewsh.hxx>
61 : : #include <sfx2/docfile.hxx>
62 : : #include <sot/storage.hxx>
63 : : #include <unotools/pathoptions.hxx>
64 : : #include <svl/itempool.hxx>
65 : : #include <vcl/virdev.hxx>
66 : : #include <vcl/svapp.hxx>
67 : : #include <unotools/ucbstreamhelper.hxx>
68 : :
69 : : #include <basegfx/polygon/b2dpolygon.hxx>
70 : : #include <basegfx/polygon/b2dpolygontools.hxx>
71 : :
72 : : #include "drwlayer.hxx"
73 : : #include "drawpage.hxx"
74 : : #include "global.hxx"
75 : : #include "document.hxx"
76 : : #include "rechead.hxx"
77 : : #include "userdat.hxx"
78 : : #include "markdata.hxx"
79 : : #include "globstr.hrc"
80 : : #include "scmod.hxx"
81 : : #include "chartarr.hxx"
82 : : #include "postit.hxx"
83 : : #include "attrib.hxx"
84 : : #include "charthelper.hxx"
85 : :
86 : : #include <vcl/field.hxx>
87 : :
88 : : #define DET_ARROW_OFFSET 1000
89 : :
90 : : using namespace ::com::sun::star;
91 : :
92 : : // STATIC DATA -----------------------------------------------------------
93 : :
94 [ + + ][ - + ]: 2211 : TYPEINIT1(ScTabDeletedHint, SfxHint);
95 [ + + ][ - + ]: 1976357 : TYPEINIT1(ScTabSizeChangedHint, SfxHint);
96 : :
97 : : static ScDrawObjFactory* pFac = NULL;
98 : : static E3dObjFactory* pF3d = NULL;
99 : : static sal_uInt16 nInst = 0;
100 : :
101 : : SfxObjectShell* ScDrawLayer::pGlobalDrawPersist = NULL;
102 : :
103 : : sal_Bool bDrawIsInUndo = false; //! Member
104 : :
105 : : // -----------------------------------------------------------------------
106 : :
107 : 30 : ScUndoObjData::ScUndoObjData( SdrObject* pObjP, const ScAddress& rOS, const ScAddress& rOE,
108 : : const ScAddress& rNS, const ScAddress& rNE ) :
109 : : SdrUndoObj( *pObjP ),
110 : : aOldStt( rOS ),
111 : : aOldEnd( rOE ),
112 : : aNewStt( rNS ),
113 : 30 : aNewEnd( rNE )
114 : : {
115 : 30 : }
116 : :
117 : 30 : ScUndoObjData::~ScUndoObjData()
118 : : {
119 [ - + ]: 60 : }
120 : :
121 : 0 : void ScUndoObjData::Undo()
122 : : {
123 : 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
124 : : OSL_ENSURE(pData,"ScUndoObjData: Daten nicht da");
125 [ # # ]: 0 : if (pData)
126 : : {
127 : 0 : pData->maStart = aOldStt;
128 : 0 : pData->maEnd = aOldEnd;
129 : : }
130 : 0 : }
131 : :
132 : 0 : void ScUndoObjData::Redo()
133 : : {
134 : 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
135 : : OSL_ENSURE(pData,"ScUndoObjData: Daten nicht da");
136 [ # # ]: 0 : if (pData)
137 : : {
138 : 0 : pData->maStart = aNewStt;
139 : 0 : pData->maEnd = aNewEnd;
140 : : }
141 : 0 : }
142 : :
143 : : // -----------------------------------------------------------------------
144 : :
145 : 28 : ScTabDeletedHint::ScTabDeletedHint( SCTAB nTabNo ) :
146 : 28 : nTab( nTabNo )
147 : : {
148 : 28 : }
149 : :
150 : 28 : ScTabDeletedHint::~ScTabDeletedHint()
151 : : {
152 [ - + ]: 28 : }
153 : :
154 : 64231 : ScTabSizeChangedHint::ScTabSizeChangedHint( SCTAB nTabNo ) :
155 : 64231 : nTab( nTabNo )
156 : : {
157 : 64231 : }
158 : :
159 : 64231 : ScTabSizeChangedHint::~ScTabSizeChangedHint()
160 : : {
161 [ - + ]: 64231 : }
162 : :
163 : : // -----------------------------------------------------------------------
164 : :
165 : : #define MAXMM 10000000
166 : :
167 : 698 : inline long TwipsToHmm (long nVal)
168 : : {
169 : : return static_cast< long >( MetricField::ConvertDoubleValue (static_cast<sal_Int64>(nVal), 0, 0,
170 : 698 : FUNIT_TWIP, FUNIT_100TH_MM) );
171 : : }
172 : :
173 : 440 : inline long HmmToTwips (long nVal)
174 : : {
175 : : return static_cast< long > ( MetricField::ConvertDoubleValue (static_cast<sal_Int64>(nVal), 0, 0,
176 : 440 : FUNIT_100TH_MM, FUNIT_TWIP) );
177 : : }
178 : :
179 : 506 : inline void TwipsToMM( long& nVal )
180 : : {
181 : 506 : nVal = TwipsToHmm (nVal);
182 : 506 : }
183 : :
184 : 48 : inline void ReverseTwipsToMM( long& nVal )
185 : : {
186 : 48 : nVal = HmmToTwips (nVal);
187 : 48 : }
188 : :
189 : 0 : void lcl_ReverseTwipsToMM( Point& rPoint )
190 : : {
191 : 0 : ReverseTwipsToMM( rPoint.X() );
192 : 0 : ReverseTwipsToMM( rPoint.Y() );
193 : 0 : }
194 : :
195 : 12 : void lcl_ReverseTwipsToMM( Rectangle& rRect )
196 : : {
197 : 12 : ReverseTwipsToMM( rRect.Left() );
198 : 12 : ReverseTwipsToMM( rRect.Right() );
199 : 12 : ReverseTwipsToMM( rRect.Top() );
200 : 12 : ReverseTwipsToMM( rRect.Bottom() );
201 : 12 : }
202 : :
203 : : // -----------------------------------------------------------------------
204 : :
205 : :
206 : 322 : ScDrawLayer::ScDrawLayer( ScDocument* pDocument, const String& rName ) :
207 [ + - ]: 644 : FmFormModel( SvtPathOptions().GetPalettePath(),
208 : : NULL, // SfxItemPool* Pool
209 : : pGlobalDrawPersist ?
210 : : pGlobalDrawPersist :
211 : : ( pDocument ? pDocument->GetDocumentShell() : NULL ),
212 : : sal_True ), // bUseExtColorTable (is set below)
213 : : aName( rName ),
214 : : pDoc( pDocument ),
215 : : pUndoGroup( NULL ),
216 : : bRecording( false ),
217 : : bAdjustEnabled( sal_True ),
218 [ + - ][ + - ]: 966 : bHyphenatorSet( false )
[ + - + - ]
219 : : {
220 : 322 : pGlobalDrawPersist = NULL; // nur einmal benutzen
221 : :
222 [ + - ]: 322 : SfxObjectShell* pObjSh = pDocument ? pDocument->GetDocumentShell() : NULL;
223 [ + - ]: 322 : XColorListRef pXCol = XColorList::GetStdColorList();
224 [ + - ]: 322 : if ( pObjSh )
225 : : {
226 [ + - ]: 322 : SetObjectShell( pObjSh );
227 : :
228 : : // set color table
229 [ + - ]: 322 : SvxColorListItem* pColItem = (SvxColorListItem*) pObjSh->GetItem( SID_COLOR_TABLE );
230 [ + + ]: 322 : if ( pColItem )
231 [ + - ][ + - ]: 292 : pXCol = pColItem->GetColorList();
232 : : }
233 [ + - ]: 322 : SetPropertyList( static_cast<XPropertyList *> (pXCol.get()) );
234 : :
235 [ + - ]: 322 : SetSwapGraphics(sal_True);
236 : :
237 [ + - ]: 322 : SetScaleUnit(MAP_100TH_MM);
238 : 322 : SfxItemPool& rPool = GetItemPool();
239 [ + - ]: 322 : rPool.SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
240 [ + - ]: 322 : SvxFrameDirectionItem aModeItem( FRMDIR_ENVIRONMENT, EE_PARA_WRITINGDIR );
241 [ + - ]: 322 : rPool.SetPoolDefaultItem( aModeItem );
242 : :
243 : : // #i33700#
244 : : // Set shadow distance defaults as PoolDefaultItems. Details see bug.
245 [ + - ][ + - ]: 322 : rPool.SetPoolDefaultItem(SdrShadowXDistItem(300));
[ + - ]
246 [ + - ][ + - ]: 322 : rPool.SetPoolDefaultItem(SdrShadowYDistItem(300));
[ + - ]
247 : :
248 : : // default for script spacing depends on locale, see SdDrawDocument ctor in sd
249 [ + - ][ + - ]: 322 : LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage();
250 [ + - ][ + - ]: 322 : if (MsLangId::isKorean(eOfficeLanguage) || eOfficeLanguage == LANGUAGE_JAPANESE)
[ - + ][ - + ]
251 : : {
252 : : // secondary is edit engine pool
253 [ # # ][ # # ]: 0 : rPool.GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
[ # # ][ # # ]
254 : : }
255 : :
256 [ + - ]: 322 : rPool.FreezeIdRanges(); // the pool is also used directly
257 : :
258 : 322 : SdrLayerAdmin& rAdmin = GetLayerAdmin();
259 [ + - ][ + - ]: 322 : rAdmin.NewLayer(rtl::OUString("vorne"), SC_LAYER_FRONT);
[ + - ]
260 [ + - ][ + - ]: 322 : rAdmin.NewLayer(rtl::OUString("hinten"), SC_LAYER_BACK);
[ + - ]
261 [ + - ][ + - ]: 322 : rAdmin.NewLayer(rtl::OUString("intern"), SC_LAYER_INTERN);
[ + - ]
262 [ + - ][ + - ]: 322 : rAdmin.NewLayer(rtl::OUString("Controls"), SC_LAYER_CONTROLS);
[ + - ]
263 [ + - ][ + - ]: 322 : rAdmin.NewLayer(rtl::OUString("hidden"), SC_LAYER_HIDDEN);
[ + - ]
264 : : // "Controls" is new - must also be created when loading
265 : :
266 : : // Link fuer URL-Fields setzen
267 [ + - ]: 322 : ScModule* pScMod = SC_MOD();
268 [ + - ]: 322 : Outliner& rOutliner = GetDrawOutliner();
269 [ + - ]: 322 : rOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
270 : :
271 : 322 : Outliner& rHitOutliner = GetHitTestOutliner();
272 [ + - ]: 322 : rHitOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
273 : :
274 : : // set FontHeight pool defaults without changing static SdrEngineDefaults
275 [ + - ]: 322 : SfxItemPool* pOutlinerPool = rOutliner.GetEditTextObjectPool();
276 [ + - ]: 322 : if ( pOutlinerPool )
277 [ + - ][ + - ]: 322 : pItemPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT )); // 12Pt
[ + - ]
278 [ + - ]: 322 : SfxItemPool* pHitOutlinerPool = rHitOutliner.GetEditTextObjectPool();
279 [ + - ]: 322 : if ( pHitOutlinerPool )
280 [ + - ][ + - ]: 322 : pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT )); // 12Pt
[ + - ]
281 : :
282 : : // URL-Buttons haben keinen Handler mehr, machen alles selber
283 : :
284 [ + + ]: 322 : if( !nInst++ )
285 : : {
286 [ + - ][ + - ]: 289 : pFac = new ScDrawObjFactory;
287 [ + - ][ + - ]: 289 : pF3d = new E3dObjFactory;
288 [ + - ]: 322 : }
289 : 322 : }
290 : :
291 [ + - ]: 309 : ScDrawLayer::~ScDrawLayer()
292 : : {
293 [ + - ][ + - ]: 309 : Broadcast(SdrHint(HINT_MODELCLEARED));
[ + - ]
294 : :
295 [ + - ]: 309 : ClearModel(sal_True);
296 : :
297 [ - + ][ # # ]: 309 : delete pUndoGroup;
298 [ + + ]: 309 : if( !--nInst )
299 : : {
300 [ + - ][ + - ]: 279 : delete pFac, pFac = NULL;
301 [ + - ][ + - ]: 279 : delete pF3d, pF3d = NULL;
302 : : }
303 [ - + ]: 618 : }
304 : :
305 : 2757 : void ScDrawLayer::UseHyphenator()
306 : : {
307 [ + + ]: 2757 : if (!bHyphenatorSet)
308 : : {
309 : : com::sun::star::uno::Reference< com::sun::star::linguistic2::XHyphenator >
310 [ + - ]: 201 : xHyphenator = LinguMgr::GetHyphenator();
311 : :
312 [ + - ][ + - ]: 201 : GetDrawOutliner().SetHyphenator( xHyphenator );
313 [ + - ]: 201 : GetHitTestOutliner().SetHyphenator( xHyphenator );
314 : :
315 : 201 : bHyphenatorSet = sal_True;
316 : : }
317 : 2757 : }
318 : :
319 : 580 : SdrPage* ScDrawLayer::AllocPage(bool bMasterPage)
320 : : {
321 : : // don't create basic until it is needed
322 : 580 : StarBASIC* pBasic = NULL;
323 [ + - ]: 580 : ScDrawPage* pPage = new ScDrawPage( *this, pBasic, bMasterPage);
324 : 580 : return pPage;
325 : : }
326 : :
327 : 63 : sal_Bool ScDrawLayer::HasObjects() const
328 : : {
329 : 63 : sal_Bool bFound = false;
330 : :
331 : 63 : sal_uInt16 nCount = GetPageCount();
332 [ + + ][ + - ]: 126 : for (sal_uInt16 i=0; i<nCount && !bFound; i++)
[ + + ]
333 [ - + ]: 63 : if (GetPage(i)->GetObjCount())
334 : 0 : bFound = sal_True;
335 : :
336 : 63 : return bFound;
337 : : }
338 : :
339 : 398 : void ScDrawLayer::UpdateBasic()
340 : : {
341 : : // don't create basic until it is needed
342 : : //! remove this method?
343 : 398 : }
344 : :
345 : 0 : SdrModel* ScDrawLayer::AllocModel() const
346 : : {
347 : : // Allocated model (for clipboard etc) must not have a pointer
348 : : // to the original model's document, pass NULL as document:
349 : :
350 [ # # ]: 0 : return new ScDrawLayer( NULL, aName );
351 : : }
352 : :
353 : 0 : Window* ScDrawLayer::GetCurDocViewWin()
354 : : {
355 : : OSL_ENSURE( pDoc, "ScDrawLayer::GetCurDocViewWin without document" );
356 [ # # ]: 0 : if ( !pDoc )
357 : 0 : return NULL;
358 : :
359 : 0 : SfxViewShell* pViewSh = SfxViewShell::Current();
360 : 0 : SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
361 : :
362 [ # # ][ # # ]: 0 : if (pViewSh && pViewSh->GetObjectShell() == pObjSh)
[ # # ]
363 : 0 : return pViewSh->GetWindow();
364 : :
365 : 0 : return NULL;
366 : : }
367 : :
368 : 580 : sal_Bool ScDrawLayer::ScAddPage( SCTAB nTab )
369 : : {
370 [ - + ]: 580 : if (bDrawIsInUndo)
371 : 0 : return false; // not inserted
372 : :
373 : 580 : ScDrawPage* pPage = (ScDrawPage*)AllocPage( false );
374 : 580 : InsertPage(pPage, static_cast<sal_uInt16>(nTab));
375 [ + + ]: 580 : if (bRecording)
376 [ + - ]: 42 : AddCalcUndo(new SdrUndoNewPage(*pPage));
377 : :
378 : 580 : ResetTab(nTab, pDoc->GetTableCount()-1);
379 : 580 : return true; // inserted
380 : : }
381 : :
382 : 28 : void ScDrawLayer::ScRemovePage( SCTAB nTab )
383 : : {
384 [ - + ]: 28 : if (bDrawIsInUndo)
385 : 28 : return;
386 : :
387 [ + - ]: 28 : Broadcast( ScTabDeletedHint( nTab ) );
388 [ + + ]: 28 : if (bRecording)
389 : : {
390 : 19 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
391 [ + - ]: 19 : AddCalcUndo(new SdrUndoDelPage(*pPage)); // Undo-Action wird Owner der Page
392 : 19 : RemovePage( static_cast<sal_uInt16>(nTab) ); // nur austragen, nicht loeschen
393 : : }
394 : : else
395 : 9 : DeletePage( static_cast<sal_uInt16>(nTab) ); // einfach weg damit
396 : :
397 : 28 : ResetTab(nTab, pDoc->GetTableCount()-1);
398 : : }
399 : :
400 : 580 : void ScDrawLayer::ScRenamePage( SCTAB nTab, const String& rNewName )
401 : : {
402 : 580 : ScDrawPage* pPage = (ScDrawPage*) GetPage(static_cast<sal_uInt16>(nTab));
403 [ + - ]: 580 : if (pPage)
404 : 580 : pPage->SetName(rNewName);
405 : 580 : }
406 : :
407 : 3 : void ScDrawLayer::ScMovePage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
408 : : {
409 : 3 : MovePage( nOldPos, nNewPos );
410 : 3 : sal_uInt16 nMinPos = std::min(nOldPos, nNewPos);
411 : 3 : ResetTab(nMinPos, pDoc->GetTableCount()-1);
412 : 3 : }
413 : :
414 : 4 : void ScDrawLayer::ScCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos, sal_Bool bAlloc )
415 : : {
416 : : //! remove argument bAlloc (always sal_False)
417 : :
418 [ - + ]: 4 : if (bDrawIsInUndo)
419 : 4 : return;
420 : :
421 : 4 : SdrPage* pOldPage = GetPage(nOldPos);
422 [ - + ]: 4 : SdrPage* pNewPage = bAlloc ? AllocPage(false) : GetPage(nNewPos);
423 : :
424 : : // kopieren
425 : :
426 [ + - ][ + - ]: 4 : if (pOldPage && pNewPage)
427 : : {
428 : 4 : SCTAB nOldTab = static_cast<SCTAB>(nOldPos);
429 : 4 : SCTAB nNewTab = static_cast<SCTAB>(nNewPos);
430 : :
431 [ + - ]: 4 : SdrObjListIter aIter( *pOldPage, IM_FLAT );
432 [ + - ]: 4 : SdrObject* pOldObject = aIter.Next();
433 [ + + ]: 7 : while (pOldObject)
434 : : {
435 [ + - ]: 3 : ScDrawObjData* pOldData = GetObjData(pOldObject);
436 [ + - ]: 3 : if (pOldData)
437 : : {
438 : 3 : pOldData->maStart.SetTab(nOldTab);
439 : 3 : pOldData->maEnd.SetTab(nOldTab);
440 : : }
441 [ + - ]: 3 : SdrObject* pNewObject = pOldObject->Clone();
442 [ + - ]: 3 : pNewObject->SetModel(this);
443 [ + - ]: 3 : pNewObject->SetPage(pNewPage);
444 : :
445 [ + - ]: 3 : pNewObject->NbcMove(Size(0,0));
446 [ + - ]: 3 : pNewPage->InsertObject( pNewObject );
447 [ + - ]: 3 : ScDrawObjData* pNewData = GetObjData(pNewObject);
448 [ + - ]: 3 : if (pNewData)
449 : : {
450 : 3 : pNewData->maStart.SetTab(nNewTab);
451 : 3 : pNewData->maEnd.SetTab(nNewTab);
452 : : }
453 : :
454 [ - + ]: 3 : if (bRecording)
455 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
[ # # ]
456 : :
457 [ + - ]: 3 : pOldObject = aIter.Next();
458 : 4 : }
459 : : }
460 : :
461 [ - + ]: 4 : if (bAlloc)
462 : 0 : InsertPage(pNewPage, nNewPos);
463 : :
464 : 4 : ResetTab(static_cast<SCTAB>(nNewPos), pDoc->GetTableCount()-1);
465 : : }
466 : :
467 : 615 : void ScDrawLayer::ResetTab( SCTAB nStart, SCTAB nEnd )
468 : : {
469 : 615 : SCTAB nPageSize = static_cast<SCTAB>(GetPageCount());
470 [ - + ]: 615 : if (nPageSize < 0)
471 : : // No drawing pages exist.
472 : 615 : return;
473 : :
474 [ + + ]: 615 : if (nEnd >= nPageSize)
475 : : // Avoid iterating beyond the last existing page.
476 : 89 : nEnd = nPageSize - 1;
477 : :
478 [ + + ]: 1114 : for (SCTAB i = nStart; i <= nEnd; ++i)
479 : : {
480 [ + - ]: 499 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(i));
481 [ - + ]: 499 : if (!pPage)
482 : 0 : continue;
483 : :
484 [ + - ]: 499 : SdrObjListIter aIter(*pPage, IM_FLAT);
485 [ + - ][ + - ]: 511 : for (SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next())
[ + + ]
486 : : {
487 [ + - ]: 12 : ScDrawObjData* pData = GetObjData(pObj);
488 [ - + ]: 12 : if (!pData)
489 : 0 : continue;
490 : :
491 : 12 : pData->maStart.SetTab(i);
492 : 12 : pData->maEnd.SetTab(i);
493 : : }
494 : 499 : }
495 : : }
496 : :
497 : 60 : inline sal_Bool IsInBlock( const ScAddress& rPos, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2 )
498 : : {
499 : 120 : return rPos.Col() >= nCol1 && rPos.Col() <= nCol2 &&
500 [ + - ][ + - ]: 120 : rPos.Row() >= nRow1 && rPos.Row() <= nRow2;
[ + - + - ]
501 : : }
502 : :
503 : 12 : void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
504 : : SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos )
505 : : {
506 : 12 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
507 : : OSL_ENSURE(pPage,"Page nicht gefunden");
508 [ - + ]: 12 : if (!pPage)
509 : 12 : return;
510 : :
511 [ + - ][ - + ]: 12 : sal_Bool bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
512 : :
513 : 12 : sal_uLong nCount = pPage->GetObjCount();
514 [ + + ]: 42 : for ( sal_uLong i = 0; i < nCount; i++ )
515 : : {
516 : 30 : SdrObject* pObj = pPage->GetObj( i );
517 : 30 : ScDrawObjData* pData = GetObjDataTab( pObj, nTab );
518 [ + - ]: 30 : if( pData )
519 : : {
520 : 30 : const ScAddress aOldStt = pData->maStart;
521 : 30 : const ScAddress aOldEnd = pData->maEnd;
522 : 30 : sal_Bool bChange = false;
523 [ + - ][ + - ]: 30 : if ( aOldStt.IsValid() && IsInBlock( aOldStt, nCol1,nRow1, nCol2,nRow2 ) )
[ + - ]
524 : : {
525 [ + - ]: 30 : pData->maStart.IncCol( nDx );
526 [ + - ]: 30 : pData->maStart.IncRow( nDy );
527 : 30 : bChange = sal_True;
528 : : }
529 [ + - ][ + - ]: 30 : if ( aOldEnd.IsValid() && IsInBlock( aOldEnd, nCol1,nRow1, nCol2,nRow2 ) )
[ + - ]
530 : : {
531 [ + - ]: 30 : pData->maEnd.IncCol( nDx );
532 [ + - ]: 30 : pData->maEnd.IncRow( nDy );
533 : 30 : bChange = sal_True;
534 : : }
535 [ + - ]: 30 : if (bChange)
536 : : {
537 [ + - ][ + - ]: 30 : if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() )
[ + + ][ + - ]
[ + - ][ + + ]
538 : 24 : pData->maStart.PutInOrder( pData->maEnd );
539 [ + - ][ + - ]: 30 : AddCalcUndo( new ScUndoObjData( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) );
[ + - ]
540 [ + - ]: 30 : RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
541 : : }
542 : : }
543 : : }
544 : : }
545 : :
546 : 65543 : void ScDrawLayer::SetPageSize( sal_uInt16 nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos )
547 : : {
548 : 65543 : SdrPage* pPage = GetPage(nPageNo);
549 [ + - ]: 65543 : if (pPage)
550 : : {
551 [ + + ]: 65543 : if ( rSize != pPage->GetSize() )
552 : : {
553 : 64231 : pPage->SetSize( rSize );
554 [ + - ]: 64231 : Broadcast( ScTabSizeChangedHint( static_cast<SCTAB>(nPageNo) ) ); // SetWorkArea() an den Views
555 : : }
556 : :
557 : : // Detektivlinien umsetzen (an neue Hoehen/Breiten anpassen)
558 : : // auch wenn Groesse gleich geblieben ist
559 : : // (einzelne Zeilen/Spalten koennen geaendert sein)
560 : :
561 [ + - ][ + + ]: 65543 : sal_Bool bNegativePage = pDoc && pDoc->IsNegativePage( static_cast<SCTAB>(nPageNo) );
562 : :
563 : 65543 : sal_uLong nCount = pPage->GetObjCount();
564 [ + + ]: 65654 : for ( sal_uLong i = 0; i < nCount; i++ )
565 : : {
566 : 111 : SdrObject* pObj = pPage->GetObj( i );
567 : 111 : ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
568 [ + + ]: 111 : if( pData )
569 : 97 : RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
570 : : }
571 : : }
572 : 65543 : }
573 : :
574 : : namespace
575 : : {
576 : : //Can't have a zero width dimension
577 : 88 : Rectangle lcl_makeSafeRectangle(const Rectangle &rNew)
578 : : {
579 : 88 : Rectangle aRect = rNew;
580 [ + + ]: 88 : if (aRect.Bottom() == aRect.Top())
581 : 3 : aRect.Bottom() = aRect.Top()+1;
582 [ - + ]: 88 : if (aRect.Right() == aRect.Left())
583 : 0 : aRect.Right() = aRect.Left()+1;
584 : 88 : return aRect;
585 : : }
586 : :
587 : 236 : Point lcl_calcAvailableDiff(ScDocument &rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const Point &aWantedDiff)
588 : : {
589 : 236 : Point aAvailableDiff(aWantedDiff);
590 : 236 : long nHeight = static_cast<long>(rDoc.GetRowHeight( nRow, nTab ) * HMM_PER_TWIPS);
591 : 236 : long nWidth = static_cast<long>(rDoc.GetColWidth( nCol, nTab ) * HMM_PER_TWIPS);
592 [ + + ]: 236 : if (aAvailableDiff.Y() > nHeight)
593 : 11 : aAvailableDiff.Y() = nHeight;
594 [ - + ]: 236 : if (aAvailableDiff.X() > nWidth)
595 : 0 : aAvailableDiff.X() = nWidth;
596 : 236 : return aAvailableDiff;
597 : : }
598 : :
599 : 0 : Rectangle lcl_UpdateCalcPoly(basegfx::B2DPolygon &rCalcPoly, int nWhichPoint, const Point &rPos)
600 : : {
601 [ # # ]: 0 : rCalcPoly.setB2DPoint(nWhichPoint, basegfx::B2DPoint(rPos.X(), rPos.Y()));
602 [ # # ]: 0 : basegfx::B2DRange aRange(basegfx::tools::getRange(rCalcPoly));
603 [ # # ][ # # ]: 0 : return Rectangle(static_cast<long>(aRange.getMinX()), static_cast<long>(aRange.getMinY()),
604 [ # # ][ # # ]: 0 : static_cast<long>(aRange.getMaxX()), static_cast<long>(aRange.getMaxY()));
[ # # ]
605 : : }
606 : : }
607 : :
608 : 127 : void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos )
609 : : {
610 : : OSL_ENSURE( pDoc, "ScDrawLayer::RecalcPos - missing document" );
611 [ - + ]: 127 : if( !pDoc )
612 : 0 : return;
613 : :
614 [ + + ]: 127 : if (rData.meType == ScDrawObjData::CellNote)
615 : : {
616 : : OSL_ENSURE( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
617 : : /* #i109372# On insert/remove rows/columns/cells: Updating the caption
618 : : position must not be done, if the cell containing the note has not
619 : : been moved yet in the document. The calling code now passes an
620 : : additional boolean stating if the cells are already moved. */
621 [ + - ]: 9 : if( bUpdateNoteCaptionPos )
622 : : /* When inside an undo action, there may be pending note captions
623 : : where cell note is already deleted (thus document cannot find
624 : : the note object anymore). The caption will be deleted later
625 : : with drawing undo. */
626 [ + + ]: 9 : if( ScPostIt* pNote = pDoc->GetNotes( rData.maStart.Tab() )->findByAddress( rData.maStart ) )
627 : 8 : pNote->UpdateCaptionPos( rData.maStart );
628 : 9 : return;
629 : : }
630 : :
631 : 118 : bool bValid1 = rData.maStart.IsValid();
632 : 118 : SCCOL nCol1 = rData.maStart.Col();
633 : 118 : SCROW nRow1 = rData.maStart.Row();
634 : 118 : SCTAB nTab1 = rData.maStart.Tab();
635 : 118 : bool bValid2 = rData.maEnd.IsValid();
636 : 118 : SCCOL nCol2 = rData.maEnd.Col();
637 : 118 : SCROW nRow2 = rData.maEnd.Row();
638 : 118 : SCTAB nTab2 = rData.maEnd.Tab();
639 : :
640 [ - + ]: 118 : if (rData.meType == ScDrawObjData::ValidationCircle)
641 : : {
642 : : // Validation circle for detective.
643 [ # # ]: 0 : rData.maLastRect = pObj->GetLogicRect();
644 : :
645 [ # # ][ # # ]: 0 : Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
646 [ # # ]: 0 : TwipsToMM( aPos.X() );
647 [ # # ]: 0 : TwipsToMM( aPos.Y() );
648 : :
649 : : // Berechnung und Werte wie in detfunc.cxx
650 : :
651 [ # # ]: 0 : Size aSize( (long)( TwipsToHmm( pDoc->GetColWidth( nCol1, nTab1) ) ),
652 [ # # ][ # # ]: 0 : (long)( TwipsToHmm( pDoc->GetRowHeight( nRow1, nTab1) ) ) );
[ # # ]
653 [ # # ]: 0 : Rectangle aRect( aPos, aSize );
654 : 0 : aRect.Left() -= 250;
655 : 0 : aRect.Right() += 250;
656 : 0 : aRect.Top() -= 70;
657 : 0 : aRect.Bottom() += 70;
658 [ # # ]: 0 : if ( bNegativePage )
659 [ # # ]: 0 : MirrorRectRTL( aRect );
660 : :
661 [ # # ][ # # ]: 0 : if ( pObj->GetLogicRect() != aRect )
[ # # ]
662 : : {
663 [ # # ]: 0 : if (bRecording)
664 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
665 : 0 : rData.maLastRect = lcl_makeSafeRectangle(aRect);
666 [ # # ]: 0 : pObj->SetLogicRect(rData.maLastRect);
667 : : }
668 : : }
669 [ - + ]: 118 : else if (rData.meType == ScDrawObjData::DetectiveArrow)
670 : : {
671 [ # # ]: 0 : rData.maLastRect = pObj->GetLogicRect();
672 [ # # ]: 0 : basegfx::B2DPolygon aCalcPoly;
673 [ # # ]: 0 : Point aOrigStartPos(pObj->GetPoint(0));
674 [ # # ]: 0 : Point aOrigEndPos(pObj->GetPoint(1));
675 [ # # ]: 0 : aCalcPoly.append(basegfx::B2DPoint(aOrigStartPos.X(), aOrigStartPos.Y()));
676 [ # # ]: 0 : aCalcPoly.append(basegfx::B2DPoint(aOrigEndPos.X(), aOrigEndPos.Y()));
677 : : //! nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden)
678 : :
679 : : SCCOL nLastCol;
680 : : SCROW nLastRow;
681 [ # # ]: 0 : if( bValid1 )
682 : : {
683 [ # # ][ # # ]: 0 : Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
684 [ # # ][ # # ]: 0 : if (!pDoc->ColHidden(nCol1, nTab1, NULL, &nLastCol))
685 [ # # ]: 0 : aPos.X() += pDoc->GetColWidth( nCol1, nTab1 ) / 4;
686 [ # # ][ # # ]: 0 : if (!pDoc->RowHidden(nRow1, nTab1, NULL, &nLastRow))
687 [ # # ]: 0 : aPos.Y() += pDoc->GetRowHeight( nRow1, nTab1 ) / 2;
688 [ # # ]: 0 : TwipsToMM( aPos.X() );
689 [ # # ]: 0 : TwipsToMM( aPos.Y() );
690 : 0 : Point aStartPos = aPos;
691 [ # # ]: 0 : if ( bNegativePage )
692 : 0 : aStartPos.X() = -aStartPos.X(); // don't modify aPos - used below
693 [ # # ][ # # ]: 0 : if ( pObj->GetPoint( 0 ) != aStartPos )
694 : : {
695 [ # # ]: 0 : if (bRecording)
696 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
697 : :
698 [ # # ]: 0 : rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos);
699 [ # # ]: 0 : pObj->SetPoint( aStartPos, 0 );
700 : : }
701 : :
702 [ # # ]: 0 : if( !bValid2 )
703 : : {
704 : 0 : Point aEndPos( aPos.X() + DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
705 [ # # ]: 0 : if (aEndPos.Y() < 0)
706 : 0 : aEndPos.Y() += (2 * DET_ARROW_OFFSET);
707 [ # # ]: 0 : if ( bNegativePage )
708 : 0 : aEndPos.X() = -aEndPos.X();
709 [ # # ][ # # ]: 0 : if ( pObj->GetPoint( 1 ) != aEndPos )
710 : : {
711 [ # # ]: 0 : if (bRecording)
712 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
713 : :
714 [ # # ]: 0 : rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos);
715 [ # # ]: 0 : pObj->SetPoint( aEndPos, 1 );
716 : : }
717 : : }
718 : : }
719 [ # # ]: 0 : if( bValid2 )
720 : : {
721 [ # # ][ # # ]: 0 : Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
722 [ # # ][ # # ]: 0 : if (!pDoc->ColHidden(nCol2, nTab2, NULL, &nLastCol))
723 [ # # ]: 0 : aPos.X() += pDoc->GetColWidth( nCol2, nTab2 ) / 4;
724 [ # # ][ # # ]: 0 : if (!pDoc->RowHidden(nRow2, nTab2, NULL, &nLastRow))
725 [ # # ]: 0 : aPos.Y() += pDoc->GetRowHeight( nRow2, nTab2 ) / 2;
726 [ # # ]: 0 : TwipsToMM( aPos.X() );
727 [ # # ]: 0 : TwipsToMM( aPos.Y() );
728 : 0 : Point aEndPos = aPos;
729 [ # # ]: 0 : if ( bNegativePage )
730 : 0 : aEndPos.X() = -aEndPos.X(); // don't modify aPos - used below
731 [ # # ][ # # ]: 0 : if ( pObj->GetPoint( 1 ) != aEndPos )
732 : : {
733 [ # # ]: 0 : if (bRecording)
734 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
735 : :
736 [ # # ]: 0 : rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos);
737 [ # # ]: 0 : pObj->SetPoint( aEndPos, 1 );
738 : : }
739 : :
740 [ # # ]: 0 : if( !bValid1 )
741 : : {
742 : 0 : Point aStartPos( aPos.X() - DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
743 [ # # ]: 0 : if (aStartPos.X() < 0)
744 : 0 : aStartPos.X() += (2 * DET_ARROW_OFFSET);
745 [ # # ]: 0 : if (aStartPos.Y() < 0)
746 : 0 : aStartPos.Y() += (2 * DET_ARROW_OFFSET);
747 [ # # ]: 0 : if ( bNegativePage )
748 : 0 : aStartPos.X() = -aStartPos.X();
749 [ # # ][ # # ]: 0 : if ( pObj->GetPoint( 0 ) != aStartPos )
750 : : {
751 [ # # ]: 0 : if (bRecording)
752 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
753 : :
754 [ # # ]: 0 : rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos);
755 [ # # ]: 0 : pObj->SetPoint( aStartPos, 0 );
756 : : }
757 : : }
758 [ # # ]: 0 : }
759 : : }
760 : : else
761 : : {
762 [ + - ][ + - ]: 118 : bool bCanResize = bValid2 && !pObj->IsResizeProtect();
[ + - ]
763 : :
764 : : //First time positioning, must be able to at least move it
765 [ + - ][ + + ]: 118 : if (rData.maLastRect.IsEmpty())
766 [ + - ]: 61 : rData.maLastRect = pObj->GetLogicRect();
767 : :
768 : : OSL_ENSURE( bValid1, "ScDrawLayer::RecalcPos - invalid start position" );
769 [ + - ][ + - ]: 118 : Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
770 [ + - ]: 118 : TwipsToMM( aPos.X() );
771 [ + - ]: 118 : TwipsToMM( aPos.Y() );
772 [ + - ]: 118 : aPos += lcl_calcAvailableDiff(*pDoc, nCol1, nRow1, nTab1, rData.maStartOffset);
773 : :
774 [ + - ]: 118 : if( bCanResize )
775 : : {
776 [ + - ][ + - ]: 118 : Point aEnd( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
777 [ + - ]: 118 : TwipsToMM( aEnd.X() );
778 [ + - ]: 118 : TwipsToMM( aEnd.Y() );
779 [ + - ]: 118 : aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset);
780 : :
781 [ + - ]: 118 : Rectangle aNew( aPos, aEnd );
782 [ - + ]: 118 : if ( bNegativePage )
783 [ # # ]: 0 : MirrorRectRTL( aNew );
784 [ + - ][ + - ]: 118 : if ( pObj->GetLogicRect() != aNew )
[ + + ]
785 : : {
786 [ + - ]: 88 : Rectangle aOld(pObj->GetLogicRect());
787 : :
788 [ - + ]: 88 : if (bRecording)
789 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
790 : 88 : rData.maLastRect = lcl_makeSafeRectangle(aNew);
791 [ + + ][ + - ]: 88 : if (pObj->IsPolyObj())
792 : : {
793 : : // Polyline objects need special treatment.
794 : 6 : Size aSizeMove(aNew.Left()-aOld.Left(), aNew.Top()-aOld.Top());
795 [ + - ]: 6 : pObj->NbcMove(aSizeMove);
796 : :
797 [ + - ][ + - ]: 6 : double fXFrac = static_cast<double>(aNew.GetWidth()) / static_cast<double>(aOld.GetWidth());
798 [ + - ][ + - ]: 6 : double fYFrac = static_cast<double>(aNew.GetHeight()) / static_cast<double>(aOld.GetHeight());
799 [ + - ][ + - ]: 6 : pObj->NbcResize(aNew.TopLeft(), Fraction(fXFrac), Fraction(fYFrac));
[ + - ]
800 : : }
801 : :
802 [ + - ]: 118 : pObj->SetLogicRect(rData.maLastRect);
803 : : }
804 : : }
805 : : else
806 : : {
807 [ # # ]: 0 : if ( bNegativePage )
808 [ # # ]: 0 : aPos.X() = -aPos.X() - rData.maLastRect.GetWidth();
809 [ # # ][ # # ]: 0 : if ( pObj->GetRelativePos() != aPos )
810 : : {
811 [ # # ]: 0 : if (bRecording)
812 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
813 : 0 : rData.maLastRect.SetPos( aPos );
814 [ # # ]: 0 : pObj->SetRelativePos( aPos );
815 : : }
816 : : }
817 : :
818 : : /*
819 : : * If we were not allowed resize the object, then the end cell anchor
820 : : * is possibly incorrect now, and if the object has no end-cell (e.g.
821 : : * missing in original .xml) we are also forced to generate one
822 : : */
823 [ + - ][ + - ]: 118 : bool bEndAnchorIsBad = !bValid2 || pObj->IsResizeProtect();
[ - + ]
824 [ - + ]: 118 : if (bEndAnchorIsBad)
825 [ # # ]: 127 : ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, *pDoc, nTab1);
826 : : }
827 : : }
828 : :
829 : 1515 : sal_Bool ScDrawLayer::GetPrintArea( ScRange& rRange, sal_Bool bSetHor, sal_Bool bSetVer ) const
830 : : {
831 : : OSL_ENSURE( pDoc, "ScDrawLayer::GetPrintArea without document" );
832 [ - + ]: 1515 : if ( !pDoc )
833 : 0 : return false;
834 : :
835 : 1515 : SCTAB nTab = rRange.aStart.Tab();
836 : : OSL_ENSURE( rRange.aEnd.Tab() == nTab, "GetPrintArea: Tab unterschiedlich" );
837 : :
838 [ + - ]: 1515 : sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
839 : :
840 : 1515 : sal_Bool bAny = false;
841 : 1515 : long nEndX = 0;
842 : 1515 : long nEndY = 0;
843 : 1515 : long nStartX = LONG_MAX;
844 : 1515 : long nStartY = LONG_MAX;
845 : :
846 : : // Grenzen ausrechnen
847 : :
848 [ + + ]: 1515 : if (!bSetHor)
849 : : {
850 : 96 : nStartX = 0;
851 : 96 : SCCOL nStartCol = rRange.aStart.Col();
852 : : SCCOL i;
853 [ - + ]: 96 : for (i=0; i<nStartCol; i++)
854 [ # # ]: 0 : nStartX +=pDoc->GetColWidth(i,nTab);
855 : 96 : nEndX = nStartX;
856 : 96 : SCCOL nEndCol = rRange.aEnd.Col();
857 [ + + ]: 828 : for (i=nStartCol; i<=nEndCol; i++)
858 [ + - ]: 732 : nEndX += pDoc->GetColWidth(i,nTab);
859 [ + - ]: 96 : nStartX = TwipsToHmm( nStartX );
860 [ + - ]: 96 : nEndX = TwipsToHmm( nEndX );
861 : : }
862 [ - + ]: 1515 : if (!bSetVer)
863 : : {
864 [ # # ]: 0 : nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab);
865 : : nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(),
866 [ # # ]: 0 : rRange.aEnd.Row(), nTab);
867 [ # # ]: 0 : nStartY = TwipsToHmm( nStartY );
868 [ # # ]: 0 : nEndY = TwipsToHmm( nEndY );
869 : : }
870 : :
871 [ - + ]: 1515 : if ( bNegativePage )
872 : : {
873 : 0 : nStartX = -nStartX; // positions are negative, swap start/end so the same comparisons work
874 : 0 : nEndX = -nEndX;
875 : 0 : ::std::swap( nStartX, nEndX );
876 : : }
877 : :
878 [ + - ]: 1515 : const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
879 : : OSL_ENSURE(pPage,"Page nicht gefunden");
880 [ + - ]: 1515 : if (pPage)
881 : : {
882 [ + - ]: 1515 : SdrObjListIter aIter( *pPage, IM_FLAT );
883 [ + - ]: 1515 : SdrObject* pObject = aIter.Next();
884 [ + + ]: 1621 : while (pObject)
885 : : {
886 : : //! Flags (ausgeblendet?) testen
887 : :
888 [ + - ]: 106 : Rectangle aObjRect = pObject->GetCurrentBoundRect();
889 : 106 : sal_Bool bFit = sal_True;
890 [ - + ][ # # ]: 106 : if ( !bSetHor && ( aObjRect.Right() < nStartX || aObjRect.Left() > nEndX ) )
[ # # ][ - + ]
891 : 0 : bFit = false;
892 [ - + ][ # # ]: 106 : if ( !bSetVer && ( aObjRect.Bottom() < nStartY || aObjRect.Top() > nEndY ) )
[ # # ][ - + ]
893 : 0 : bFit = false;
894 : : // #i104716# don't include hidden note objects
895 [ + - ][ + - ]: 106 : if ( bFit && pObject->GetLayer() != SC_LAYER_HIDDEN )
[ + - ][ + - ]
896 : : {
897 [ + - ]: 106 : if (bSetHor)
898 : : {
899 [ + - ]: 106 : if (aObjRect.Left() < nStartX) nStartX = aObjRect.Left();
900 [ + + ]: 106 : if (aObjRect.Right() > nEndX) nEndX = aObjRect.Right();
901 : : }
902 [ + - ]: 106 : if (bSetVer)
903 : : {
904 [ + + ]: 106 : if (aObjRect.Top() < nStartY) nStartY = aObjRect.Top();
905 [ + + ]: 106 : if (aObjRect.Bottom() > nEndY) nEndY = aObjRect.Bottom();
906 : : }
907 : 106 : bAny = sal_True;
908 : : }
909 : :
910 [ + - ]: 106 : pObject = aIter.Next();
911 : 1515 : }
912 : : }
913 : :
914 [ - + ]: 1515 : if ( bNegativePage )
915 : : {
916 : 0 : nStartX = -nStartX; // reverse transformation, so the same cell address calculation works
917 : 0 : nEndX = -nEndX;
918 : 0 : ::std::swap( nStartX, nEndX );
919 : : }
920 : :
921 [ + + ]: 1515 : if (bAny)
922 : : {
923 : : OSL_ENSURE( nStartX<=nEndX && nStartY<=nEndY, "Start/End falsch in ScDrawLayer::GetPrintArea" );
924 : :
925 [ + - ]: 98 : if (bSetHor)
926 : : {
927 [ + - ]: 98 : nStartX = HmmToTwips( nStartX );
928 [ + - ]: 98 : nEndX = HmmToTwips( nEndX );
929 : : long nWidth;
930 : : SCCOL i;
931 : :
932 : 98 : nWidth = 0;
933 [ + - ][ + + ]: 220 : for (i=0; i<=MAXCOL && nWidth<=nStartX; i++)
[ + + ]
934 [ + - ]: 122 : nWidth += pDoc->GetColWidth(i,nTab);
935 [ + + ]: 98 : rRange.aStart.SetCol( i>0 ? (i-1) : 0 );
936 : :
937 : 98 : nWidth = 0;
938 [ + - ][ + + ]: 382 : for (i=0; i<=MAXCOL && nWidth<=nEndX; i++) //! bei Start anfangen
[ + + ]
939 [ + - ]: 284 : nWidth += pDoc->GetColWidth(i,nTab);
940 [ + - ]: 98 : rRange.aEnd.SetCol( i>0 ? (i-1) : 0 );
941 : : }
942 : :
943 [ + - ]: 98 : if (bSetVer)
944 : : {
945 [ + - ]: 98 : nStartY = HmmToTwips( nStartY );
946 [ + - ]: 98 : nEndY = HmmToTwips( nEndY );
947 [ + - ]: 98 : SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY);
948 [ + + ]: 98 : rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0);
949 [ + - ]: 98 : nRow = pDoc->GetRowForHeight( nTab, nEndY);
950 : : rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW :
951 [ + - ][ + - ]: 98 : (nRow>0 ? (nRow-1) : 0));
952 : : }
953 : : }
954 : : else
955 : : {
956 [ + + ]: 1417 : if (bSetHor)
957 : : {
958 : 1321 : rRange.aStart.SetCol(0);
959 : 1321 : rRange.aEnd.SetCol(0);
960 : : }
961 [ + - ]: 1417 : if (bSetVer)
962 : : {
963 : 1417 : rRange.aStart.SetRow(0);
964 : 1417 : rRange.aEnd.SetRow(0);
965 : : }
966 : : }
967 : 1515 : return bAny;
968 : : }
969 : :
970 : 116 : void ScDrawLayer::AddCalcUndo( SdrUndoAction* pUndo )
971 : : {
972 [ + + ]: 116 : if (bRecording)
973 : : {
974 [ + + ]: 86 : if (!pUndoGroup)
975 [ + - ]: 74 : pUndoGroup = new SdrUndoGroup(*this);
976 : :
977 : 86 : pUndoGroup->AddAction( pUndo );
978 : : }
979 : : else
980 [ + - ]: 30 : delete pUndo;
981 : 116 : }
982 : :
983 : 124 : void ScDrawLayer::BeginCalcUndo()
984 : : {
985 [ - + ]: 124 : DELETEZ(pUndoGroup);
986 : 124 : bRecording = sal_True;
987 : 124 : }
988 : :
989 : 176 : SdrUndoGroup* ScDrawLayer::GetCalcUndo()
990 : : {
991 : 176 : SdrUndoGroup* pRet = pUndoGroup;
992 : 176 : pUndoGroup = NULL;
993 : 176 : bRecording = false;
994 : 176 : return pRet;
995 : : }
996 : :
997 : 28 : void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
998 : : SCsCOL nDx,SCsROW nDy, sal_Bool bInsDel, bool bUpdateNoteCaptionPos )
999 : : {
1000 : : OSL_ENSURE( pDoc, "ScDrawLayer::MoveArea without document" );
1001 [ + - ]: 28 : if ( !pDoc )
1002 : : return;
1003 : :
1004 [ + - ]: 28 : if (!bAdjustEnabled)
1005 : : return;
1006 : :
1007 [ + - ]: 28 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1008 : : OSL_ENSURE(pPage,"Page not found");
1009 [ + - ]: 28 : if (!pPage)
1010 : : return;
1011 : :
1012 : : // for an empty page, there's no need to calculate the row heights
1013 [ + - ][ + + ]: 28 : if (!pPage->GetObjCount())
1014 : : return;
1015 : :
1016 [ + - ]: 12 : sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1017 : :
1018 [ + - ]: 12 : Rectangle aRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1019 [ + - ]: 12 : lcl_ReverseTwipsToMM( aRect );
1020 : : //! use twips directly?
1021 : :
1022 : 12 : Point aMove;
1023 : :
1024 [ - + ]: 12 : if (nDx > 0)
1025 [ # # ]: 0 : for (SCsCOL s=0; s<nDx; s++)
1026 [ # # ]: 0 : aMove.X() += pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
1027 : : else
1028 [ - + ]: 12 : for (SCsCOL s=-1; s>=nDx; s--)
1029 [ # # ]: 0 : aMove.X() -= pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
1030 [ + + ]: 12 : if (nDy > 0)
1031 [ + - ]: 6 : aMove.Y() += pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab);
1032 : : else
1033 [ + - ]: 6 : aMove.Y() -= pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab);
1034 : :
1035 [ - + ]: 12 : if ( bNegativePage )
1036 : 0 : aMove.X() = -aMove.X();
1037 : :
1038 : 12 : Point aTopLeft = aRect.TopLeft(); // Anfang beim Verkleinern
1039 [ + - ]: 12 : if (bInsDel)
1040 : : {
1041 [ - + ][ # # ]: 12 : if ( aMove.X() != 0 && nDx < 0 ) // nDx counts cells, sign is independent of RTL
[ - + ]
1042 : 0 : aTopLeft.X() += aMove.X();
1043 [ + + ]: 12 : if ( aMove.Y() < 0 )
1044 : 6 : aTopLeft.Y() += aMove.Y();
1045 : : }
1046 : :
1047 : : //
1048 : : // Detektiv-Pfeile: Zellpositionen anpassen
1049 : : //
1050 : :
1051 [ + - ]: 28 : MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, bUpdateNoteCaptionPos );
1052 : : }
1053 : :
1054 : 1769 : sal_Bool ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow )
1055 : : {
1056 : : OSL_ENSURE( pDoc, "ScDrawLayer::HasObjectsInRows without document" );
1057 [ - + ]: 1769 : if ( !pDoc )
1058 : 0 : return false;
1059 : :
1060 [ + - ]: 1769 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1061 : : OSL_ENSURE(pPage,"Page not found");
1062 [ - + ]: 1769 : if (!pPage)
1063 : 0 : return sal_False;
1064 : :
1065 : : // for an empty page, there's no need to calculate the row heights
1066 [ + - ][ + + ]: 1769 : if (!pPage->GetObjCount())
1067 : 1752 : return sal_False;
1068 : :
1069 [ + - ]: 17 : Rectangle aTestRect;
1070 : :
1071 [ + - ]: 17 : aTestRect.Top() += pDoc->GetRowHeight( 0, nStartRow-1, nTab);
1072 : :
1073 [ - + ]: 17 : if (nEndRow==MAXROW)
1074 : 0 : aTestRect.Bottom() = MAXMM;
1075 : : else
1076 : : {
1077 : 17 : aTestRect.Bottom() = aTestRect.Top();
1078 [ + - ]: 17 : aTestRect.Bottom() += pDoc->GetRowHeight( nStartRow, nEndRow, nTab);
1079 [ + - ]: 17 : TwipsToMM( aTestRect.Bottom() );
1080 : : }
1081 : :
1082 [ + - ]: 17 : TwipsToMM( aTestRect.Top() );
1083 : :
1084 : 17 : aTestRect.Left() = 0;
1085 : 17 : aTestRect.Right() = MAXMM;
1086 : :
1087 [ + - ]: 17 : sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1088 [ - + ]: 17 : if ( bNegativePage )
1089 [ # # ]: 0 : MirrorRectRTL( aTestRect );
1090 : :
1091 : 17 : sal_Bool bFound = false;
1092 : :
1093 [ + - ]: 17 : Rectangle aObjRect;
1094 [ + - ]: 17 : SdrObjListIter aIter( *pPage );
1095 [ + - ]: 17 : SdrObject* pObject = aIter.Next();
1096 [ + + ][ + - ]: 35 : while ( pObject && !bFound )
[ + + ]
1097 : : {
1098 [ + - ]: 18 : aObjRect = pObject->GetSnapRect(); //! GetLogicRect ?
1099 [ + - ][ + + ]: 18 : if (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft()))
[ + - ][ + - ]
[ - + ][ + + ]
[ + - ][ + +
# # # # ]
1100 : 9 : bFound = true;
1101 : :
1102 [ + - ]: 18 : pObject = aIter.Next();
1103 : : }
1104 : :
1105 : 1769 : return bFound;
1106 : : }
1107 : :
1108 : 1 : void ScDrawLayer::DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
1109 : : SCCOL nCol2,SCROW nRow2 )
1110 : : {
1111 : : OSL_ENSURE( pDoc, "ScDrawLayer::DeleteObjectsInArea without document" );
1112 [ - + ]: 1 : if ( !pDoc )
1113 : 0 : return;
1114 : :
1115 : 1 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1116 : : OSL_ENSURE(pPage,"Page ?");
1117 [ - + ]: 1 : if (!pPage)
1118 : 0 : return;
1119 : :
1120 : 1 : pPage->RecalcObjOrdNums();
1121 : :
1122 : 1 : sal_uLong nObjCount = pPage->GetObjCount();
1123 [ - + ]: 1 : if (nObjCount)
1124 : : {
1125 : 0 : long nDelCount = 0;
1126 [ # # ]: 0 : Rectangle aDelRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1127 : :
1128 [ # # ]: 0 : SdrObject** ppObj = new SdrObject*[nObjCount];
1129 : :
1130 [ # # ]: 0 : SdrObjListIter aIter( *pPage, IM_FLAT );
1131 [ # # ]: 0 : SdrObject* pObject = aIter.Next();
1132 [ # # ]: 0 : while (pObject)
1133 : : {
1134 : : // do not delete note caption, they are always handled by the cell note
1135 : : // TODO: detective objects are still deleted, is this desired?
1136 [ # # ][ # # ]: 0 : if (!IsNoteCaption( pObject ))
1137 : : {
1138 [ # # ]: 0 : Rectangle aObjRect = pObject->GetCurrentBoundRect();
1139 [ # # ][ # # ]: 0 : if ( aDelRect.IsInside( aObjRect ) )
1140 : 0 : ppObj[nDelCount++] = pObject;
1141 : : }
1142 : :
1143 [ # # ]: 0 : pObject = aIter.Next();
1144 : : }
1145 : :
1146 : : long i;
1147 [ # # ]: 0 : if (bRecording)
1148 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
1149 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
[ # # ]
1150 : :
1151 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
1152 [ # # ][ # # ]: 0 : pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1153 : :
1154 [ # # ]: 1 : delete[] ppObj;
1155 : : }
1156 : : }
1157 : :
1158 : 0 : void ScDrawLayer::DeleteObjectsInSelection( const ScMarkData& rMark )
1159 : : {
1160 : : OSL_ENSURE( pDoc, "ScDrawLayer::DeleteObjectsInSelection without document" );
1161 [ # # ]: 0 : if ( !pDoc )
1162 : : return;
1163 : :
1164 [ # # ]: 0 : if ( !rMark.IsMultiMarked() )
1165 : : return;
1166 : :
1167 : 0 : ScRange aMarkRange;
1168 [ # # ]: 0 : rMark.GetMultiMarkArea( aMarkRange );
1169 : :
1170 [ # # ]: 0 : SCTAB nTabCount = pDoc->GetTableCount();
1171 [ # # ][ # # ]: 0 : ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
1172 [ # # ][ # # ]: 0 : for (; itr != itrEnd && *itr < nTabCount; ++itr)
[ # # ][ # # ]
[ # # ][ # # ]
1173 : : {
1174 [ # # ]: 0 : SCTAB nTab = *itr;
1175 [ # # ]: 0 : SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1176 [ # # ]: 0 : if (pPage)
1177 : : {
1178 [ # # ]: 0 : pPage->RecalcObjOrdNums();
1179 [ # # ]: 0 : sal_uLong nObjCount = pPage->GetObjCount();
1180 [ # # ]: 0 : if (nObjCount)
1181 : : {
1182 : 0 : long nDelCount = 0;
1183 : : // Rechteck um die ganze Selektion
1184 : : Rectangle aMarkBound = pDoc->GetMMRect(
1185 : 0 : aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
1186 [ # # ]: 0 : aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab );
1187 : :
1188 [ # # ]: 0 : SdrObject** ppObj = new SdrObject*[nObjCount];
1189 : :
1190 [ # # ]: 0 : SdrObjListIter aIter( *pPage, IM_FLAT );
1191 [ # # ]: 0 : SdrObject* pObject = aIter.Next();
1192 [ # # ]: 0 : while (pObject)
1193 : : {
1194 : : // do not delete note caption, they are always handled by the cell note
1195 : : // TODO: detective objects are still deleted, is this desired?
1196 [ # # ][ # # ]: 0 : if (!IsNoteCaption( pObject ))
1197 : : {
1198 [ # # ]: 0 : Rectangle aObjRect = pObject->GetCurrentBoundRect();
1199 [ # # ][ # # ]: 0 : if ( aMarkBound.IsInside( aObjRect ) )
1200 : : {
1201 [ # # ]: 0 : ScRange aRange = pDoc->GetRange( nTab, aObjRect );
1202 [ # # ][ # # ]: 0 : if (rMark.IsAllMarked(aRange))
1203 : 0 : ppObj[nDelCount++] = pObject;
1204 : : }
1205 : : }
1206 : :
1207 [ # # ]: 0 : pObject = aIter.Next();
1208 : : }
1209 : :
1210 : : // Objekte loeschen (rueckwaerts)
1211 : :
1212 : : long i;
1213 [ # # ]: 0 : if (bRecording)
1214 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
1215 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
[ # # ]
1216 : :
1217 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
1218 [ # # ][ # # ]: 0 : pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1219 : :
1220 [ # # ]: 0 : delete[] ppObj;
1221 : : }
1222 : : }
1223 : : else
1224 : : {
1225 : : OSL_FAIL("pPage?");
1226 : : }
1227 : : }
1228 : : }
1229 : :
1230 : 0 : void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& rRange )
1231 : : {
1232 : : // copy everything in the specified range into the same page (sheet) in the clipboard doc
1233 : :
1234 : 0 : SdrPage* pSrcPage = GetPage(static_cast<sal_uInt16>(nTab));
1235 [ # # ]: 0 : if (pSrcPage)
1236 : : {
1237 : 0 : ScDrawLayer* pDestModel = NULL;
1238 : 0 : SdrPage* pDestPage = NULL;
1239 : :
1240 [ # # ]: 0 : SdrObjListIter aIter( *pSrcPage, IM_FLAT );
1241 [ # # ]: 0 : SdrObject* pOldObject = aIter.Next();
1242 [ # # ]: 0 : while (pOldObject)
1243 : : {
1244 [ # # ]: 0 : Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1245 : : // do not copy internal objects (detective) and note captions
1246 [ # # ][ # # ]: 0 : if ( rRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1247 : : {
1248 [ # # ]: 0 : if ( !pDestModel )
1249 : : {
1250 [ # # ]: 0 : pDestModel = pClipDoc->GetDrawLayer(); // does the document already have a drawing layer?
1251 [ # # ]: 0 : if ( !pDestModel )
1252 : : {
1253 : : // allocate drawing layer in clipboard document only if there are objects to copy
1254 : :
1255 [ # # ]: 0 : pClipDoc->InitDrawLayer(); //! create contiguous pages
1256 [ # # ]: 0 : pDestModel = pClipDoc->GetDrawLayer();
1257 : : }
1258 [ # # ]: 0 : if (pDestModel)
1259 [ # # ]: 0 : pDestPage = pDestModel->GetPage( static_cast<sal_uInt16>(nTab) );
1260 : : }
1261 : :
1262 : : OSL_ENSURE( pDestPage, "no page" );
1263 [ # # ]: 0 : if (pDestPage)
1264 : : {
1265 [ # # ]: 0 : SdrObject* pNewObject = pOldObject->Clone();
1266 [ # # ]: 0 : pNewObject->SetModel(pDestModel);
1267 [ # # ]: 0 : pNewObject->SetPage(pDestPage);
1268 : :
1269 [ # # ]: 0 : uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) );
1270 [ # # ]: 0 : if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise
1271 [ # # ]: 0 : pNewObject->NbcMove(Size(0,0));
1272 [ # # ]: 0 : pDestPage->InsertObject( pNewObject );
1273 : :
1274 : : // no undo needed in clipboard document
1275 : : // charts are not updated
1276 : : }
1277 : : }
1278 : :
1279 [ # # ]: 0 : pOldObject = aIter.Next();
1280 : 0 : }
1281 : : }
1282 : 0 : }
1283 : :
1284 : 0 : sal_Bool lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange )
1285 : : {
1286 : : // check if every range of rRangesVector is completely in rClipRange
1287 : :
1288 : 0 : ::std::vector< ScRangeList >::const_iterator aIt = rRangesVector.begin();
1289 [ # # ][ # # ]: 0 : for( ;aIt!=rRangesVector.end(); ++aIt )
[ # # ]
1290 : : {
1291 [ # # ]: 0 : const ScRangeList& rRanges = *aIt;
1292 [ # # ][ # # ]: 0 : for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
1293 : : {
1294 [ # # ]: 0 : ScRange aRange = *rRanges[ i ];
1295 [ # # ]: 0 : if ( !rClipRange.In( aRange ) )
1296 : : {
1297 : 0 : return false; // at least one range is not valid
1298 : : }
1299 : : }
1300 : : }
1301 : :
1302 : 0 : return sal_True; // everything is fine
1303 : : }
1304 : :
1305 : 0 : sal_Bool lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos )
1306 : : {
1307 : 0 : sal_Bool bChanged = false;
1308 : :
1309 : 0 : ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin();
1310 [ # # ][ # # ]: 0 : for( ;aIt!=rRangesVector.end(); ++aIt )
[ # # ]
1311 : : {
1312 [ # # ]: 0 : ScRangeList& rRanges = *aIt;
1313 [ # # ][ # # ]: 0 : for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
1314 : : {
1315 [ # # ]: 0 : ScRange* pRange = rRanges[ i ];
1316 [ # # ]: 0 : if ( rSourceRange.In( *pRange ) )
1317 : : {
1318 : 0 : SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col();
1319 : 0 : SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row();
1320 : 0 : SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab();
1321 [ # # ]: 0 : pRange->Move( nDiffX, nDiffY, nDiffZ );
1322 : 0 : bChanged = sal_True;
1323 : : }
1324 : : }
1325 : : }
1326 : :
1327 : 0 : return bChanged;
1328 : : }
1329 : :
1330 : 0 : void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const Rectangle& rSourceRange,
1331 : : const ScAddress& rDestPos, const Rectangle& rDestRange )
1332 : : {
1333 : : OSL_ENSURE( pDoc, "ScDrawLayer::CopyFromClip without document" );
1334 [ # # ]: 0 : if ( !pDoc )
1335 : : return;
1336 : :
1337 [ # # ]: 0 : if (!pClipModel)
1338 : : return;
1339 : :
1340 [ # # ]: 0 : if (bDrawIsInUndo) //! can this happen?
1341 : : {
1342 : : OSL_FAIL("CopyFromClip, bDrawIsInUndo");
1343 : : return;
1344 : : }
1345 : :
1346 : 0 : sal_Bool bMirrorObj = ( rSourceRange.Left() < 0 && rSourceRange.Right() < 0 &&
1347 : 0 : rDestRange.Left() > 0 && rDestRange.Right() > 0 ) ||
1348 : 0 : ( rSourceRange.Left() > 0 && rSourceRange.Right() > 0 &&
1349 [ # # ][ # # ]: 0 : rDestRange.Left() < 0 && rDestRange.Right() < 0 );
[ # # # #
# # # # #
# # # ]
1350 : 0 : Rectangle aMirroredSource = rSourceRange;
1351 [ # # ]: 0 : if ( bMirrorObj )
1352 [ # # ]: 0 : MirrorRectRTL( aMirroredSource );
1353 : :
1354 : 0 : SCTAB nDestTab = rDestPos.Tab();
1355 : :
1356 [ # # ]: 0 : SdrPage* pSrcPage = pClipModel->GetPage(static_cast<sal_uInt16>(nSourceTab));
1357 [ # # ]: 0 : SdrPage* pDestPage = GetPage(static_cast<sal_uInt16>(nDestTab));
1358 : : OSL_ENSURE( pSrcPage && pDestPage, "draw page missing" );
1359 [ # # ][ # # ]: 0 : if ( !pSrcPage || !pDestPage )
1360 : : return;
1361 : :
1362 [ # # ]: 0 : SdrObjListIter aIter( *pSrcPage, IM_FLAT );
1363 [ # # ]: 0 : SdrObject* pOldObject = aIter.Next();
1364 : :
1365 : 0 : ScDocument* pClipDoc = pClipModel->GetDocument();
1366 : : // a clipboard document and its source share the same document item pool,
1367 : : // so the pointers can be compared to see if this is copy&paste within
1368 : : // the same document
1369 [ # # ][ # # ]: 0 : sal_Bool bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool();
[ # # ][ # # ]
[ # # ]
1370 [ # # ][ # # ]: 0 : sal_Bool bDestClip = pDoc && pDoc->IsClipboard();
1371 : :
1372 : : //#i110034# charts need correct sheet names for xml range conversion during load
1373 : : //so the target sheet name is temporarily renamed (if we have any SdrObjects)
1374 : 0 : rtl::OUString aDestTabName;
1375 : 0 : sal_Bool bRestoreDestTabName = false;
1376 [ # # ][ # # ]: 0 : if( pOldObject && !bSameDoc && !bDestClip )
[ # # ]
1377 : : {
1378 [ # # ][ # # ]: 0 : if( pDoc && pClipDoc )
1379 : : {
1380 : 0 : rtl::OUString aSourceTabName;
1381 [ # # ][ # # ]: 0 : if( pClipDoc->GetName( nSourceTab, aSourceTabName )
[ # # ][ # # ]
1382 [ # # ]: 0 : && pDoc->GetName( nDestTab, aDestTabName ) )
1383 : : {
1384 [ # # ][ # # ]: 0 : if( !aSourceTabName.equals(aDestTabName) &&
[ # # ]
1385 [ # # ]: 0 : pDoc->ValidNewTabName(aSourceTabName) )
1386 : : {
1387 [ # # ]: 0 : bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //sal_Bool bUpdateRef = sal_True, sal_Bool bExternalDocument = sal_False
1388 : : }
1389 : 0 : }
1390 : : }
1391 : : }
1392 : :
1393 : : // first mirror, then move
1394 : 0 : Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() );
1395 : :
1396 [ # # ]: 0 : long nDestWidth = rDestRange.GetWidth();
1397 [ # # ]: 0 : long nDestHeight = rDestRange.GetHeight();
1398 [ # # ]: 0 : long nSourceWidth = rSourceRange.GetWidth();
1399 [ # # ]: 0 : long nSourceHeight = rSourceRange.GetHeight();
1400 : :
1401 : 0 : long nWidthDiff = nDestWidth - nSourceWidth;
1402 : 0 : long nHeightDiff = nDestHeight - nSourceHeight;
1403 : :
1404 [ # # ]: 0 : Fraction aHorFract(1,1);
1405 [ # # ]: 0 : Fraction aVerFract(1,1);
1406 : 0 : sal_Bool bResize = false;
1407 : : // sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
1408 : : // don't resize to empty size when pasting into hidden columns or rows
1409 [ # # ][ # # ]: 0 : if ( Abs(nWidthDiff) > 1 && nDestWidth > 1 && nSourceWidth > 1 )
[ # # ][ # # ]
1410 : : {
1411 [ # # ][ # # ]: 0 : aHorFract = Fraction( nDestWidth, nSourceWidth );
1412 : 0 : bResize = sal_True;
1413 : : }
1414 [ # # ][ # # ]: 0 : if ( Abs(nHeightDiff) > 1 && nDestHeight > 1 && nSourceHeight > 1 )
[ # # ][ # # ]
1415 : : {
1416 [ # # ][ # # ]: 0 : aVerFract = Fraction( nDestHeight, nSourceHeight );
1417 : 0 : bResize = sal_True;
1418 : : }
1419 : 0 : Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving)
1420 : :
1421 [ # # ]: 0 : while (pOldObject)
1422 : : {
1423 [ # # ]: 0 : Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1424 : : // do not copy internal objects (detective) and note captions
1425 [ # # ][ # # ]: 0 : if ( rSourceRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1426 : : {
1427 [ # # ]: 0 : SdrObject* pNewObject = pOldObject->Clone();
1428 [ # # ]: 0 : pNewObject->SetModel(this);
1429 [ # # ]: 0 : pNewObject->SetPage(pDestPage);
1430 : :
1431 [ # # ]: 0 : if ( bMirrorObj )
1432 [ # # ]: 0 : MirrorRTL( pNewObject ); // first mirror, then move
1433 : :
1434 [ # # ]: 0 : pNewObject->NbcMove( aMove );
1435 [ # # ]: 0 : if ( bResize )
1436 [ # # ]: 0 : pNewObject->NbcResize( aRefPos, aHorFract, aVerFract );
1437 : :
1438 [ # # ]: 0 : pDestPage->InsertObject( pNewObject );
1439 [ # # ]: 0 : if (bRecording)
1440 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
[ # # ]
1441 : :
1442 : : //#i110034# handle chart data references (after InsertObject)
1443 : :
1444 [ # # ][ # # ]: 0 : if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 )
1445 : : {
1446 [ # # ]: 0 : uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pNewObject)->GetObjRef();
1447 [ # # ]: 0 : uno::Reference< embed::XClassifiedObject > xClassified( xIPObj, uno::UNO_QUERY );
1448 [ # # ]: 0 : SvGlobalName aObjectClassName;
1449 [ # # ]: 0 : if ( xClassified.is() )
1450 : : {
1451 : : try {
1452 [ # # ][ # # ]: 0 : aObjectClassName = SvGlobalName( xClassified->getClassID() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1453 [ # # ]: 0 : } catch( uno::Exception& )
1454 : : {
1455 : : // TODO: handle error?
1456 : : }
1457 : : }
1458 : :
1459 [ # # ][ # # ]: 0 : if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) )
[ # # ][ # # ]
1460 : : {
1461 [ # # ]: 0 : uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) );
1462 [ # # ][ # # ]: 0 : if( xNewChart.is() && !xNewChart->hasInternalDataProvider() )
[ # # ][ # # ]
[ # # ]
1463 : : {
1464 [ # # ]: 0 : String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName();
1465 [ # # ]: 0 : ::std::vector< ScRangeList > aRangesVector;
1466 [ # # ][ # # ]: 0 : pDoc->GetChartRanges( aChartName, aRangesVector, pDoc );
1467 [ # # ]: 0 : if( !aRangesVector.empty() )
1468 : : {
1469 : 0 : sal_Bool bInSourceRange = false;
1470 : 0 : ScRange aClipRange;
1471 [ # # ]: 0 : if ( pClipDoc )
1472 : : {
1473 : : SCCOL nClipStartX;
1474 : : SCROW nClipStartY;
1475 : : SCCOL nClipEndX;
1476 : : SCROW nClipEndY;
1477 [ # # ]: 0 : pClipDoc->GetClipStart( nClipStartX, nClipStartY );
1478 [ # # ]: 0 : pClipDoc->GetClipArea( nClipEndX, nClipEndY, sal_True );
1479 : 0 : nClipEndX = nClipEndX + nClipStartX;
1480 : 0 : nClipEndY += nClipStartY; // GetClipArea returns the difference
1481 : :
1482 [ # # ]: 0 : SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab;
1483 : : aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab,
1484 : 0 : nClipEndX, nClipEndY, nClipTab );
1485 : :
1486 [ # # ]: 0 : bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange );
1487 : : }
1488 : :
1489 : : // always lose references when pasting into a clipboard document (transpose)
1490 [ # # ][ # # ]: 0 : if ( ( bInSourceRange || bSameDoc ) && !bDestClip )
[ # # ]
1491 : : {
1492 [ # # ]: 0 : if ( bInSourceRange )
1493 : : {
1494 [ # # ]: 0 : if ( rDestPos != aClipRange.aStart )
1495 : : {
1496 : : // update the data ranges to the new (copied) position
1497 [ # # ][ # # ]: 0 : if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) )
1498 [ # # ][ # # ]: 0 : pDoc->SetChartRanges( aChartName, aRangesVector );
1499 : : }
1500 : : }
1501 : : else
1502 : : {
1503 : : // leave the ranges unchanged
1504 : : }
1505 : : }
1506 : : else
1507 : : {
1508 : : // pasting into a new document without the complete source data
1509 : : // -> break connection to source data and switch to own data
1510 : :
1511 [ # # ][ # # ]: 0 : uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY );
1512 [ # # ]: 0 : uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY );
1513 [ # # ][ # # ]: 0 : if( xOldChartDoc.is() && xNewChartDoc.is() )
[ # # ]
1514 [ # # ][ # # ]: 0 : xNewChartDoc->attachData( xOldChartDoc->getData() );
[ # # ][ # # ]
1515 : :
1516 : : // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
1517 : : }
1518 [ # # ]: 0 : }
1519 : 0 : }
1520 [ # # ]: 0 : }
1521 : : }
1522 : : }
1523 : :
1524 [ # # ]: 0 : pOldObject = aIter.Next();
1525 : : }
1526 : :
1527 [ # # ]: 0 : if( bRestoreDestTabName )
1528 [ # # ]: 0 : pDoc->RenameTab( nDestTab, aDestTabName );
1529 : : }
1530 : :
1531 : 4 : void ScDrawLayer::MirrorRTL( SdrObject* pObj )
1532 : : {
1533 : 4 : sal_uInt16 nIdent = pObj->GetObjIdentifier();
1534 : :
1535 : : // don't mirror OLE or graphics, otherwise ask the object
1536 : : // if it can be mirrored
1537 [ + - ][ + - ]: 4 : sal_Bool bCanMirror = ( nIdent != OBJ_GRAF && nIdent != OBJ_OLE2 );
1538 [ + - ]: 4 : if (bCanMirror)
1539 : : {
1540 [ + - ]: 4 : SdrObjTransformInfoRec aInfo;
1541 [ + - ]: 4 : pObj->TakeObjInfo( aInfo );
1542 : 4 : bCanMirror = aInfo.bMirror90Allowed;
1543 : : }
1544 : :
1545 [ + - ]: 4 : if (bCanMirror)
1546 : : {
1547 : 4 : Point aRef1( 0, 0 );
1548 : 4 : Point aRef2( 0, 1 );
1549 [ - + ]: 4 : if (bRecording)
1550 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoGeoObj( *pObj ) );
[ # # ]
1551 [ + - ]: 4 : pObj->Mirror( aRef1, aRef2 );
1552 : : }
1553 : : else
1554 : : {
1555 : : // Move instead of mirroring:
1556 : : // New start position is negative of old end position
1557 : : // -> move by sum of start and end position
1558 [ # # ]: 0 : Rectangle aObjRect = pObj->GetLogicRect();
1559 : 0 : Size aMoveSize( -(aObjRect.Left() + aObjRect.Right()), 0 );
1560 [ # # ]: 0 : if (bRecording)
1561 [ # # ][ # # ]: 0 : AddCalcUndo( new SdrUndoMoveObj( *pObj, aMoveSize ) );
[ # # ]
1562 [ # # ]: 0 : pObj->Move( aMoveSize );
1563 : : }
1564 : 4 : }
1565 : :
1566 : 0 : void ScDrawLayer::MirrorRectRTL( Rectangle& rRect )
1567 : : {
1568 : : // mirror and swap left/right
1569 : 0 : long nTemp = rRect.Left();
1570 : 0 : rRect.Left() = -rRect.Right();
1571 : 0 : rRect.Right() = -nTemp;
1572 : 0 : }
1573 : :
1574 : 29 : Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, bool bMergedCell )
1575 : : {
1576 : 29 : Rectangle aCellRect;
1577 : : OSL_ENSURE( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
1578 [ + - ]: 29 : if( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ) )
1579 : : {
1580 : : // find top left position of passed cell address
1581 : 29 : Point aTopLeft;
1582 [ + + ]: 130 : for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol )
1583 [ + - ]: 101 : aTopLeft.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
1584 [ + - ]: 29 : if( rPos.Row() > 0 )
1585 [ + - ]: 29 : aTopLeft.Y() += rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() );
1586 : :
1587 : : // find bottom-right position of passed cell address
1588 : 29 : ScAddress aEndPos = rPos;
1589 [ + - ]: 29 : if( bMergedCell )
1590 : : {
1591 [ + - ]: 29 : const ScMergeAttr* pMerge = static_cast< const ScMergeAttr* >( rDoc.GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), ATTR_MERGE ) );
1592 [ - + ]: 29 : if( pMerge->GetColMerge() > 1 )
1593 [ # # ]: 0 : aEndPos.IncCol( pMerge->GetColMerge() - 1 );
1594 [ - + ]: 29 : if( pMerge->GetRowMerge() > 1 )
1595 [ # # ]: 0 : aEndPos.IncRow( pMerge->GetRowMerge() - 1 );
1596 : : }
1597 : 29 : Point aBotRight = aTopLeft;
1598 [ + + ]: 58 : for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol )
1599 [ + - ]: 29 : aBotRight.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
1600 [ + - ]: 29 : aBotRight.Y() += rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() );
1601 : :
1602 : : // twips -> 1/100 mm
1603 : 29 : aTopLeft.X() = static_cast< long >( aTopLeft.X() * HMM_PER_TWIPS );
1604 : 29 : aTopLeft.Y() = static_cast< long >( aTopLeft.Y() * HMM_PER_TWIPS );
1605 : 29 : aBotRight.X() = static_cast< long >( aBotRight.X() * HMM_PER_TWIPS );
1606 : 29 : aBotRight.Y() = static_cast< long >( aBotRight.Y() * HMM_PER_TWIPS );
1607 : :
1608 [ + - ]: 29 : aCellRect = Rectangle( aTopLeft, aBotRight );
1609 [ + - ][ - + ]: 29 : if( rDoc.IsNegativePage( rPos.Tab() ) )
1610 [ # # ]: 29 : MirrorRectRTL( aCellRect );
1611 : : }
1612 : 29 : return aCellRect;
1613 : : }
1614 : :
1615 : 0 : String ScDrawLayer::GetVisibleName( SdrObject* pObj )
1616 : : {
1617 [ # # ]: 0 : String aName = pObj->GetName();
1618 [ # # ][ # # ]: 0 : if ( pObj->GetObjIdentifier() == OBJ_OLE2 )
1619 : : {
1620 : : // For OLE, the user defined name (GetName) is used
1621 : : // if it's not empty (accepting possibly duplicate names),
1622 : : // otherwise the persist name is used so every object appears
1623 : : // in the Navigator at all.
1624 : :
1625 [ # # ]: 0 : if ( !aName.Len() )
1626 [ # # ][ # # ]: 0 : aName = static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
[ # # ]
1627 : : }
1628 : 0 : return aName;
1629 : : }
1630 : :
1631 : 1 : inline sal_Bool IsNamedObject( SdrObject* pObj, const String& rName )
1632 : : {
1633 : : // sal_True if rName is the object's Name or PersistName
1634 : : // (used to find a named object)
1635 : :
1636 [ + - ][ + - ]: 2 : return ( pObj->GetName().equals(rName) ||
[ + - ][ + - ]
[ # # # # ]
1637 [ + - ]: 1 : ( pObj->GetObjIdentifier() == OBJ_OLE2 &&
1638 [ + - ][ + - ]: 3 : static_cast<SdrOle2Obj*>(pObj)->GetPersistName() == rName ) );
[ + - ][ - + ]
[ + - ][ + - ]
[ # # ][ + - ]
1639 : : }
1640 : :
1641 : 10 : SdrObject* ScDrawLayer::GetNamedObject( const String& rName, sal_uInt16 nId, SCTAB& rFoundTab ) const
1642 : : {
1643 : 10 : sal_uInt16 nTabCount = GetPageCount();
1644 [ + + ]: 20 : for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1645 : : {
1646 : 10 : const SdrPage* pPage = GetPage(nTab);
1647 : : OSL_ENSURE(pPage,"Page ?");
1648 [ + - ]: 10 : if (pPage)
1649 : : {
1650 [ + - ]: 10 : SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
1651 [ + - ]: 10 : SdrObject* pObject = aIter.Next();
1652 [ + + ]: 11 : while (pObject)
1653 : : {
1654 [ + - ][ + - ]: 1 : if ( nId == 0 || pObject->GetObjIdentifier() == nId )
[ + - ][ + - ]
1655 [ + - ][ - + ]: 1 : if ( IsNamedObject( pObject, rName ) )
1656 : : {
1657 : 0 : rFoundTab = static_cast<SCTAB>(nTab);
1658 : 0 : return pObject;
1659 : : }
1660 : :
1661 [ + - ]: 1 : pObject = aIter.Next();
1662 [ + - ]: 10 : }
1663 : : }
1664 : : }
1665 : :
1666 : 10 : return NULL;
1667 : : }
1668 : :
1669 : 0 : String ScDrawLayer::GetNewGraphicName( long* pnCounter ) const
1670 : : {
1671 [ # # ][ # # ]: 0 : String aBase = ScGlobal::GetRscString(STR_GRAPHICNAME);
1672 [ # # ]: 0 : aBase += ' ';
1673 : :
1674 : 0 : sal_Bool bThere = sal_True;
1675 [ # # ]: 0 : String aGraphicName;
1676 : : SCTAB nDummy;
1677 [ # # ]: 0 : long nId = pnCounter ? *pnCounter : 0;
1678 [ # # ]: 0 : while (bThere)
1679 : : {
1680 : 0 : ++nId;
1681 [ # # ]: 0 : aGraphicName = aBase;
1682 [ # # ][ # # ]: 0 : aGraphicName += String::CreateFromInt32( nId );
[ # # ]
1683 [ # # ]: 0 : bThere = ( GetNamedObject( aGraphicName, 0, nDummy ) != NULL );
1684 : : }
1685 : :
1686 [ # # ]: 0 : if ( pnCounter )
1687 : 0 : *pnCounter = nId;
1688 : :
1689 [ # # ]: 0 : return aGraphicName;
1690 : : }
1691 : :
1692 : 58 : void ScDrawLayer::EnsureGraphicNames()
1693 : : {
1694 : : // make sure all graphic objects have names (after Excel import etc.)
1695 : :
1696 : 58 : sal_uInt16 nTabCount = GetPageCount();
1697 [ + + ]: 232 : for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1698 : : {
1699 : 174 : SdrPage* pPage = GetPage(nTab);
1700 : : OSL_ENSURE(pPage,"Page ?");
1701 [ + - ]: 174 : if (pPage)
1702 : : {
1703 [ + - ]: 174 : SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
1704 [ + - ]: 174 : SdrObject* pObject = aIter.Next();
1705 : :
1706 : : /* The index passed to GetNewGraphicName() will be set to
1707 : : the used index in each call. This prevents the repeated search
1708 : : for all names from 1 to current index. */
1709 : 174 : long nCounter = 0;
1710 : :
1711 [ + + ]: 242 : while (pObject)
1712 : : {
1713 [ + - ][ + + ]: 68 : if ( pObject->GetObjIdentifier() == OBJ_GRAF && pObject->GetName().isEmpty())
[ + - ][ - + ]
[ + + ]
[ - + # # ]
1714 [ # # ][ # # ]: 0 : pObject->SetName( GetNewGraphicName( &nCounter ) );
[ # # ][ # # ]
1715 : :
1716 [ + - ]: 68 : pObject = aIter.Next();
1717 : 174 : }
1718 : : }
1719 : : }
1720 : 58 : }
1721 : :
1722 : : namespace
1723 : : {
1724 : 626 : SdrObjUserData* GetFirstUserDataOfType(const SdrObject *pObj, sal_uInt16 nId)
1725 : : {
1726 [ + - ]: 626 : sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
1727 [ + + ]: 626 : for( sal_uInt16 i = 0; i < nCount; i++ )
1728 : : {
1729 : 241 : SdrObjUserData* pData = pObj->GetUserData( i );
1730 [ + - ][ + - ]: 241 : if( pData && pData->GetInventor() == SC_DRAWLAYER && pData->GetId() == nId )
[ + - ][ + - ]
1731 : 241 : return pData;
1732 : : }
1733 : 626 : return NULL;
1734 : : }
1735 : :
1736 : 3 : void DeleteFirstUserDataOfType(SdrObject *pObj, sal_uInt16 nId)
1737 : : {
1738 [ + - ]: 3 : sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
1739 [ - + ]: 3 : for( sal_uInt16 i = nCount; i > 0; i-- )
1740 : : {
1741 : 0 : SdrObjUserData* pData = pObj->GetUserData( i-1 );
1742 [ # # ][ # # ]: 0 : if( pData && pData->GetInventor() == SC_DRAWLAYER && pData->GetId() == nId )
[ # # ][ # # ]
1743 : 0 : pObj->DeleteUserData(i-1);
1744 : : }
1745 : 3 : }
1746 : : }
1747 : :
1748 : 70 : void ScDrawLayer::SetCellAnchored( SdrObject &rObj, const ScDrawObjData &rAnchor )
1749 : : {
1750 : 70 : ScDrawObjData* pAnchor = GetObjData( &rObj, true );
1751 : 70 : pAnchor->maStart = rAnchor.maStart;
1752 : 70 : pAnchor->maEnd = rAnchor.maEnd;
1753 : 70 : pAnchor->maStartOffset = rAnchor.maStartOffset;
1754 : 70 : pAnchor->maEndOffset = rAnchor.maEndOffset;
1755 : 70 : }
1756 : :
1757 : 16 : void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab )
1758 : : {
1759 [ + - ]: 16 : Rectangle aObjRect(rObj.GetLogicRect());
1760 [ + - ]: 16 : ScRange aRange = rDoc.GetRange( nTab, aObjRect );
1761 : :
1762 [ + - ]: 16 : Rectangle aCellRect;
1763 : :
1764 [ + - ]: 16 : ScDrawObjData aAnchor;
1765 : 16 : aAnchor.maStart = aRange.aStart;
1766 : 16 : aCellRect = rDoc.GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
1767 [ + - ]: 32 : aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() );
1768 : 16 : aAnchor.maStartOffset.Y() = aObjRect.Top()-aCellRect.Top();
1769 [ + - ][ + - ]: 16 : if (!rDoc.IsNegativePage(nTab))
1770 : 16 : aAnchor.maStartOffset.X() = aObjRect.Left()-aCellRect.Left();
1771 : : else
1772 : 0 : aAnchor.maStartOffset.X() = aCellRect.Right()-aObjRect.Right();
1773 : :
1774 : 16 : aAnchor.maEnd = aRange.aEnd;
1775 : 16 : aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(),
1776 [ + - ]: 32 : aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab() );
1777 : 16 : aAnchor.maEndOffset.Y() = aObjRect.Bottom()-aCellRect.Top();
1778 [ + - ][ + - ]: 16 : if (!rDoc.IsNegativePage(nTab))
1779 : 16 : aAnchor.maEndOffset.X() = aObjRect.Right()-aCellRect.Left();
1780 : : else
1781 : 0 : aAnchor.maEndOffset.X() = aCellRect.Right()-aObjRect.Left();
1782 : :
1783 [ + - ][ + - ]: 16 : SetCellAnchored( rObj, aAnchor );
1784 : 16 : }
1785 : :
1786 : 2 : void ScDrawLayer::UpdateCellAnchorFromPositionEnd( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab )
1787 : : {
1788 [ + - ]: 2 : Rectangle aObjRect(rObj.GetLogicRect());
1789 [ + - ]: 2 : ScRange aRange = rDoc.GetRange( nTab, aObjRect );
1790 : :
1791 [ + - ]: 2 : ScDrawObjData* pAnchor = GetObjData( &rObj, true );
1792 : 2 : pAnchor->maEnd = aRange.aEnd;
1793 : :
1794 [ + - ]: 2 : Rectangle aCellRect;
1795 : 2 : aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(),
1796 [ + - ]: 4 : aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab() );
1797 : 2 : pAnchor->maEndOffset.Y() = aObjRect.Bottom()-aCellRect.Top();
1798 [ + - ][ + - ]: 2 : if (!rDoc.IsNegativePage(nTab))
1799 : 2 : pAnchor->maEndOffset.X() = aObjRect.Right()-aCellRect.Left();
1800 : : else
1801 : 0 : pAnchor->maEndOffset.X() = aCellRect.Right()-aObjRect.Left();
1802 : 2 : }
1803 : :
1804 : 3 : void ScDrawLayer::SetPageAnchored( SdrObject &rObj )
1805 : : {
1806 : 3 : DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA);
1807 : 3 : }
1808 : :
1809 : 28 : ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
1810 : : {
1811 : : //If this object has a cell anchor associated with it
1812 : : //then its cell-anchored, otherwise its page-anchored
1813 : 28 : return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
1814 : : }
1815 : :
1816 : 626 : ScDrawObjData* ScDrawLayer::GetObjData( SdrObject* pObj, sal_Bool bCreate )
1817 : : {
1818 [ + + ]: 626 : if (SdrObjUserData *pData = GetFirstUserDataOfType(pObj, SC_UD_OBJDATA))
1819 : 241 : return (ScDrawObjData*) pData;
1820 : :
1821 [ + - ][ + + ]: 385 : if( pObj && bCreate )
1822 : : {
1823 [ + - ]: 91 : ScDrawObjData* pData = new ScDrawObjData;
1824 : 91 : pObj->AppendUserData(pData);
1825 : 91 : return pData;
1826 : : }
1827 : 626 : return 0;
1828 : : }
1829 : :
1830 : 159 : ScDrawObjData* ScDrawLayer::GetObjDataTab( SdrObject* pObj, SCTAB nTab )
1831 : : {
1832 : 159 : ScDrawObjData* pData = GetObjData( pObj );
1833 [ + + ]: 159 : if ( pData )
1834 : : {
1835 [ + - ]: 137 : if ( pData->maStart.IsValid() )
1836 : 137 : pData->maStart.SetTab( nTab );
1837 [ + + ]: 137 : if ( pData->maEnd.IsValid() )
1838 : 120 : pData->maEnd.SetTab( nTab );
1839 : : }
1840 : 159 : return pData;
1841 : : }
1842 : :
1843 : 12 : bool ScDrawLayer::IsNoteCaption( SdrObject* pObj )
1844 : : {
1845 [ + - ]: 12 : ScDrawObjData* pData = pObj ? GetObjData( pObj ) : 0;
1846 [ + - ][ - + ]: 12 : return pData && pData->meType == ScDrawObjData::CellNote;
1847 : : }
1848 : :
1849 : 8 : ScDrawObjData* ScDrawLayer::GetNoteCaptionData( SdrObject* pObj, SCTAB nTab )
1850 : : {
1851 [ + - ]: 8 : ScDrawObjData* pData = pObj ? GetObjDataTab( pObj, nTab ) : 0;
1852 [ + - ][ + - ]: 8 : return (pData && pData->meType == ScDrawObjData::CellNote) ? pData : 0;
1853 : : }
1854 : :
1855 : 0 : ScIMapInfo* ScDrawLayer::GetIMapInfo( SdrObject* pObj )
1856 : : {
1857 : 0 : return (ScIMapInfo*)GetFirstUserDataOfType(pObj, SC_UD_IMAPDATA);
1858 : : }
1859 : :
1860 : 0 : IMapObject* ScDrawLayer::GetHitIMapObject( SdrObject* pObj,
1861 : : const Point& rWinPoint, const Window& rCmpWnd )
1862 : : {
1863 [ # # ]: 0 : const MapMode aMap100( MAP_100TH_MM );
1864 [ # # ]: 0 : MapMode aWndMode = rCmpWnd.GetMapMode();
1865 [ # # ]: 0 : Point aRelPoint( rCmpWnd.LogicToLogic( rWinPoint, &aWndMode, &aMap100 ) );
1866 [ # # ][ # # ]: 0 : Rectangle aLogRect = rCmpWnd.LogicToLogic( pObj->GetLogicRect(), &aWndMode, &aMap100 );
1867 [ # # ]: 0 : ScIMapInfo* pIMapInfo = GetIMapInfo( pObj );
1868 : 0 : IMapObject* pIMapObj = NULL;
1869 : :
1870 [ # # ]: 0 : if ( pIMapInfo )
1871 : : {
1872 : 0 : Size aGraphSize;
1873 : 0 : ImageMap& rImageMap = (ImageMap&) pIMapInfo->GetImageMap();
1874 [ # # ]: 0 : Graphic aGraphic;
1875 : 0 : sal_Bool bObjSupported = false;
1876 : :
1877 [ # # ][ # # ]: 0 : if ( pObj->ISA( SdrGrafObj ) ) // einfaches Grafik-Objekt
[ # # ]
1878 : : {
1879 : 0 : const SdrGrafObj* pGrafObj = (const SdrGrafObj*) pObj;
1880 : 0 : const GeoStat& rGeo = pGrafObj->GetGeoStat();
1881 [ # # ]: 0 : const Graphic& rGraphic = pGrafObj->GetGraphic();
1882 : :
1883 : : // Drehung rueckgaengig
1884 [ # # ]: 0 : if ( rGeo.nDrehWink )
1885 : 0 : RotatePoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nSin, rGeo.nCos );
1886 : :
1887 : : // Spiegelung rueckgaengig
1888 [ # # ][ # # ]: 0 : if ( ( (const SdrGrafObjGeoData*) pGrafObj->GetGeoData() )->bMirrored )
1889 : 0 : aRelPoint.X() = aLogRect.Right() + aLogRect.Left() - aRelPoint.X();
1890 : :
1891 : : // ggf. Unshear:
1892 [ # # ]: 0 : if ( rGeo.nShearWink )
1893 : 0 : ShearPoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nTan );
1894 : :
1895 : :
1896 [ # # ][ # # ]: 0 : if ( rGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
[ # # ]
1897 : : aGraphSize = rCmpWnd.PixelToLogic( rGraphic.GetPrefSize(),
1898 [ # # ][ # # ]: 0 : aMap100 );
1899 : : else
1900 : : aGraphSize = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(),
1901 : : rGraphic.GetPrefMapMode(),
1902 [ # # ][ # # ]: 0 : aMap100 );
[ # # ][ # # ]
1903 : :
1904 : 0 : bObjSupported = sal_True;
1905 : : }
1906 [ # # ][ # # ]: 0 : else if ( pObj->ISA( SdrOle2Obj ) ) // OLE-Objekt
[ # # ]
1907 : : {
1908 : : // TODO/LEAN: working with visual area needs running state
1909 [ # # ]: 0 : aGraphSize = ((const SdrOle2Obj*)pObj)->GetOrigObjSize();
1910 : 0 : bObjSupported = true;
1911 : : }
1912 : :
1913 : : // hat alles geklappt, dann HitTest ausfuehren
1914 [ # # ]: 0 : if ( bObjSupported )
1915 : : {
1916 : : // relativen Mauspunkt berechnen
1917 : 0 : aRelPoint -= aLogRect.TopLeft();
1918 [ # # ][ # # ]: 0 : pIMapObj = rImageMap.GetHitIMapObject( aGraphSize, aLogRect.GetSize(), aRelPoint );
1919 [ # # ]: 0 : }
1920 : : }
1921 : :
1922 [ # # ][ # # ]: 0 : return pIMapObj;
1923 : : }
1924 : :
1925 : 0 : ScMacroInfo* ScDrawLayer::GetMacroInfo( SdrObject* pObj, sal_Bool bCreate )
1926 : : {
1927 [ # # ]: 0 : if (SdrObjUserData *pData = GetFirstUserDataOfType(pObj, SC_UD_MACRODATA))
1928 : 0 : return (ScMacroInfo*) pData;
1929 : :
1930 [ # # ]: 0 : if ( bCreate )
1931 : : {
1932 [ # # ]: 0 : ScMacroInfo* pData = new ScMacroInfo;
1933 : 0 : pObj->AppendUserData(pData);
1934 : 0 : return pData;
1935 : : }
1936 : 0 : return 0;
1937 : : }
1938 : :
1939 : 6 : void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell* pPersist)
1940 : : {
1941 : : OSL_ENSURE(!pGlobalDrawPersist,"SetGlobalDrawPersist mehrfach");
1942 : 6 : pGlobalDrawPersist = pPersist;
1943 : 6 : }
1944 : :
1945 : 69676 : void ScDrawLayer::SetChanged( sal_Bool bFlg /* = sal_True */ )
1946 : : {
1947 [ + - ][ + - ]: 69676 : if ( bFlg && pDoc )
1948 : 69676 : pDoc->SetChartListenerCollectionNeedsUpdate( sal_True );
1949 : 69676 : FmFormModel::SetChanged( bFlg );
1950 : 69676 : }
1951 : :
1952 : 0 : SdrLayerID ScDrawLayer::GetControlExportLayerId( const SdrObject & ) const
1953 : : {
1954 : : // Layer fuer Export von Form-Controls in Versionen vor 5.0 - immer SC_LAYER_FRONT
1955 : 0 : return SC_LAYER_FRONT;
1956 : : }
1957 : :
1958 : 12 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ScDrawLayer::createUnoModel()
1959 : : {
1960 : 12 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRet;
1961 [ + - ][ + - ]: 12 : if( pDoc && pDoc->GetDocumentShell() )
[ + - ]
1962 [ + - ][ + - ]: 12 : xRet = pDoc->GetDocumentShell()->GetModel();
1963 : :
1964 : 12 : return xRet;
1965 : : }
1966 : :
1967 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|