Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <cassert>
21 :
22 : #include <svx/svdpage.hxx>
23 :
24 : // HACK
25 : #include <sot/storage.hxx>
26 : #include <comphelper/classids.hxx>
27 : #include <svx/svdview.hxx>
28 : #include <string.h>
29 : #include <vcl/svapp.hxx>
30 :
31 : #include <tools/diagnose_ex.h>
32 : #include <tools/helpers.hxx>
33 :
34 : #include <svx/svdetc.hxx>
35 : #include <svx/svdobj.hxx>
36 : #include <svx/svdogrp.hxx>
37 : #include <svx/svdograf.hxx>
38 : #include <svx/svdoedge.hxx>
39 : #include <svx/svdoole2.hxx>
40 : #include "svx/svditer.hxx"
41 : #include <svx/svdmodel.hxx>
42 : #include <svx/svdlayer.hxx>
43 : #include <svx/svdotext.hxx>
44 : #include <svx/svdpagv.hxx>
45 : #include <svx/svdundo.hxx>
46 : #include <svx/fmglob.hxx>
47 : #include <svx/polysc3d.hxx>
48 :
49 : #include <svx/fmdpage.hxx>
50 :
51 : #include <sfx2/objsh.hxx>
52 : #include <sdr/contact/viewcontactofsdrpage.hxx>
53 : #include <svx/sdr/contact/viewobjectcontact.hxx>
54 : #include <svx/sdr/contact/displayinfo.hxx>
55 : #include <algorithm>
56 : #include <svl/smplhint.hxx>
57 : #include <rtl/strbuf.hxx>
58 : #include <libxml/xmlwriter.h>
59 :
60 : using namespace ::com::sun::star;
61 :
62 0 : class SdrObjList::WeakSdrObjectContainerType
63 : : public ::std::vector<SdrObjectWeakRef>
64 : {
65 : public:
66 0 : explicit WeakSdrObjectContainerType (const sal_Int32 nInitialSize)
67 0 : : ::std::vector<SdrObjectWeakRef>(nInitialSize) {};
68 : };
69 :
70 :
71 :
72 : static const sal_Int32 InitialObjectContainerCapacity (64);
73 :
74 278528 : TYPEINIT0(SdrObjList);
75 :
76 48057 : SdrObjList::SdrObjList(SdrModel* pNewModel, SdrPage* pNewPage, SdrObjList* pNewUpList):
77 : maList(),
78 : mxNavigationOrder(),
79 48057 : mbIsNavigationOrderDirty(false)
80 : {
81 48057 : maList.reserve(InitialObjectContainerCapacity);
82 48057 : pModel=pNewModel;
83 48057 : pPage=pNewPage;
84 48057 : pUpList=pNewUpList;
85 48057 : bObjOrdNumsDirty=false;
86 48057 : bRectsDirty=false;
87 48057 : pOwnerObj=NULL;
88 48057 : eListKind=SDROBJLIST_UNKNOWN;
89 48057 : }
90 :
91 0 : SdrObjList::SdrObjList():
92 : maList(),
93 : mxNavigationOrder(),
94 0 : mbIsNavigationOrderDirty(false)
95 : {
96 0 : maList.reserve(InitialObjectContainerCapacity);
97 0 : pModel=NULL;
98 0 : pPage=NULL;
99 0 : pUpList=NULL;
100 0 : bObjOrdNumsDirty=false;
101 0 : bRectsDirty=false;
102 0 : pOwnerObj=NULL;
103 0 : eListKind=SDROBJLIST_UNKNOWN;
104 0 : }
105 :
106 130124 : SdrObjList::~SdrObjList()
107 : {
108 :
109 : // To avoid that the Clear() method will broadcast changes when in destruction
110 : // which would call virtual methos (not allowed in destructor), the model is set
111 : // to NULL here.
112 47606 : pModel = 0L;
113 :
114 47606 : Clear(); // delete contents of container
115 82518 : }
116 :
117 0 : SdrObjList* SdrObjList::Clone() const
118 : {
119 0 : SdrObjList* const pObjList = new SdrObjList();
120 0 : pObjList->lateInit(*this);
121 0 : return pObjList;
122 : }
123 :
124 1 : void SdrObjList::lateInit(const SdrObjList& rSrcList)
125 : {
126 : // this function is only supposed to be called once, right after construction
127 : assert(maList.empty());
128 :
129 1 : eListKind=rSrcList.eListKind;
130 1 : CopyObjects(rSrcList);
131 1 : }
132 :
133 30 : void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
134 : {
135 30 : Clear();
136 30 : bObjOrdNumsDirty=false;
137 30 : bRectsDirty =false;
138 30 : size_t nCloneErrCnt = 0;
139 30 : const size_t nCount = rSrcList.GetObjCount();
140 30 : SdrInsertReason aReason(SDRREASON_COPY);
141 462 : for (size_t no=0; no<nCount; ++no) {
142 432 : SdrObject* pSO=rSrcList.GetObj(no);
143 :
144 432 : SdrObject* pDO = pSO->Clone();
145 :
146 432 : if (pDO!=NULL) {
147 432 : pDO->SetModel(pModel);
148 432 : pDO->SetPage(pPage);
149 432 : NbcInsertObject(pDO, SAL_MAX_SIZE, &aReason);
150 : } else {
151 0 : nCloneErrCnt++;
152 : }
153 : }
154 :
155 : // and now for the Connectors
156 : // The new objects would be shown in the rSrcList
157 : // and then the object connections are made.
158 : // Similar implementation are setup as the following:
159 : // void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
160 : // SdrModel* SdrExchangeView::GetMarkedObjModel() const
161 : // BOOL SdrExchangeView::Paste(const SdrModel& rMod,...)
162 : // void SdrEditView::CopyMarked()
163 30 : if (nCloneErrCnt==0) {
164 462 : for (size_t no=0; no<nCount; ++no) {
165 432 : const SdrObject* pSrcOb=rSrcList.GetObj(no);
166 432 : const SdrEdgeObj* pSrcEdge=PTR_CAST(SdrEdgeObj,pSrcOb);
167 432 : if (pSrcEdge!=NULL) {
168 0 : SdrObject* pSrcNode1=pSrcEdge->GetConnectedNode(true);
169 0 : SdrObject* pSrcNode2=pSrcEdge->GetConnectedNode(false);
170 0 : if (pSrcNode1!=NULL && pSrcNode1->GetObjList()!=pSrcEdge->GetObjList()) pSrcNode1=NULL; // can't do this
171 0 : if (pSrcNode2!=NULL && pSrcNode2->GetObjList()!=pSrcEdge->GetObjList()) pSrcNode2=NULL; // across all lists (yet)
172 0 : if (pSrcNode1!=NULL || pSrcNode2!=NULL) {
173 0 : SdrObject* pEdgeObjTmp=GetObj(no);
174 0 : SdrEdgeObj* pDstEdge=PTR_CAST(SdrEdgeObj,pEdgeObjTmp);
175 0 : if (pDstEdge!=NULL) {
176 0 : if (pSrcNode1!=NULL) {
177 0 : sal_uIntPtr nDstNode1=pSrcNode1->GetOrdNum();
178 0 : SdrObject* pDstNode1=GetObj(nDstNode1);
179 0 : if (pDstNode1!=NULL) { // else we get an error!
180 0 : pDstEdge->ConnectToNode(true,pDstNode1);
181 : } else {
182 : OSL_FAIL("SdrObjList::operator=(): pDstNode1==NULL!");
183 : }
184 : }
185 0 : if (pSrcNode2!=NULL) {
186 0 : sal_uIntPtr nDstNode2=pSrcNode2->GetOrdNum();
187 0 : SdrObject* pDstNode2=GetObj(nDstNode2);
188 0 : if (pDstNode2!=NULL) { // else the node was probably not selected
189 0 : pDstEdge->ConnectToNode(false,pDstNode2);
190 : } else {
191 : OSL_FAIL("SdrObjList::operator=(): pDstNode2==NULL!");
192 : }
193 : }
194 : } else {
195 : OSL_FAIL("SdrObjList::operator=(): pDstEdge==NULL!");
196 : }
197 : }
198 : }
199 : }
200 : } else {
201 : #ifdef DBG_UTIL
202 : OStringBuffer aStr("SdrObjList::operator=(): Error when cloning ");
203 :
204 : if(nCloneErrCnt == 1)
205 : {
206 : aStr.append("a drawing object.");
207 : }
208 : else
209 : {
210 : aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
211 : aStr.append(" drawing objects.");
212 : }
213 :
214 : aStr.append(" Not copying connectors.");
215 :
216 : OSL_FAIL(aStr.getStr());
217 : #endif
218 : }
219 30 : }
220 :
221 49965 : void SdrObjList::Clear()
222 : {
223 49965 : bool bObjectsRemoved(false);
224 :
225 180906 : while( ! maList.empty())
226 : {
227 : // remove last object from list
228 80976 : SdrObject* pObj = maList.back();
229 80976 : RemoveObjectFromContainer(maList.size()-1);
230 :
231 : // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
232 : // to delete the object and thus refresh visualisations
233 80976 : pObj->GetViewContact().flushViewObjectContacts(true);
234 :
235 80976 : bObjectsRemoved = true;
236 :
237 : // sent remove hint (after removal, see RemoveObject())
238 80976 : if(pModel)
239 : {
240 7026 : SdrHint aHint(*pObj);
241 7026 : aHint.SetKind(HINT_OBJREMOVED);
242 7026 : aHint.SetPage(pPage);
243 7026 : pModel->Broadcast(aHint);
244 : }
245 :
246 : // delete the object itself
247 80976 : SdrObject::Free( pObj );
248 : }
249 :
250 49965 : if(pModel && bObjectsRemoved)
251 : {
252 1713 : pModel->SetChanged();
253 : }
254 49965 : }
255 :
256 169 : SdrPage* SdrObjList::GetPage() const
257 : {
258 169 : return pPage;
259 : }
260 :
261 114418 : void SdrObjList::SetPage(SdrPage* pNewPage)
262 : {
263 114418 : if (pPage!=pNewPage) {
264 73912 : pPage=pNewPage;
265 73912 : const size_t nCount = GetObjCount();
266 129931 : for (size_t no=0; no<nCount; ++no) {
267 56019 : SdrObject* pObj=GetObj(no);
268 56019 : pObj->SetPage(pPage);
269 : }
270 : }
271 114418 : }
272 :
273 568420 : SdrModel* SdrObjList::GetModel() const
274 : {
275 568420 : return pModel;
276 : }
277 :
278 47190 : void SdrObjList::SetModel(SdrModel* pNewModel)
279 : {
280 47190 : if (pModel!=pNewModel) {
281 40532 : pModel=pNewModel;
282 40532 : const size_t nCount = GetObjCount();
283 40867 : for (size_t i=0; i<nCount; ++i) {
284 335 : SdrObject* pObj=GetObj(i);
285 335 : pObj->SetModel(pModel);
286 : }
287 : }
288 47190 : }
289 :
290 20946 : void SdrObjList::RecalcObjOrdNums()
291 : {
292 20946 : const size_t nCount = GetObjCount();
293 262948 : for (size_t no=0; no<nCount; ++no) {
294 242002 : SdrObject* pObj=GetObj(no);
295 242002 : pObj->SetOrdNum(no);
296 : }
297 20946 : bObjOrdNumsDirty=false;
298 20946 : }
299 :
300 65658 : void SdrObjList::RecalcRects()
301 : {
302 65658 : aOutRect=Rectangle();
303 65658 : aSnapRect=aOutRect;
304 65658 : const size_t nCount = GetObjCount();
305 252333 : for (size_t i=0; i<nCount; ++i) {
306 186675 : SdrObject* pObj=GetObj(i);
307 186675 : if (i==0) {
308 52245 : aOutRect=pObj->GetCurrentBoundRect();
309 52245 : aSnapRect=pObj->GetSnapRect();
310 : } else {
311 134430 : aOutRect.Union(pObj->GetCurrentBoundRect());
312 134430 : aSnapRect.Union(pObj->GetSnapRect());
313 : }
314 : }
315 65658 : }
316 :
317 19585110 : void SdrObjList::SetRectsDirty()
318 : {
319 19585110 : bRectsDirty=true;
320 19585110 : if (pUpList!=NULL) pUpList->SetRectsDirty();
321 19585110 : }
322 :
323 111933 : void SdrObjList::impChildInserted(SdrObject& rChild)
324 : {
325 111933 : sdr::contact::ViewContact* pParent = rChild.GetViewContact().GetParentContact();
326 :
327 111933 : if(pParent)
328 : {
329 111933 : pParent->ActionChildInserted(rChild.GetViewContact());
330 : }
331 111933 : }
332 :
333 110868 : void SdrObjList::NbcInsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* /*pReason*/)
334 : {
335 : DBG_ASSERT(pObj!=NULL,"SdrObjList::NbcInsertObject(NULL)");
336 110868 : if (pObj!=NULL) {
337 : DBG_ASSERT(!pObj->IsInserted(),"ZObjekt already has the status Inserted.");
338 110868 : const size_t nCount = GetObjCount();
339 110868 : if (nPos>nCount) nPos=nCount;
340 110868 : InsertObjectIntoContainer(*pObj,nPos);
341 :
342 110868 : if (nPos<nCount) bObjOrdNumsDirty=true;
343 110868 : pObj->SetOrdNum(nPos);
344 110868 : pObj->SetObjList(this);
345 110868 : pObj->SetPage(pPage);
346 :
347 : // Inform the parent about change to allow invalidations at
348 : // evtl. existing parent visualisations
349 110868 : impChildInserted(*pObj);
350 :
351 110868 : if (!bRectsDirty) {
352 35511 : aOutRect.Union(pObj->GetCurrentBoundRect());
353 35511 : aSnapRect.Union(pObj->GetSnapRect());
354 : }
355 110868 : pObj->SetInserted(true); // calls the UserCall (among others)
356 : }
357 110868 : }
358 :
359 100774 : void SdrObjList::InsertObject(SdrObject* pObj, size_t nPos, const SdrInsertReason* pReason)
360 : {
361 : DBG_ASSERT(pObj!=NULL,"SdrObjList::InsertObject(NULL)");
362 :
363 100774 : if(pObj)
364 : {
365 : // if anchor is used, reset it before grouping
366 100774 : if(GetOwnerObj())
367 : {
368 85295 : const Point& rAnchorPos = pObj->GetAnchorPos();
369 85295 : if(rAnchorPos.X() || rAnchorPos.Y())
370 0 : pObj->NbcSetAnchorPos(Point());
371 : }
372 :
373 : // do insert to new group
374 100774 : NbcInsertObject(pObj, nPos, pReason);
375 :
376 : // In case the object is inserted into a group and doesn't overlap with
377 : // the group's other members, it needs an own repaint.
378 100774 : if(pOwnerObj)
379 : {
380 : // only repaint here
381 85295 : pOwnerObj->ActionChanged();
382 : }
383 :
384 100774 : if(pModel)
385 : {
386 : // TODO: We need a different broadcast here!
387 : // Repaint from object number ... (heads-up: GroupObj)
388 100643 : if(pObj->GetPage())
389 : {
390 100643 : SdrHint aHint(*pObj);
391 :
392 100643 : aHint.SetKind(HINT_OBJINSERTED);
393 100643 : pModel->Broadcast(aHint);
394 : }
395 :
396 100643 : pModel->SetChanged();
397 : }
398 : }
399 100774 : }
400 :
401 20551 : SdrObject* SdrObjList::NbcRemoveObject(size_t nObjNum)
402 : {
403 20551 : if (nObjNum >= maList.size())
404 : {
405 : OSL_ASSERT(nObjNum<maList.size());
406 0 : return NULL;
407 : }
408 :
409 20551 : const size_t nCount = GetObjCount();
410 20551 : SdrObject* pObj=maList[nObjNum];
411 20551 : RemoveObjectFromContainer(nObjNum);
412 :
413 : DBG_ASSERT(pObj!=NULL,"Could not find object to remove.");
414 20551 : if (pObj!=NULL) {
415 : // flushViewObjectContacts() clears the VOC's and those invalidate
416 20551 : pObj->GetViewContact().flushViewObjectContacts(true);
417 :
418 : DBG_ASSERT(pObj->IsInserted(),"ZObjekt does not have the status Inserted.");
419 20551 : pObj->SetInserted(false); // Ruft u.a. den UserCall
420 20551 : pObj->SetObjList(NULL);
421 20551 : pObj->SetPage(NULL);
422 20551 : if (!bObjOrdNumsDirty) { // optimizing for the case that the last object has to be removed
423 0 : if (nObjNum+1!=nCount) {
424 0 : bObjOrdNumsDirty=true;
425 : }
426 : }
427 20551 : SetRectsDirty();
428 : }
429 20551 : return pObj;
430 : }
431 :
432 8235 : SdrObject* SdrObjList::RemoveObject(size_t nObjNum)
433 : {
434 8235 : if (nObjNum >= maList.size())
435 : {
436 : OSL_ASSERT(nObjNum<maList.size());
437 0 : return NULL;
438 : }
439 :
440 8235 : const size_t nCount = GetObjCount();
441 8235 : SdrObject* pObj=maList[nObjNum];
442 8235 : RemoveObjectFromContainer(nObjNum);
443 :
444 : DBG_ASSERT(pObj!=NULL,"Object to remove not found.");
445 8235 : if(pObj)
446 : {
447 : // flushViewObjectContacts() clears the VOC's and those invalidate
448 8235 : pObj->GetViewContact().flushViewObjectContacts(true);
449 :
450 : DBG_ASSERT(pObj->IsInserted(),"ZObjekt does not have the status Inserted.");
451 8235 : if (pModel!=NULL) {
452 : // TODO: We need a different broadcast here.
453 8235 : if (pObj->GetPage()!=NULL) {
454 8235 : SdrHint aHint(*pObj);
455 8235 : aHint.SetKind(HINT_OBJREMOVED);
456 8235 : pModel->Broadcast(aHint);
457 : }
458 8235 : pModel->SetChanged();
459 : }
460 8235 : pObj->SetInserted(false); // calls, among other things, the UserCall
461 8235 : pObj->SetObjList(NULL);
462 8235 : pObj->SetPage(NULL);
463 8235 : if (!bObjOrdNumsDirty) { // optimization for the case that the last object is removed
464 0 : if (nObjNum+1!=nCount) {
465 0 : bObjOrdNumsDirty=true;
466 : }
467 : }
468 8235 : SetRectsDirty();
469 :
470 8235 : if(pOwnerObj && !GetObjCount())
471 : {
472 : // empty group created; it needs to be repainted since it's
473 : // visualization changes
474 5 : pOwnerObj->ActionChanged();
475 : }
476 : }
477 8235 : return pObj;
478 : }
479 :
480 0 : SdrObject* SdrObjList::NbcReplaceObject(SdrObject* pNewObj, size_t nObjNum)
481 : {
482 0 : if (nObjNum >= maList.size() || pNewObj == NULL)
483 : {
484 : OSL_ASSERT(nObjNum<maList.size());
485 : OSL_ASSERT(pNewObj!=NULL);
486 0 : return NULL;
487 : }
488 :
489 0 : SdrObject* pObj=maList[nObjNum];
490 : DBG_ASSERT(pObj!=NULL,"SdrObjList::ReplaceObject: Could not find object to remove.");
491 0 : if (pObj!=NULL) {
492 : DBG_ASSERT(pObj->IsInserted(),"SdrObjList::ReplaceObject: ZObjekt does not have status Inserted.");
493 0 : pObj->SetInserted(false);
494 0 : pObj->SetObjList(NULL);
495 0 : pObj->SetPage(NULL);
496 0 : ReplaceObjectInContainer(*pNewObj,nObjNum);
497 :
498 : // flushViewObjectContacts() clears the VOC's and those invalidate
499 0 : pObj->GetViewContact().flushViewObjectContacts(true);
500 :
501 0 : pNewObj->SetOrdNum(nObjNum);
502 0 : pNewObj->SetObjList(this);
503 0 : pNewObj->SetPage(pPage);
504 :
505 : // Inform the parent about change to allow invalidations at
506 : // evtl. existing parent visualisations
507 0 : impChildInserted(*pNewObj);
508 :
509 0 : pNewObj->SetInserted(true);
510 0 : SetRectsDirty();
511 : }
512 0 : return pObj;
513 : }
514 :
515 1065 : SdrObject* SdrObjList::ReplaceObject(SdrObject* pNewObj, size_t nObjNum)
516 : {
517 1065 : if (nObjNum >= maList.size())
518 : {
519 : OSL_ASSERT(nObjNum<maList.size());
520 0 : return NULL;
521 : }
522 1065 : if (pNewObj == NULL)
523 : {
524 : OSL_ASSERT(pNewObj!=NULL);
525 0 : return NULL;
526 : }
527 :
528 1065 : SdrObject* pObj=maList[nObjNum];
529 : DBG_ASSERT(pObj!=NULL,"SdrObjList::ReplaceObject: Could not find object to remove.");
530 1065 : if (pObj!=NULL) {
531 : DBG_ASSERT(pObj->IsInserted(),"SdrObjList::ReplaceObject: ZObjekt does not have status Inserted.");
532 1065 : if (pModel!=NULL) {
533 : // TODO: We need a different broadcast here.
534 1065 : if (pObj->GetPage()!=NULL) {
535 1065 : SdrHint aHint(*pObj);
536 1065 : aHint.SetKind(HINT_OBJREMOVED);
537 1065 : pModel->Broadcast(aHint);
538 : }
539 : }
540 1065 : pObj->SetInserted(false);
541 1065 : pObj->SetObjList(NULL);
542 1065 : pObj->SetPage(NULL);
543 1065 : ReplaceObjectInContainer(*pNewObj,nObjNum);
544 :
545 : // flushViewObjectContacts() clears the VOC's and those invalidate
546 1065 : pObj->GetViewContact().flushViewObjectContacts(true);
547 :
548 1065 : pNewObj->SetOrdNum(nObjNum);
549 1065 : pNewObj->SetObjList(this);
550 1065 : pNewObj->SetPage(pPage);
551 :
552 : // Inform the parent about change to allow invalidations at
553 : // evtl. existing parent visualisations
554 1065 : impChildInserted(*pNewObj);
555 :
556 1065 : pNewObj->SetInserted(true);
557 1065 : if (pModel!=NULL) {
558 : // TODO: We need a different broadcast here.
559 1065 : if (pNewObj->GetPage()!=NULL) {
560 1065 : SdrHint aHint(*pNewObj);
561 1065 : aHint.SetKind(HINT_OBJINSERTED);
562 1065 : pModel->Broadcast(aHint);
563 : }
564 1065 : pModel->SetChanged();
565 : }
566 1065 : SetRectsDirty();
567 : }
568 1065 : return pObj;
569 : }
570 :
571 11222 : SdrObject* SdrObjList::SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
572 : {
573 11222 : if (nOldObjNum >= maList.size() || nNewObjNum >= maList.size())
574 : {
575 : OSL_ASSERT(nOldObjNum<maList.size());
576 : OSL_ASSERT(nNewObjNum<maList.size());
577 1 : return NULL;
578 : }
579 :
580 11221 : SdrObject* pObj=maList[nOldObjNum];
581 11221 : if (nOldObjNum==nNewObjNum) return pObj;
582 : DBG_ASSERT(pObj!=NULL,"SdrObjList::SetObjectOrdNum: Object not found.");
583 8076 : if (pObj!=NULL) {
584 : DBG_ASSERT(pObj->IsInserted(),"SdrObjList::SetObjectOrdNum: ZObjekt does not have status Inserted.");
585 8076 : RemoveObjectFromContainer(nOldObjNum);
586 8076 : InsertObjectIntoContainer(*pObj,nNewObjNum);
587 :
588 : // No need to delete visualisation data since same object
589 : // gets inserted again. Also a single ActionChanged is enough
590 8076 : pObj->ActionChanged();
591 :
592 8076 : pObj->SetOrdNum(nNewObjNum);
593 8076 : bObjOrdNumsDirty=true;
594 8076 : if (pModel!=NULL)
595 : {
596 : // TODO: We need a different broadcast here.
597 8076 : if (pObj->GetPage()!=NULL) pModel->Broadcast(SdrHint(*pObj));
598 8076 : pModel->SetChanged();
599 : }
600 : }
601 8076 : return pObj;
602 : }
603 :
604 67404 : const Rectangle& SdrObjList::GetAllObjSnapRect() const
605 : {
606 67404 : if (bRectsDirty) {
607 8366 : const_cast<SdrObjList*>(this)->RecalcRects();
608 8366 : const_cast<SdrObjList*>(this)->bRectsDirty=false;
609 : }
610 67404 : return aSnapRect;
611 : }
612 :
613 62905 : const Rectangle& SdrObjList::GetAllObjBoundRect() const
614 : {
615 : // #i106183# for deep group hierarchies like in chart2, the invalidates
616 : // through the hierarchy are not correct; use a 2nd hint for the needed
617 : // recalculation. Future versions will have no bool flag at all, but
618 : // just aOutRect in empty state to represent an invalid state, thus
619 : // it's a step in the right direction.
620 62905 : if (bRectsDirty || aOutRect.IsEmpty())
621 : {
622 57292 : const_cast<SdrObjList*>(this)->RecalcRects();
623 57292 : const_cast<SdrObjList*>(this)->bRectsDirty=false;
624 : }
625 62905 : return aOutRect;
626 : }
627 :
628 4428 : void SdrObjList::NbcReformatAllTextObjects()
629 : {
630 4428 : size_t nCount=GetObjCount();
631 4428 : size_t nNum=0;
632 :
633 9244 : while (nNum<nCount)
634 : {
635 388 : SdrObject* pObj = GetObj(nNum);
636 :
637 388 : pObj->NbcReformatText();
638 388 : nCount=GetObjCount(); // ReformatText may delete an object
639 388 : nNum++;
640 : }
641 :
642 4428 : }
643 :
644 4412 : void SdrObjList::ReformatAllTextObjects()
645 : {
646 4412 : NbcReformatAllTextObjects();
647 4412 : }
648 :
649 : /** steps over all available objects and reformats all
650 : edge objects that are connected to other objects so that
651 : they may reposition themselves.
652 : */
653 3363 : void SdrObjList::ReformatAllEdgeObjects()
654 : {
655 : // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
656 3363 : SdrObjListIter aIter(*this, IM_DEEPNOGROUPS);
657 :
658 55973 : while(aIter.IsMore())
659 : {
660 49247 : SdrEdgeObj* pSdrEdgeObj = dynamic_cast< SdrEdgeObj* >(aIter.Next());
661 :
662 49247 : if(pSdrEdgeObj)
663 : {
664 3 : pSdrEdgeObj->Reformat();
665 : }
666 3363 : }
667 3363 : }
668 :
669 0 : void SdrObjList::BurnInStyleSheetAttributes()
670 : {
671 0 : for(size_t a = 0; a < GetObjCount(); ++a)
672 : {
673 0 : GetObj(a)->BurnInStyleSheetAttributes();
674 : }
675 0 : }
676 :
677 6185233 : size_t SdrObjList::GetObjCount() const
678 : {
679 6185233 : return maList.size();
680 : }
681 :
682 :
683 :
684 :
685 4771870 : SdrObject* SdrObjList::GetObj(size_t nNum) const
686 : {
687 4771870 : if (nNum >= maList.size())
688 : {
689 : OSL_ASSERT(nNum<maList.size());
690 0 : return NULL;
691 : }
692 : else
693 4771870 : return maList[nNum];
694 : }
695 :
696 :
697 :
698 :
699 4 : bool SdrObjList::IsReadOnly() const
700 : {
701 4 : bool bRet = false;
702 4 : if (pPage!=NULL && pPage!=this) bRet=pPage->IsReadOnly();
703 4 : return bRet;
704 : }
705 :
706 0 : size_t SdrObjList::CountAllObjects() const
707 : {
708 0 : const size_t nCount=GetObjCount();
709 0 : size_t nCnt=nCount;
710 0 : for (size_t nNum=0; nNum<nCount; nNum++) {
711 0 : SdrObjList* pSubOL=GetObj(nNum)->GetSubList();
712 0 : if (pSubOL!=NULL) {
713 0 : nCnt+=pSubOL->CountAllObjects();
714 : }
715 : }
716 0 : return nCnt;
717 : }
718 :
719 0 : void SdrObjList::FlattenGroups()
720 : {
721 0 : const size_t nObj = GetObjCount();
722 0 : for( size_t i = nObj; i>0; )
723 0 : UnGroupObj(--i);
724 0 : }
725 :
726 0 : void SdrObjList::UnGroupObj( size_t nObjNum )
727 : {
728 : // if the given object is no group, this method is a noop
729 0 : SdrObject* pUngroupObj = GetObj( nObjNum );
730 0 : if( pUngroupObj )
731 : {
732 0 : SdrObjList* pSrcLst = pUngroupObj->GetSubList();
733 0 : if( pUngroupObj->ISA( SdrObjGroup ) && pSrcLst )
734 : {
735 0 : SdrObjGroup* pUngroupGroup = static_cast< SdrObjGroup* > (pUngroupObj);
736 :
737 : // ungroup recursively (has to be head recursion,
738 : // otherwise our indices will get trashed when doing it in
739 : // the loop)
740 0 : pSrcLst->FlattenGroups();
741 :
742 : // the position at which we insert the members of rUngroupGroup
743 0 : size_t nInsertPos( pUngroupGroup->GetOrdNum() );
744 :
745 0 : const size_t nCount = pSrcLst->GetObjCount();
746 0 : for( size_t i=0; i<nCount; ++i )
747 : {
748 0 : SdrObject* pObj = pSrcLst->RemoveObject(0);
749 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL, pUngroupGroup);
750 0 : InsertObject(pObj, nInsertPos, &aReason);
751 0 : ++nInsertPos;
752 : }
753 :
754 0 : RemoveObject(nInsertPos);
755 : }
756 : }
757 : #ifdef DBG_UTIL
758 : else
759 : OSL_FAIL("SdrObjList::UnGroupObj: object index invalid");
760 : #endif
761 0 : }
762 :
763 :
764 :
765 :
766 237873 : bool SdrObjList::HasObjectNavigationOrder() const
767 : {
768 237873 : return mxNavigationOrder.get() != NULL;
769 : }
770 :
771 :
772 :
773 :
774 0 : void SdrObjList::SetObjectNavigationPosition (
775 : SdrObject& rObject,
776 : const sal_uInt32 nNewPosition)
777 : {
778 : // When the navigation order container has not yet been created then
779 : // create one now. It is initialized with the z-order taken from
780 : // maList.
781 0 : if (mxNavigationOrder.get() == NULL)
782 : {
783 0 : mxNavigationOrder.reset(new WeakSdrObjectContainerType(maList.size()));
784 : ::std::copy(
785 : maList.begin(),
786 : maList.end(),
787 0 : mxNavigationOrder->begin());
788 : }
789 : OSL_ASSERT(mxNavigationOrder.get()!=NULL);
790 : OSL_ASSERT( mxNavigationOrder->size() == maList.size());
791 :
792 0 : SdrObjectWeakRef aReference (&rObject);
793 :
794 : // Look up the object whose navigation position is to be changed.
795 : WeakSdrObjectContainerType::iterator iObject (::std::find(
796 0 : mxNavigationOrder->begin(),
797 0 : mxNavigationOrder->end(),
798 0 : aReference));
799 0 : if (iObject == mxNavigationOrder->end())
800 : {
801 : // The given object is not a member of the navigation order.
802 0 : return;
803 : }
804 :
805 : // Move the object to its new position.
806 0 : const sal_uInt32 nOldPosition = ::std::distance(mxNavigationOrder->begin(), iObject);
807 0 : if (nOldPosition != nNewPosition)
808 : {
809 0 : mxNavigationOrder->erase(iObject);
810 0 : sal_uInt32 nInsertPosition (nNewPosition);
811 : // Adapt insertion position for the just erased object.
812 0 : if (nNewPosition >= nOldPosition)
813 0 : nInsertPosition -= 1;
814 0 : if (nInsertPosition >= mxNavigationOrder->size())
815 0 : mxNavigationOrder->push_back(aReference);
816 : else
817 0 : mxNavigationOrder->insert(mxNavigationOrder->begin()+nInsertPosition, aReference);
818 :
819 0 : mbIsNavigationOrderDirty = true;
820 :
821 : // The navigation order is written out to file so mark the model as modified.
822 0 : if (pModel != NULL)
823 0 : pModel->SetChanged();
824 0 : }
825 : }
826 :
827 :
828 :
829 :
830 1 : SdrObject* SdrObjList::GetObjectForNavigationPosition (const sal_uInt32 nNavigationPosition) const
831 : {
832 1 : if (HasObjectNavigationOrder())
833 : {
834 : // There is a user defined navigation order. Make sure the object
835 : // index is correct and look up the object in mxNavigationOrder.
836 0 : if (nNavigationPosition >= mxNavigationOrder->size())
837 : {
838 : OSL_ASSERT(nNavigationPosition < mxNavigationOrder->size());
839 : }
840 : else
841 0 : return (*mxNavigationOrder)[nNavigationPosition].get();
842 : }
843 : else
844 : {
845 : // There is no user defined navigation order. Use the z-order
846 : // instead.
847 1 : if (nNavigationPosition >= maList.size())
848 : {
849 : OSL_ASSERT(nNavigationPosition < maList.size());
850 : }
851 : else
852 1 : return maList[nNavigationPosition];
853 : }
854 0 : return NULL;
855 : }
856 :
857 :
858 :
859 :
860 0 : void SdrObjList::ClearObjectNavigationOrder()
861 : {
862 0 : mxNavigationOrder.reset();
863 0 : mbIsNavigationOrderDirty = true;
864 0 : }
865 :
866 :
867 :
868 :
869 347 : bool SdrObjList::RecalcNavigationPositions()
870 : {
871 347 : if (mbIsNavigationOrderDirty)
872 : {
873 0 : if (mxNavigationOrder.get() != NULL)
874 : {
875 0 : mbIsNavigationOrderDirty = false;
876 :
877 0 : WeakSdrObjectContainerType::iterator iObject;
878 0 : WeakSdrObjectContainerType::const_iterator iEnd (mxNavigationOrder->end());
879 0 : sal_uInt32 nIndex (0);
880 0 : for (iObject=mxNavigationOrder->begin(); iObject!=iEnd; ++iObject,++nIndex)
881 0 : (*iObject)->SetNavigationPosition(nIndex);
882 : }
883 : }
884 :
885 347 : return mxNavigationOrder.get() != NULL;
886 : }
887 :
888 :
889 :
890 :
891 0 : void SdrObjList::SetNavigationOrder (const uno::Reference<container::XIndexAccess>& rxOrder)
892 : {
893 0 : if (rxOrder.is())
894 : {
895 0 : const sal_Int32 nCount = rxOrder->getCount();
896 0 : if ((sal_uInt32)nCount != maList.size())
897 0 : return;
898 :
899 0 : if (mxNavigationOrder.get() == NULL)
900 0 : mxNavigationOrder.reset(new WeakSdrObjectContainerType(nCount));
901 :
902 0 : for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
903 : {
904 0 : uno::Reference<uno::XInterface> xShape (rxOrder->getByIndex(nIndex), uno::UNO_QUERY);
905 0 : SdrObject* pObject = SdrObject::getSdrObjectFromXShape(xShape);
906 0 : if (pObject == NULL)
907 0 : break;
908 0 : (*mxNavigationOrder)[nIndex] = pObject;
909 0 : }
910 :
911 0 : mbIsNavigationOrderDirty = true;
912 : }
913 : else
914 0 : ClearObjectNavigationOrder();
915 : }
916 :
917 :
918 :
919 :
920 118944 : void SdrObjList::InsertObjectIntoContainer (
921 : SdrObject& rObject,
922 : const sal_uInt32 nInsertPosition)
923 : {
924 : OSL_ASSERT(nInsertPosition<=maList.size());
925 :
926 : // Update the navigation positions.
927 118944 : if (HasObjectNavigationOrder())
928 : {
929 : // The new object does not have a user defined position so append it
930 : // to the list.
931 0 : rObject.SetNavigationPosition(mxNavigationOrder->size());
932 0 : mxNavigationOrder->push_back(&rObject);
933 : }
934 :
935 : // Insert object into object list. Because the insert() method requires
936 : // a valid iterator as insertion position, we have to use push_back() to
937 : // insert at the end of the list.
938 118944 : if (nInsertPosition >= maList.size())
939 108910 : maList.push_back(&rObject);
940 : else
941 10034 : maList.insert(maList.begin()+nInsertPosition, &rObject);
942 118944 : bObjOrdNumsDirty=true;
943 118944 : }
944 :
945 :
946 :
947 :
948 1065 : void SdrObjList::ReplaceObjectInContainer (
949 : SdrObject& rNewObject,
950 : const sal_uInt32 nObjectPosition)
951 : {
952 1065 : if (nObjectPosition >= maList.size())
953 : {
954 : OSL_ASSERT(nObjectPosition<maList.size());
955 1065 : return;
956 : }
957 :
958 : // Update the navigation positions.
959 1065 : if (HasObjectNavigationOrder())
960 : {
961 : // A user defined position of the object that is to be replaced is
962 : // not transferred to the new object so erase the former and append
963 : // the later object from/to the navigation order.
964 : OSL_ASSERT(nObjectPosition < maList.size());
965 0 : SdrObjectWeakRef aReference (maList[nObjectPosition]);
966 : WeakSdrObjectContainerType::iterator iObject (::std::find(
967 0 : mxNavigationOrder->begin(),
968 0 : mxNavigationOrder->end(),
969 0 : aReference));
970 0 : if (iObject != mxNavigationOrder->end())
971 0 : mxNavigationOrder->erase(iObject);
972 :
973 0 : mxNavigationOrder->push_back(&rNewObject);
974 :
975 0 : mbIsNavigationOrderDirty = true;
976 : }
977 :
978 1065 : maList[nObjectPosition] = &rNewObject;
979 1065 : bObjOrdNumsDirty=true;
980 : }
981 :
982 :
983 :
984 :
985 117838 : void SdrObjList::RemoveObjectFromContainer (
986 : const sal_uInt32 nObjectPosition)
987 : {
988 117838 : if (nObjectPosition >= maList.size())
989 : {
990 : OSL_ASSERT(nObjectPosition<maList.size());
991 117838 : return;
992 : }
993 :
994 : // Update the navigation positions.
995 117838 : if (HasObjectNavigationOrder())
996 : {
997 0 : SdrObjectWeakRef aReference (maList[nObjectPosition]);
998 : WeakSdrObjectContainerType::iterator iObject (::std::find(
999 0 : mxNavigationOrder->begin(),
1000 0 : mxNavigationOrder->end(),
1001 0 : aReference));
1002 0 : if (iObject != mxNavigationOrder->end())
1003 0 : mxNavigationOrder->erase(iObject);
1004 0 : mbIsNavigationOrderDirty = true;
1005 : }
1006 :
1007 117838 : maList.erase(maList.begin()+nObjectPosition);
1008 117838 : bObjOrdNumsDirty=true;
1009 : }
1010 :
1011 0 : void SdrObjList::dumpAsXml(xmlTextWriterPtr pWriter) const
1012 : {
1013 0 : xmlTextWriterStartElement(pWriter, BAD_CAST("sdrObjList"));
1014 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1015 0 : xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
1016 :
1017 0 : size_t nObjCount = GetObjCount();
1018 0 : for (size_t i = 0; i < nObjCount; ++i)
1019 : {
1020 0 : if (const SdrObject* pObject = GetObj(i))
1021 0 : pObject->dumpAsXml(pWriter);
1022 : }
1023 :
1024 0 : xmlTextWriterEndElement(pWriter);
1025 0 : }
1026 :
1027 :
1028 :
1029 :
1030 :
1031 40 : void SdrPageGridFrameList::Clear()
1032 : {
1033 40 : sal_uInt16 nCount=GetCount();
1034 80 : for (sal_uInt16 i=0; i<nCount; i++) {
1035 40 : delete GetObject(i);
1036 : }
1037 40 : aList.clear();
1038 40 : }
1039 :
1040 :
1041 : // PageUser section
1042 :
1043 3649 : void SdrPage::AddPageUser(sdr::PageUser& rNewUser)
1044 : {
1045 3649 : maPageUsers.push_back(&rNewUser);
1046 3649 : }
1047 :
1048 3627 : void SdrPage::RemovePageUser(sdr::PageUser& rOldUser)
1049 : {
1050 3627 : const sdr::PageUserVector::iterator aFindResult = ::std::find(maPageUsers.begin(), maPageUsers.end(), &rOldUser);
1051 3627 : if(aFindResult != maPageUsers.end())
1052 : {
1053 3627 : maPageUsers.erase(aFindResult);
1054 : }
1055 3627 : }
1056 :
1057 :
1058 : // DrawContact section
1059 :
1060 6396 : sdr::contact::ViewContact* SdrPage::CreateObjectSpecificViewContact()
1061 : {
1062 6396 : return new sdr::contact::ViewContactOfSdrPage(*this);
1063 : }
1064 :
1065 188261 : sdr::contact::ViewContact& SdrPage::GetViewContact() const
1066 : {
1067 188261 : if(!mpViewContact)
1068 : {
1069 : const_cast< SdrPage* >(this)->mpViewContact =
1070 6396 : const_cast< SdrPage* >(this)->CreateObjectSpecificViewContact();
1071 : }
1072 :
1073 188261 : return *mpViewContact;
1074 : }
1075 :
1076 :
1077 :
1078 6795 : void SdrPageProperties::ImpRemoveStyleSheet()
1079 : {
1080 6795 : if(mpStyleSheet)
1081 : {
1082 262 : EndListening(*mpStyleSheet);
1083 262 : mpProperties->SetParent(0);
1084 262 : mpStyleSheet = 0;
1085 : }
1086 6795 : }
1087 :
1088 1154 : void SdrPageProperties::ImpAddStyleSheet(SfxStyleSheet& rNewStyleSheet)
1089 : {
1090 1154 : if(mpStyleSheet != &rNewStyleSheet)
1091 : {
1092 267 : ImpRemoveStyleSheet();
1093 267 : mpStyleSheet = &rNewStyleSheet;
1094 267 : StartListening(rNewStyleSheet);
1095 267 : mpProperties->SetParent(&rNewStyleSheet.GetItemSet());
1096 : }
1097 1154 : }
1098 :
1099 3090 : void ImpPageChange(SdrPage& rSdrPage)
1100 : {
1101 3090 : rSdrPage.ActionChanged();
1102 :
1103 3090 : if(rSdrPage.GetModel())
1104 : {
1105 3090 : rSdrPage.GetModel()->SetChanged(true);
1106 3090 : SdrHint aHint(HINT_PAGEORDERCHG);
1107 3090 : aHint.SetPage(&rSdrPage);
1108 3090 : rSdrPage.GetModel()->Broadcast(aHint);
1109 : }
1110 3090 : }
1111 :
1112 6602 : SdrPageProperties::SdrPageProperties(SdrPage& rSdrPage)
1113 : : SfxListener(),
1114 : mpSdrPage(&rSdrPage),
1115 : mpStyleSheet(0),
1116 6602 : mpProperties(new SfxItemSet(mpSdrPage->GetModel()->GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST))
1117 : {
1118 6602 : if(!rSdrPage.IsMasterPage())
1119 : {
1120 5816 : mpProperties->Put(XFillStyleItem(drawing::FillStyle_NONE));
1121 : }
1122 6602 : }
1123 :
1124 19581 : SdrPageProperties::~SdrPageProperties()
1125 : {
1126 6527 : ImpRemoveStyleSheet();
1127 6527 : delete mpProperties;
1128 13054 : }
1129 :
1130 461 : void SdrPageProperties::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
1131 : {
1132 461 : const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint* >(&rHint);
1133 :
1134 461 : if(pSimpleHint)
1135 : {
1136 461 : switch(pSimpleHint->GetId())
1137 : {
1138 : case SFX_HINT_DATACHANGED :
1139 : {
1140 : // notify change, broadcast
1141 461 : ImpPageChange(*mpSdrPage);
1142 461 : break;
1143 : }
1144 : case SFX_HINT_DYING :
1145 : {
1146 : // Style needs to be forgotten
1147 0 : ImpRemoveStyleSheet();
1148 0 : break;
1149 : }
1150 : }
1151 : }
1152 461 : }
1153 :
1154 0 : bool SdrPageProperties::isUsedByModel() const
1155 : {
1156 : assert(mpSdrPage);
1157 0 : return mpSdrPage->IsInserted();
1158 : }
1159 :
1160 :
1161 126 : void SdrPageProperties::PutItemSet(const SfxItemSet& rSet)
1162 : {
1163 : OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1164 126 : mpProperties->Put(rSet);
1165 126 : ImpPageChange(*mpSdrPage);
1166 126 : }
1167 :
1168 68 : void SdrPageProperties::PutItem(const SfxPoolItem& rItem)
1169 : {
1170 : OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1171 68 : mpProperties->Put(rItem);
1172 68 : ImpPageChange(*mpSdrPage);
1173 68 : }
1174 :
1175 1280 : void SdrPageProperties::ClearItem(const sal_uInt16 nWhich)
1176 : {
1177 1280 : mpProperties->ClearItem(nWhich);
1178 1280 : ImpPageChange(*mpSdrPage);
1179 1280 : }
1180 :
1181 1155 : void SdrPageProperties::SetStyleSheet(SfxStyleSheet* pStyleSheet)
1182 : {
1183 1155 : if(pStyleSheet)
1184 : {
1185 1154 : ImpAddStyleSheet(*pStyleSheet);
1186 : }
1187 : else
1188 : {
1189 1 : ImpRemoveStyleSheet();
1190 : }
1191 :
1192 1155 : ImpPageChange(*mpSdrPage);
1193 1155 : }
1194 :
1195 :
1196 :
1197 :
1198 349417 : TYPEINIT1(SdrPage,SdrObjList);
1199 6601 : SdrPage::SdrPage(SdrModel& rNewModel, bool bMasterPage)
1200 : : SdrObjList(&rNewModel, this),
1201 : mpViewContact(0L),
1202 : nWdt(10L),
1203 : nHgt(10L),
1204 : nBordLft(0L),
1205 : nBordUpp(0L),
1206 : nBordRgt(0L),
1207 : nBordLwr(0L),
1208 6601 : pLayerAdmin(new SdrLayerAdmin(&rNewModel.GetLayerAdmin())),
1209 : mpSdrPageProperties(0),
1210 : mpMasterPageDescriptor(0L),
1211 : nPageNum(0L),
1212 : mbMaster(bMasterPage),
1213 : mbInserted(false),
1214 : mbObjectsNotPersistent(false),
1215 13202 : mbPageBorderOnlyLeftRight(false)
1216 : {
1217 6601 : aPrefVisiLayers.SetAll();
1218 6601 : eListKind = (bMasterPage) ? SDROBJLIST_MASTERPAGE : SDROBJLIST_DRAWPAGE;
1219 :
1220 6601 : mpSdrPageProperties = new SdrPageProperties(*this);
1221 6601 : }
1222 :
1223 1 : SdrPage::SdrPage(const SdrPage& rSrcPage)
1224 : : SdrObjList(rSrcPage.pModel, this),
1225 : tools::WeakBase< SdrPage >(),
1226 : mpViewContact(0L),
1227 : nWdt(rSrcPage.nWdt),
1228 : nHgt(rSrcPage.nHgt),
1229 : nBordLft(rSrcPage.nBordLft),
1230 : nBordUpp(rSrcPage.nBordUpp),
1231 : nBordRgt(rSrcPage.nBordRgt),
1232 : nBordLwr(rSrcPage.nBordLwr),
1233 2 : pLayerAdmin(new SdrLayerAdmin(rSrcPage.pModel->GetLayerAdmin())),
1234 : mpSdrPageProperties(0),
1235 : mpMasterPageDescriptor(0L),
1236 : nPageNum(rSrcPage.nPageNum),
1237 : mbMaster(rSrcPage.mbMaster),
1238 : mbInserted(false),
1239 : mbObjectsNotPersistent(rSrcPage.mbObjectsNotPersistent),
1240 3 : mbPageBorderOnlyLeftRight(rSrcPage.mbPageBorderOnlyLeftRight)
1241 : {
1242 1 : aPrefVisiLayers.SetAll();
1243 1 : }
1244 :
1245 13359 : SdrPage::~SdrPage()
1246 : {
1247 6527 : if( mxUnoPage.is() ) try
1248 : {
1249 3737 : uno::Reference< lang::XComponent > xPageComponent( mxUnoPage, uno::UNO_QUERY_THROW );
1250 3737 : mxUnoPage.clear();
1251 3737 : xPageComponent->dispose();
1252 : }
1253 0 : catch( const uno::Exception& )
1254 : {
1255 : DBG_UNHANDLED_EXCEPTION();
1256 : }
1257 :
1258 : // tell all the registered PageUsers that the page is in destruction
1259 : // This causes some (all?) PageUsers to remove themselves from the list
1260 : // of page users. Therefore we have to use a copy of the list for the
1261 : // iteration.
1262 6527 : sdr::PageUserVector aListCopy (maPageUsers.begin(), maPageUsers.end());
1263 6528 : for(sdr::PageUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); ++aIterator)
1264 : {
1265 1 : sdr::PageUser* pPageUser = *aIterator;
1266 : DBG_ASSERT(pPageUser, "SdrPage::~SdrPage: corrupt PageUser list (!)");
1267 1 : pPageUser->PageInDestruction(*this);
1268 : }
1269 :
1270 : // Clear the vector. This means that user do not need to call RemovePageUser()
1271 : // when they get called from PageInDestruction().
1272 6527 : maPageUsers.clear();
1273 :
1274 6527 : delete pLayerAdmin;
1275 :
1276 6527 : TRG_ClearMasterPage();
1277 :
1278 6527 : if(mpViewContact)
1279 : {
1280 6324 : delete mpViewContact;
1281 6324 : mpViewContact = 0L;
1282 : }
1283 :
1284 : {
1285 6527 : delete mpSdrPageProperties;
1286 6527 : mpSdrPageProperties = 0;
1287 6527 : }
1288 :
1289 6832 : }
1290 :
1291 1 : void SdrPage::lateInit(const SdrPage& rSrcPage, SdrModel* const pNewModel)
1292 : {
1293 : assert(!mpViewContact);
1294 : assert(!mpSdrPageProperties);
1295 : assert(!mxUnoPage.is());
1296 :
1297 1 : if (pNewModel && (pNewModel != pModel))
1298 : {
1299 0 : pModel = pNewModel;
1300 0 : impl_setModelForLayerAdmin(pNewModel);
1301 : }
1302 :
1303 : // copy all the local parameters to make this instance
1304 : // a valid copy of source page before copying and inserting
1305 : // the contained objects
1306 1 : mbMaster = rSrcPage.mbMaster;
1307 1 : mbPageBorderOnlyLeftRight = rSrcPage.mbPageBorderOnlyLeftRight;
1308 1 : aPrefVisiLayers = rSrcPage.aPrefVisiLayers;
1309 1 : nWdt = rSrcPage.nWdt;
1310 1 : nHgt = rSrcPage.nHgt;
1311 1 : nBordLft = rSrcPage.nBordLft;
1312 1 : nBordUpp = rSrcPage.nBordUpp;
1313 1 : nBordRgt = rSrcPage.nBordRgt;
1314 1 : nBordLwr = rSrcPage.nBordLwr;
1315 1 : nPageNum = rSrcPage.nPageNum;
1316 :
1317 1 : if(rSrcPage.TRG_HasMasterPage())
1318 : {
1319 0 : TRG_SetMasterPage(rSrcPage.TRG_GetMasterPage());
1320 0 : TRG_SetMasterPageVisibleLayers(rSrcPage.TRG_GetMasterPageVisibleLayers());
1321 : }
1322 : else
1323 : {
1324 1 : TRG_ClearMasterPage();
1325 : }
1326 :
1327 1 : mbObjectsNotPersistent = rSrcPage.mbObjectsNotPersistent;
1328 :
1329 : {
1330 1 : mpSdrPageProperties = new SdrPageProperties(*this);
1331 :
1332 1 : if(!IsMasterPage())
1333 : {
1334 0 : mpSdrPageProperties->PutItemSet(rSrcPage.getSdrPageProperties().GetItemSet());
1335 : }
1336 :
1337 1 : mpSdrPageProperties->SetStyleSheet(rSrcPage.getSdrPageProperties().GetStyleSheet());
1338 : }
1339 :
1340 : // Now copy the contained objects
1341 1 : SdrObjList::lateInit(rSrcPage);
1342 :
1343 : // be careful and correct eListKind, a member of SdrObjList which
1344 : // will be changed by the SdrObjList::lateInit before...
1345 1 : eListKind = (mbMaster) ? SDROBJLIST_MASTERPAGE : SDROBJLIST_DRAWPAGE;
1346 1 : }
1347 :
1348 0 : SdrPage* SdrPage::Clone() const
1349 : {
1350 0 : return Clone(NULL);
1351 : }
1352 :
1353 0 : SdrPage* SdrPage::Clone(SdrModel* pNewModel) const
1354 : {
1355 0 : if (pNewModel==NULL) pNewModel=pModel;
1356 0 : SdrPage* pPage2=new SdrPage(*pNewModel);
1357 0 : pPage2->lateInit(*this);
1358 0 : return pPage2;
1359 : }
1360 :
1361 14188 : void SdrPage::SetSize(const Size& aSiz)
1362 : {
1363 14188 : bool bChanged(false);
1364 :
1365 14188 : if(aSiz.Width() != nWdt)
1366 : {
1367 12214 : nWdt = aSiz.Width();
1368 12214 : bChanged = true;
1369 : }
1370 :
1371 14188 : if(aSiz.Height() != nHgt)
1372 : {
1373 11646 : nHgt = aSiz.Height();
1374 11646 : bChanged = true;
1375 : }
1376 :
1377 14188 : if(bChanged)
1378 : {
1379 13172 : SetChanged();
1380 : }
1381 14188 : }
1382 :
1383 21898 : Size SdrPage::GetSize() const
1384 : {
1385 21898 : return Size(nWdt,nHgt);
1386 : }
1387 :
1388 32423 : sal_Int32 SdrPage::GetWdt() const
1389 : {
1390 32423 : return nWdt;
1391 : }
1392 :
1393 0 : void SdrPage::SetOrientation(Orientation eOri)
1394 : {
1395 : // square: handle like portrait format
1396 0 : Size aSiz(GetSize());
1397 0 : if (aSiz.Width()!=aSiz.Height()) {
1398 0 : if ((eOri==ORIENTATION_PORTRAIT) == (aSiz.Width()>aSiz.Height())) {
1399 0 : SetSize(Size(aSiz.Height(),aSiz.Width()));
1400 : }
1401 : }
1402 0 : }
1403 :
1404 0 : Orientation SdrPage::GetOrientation() const
1405 : {
1406 : // square: handle like portrait format
1407 0 : Orientation eRet=ORIENTATION_PORTRAIT;
1408 0 : Size aSiz(GetSize());
1409 0 : if (aSiz.Width()>aSiz.Height()) eRet=ORIENTATION_LANDSCAPE;
1410 0 : return eRet;
1411 : }
1412 :
1413 32423 : sal_Int32 SdrPage::GetHgt() const
1414 : {
1415 32423 : return nHgt;
1416 : }
1417 :
1418 198 : void SdrPage::SetBorder(sal_Int32 nLft, sal_Int32 nUpp, sal_Int32 nRgt, sal_Int32 nLwr)
1419 : {
1420 198 : bool bChanged(false);
1421 :
1422 198 : if(nBordLft != nLft)
1423 : {
1424 198 : nBordLft = nLft;
1425 198 : bChanged = true;
1426 : }
1427 :
1428 198 : if(nBordUpp != nUpp)
1429 : {
1430 198 : nBordUpp = nUpp;
1431 198 : bChanged = true;
1432 : }
1433 :
1434 198 : if(nBordRgt != nRgt)
1435 : {
1436 195 : nBordRgt = nRgt;
1437 195 : bChanged = true;
1438 : }
1439 :
1440 198 : if(nBordLwr != nLwr)
1441 : {
1442 195 : nBordLwr = nLwr;
1443 195 : bChanged = true;
1444 : }
1445 :
1446 198 : if(bChanged)
1447 : {
1448 198 : SetChanged();
1449 : }
1450 198 : }
1451 :
1452 102 : void SdrPage::SetLftBorder(sal_Int32 nBorder)
1453 : {
1454 102 : if(nBordLft != nBorder)
1455 : {
1456 102 : nBordLft = nBorder;
1457 102 : SetChanged();
1458 : }
1459 102 : }
1460 :
1461 102 : void SdrPage::SetUppBorder(sal_Int32 nBorder)
1462 : {
1463 102 : if(nBordUpp != nBorder)
1464 : {
1465 102 : nBordUpp = nBorder;
1466 102 : SetChanged();
1467 : }
1468 102 : }
1469 :
1470 102 : void SdrPage::SetRgtBorder(sal_Int32 nBorder)
1471 : {
1472 102 : if(nBordRgt != nBorder)
1473 : {
1474 102 : nBordRgt=nBorder;
1475 102 : SetChanged();
1476 : }
1477 102 : }
1478 :
1479 102 : void SdrPage::SetLwrBorder(sal_Int32 nBorder)
1480 : {
1481 102 : if(nBordLwr != nBorder)
1482 : {
1483 102 : nBordLwr=nBorder;
1484 102 : SetChanged();
1485 : }
1486 102 : }
1487 :
1488 23477 : sal_Int32 SdrPage::GetLftBorder() const
1489 : {
1490 23477 : return nBordLft;
1491 : }
1492 :
1493 22485 : sal_Int32 SdrPage::GetUppBorder() const
1494 : {
1495 22485 : return nBordUpp;
1496 : }
1497 :
1498 12873 : sal_Int32 SdrPage::GetRgtBorder() const
1499 : {
1500 12873 : return nBordRgt;
1501 : }
1502 :
1503 12873 : sal_Int32 SdrPage::GetLwrBorder() const
1504 : {
1505 12873 : return nBordLwr;
1506 : }
1507 :
1508 0 : void SdrPage::impl_setModelForLayerAdmin(SdrModel* const pNewModel)
1509 : {
1510 0 : if (pNewModel!=NULL) {
1511 0 : pLayerAdmin->SetParent(&pNewModel->GetLayerAdmin());
1512 : } else {
1513 0 : pLayerAdmin->SetParent(NULL);
1514 : }
1515 0 : pLayerAdmin->SetModel(pNewModel);
1516 0 : }
1517 :
1518 6603 : void SdrPage::SetModel(SdrModel* pNewModel)
1519 : {
1520 6603 : SdrModel* pOldModel=pModel;
1521 6603 : SdrObjList::SetModel(pNewModel);
1522 :
1523 6603 : if (pNewModel!=pOldModel)
1524 : {
1525 0 : impl_setModelForLayerAdmin( pNewModel );
1526 :
1527 : // create new SdrPageProperties with new model (due to SfxItemSet there)
1528 : // and copy ItemSet and StyleSheet
1529 0 : SdrPageProperties *pNew = new SdrPageProperties(*this);
1530 :
1531 0 : if(!IsMasterPage())
1532 : {
1533 0 : pNew->PutItemSet(getSdrPageProperties().GetItemSet());
1534 : }
1535 :
1536 0 : pNew->SetStyleSheet(getSdrPageProperties().GetStyleSheet());
1537 :
1538 0 : delete mpSdrPageProperties;
1539 0 : mpSdrPageProperties = pNew;
1540 : }
1541 :
1542 : // update listeners at possible API wrapper object
1543 6603 : if( pOldModel != pNewModel )
1544 : {
1545 0 : if( mxUnoPage.is() )
1546 : {
1547 0 : SvxDrawPage* pPage2 = SvxDrawPage::getImplementation( mxUnoPage );
1548 0 : if( pPage2 )
1549 0 : pPage2->ChangeModel( pNewModel );
1550 : }
1551 : }
1552 6603 : }
1553 :
1554 :
1555 :
1556 : // #i68775# React on PageNum changes (from Model in most cases)
1557 7727 : void SdrPage::SetPageNum(sal_uInt16 nNew)
1558 : {
1559 7727 : if(nNew != nPageNum)
1560 : {
1561 : // change
1562 2282 : nPageNum = nNew;
1563 :
1564 : // notify visualisations, also notifies e.g. buffered MasterPages
1565 2282 : ActionChanged();
1566 : }
1567 7727 : }
1568 :
1569 10962 : sal_uInt16 SdrPage::GetPageNum() const
1570 : {
1571 10962 : if (!mbInserted)
1572 782 : return 0;
1573 :
1574 10180 : if (mbMaster) {
1575 1002 : if (pModel && pModel->IsMPgNumsDirty())
1576 5 : pModel->RecalcPageNums(true);
1577 : } else {
1578 9178 : if (pModel && pModel->IsPagNumsDirty())
1579 346 : pModel->RecalcPageNums(false);
1580 : }
1581 10180 : return nPageNum;
1582 : }
1583 :
1584 16275 : void SdrPage::SetChanged()
1585 : {
1586 : // For test purposes, use the new ViewContact for change
1587 : // notification now.
1588 16275 : ActionChanged();
1589 :
1590 16275 : if( pModel )
1591 : {
1592 16275 : pModel->SetChanged();
1593 : }
1594 16275 : }
1595 :
1596 :
1597 : // MasterPage interface
1598 :
1599 2077 : void SdrPage::TRG_SetMasterPage(SdrPage& rNew)
1600 : {
1601 2077 : if(mpMasterPageDescriptor && &(mpMasterPageDescriptor->GetUsedPage()) == &rNew)
1602 2146 : return;
1603 :
1604 2008 : if(mpMasterPageDescriptor)
1605 0 : TRG_ClearMasterPage();
1606 :
1607 2008 : mpMasterPageDescriptor = new sdr::MasterPageDescriptor(*this, rNew);
1608 2008 : GetViewContact().ActionChanged();
1609 : }
1610 :
1611 6964 : void SdrPage::TRG_ClearMasterPage()
1612 : {
1613 6964 : if(mpMasterPageDescriptor)
1614 : {
1615 1993 : SetChanged();
1616 :
1617 : // the flushViewObjectContacts() will do needed invalidates by deleting the involved VOCs
1618 1993 : mpMasterPageDescriptor->GetUsedPage().GetViewContact().flushViewObjectContacts(true);
1619 :
1620 1993 : delete mpMasterPageDescriptor;
1621 1993 : mpMasterPageDescriptor = 0L;
1622 : }
1623 6964 : }
1624 :
1625 9874 : SdrPage& SdrPage::TRG_GetMasterPage() const
1626 : {
1627 : DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPage(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1628 9874 : return mpMasterPageDescriptor->GetUsedPage();
1629 : }
1630 :
1631 1265 : const SetOfByte& SdrPage::TRG_GetMasterPageVisibleLayers() const
1632 : {
1633 : DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1634 1265 : return mpMasterPageDescriptor->GetVisibleLayers();
1635 : }
1636 :
1637 515 : void SdrPage::TRG_SetMasterPageVisibleLayers(const SetOfByte& rNew)
1638 : {
1639 : DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_SetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1640 515 : mpMasterPageDescriptor->SetVisibleLayers(rNew);
1641 515 : }
1642 :
1643 12345 : sdr::contact::ViewContact& SdrPage::TRG_GetMasterPageDescriptorViewContact() const
1644 : {
1645 : DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPageDescriptorViewContact(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1646 12345 : return mpMasterPageDescriptor->GetViewContact();
1647 : }
1648 :
1649 : // used from SdrModel::RemoveMasterPage
1650 6 : void SdrPage::TRG_ImpMasterPageRemoved(const SdrPage& rRemovedPage)
1651 : {
1652 6 : if(TRG_HasMasterPage())
1653 : {
1654 6 : if(&TRG_GetMasterPage() == &rRemovedPage)
1655 : {
1656 0 : TRG_ClearMasterPage();
1657 : }
1658 : }
1659 6 : }
1660 :
1661 0 : const SdrPageGridFrameList* SdrPage::GetGridFrameList(const SdrPageView* /*pPV*/, const Rectangle* /*pRect*/) const
1662 : {
1663 0 : return NULL;
1664 : }
1665 :
1666 0 : OUString SdrPage::GetLayoutName() const
1667 : {
1668 0 : return OUString();
1669 : }
1670 :
1671 13131 : void SdrPage::SetInserted( bool bIns )
1672 : {
1673 13131 : if( (bool) mbInserted != bIns )
1674 : {
1675 13131 : mbInserted = bIns;
1676 :
1677 : // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
1678 13131 : SdrObjListIter aIter(*this, IM_DEEPNOGROUPS);
1679 :
1680 42675 : while ( aIter.IsMore() )
1681 : {
1682 16413 : SdrObject* pObj = aIter.Next();
1683 16413 : if ( pObj->ISA(SdrOle2Obj) )
1684 : {
1685 185 : if( mbInserted )
1686 0 : static_cast<SdrOle2Obj*>(pObj)->Connect();
1687 : else
1688 185 : static_cast<SdrOle2Obj*>(pObj)->Disconnect();
1689 : }
1690 13131 : }
1691 : }
1692 13131 : }
1693 :
1694 0 : void SdrPage::SetUnoPage(uno::Reference<drawing::XDrawPage> const& xNewPage)
1695 : {
1696 0 : mxUnoPage = xNewPage;
1697 0 : }
1698 :
1699 144038 : uno::Reference< uno::XInterface > SdrPage::getUnoPage()
1700 : {
1701 144038 : if( !mxUnoPage.is() )
1702 : {
1703 : // create one
1704 3778 : mxUnoPage = createUnoPage();
1705 : }
1706 :
1707 144038 : return mxUnoPage;
1708 : }
1709 :
1710 321 : uno::Reference< uno::XInterface > SdrPage::createUnoPage()
1711 : {
1712 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInt =
1713 321 : static_cast<cppu::OWeakObject*>( new SvxFmDrawPage( this ) );
1714 321 : return xInt;
1715 : }
1716 :
1717 24543 : SfxStyleSheet* SdrPage::GetTextStyleSheetForObject( SdrObject* pObj ) const
1718 : {
1719 24543 : return pObj->GetStyleSheet();
1720 : }
1721 :
1722 : /** returns an averaged background color of this page */
1723 : // #i75566# GetBackgroundColor -> GetPageBackgroundColor and bScreenDisplay hint value
1724 1890 : Color SdrPage::GetPageBackgroundColor( SdrPageView* pView, bool bScreenDisplay ) const
1725 : {
1726 1890 : Color aColor;
1727 :
1728 1890 : if(bScreenDisplay && (!pView || pView->GetApplicationDocumentColor() == COL_AUTO))
1729 : {
1730 1745 : svtools::ColorConfig aColorConfig;
1731 1745 : aColor = aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor;
1732 : }
1733 : else
1734 : {
1735 145 : aColor = pView->GetApplicationDocumentColor();
1736 : }
1737 :
1738 1890 : const SfxItemSet* pBackgroundFill = &getSdrPageProperties().GetItemSet();
1739 :
1740 1890 : if(!IsMasterPage() && TRG_HasMasterPage())
1741 : {
1742 1763 : if(drawing::FillStyle_NONE == static_cast<const XFillStyleItem&>(pBackgroundFill->Get(XATTR_FILLSTYLE)).GetValue())
1743 : {
1744 1763 : pBackgroundFill = &TRG_GetMasterPage().getSdrPageProperties().GetItemSet();
1745 : }
1746 : }
1747 :
1748 1890 : GetDraftFillColor(*pBackgroundFill, aColor);
1749 :
1750 1890 : return aColor;
1751 : }
1752 :
1753 : /** *deprecated, use GetBackgroundColor with SdrPageView */
1754 194 : Color SdrPage::GetPageBackgroundColor() const
1755 : // #i75566# GetBackgroundColor -> GetPageBackgroundColor
1756 : {
1757 194 : return GetPageBackgroundColor( NULL, true );
1758 : }
1759 :
1760 : /** this method returns true if the object from the ViewObjectContact should
1761 : be visible on this page while rendering.
1762 : bEdit selects if visibility test is for an editing view or a final render,
1763 : like printing.
1764 : */
1765 2828 : bool SdrPage::checkVisibility(
1766 : const sdr::contact::ViewObjectContact& /*rOriginal*/,
1767 : const sdr::contact::DisplayInfo& /*rDisplayInfo*/,
1768 : bool /*bEdit*/)
1769 : {
1770 : // this will be handled in the application if needed
1771 2828 : return true;
1772 : }
1773 :
1774 : // DrawContact support: Methods for handling Page changes
1775 23722 : void SdrPage::ActionChanged() const
1776 : {
1777 : // Do necessary ViewContact actions
1778 23722 : GetViewContact().ActionChanged();
1779 :
1780 : // #i48535# also handle MasterPage change
1781 23722 : if(TRG_HasMasterPage())
1782 : {
1783 3848 : TRG_GetMasterPageDescriptorViewContact().ActionChanged();
1784 : }
1785 23722 : }
1786 :
1787 : // sdr::Comment interface
1788 :
1789 0 : const SdrPageProperties* SdrPage::getCorrectSdrPageProperties() const
1790 : {
1791 0 : if(mpMasterPageDescriptor)
1792 : {
1793 0 : return mpMasterPageDescriptor->getCorrectSdrPageProperties();
1794 : }
1795 : else
1796 : {
1797 0 : return &getSdrPageProperties();
1798 : }
1799 : }
1800 :
1801 :
1802 : // use new redirector instead of pPaintProc
1803 :
1804 0 : StandardCheckVisisbilityRedirector::StandardCheckVisisbilityRedirector()
1805 0 : : ViewObjectContactRedirector()
1806 : {
1807 0 : }
1808 :
1809 0 : StandardCheckVisisbilityRedirector::~StandardCheckVisisbilityRedirector()
1810 : {
1811 0 : }
1812 :
1813 0 : drawinglayer::primitive2d::Primitive2DSequence StandardCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence(
1814 : const sdr::contact::ViewObjectContact& rOriginal,
1815 : const sdr::contact::DisplayInfo& rDisplayInfo)
1816 : {
1817 0 : SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
1818 :
1819 0 : if(pObject)
1820 : {
1821 0 : if(pObject->GetPage())
1822 : {
1823 0 : if(pObject->GetPage()->checkVisibility(rOriginal, rDisplayInfo, false))
1824 : {
1825 0 : return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1826 : }
1827 : }
1828 :
1829 0 : return drawinglayer::primitive2d::Primitive2DSequence();
1830 : }
1831 : else
1832 : {
1833 : // not an object, maybe a page
1834 0 : return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1835 : }
1836 435 : }
1837 :
1838 :
1839 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|